cache: allow various flags, and addition of dependencies

Allow controlling 'cache download' more closely to 'upgrade' so
it can be used to pre-download packages for ugprade.
cute-signatures
Timo Teräs 2022-01-21 14:29:46 +02:00
parent a2cd188039
commit 10d0043063
2 changed files with 66 additions and 16 deletions

View File

@ -8,9 +8,9 @@ apk cache - manage a local cache of package files
*apk cache* [<_options_>...] clean *apk cache* [<_options_>...] clean
*apk cache* [<_options_>...] download *apk cache* [<_options_>...] download [_dependency_...]
*apk cache* [<_options_>...] sync *apk cache* [<_options_>...] sync [_dependency_...]
# DESCRIPTION # DESCRIPTION
@ -18,16 +18,29 @@ Manage local package cache by removing obsolete packages, or downloading
missing or newer packages from the repositories. missing or newer packages from the repositories.
*apk cache download* will fetch package files from the repositories and store *apk cache download* will fetch package files from the repositories and store
them in the cache, which must be enabled upfront (see *apk-cache*(5)). them in the cache, which must be enabled upfront (see *apk-cache*(5)). By
default _world_ dependencies are used to determine what to download. If
_dependency_ arguments are given, they will by default replace the _world_.
*apk cache clean* will remove package files which are no longer necessary, *apk cache clean* will remove package files which no longer exist in any
having been made obsolete by new versions or no longer being transitively repository index.
depended on by packages in _world_.
*apk cache sync* performs both operations. *apk cache sync* performs both operations.
# OPTIONS # OPTIONS
*--add-dependencies*
Add the argument dependencies to _world_ dependencies when determining
which packages to download.
*-a, --available*
Selected packages to be downloaded from active repositories even if
it means replacing or downgrading the installed package.
*--ignore-conflict*
Ignore conflicts when resolving dependencies. This can be useful when
pre-populating cache for creation of multiple images in one go.
*-l, --latest* *-l, --latest*
Always choose the latest package by version. However, the versions Always choose the latest package by version. However, the versions
considered are based on the package pinning. Primarily this overrides considered are based on the package pinning. Primarily this overrides
@ -39,3 +52,6 @@ depended on by packages in _world_.
avoid changing installed package unless it is required by the newly avoid changing installed package unless it is required by the newly
added _packages_ or their dependencies. This changes the default added _packages_ or their dependencies. This changes the default
preference to upgrading the package to the latest installable version. preference to upgrading the package to the latest installable version.
*-s, --simulate*
Simulate the requested operation without making any changes.

View File

@ -26,11 +26,16 @@
struct cache_ctx { struct cache_ctx {
unsigned short solver_flags; unsigned short solver_flags;
int add_dependencies : 1;
}; };
#define CACHE_OPTIONS(OPT) \ #define CACHE_OPTIONS(OPT) \
OPT(OPT_CACHE_add_dependencies, "add-dependencies") \
OPT(OPT_CACHE_available, APK_OPT_SH("a") "available") \
OPT(OPT_CACHE_ignore_conflict, "ignore-conflict") \
OPT(OPT_CACHE_latest, APK_OPT_SH("l") "latest") \ OPT(OPT_CACHE_latest, APK_OPT_SH("l") "latest") \
OPT(OPT_CACHE_upgrade, APK_OPT_SH("u") "upgrade") OPT(OPT_CACHE_upgrade, APK_OPT_SH("u") "upgrade") \
OPT(OPT_CACHE_simulate, APK_OPT_SH("s") "simulate") \
APK_OPT_APPLET(option_desc, CACHE_OPTIONS); APK_OPT_APPLET(option_desc, CACHE_OPTIONS);
@ -39,12 +44,24 @@ static int option_parse_applet(void *ctx, struct apk_ctx *ac, int opt, const cha
struct cache_ctx *cctx = (struct cache_ctx *) ctx; struct cache_ctx *cctx = (struct cache_ctx *) ctx;
switch (opt) { switch (opt) {
case OPT_CACHE_upgrade: case OPT_CACHE_add_dependencies:
cctx->solver_flags |= APK_SOLVERF_UPGRADE; cctx->add_dependencies = 1;
break;
case OPT_CACHE_available:
cctx->solver_flags |= APK_SOLVERF_AVAILABLE;
break;
case OPT_CACHE_ignore_conflict:
cctx->solver_flags |= APK_SOLVERF_IGNORE_CONFLICT;
break; break;
case OPT_CACHE_latest: case OPT_CACHE_latest:
cctx->solver_flags |= APK_SOLVERF_LATEST; cctx->solver_flags |= APK_SOLVERF_LATEST;
break; break;
case OPT_CACHE_upgrade:
cctx->solver_flags |= APK_SOLVERF_UPGRADE;
break;
case OPT_CACHE_simulate:
ac->flags |= APK_SIMULATE;
break;
default: default:
return -ENOTSUP; return -ENOTSUP;
} }
@ -67,17 +84,32 @@ static void progress_cb(void *ctx, size_t bytes_done)
apk_print_progress(&prog->prog, prog->done + bytes_done, prog->total); apk_print_progress(&prog->prog, prog->done + bytes_done, prog->total);
} }
static int cache_download(struct cache_ctx *cctx, struct apk_database *db) static int cache_download(struct cache_ctx *cctx, struct apk_database *db, struct apk_string_array *args)
{ {
struct apk_out *out = &db->ctx->out; struct apk_out *out = &db->ctx->out;
struct apk_changeset changeset = {}; struct apk_changeset changeset = {};
struct apk_change *change; struct apk_change *change;
struct apk_package *pkg; struct apk_package *pkg;
struct apk_repository *repo; struct apk_repository *repo;
struct apk_dependency_array *deps;
struct apk_dependency dep;
struct progress prog = { .prog = db->ctx->progress }; struct progress prog = { .prog = db->ctx->progress };
int r, ret = 0; int i, r, ret = 0;
r = apk_solver_solve(db, cctx->solver_flags, db->world, &changeset); apk_dependency_array_init(&deps);
if (args->num == 1 || cctx->add_dependencies)
apk_dependency_array_copy(&deps, db->world);
for (i = 1; i < args->num; i++) {
apk_blob_t b = APK_BLOB_STR(args->item[i]);
apk_blob_pull_dep(&b, db, &dep);
if (APK_BLOB_IS_NULL(b)) {
apk_err(out, "bad dependency: %s", args->item[i]);
return -EINVAL;
}
*apk_dependency_array_add(&deps) = dep;
}
r = apk_solver_solve(db, cctx->solver_flags, deps, &changeset);
apk_dependency_array_free(&deps);
if (r < 0) { if (r < 0) {
apk_err(out, "Unable to select packages. Run apk fix."); apk_err(out, "Unable to select packages. Run apk fix.");
return r; return r;
@ -85,8 +117,10 @@ static int cache_download(struct cache_ctx *cctx, struct apk_database *db)
foreach_array_item(change, changeset.changes) { foreach_array_item(change, changeset.changes) {
pkg = change->new_pkg; pkg = change->new_pkg;
if ((pkg != NULL) && !(pkg->repos & db->local_repos)) if (!pkg || (pkg->repos & db->local_repos) || !pkg->installed_size)
prog.total += pkg->size; continue;
if (!apk_db_select_repo(db, pkg)) continue;
prog.total += pkg->size;
} }
foreach_array_item(change, changeset.changes) { foreach_array_item(change, changeset.changes) {
@ -153,7 +187,7 @@ static int cache_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *ar
char *arg; char *arg;
int r = 0, actions = 0; int r = 0, actions = 0;
if (args->num != 1) if (args->num < 1)
return -EINVAL; return -EINVAL;
arg = args->item[0]; arg = args->item[0];
@ -175,7 +209,7 @@ static int cache_main(void *ctx, struct apk_ctx *ac, struct apk_string_array *ar
if (r == 0 && (actions & CACHE_CLEAN)) if (r == 0 && (actions & CACHE_CLEAN))
r = cache_clean(db); r = cache_clean(db);
if (r == 0 && (actions & CACHE_DOWNLOAD)) if (r == 0 && (actions & CACHE_DOWNLOAD))
r = cache_download(cctx, db); r = cache_download(cctx, db, args);
err: err:
return r; return r;
} }