From bda4452016aab6ccca7491eb0d13ab82910d2e24 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sat, 25 Jan 2020 13:05:46 +0100 Subject: [PATCH] xbps-install: improved -D,--download-only support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added support to download all dependencies even if the euid does not have write perms to rootdir. In this mode we only care if cachedir is writable, rootdir access is not necessary. This is really useful to download all binary packages required by any number of packages as any regular user to later perform off-line installations, i.e: ``` $ xbps-install -c $PWD/cachedir -yD xbps ... $ tree cachedir cachedir/ ├── acl-2.2.53_1.x86_64-musl.xbps ├── acl-2.2.53_1.x86_64-musl.xbps.sig ├── attr-2.4.48_1.x86_64-musl.xbps ├── attr-2.4.48_1.x86_64-musl.xbps.sig ├── bzip2-1.0.8_1.x86_64-musl.xbps ├── bzip2-1.0.8_1.x86_64-musl.xbps.sig ├── ca-certificates-20190110_1.noarch.xbps ├── ca-certificates-20190110_1.noarch.xbps.sig ├── libarchive-3.4.1_1.x86_64-musl.xbps ├── libarchive-3.4.1_1.x86_64-musl.xbps.sig ├── libcrypto45-3.0.2_2.x86_64-musl.xbps ├── libcrypto45-3.0.2_2.x86_64-musl.xbps.sig ├── liblz4-1.9.2_1.x86_64-musl.xbps ├── liblz4-1.9.2_1.x86_64-musl.xbps.sig ├── liblzma-5.2.4_2.x86_64-musl.xbps ├── liblzma-5.2.4_2.x86_64-musl.xbps.sig ├── libressl-3.0.2_2.x86_64-musl.xbps ├── libressl-3.0.2_2.x86_64-musl.xbps.sig ├── libssl47-3.0.2_2.x86_64-musl.xbps ├── libssl47-3.0.2_2.x86_64-musl.xbps.sig ├── libtls19-3.0.2_2.x86_64-musl.xbps ├── libtls19-3.0.2_2.x86_64-musl.xbps.sig ├── libxbps-0.57.1_8.x86_64-musl.xbps ├── libxbps-0.57.1_8.x86_64-musl.xbps.sig ├── libzstd-1.4.4_1.x86_64-musl.xbps ├── libzstd-1.4.4_1.x86_64-musl.xbps.sig ├── musl-1.1.24_1.x86_64-musl.xbps ├── musl-1.1.24_1.x86_64-musl.xbps.sig ├── run-parts-4.9.1_1.x86_64-musl.xbps ├── run-parts-4.9.1_1.x86_64-musl.xbps.sig ├── xbps-0.57.1_8.x86_64-musl.xbps ├── xbps-0.57.1_8.x86_64-musl.xbps.sig ├── xbps-triggers-0.113_3.noarch.xbps ├── xbps-triggers-0.113_3.noarch.xbps.sig ├── zlib-1.2.11_3.x86_64-musl.xbps └── zlib-1.2.11_3.x86_64-musl.xbps.sig 0 directories, 36 files $ ``` Inpired by #213 Closes #213 --- bin/xbps-install/main.c | 8 +++++--- bin/xbps-install/util.c | 12 +++++++----- lib/repo_pkgdeps.c | 10 ++++++++++ lib/transaction_fetch.c | 1 - lib/transaction_ops.c | 9 +++++++++ lib/transaction_prepare.c | 23 ++++++++++++++++++++++- 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/bin/xbps-install/main.c b/bin/xbps-install/main.c index d060723f..9ee4964b 100644 --- a/bin/xbps-install/main.c +++ b/bin/xbps-install/main.c @@ -243,9 +243,11 @@ main(int argc, char **argv) if (syncf && !update && (argc == optind)) exit(EXIT_SUCCESS); - if (!drun && (rv = xbps_pkgdb_lock(&xh)) != 0) { - fprintf(stderr, "Failed to lock the pkgdb: %s\n", strerror(rv)); - exit(rv); + if (!(xh.flags & XBPS_FLAG_DOWNLOAD_ONLY) && !drun) { + if ((rv = xbps_pkgdb_lock(&xh)) != 0) { + fprintf(stderr, "Failed to lock the pkgdb: %s\n", strerror(rv)); + exit(rv); + } } eexist = optind; diff --git a/bin/xbps-install/util.c b/bin/xbps-install/util.c index 84753edb..49c5beb5 100644 --- a/bin/xbps-install/util.c +++ b/bin/xbps-install/util.c @@ -138,6 +138,10 @@ print_trans_colmode(struct transaction *trans, int cols) pkgname = xbps_pkg_name(pkgver); assert(pkgname); + if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + tract = "download"; + } + if (strcmp(tract, "install") == 0) { trans->inst_pkgcnt++; } else if (strcmp(tract, "update") == 0) { @@ -147,16 +151,14 @@ print_trans_colmode(struct transaction *trans, int cols) } else if (strcmp(tract, "configure") == 0) { trans->cf_pkgcnt++; } + ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname); + if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { - trans->inst_pkgcnt = 0; - trans->up_pkgcnt = 0; - trans->rm_pkgcnt = 0; - trans->cf_pkgcnt = 0; + ipkgd = NULL; } if (dload) { trans->dl_pkgcnt++; } - ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname); if (ipkgd) { xbps_dictionary_get_cstring_nocopy(ipkgd, "pkgver", &ipkgver); iver = xbps_pkg_version(ipkgver); diff --git a/lib/repo_pkgdeps.c b/lib/repo_pkgdeps.c index 0dbb0010..21b529b1 100644 --- a/lib/repo_pkgdeps.c +++ b/lib/repo_pkgdeps.c @@ -198,6 +198,16 @@ find_repo_deps(struct xbps_handle *xhp, foundvpkg = true; } } + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + /* + * if XBPS_FLAG_DOWNLOAD_ONLY always assume + * all deps are not installed. This way one can download + * the whole set of binary packages to perform an + * off-line installation later on. + */ + curpkgd = NULL; + } + if (curpkgd == NULL) { if (errno && errno != ENOENT) { /* error */ diff --git a/lib/transaction_fetch.c b/lib/transaction_fetch.c index 67c8ecbf..e6749f68 100644 --- a/lib/transaction_fetch.c +++ b/lib/transaction_fetch.c @@ -24,7 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 03725ee3..cbdc9721 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -81,6 +81,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall, } else { pkg_pkgdb = xbps_pkgdb_get_pkg(xhp, pkg); } + + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + pkg_pkgdb = NULL; + } + /* * Find out if the pkg has been found in repository pool. */ @@ -254,6 +259,10 @@ xbps_autoupdate(struct xbps_handle *xhp) xbps_dbg_printf(xhp, "%s: trans_find_pkg xbps: %d\n", __func__, rv); if (rv == 0) { + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + xhp->flags |= XBPS_FLAG_FORCE_REMOVE_REVDEPS; + return 1; + } /* a new xbps version is available, check its revdeps */ rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps"); for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { diff --git a/lib/transaction_prepare.c b/lib/transaction_prepare.c index 5e3aa052..1ac27ef9 100644 --- a/lib/transaction_prepare.c +++ b/lib/transaction_prepare.c @@ -62,7 +62,6 @@ compute_transaction_stats(struct xbps_handle *xhp) struct statvfs svfs; uint64_t rootdir_free_size, tsize, dlsize, instsize, rmsize; uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt, dl_pkgcnt; - const char *tract, *pkgver, *repo; inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = dl_pkgcnt = 0; tsize = dlsize = instsize = rmsize = 0; @@ -72,6 +71,7 @@ compute_transaction_stats(struct xbps_handle *xhp) return EINVAL; while ((obj = xbps_object_iterator_next(iter)) != NULL) { + const char *pkgver = NULL, *repo = NULL, *tract = NULL; bool preserve = false; /* * Count number of pkgs to be removed, configured, @@ -82,6 +82,20 @@ compute_transaction_stats(struct xbps_handle *xhp) xbps_dictionary_get_cstring_nocopy(obj, "repository", &repo); xbps_dictionary_get_bool(obj, "preserve", &preserve); + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + tract = "download"; + if (xbps_repository_is_remote(repo) && + !xbps_binpkg_exists(xhp, obj)) { + xbps_dictionary_get_uint64(obj, + "filename-size", &tsize); + tsize += 512; + dlsize += tsize; + dl_pkgcnt++; + xbps_dictionary_set_bool(obj, "download", true); + } + continue; + } + if (strcmp(tract, "configure") == 0) { cf_pkgcnt++; continue; @@ -347,6 +361,13 @@ xbps_transaction_prepare(struct xbps_handle *xhp) if (all_on_hold) goto out; + /* + * Do not perform any checks if XBPS_FLAG_DOWNLOAD_ONLY + * is set. We just need to download the archives (dependencies). + */ + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) + goto out; + /* * Check for packages to be replaced. */