db: prefer local repositories, and implement --no-network
this helps boots sequence when network is not available.cute-signatures
parent
ced1fa83d6
commit
f02f326238
|
@ -55,7 +55,8 @@ static struct apk_option generic_options[] = {
|
|||
{ 0x107, "keys-dir", "Override directory of trusted keys",
|
||||
required_argument, "KEYSDIR" },
|
||||
{ 0x108, "repositories-file", "Override repositories file",
|
||||
required_argument, "REPOFILE" }
|
||||
required_argument, "REPOFILE" },
|
||||
{ 0x109, "no-network", "Do not use network (cache is still used)" },
|
||||
};
|
||||
|
||||
const char *apk_error_str(int error)
|
||||
|
@ -380,6 +381,9 @@ int main(int argc, char **argv)
|
|||
case 0x105:
|
||||
apk_wait = atoi(optarg);
|
||||
break;
|
||||
case 0x109:
|
||||
apk_flags |= APK_NO_NETWORK;
|
||||
break;
|
||||
default:
|
||||
if (applet == NULL || applet->parse == NULL ||
|
||||
applet->parse(ctx, &dbopts, r,
|
||||
|
|
|
@ -98,6 +98,7 @@ struct apk_database {
|
|||
unsigned name_id, num_repos;
|
||||
const char *cache_dir;
|
||||
int permanent;
|
||||
unsigned int local_repos;
|
||||
|
||||
struct apk_dependency_array *world;
|
||||
struct apk_string_array *protected_paths;
|
||||
|
@ -159,6 +160,8 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo);
|
|||
int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
|
||||
|
||||
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
|
||||
struct apk_repository *apk_db_select_repo(struct apk_database *db,
|
||||
struct apk_package *pkg);
|
||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
|
||||
|
||||
int apk_db_cache_active(struct apk_database *db);
|
||||
|
|
|
@ -63,6 +63,7 @@ extern unsigned int apk_flags;
|
|||
#define APK_PURGE 0x0200
|
||||
#define APK_INTERACTIVE 0x0400
|
||||
#define APK_RECURSIVE_DELETE 0x0800
|
||||
#define APK_NO_NETWORK 0x1000
|
||||
|
||||
#define apk_error(args...) do { apk_log("ERROR: ", args); } while (0)
|
||||
#define apk_warning(args...) do { if (apk_verbosity > 0) { apk_log("WARNING: ", args); } } while (0)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation. See http://www.gnu.org/ for details.
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@ struct apk_change {
|
|||
|
||||
struct apk_state {
|
||||
unsigned int refs, num_names;
|
||||
struct apk_database *db;
|
||||
struct list_head change_list_head;
|
||||
apk_name_state_t name[];
|
||||
};
|
||||
|
|
17
src/cache.c
17
src/cache.c
|
@ -28,6 +28,7 @@ static int cache_download(struct apk_database *db)
|
|||
struct apk_state *state;
|
||||
struct apk_change *change;
|
||||
struct apk_package *pkg;
|
||||
struct apk_repository *repo;
|
||||
char item[PATH_MAX], cacheitem[PATH_MAX];
|
||||
int i, r = 0;
|
||||
|
||||
|
@ -54,17 +55,13 @@ static int cache_download(struct apk_database *db)
|
|||
if (faccessat(db->cache_fd, cacheitem, R_OK, 0) == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < db->num_repos; i++) {
|
||||
if (!(pkg->repos & BIT(i)))
|
||||
continue;
|
||||
repo = apk_db_select_repo(db, pkg);
|
||||
if (repo == NULL)
|
||||
continue;
|
||||
|
||||
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
|
||||
r = apk_cache_download(db, db->repos[i].url,
|
||||
item, cacheitem,
|
||||
APK_SIGN_VERIFY_IDENTITY);
|
||||
if (r != 0)
|
||||
return r;
|
||||
}
|
||||
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
|
||||
apk_cache_download(db, repo->url, item, cacheitem,
|
||||
APK_SIGN_VERIFY_IDENTITY);
|
||||
}
|
||||
|
||||
err:
|
||||
|
|
|
@ -1156,6 +1156,37 @@ static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
|
|||
return apk_bstream_from_url(tmp);
|
||||
}
|
||||
|
||||
struct apk_repository *apk_db_select_repo(struct apk_database *db,
|
||||
struct apk_package *pkg)
|
||||
{
|
||||
unsigned int repos = pkg->repos;
|
||||
int i;
|
||||
|
||||
/* Always prefer local repositories */
|
||||
if ((repos & db->local_repos) != 0)
|
||||
repos &= db->local_repos;
|
||||
|
||||
/* Pick first repository providing this package */
|
||||
for (i = 0; i < APK_MAX_REPOS; i++)
|
||||
if (repos & BIT(i))
|
||||
break;
|
||||
|
||||
if (i >= APK_MAX_REPOS)
|
||||
return NULL;
|
||||
|
||||
/* If this is a remote repository, and we have no network,
|
||||
* check that we have it in cache */
|
||||
if ((db->local_repos & BIT(i)) == 0 && (apk_flags & APK_NO_NETWORK)) {
|
||||
char cacheitem[PATH_MAX];
|
||||
|
||||
apk_pkg_format_cache(pkg, APK_BLOB_BUF(cacheitem));
|
||||
if (faccessat(db->cache_fd, cacheitem, R_OK, 0) != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &db->repos[i];
|
||||
}
|
||||
|
||||
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
|
||||
{
|
||||
char cacheitem[PATH_MAX];
|
||||
|
@ -1282,6 +1313,8 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
|
|||
targz = 0;
|
||||
}
|
||||
} else {
|
||||
db->local_repos |= BIT(r);
|
||||
|
||||
bs = apk_repository_file_open(repo, apkindex_tar_gz);
|
||||
if (bs == NULL) {
|
||||
bs = apk_repository_file_open(repo, apk_index_gz);
|
||||
|
@ -1686,22 +1719,18 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
|||
struct apk_bstream *bs = NULL;
|
||||
struct apk_istream *tar;
|
||||
char file[PATH_MAX];
|
||||
int r, i, need_copy = FALSE;
|
||||
int r, need_copy = FALSE;
|
||||
|
||||
if (newpkg->filename == NULL) {
|
||||
struct apk_repository *repo;
|
||||
|
||||
for (i = 0; i < APK_MAX_REPOS; i++)
|
||||
if (newpkg->repos & BIT(i))
|
||||
break;
|
||||
|
||||
if (i >= APK_MAX_REPOS) {
|
||||
apk_error("%s-%s: not present in any repository",
|
||||
repo = apk_db_select_repo(db, newpkg);
|
||||
if (repo == NULL) {
|
||||
apk_error("%s-%s: package is not currently available",
|
||||
newpkg->name->name, newpkg->version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
repo = &db->repos[i];
|
||||
if (apk_db_cache_active(db) &&
|
||||
repo->csum.type != APK_CHECKSUM_NONE) {
|
||||
apk_pkg_format_cache(newpkg, APK_BLOB_BUF(file));
|
||||
|
|
16
src/fetch.c
16
src/fetch.c
|
@ -95,8 +95,9 @@ static int fetch_package(struct fetch_ctx *fctx,
|
|||
struct apk_package *pkg)
|
||||
{
|
||||
struct apk_istream *is;
|
||||
struct apk_repository *repo;
|
||||
char pkgfile[PATH_MAX], url[PATH_MAX];
|
||||
int r, i, fd;
|
||||
int r, fd;
|
||||
|
||||
apk_pkg_format_plain(pkg, APK_BLOB_BUF(pkgfile));
|
||||
|
||||
|
@ -110,12 +111,9 @@ static int fetch_package(struct fetch_ctx *fctx,
|
|||
}
|
||||
|
||||
apk_message("Downloading %s-%s", pkg->name->name, pkg->version);
|
||||
for (i = 0; i < APK_MAX_REPOS; i++)
|
||||
if (pkg->repos & BIT(i))
|
||||
break;
|
||||
|
||||
if (i >= APK_MAX_REPOS) {
|
||||
apk_error("%s-%s: not present in any repository",
|
||||
repo = apk_db_select_repo(db, pkg);
|
||||
if (repo == NULL) {
|
||||
apk_error("%s-%s: package is not currently available",
|
||||
pkg->name->name, pkg->version);
|
||||
return -1;
|
||||
}
|
||||
|
@ -123,8 +121,8 @@ static int fetch_package(struct fetch_ctx *fctx,
|
|||
if (apk_flags & APK_SIMULATE)
|
||||
return 0;
|
||||
|
||||
snprintf(url, sizeof(url), "%s%s%s", db->repos[i].url,
|
||||
db->repos[i].url[strlen(db->repos[i].url)-1] == '/' ? "" : "/",
|
||||
snprintf(url, sizeof(url), "%s%s%s", repo->url,
|
||||
repo->url[strlen(repo->url)-1] == '/' ? "" : "/",
|
||||
pkgfile);
|
||||
|
||||
if (fctx->flags & FETCH_STDOUT) {
|
||||
|
|
|
@ -142,6 +142,7 @@ struct apk_state *apk_state_new(struct apk_database *db)
|
|||
state = (struct apk_state*) calloc(1, num_bytes);
|
||||
state->refs = 1;
|
||||
state->num_names = db->name_id;
|
||||
state->db = db;
|
||||
list_init(&state->change_list_head);
|
||||
|
||||
/* Instantiate each 'name' target in world, and lockout incompatible
|
||||
|
@ -292,6 +293,10 @@ int apk_state_lock_dependency(struct apk_state *state,
|
|||
if (apk_pkg_get_state(c->pkgs[i]) == APK_PKG_INSTALLED)
|
||||
installed = pkg;
|
||||
|
||||
if (pkg->filename == NULL &&
|
||||
apk_db_select_repo(state->db, pkg) == NULL)
|
||||
continue;
|
||||
|
||||
if (latest == NULL) {
|
||||
latest = pkg;
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue