db: prefer local repositories, and implement --no-network

this helps boots sequence when network is not available.
cute-signatures
Timo Teras 2009-08-06 16:00:20 +03:00
parent ced1fa83d6
commit f02f326238
8 changed files with 67 additions and 29 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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[];
};

View File

@ -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:

View File

@ -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));

View File

@ -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) {

View File

@ -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;