xbps-install: improved -D,--download-only support.

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
This commit is contained in:
Juan RP 2020-01-25 13:05:46 +01:00
parent ed5e481e77
commit bda4452016
No known key found for this signature in database
GPG Key ID: AF19F6CB482F9368
6 changed files with 53 additions and 10 deletions

View File

@ -243,10 +243,12 @@ main(int argc, char **argv)
if (syncf && !update && (argc == optind)) if (syncf && !update && (argc == optind))
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
if (!drun && (rv = xbps_pkgdb_lock(&xh)) != 0) { 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)); fprintf(stderr, "Failed to lock the pkgdb: %s\n", strerror(rv));
exit(rv); exit(rv);
} }
}
eexist = optind; eexist = optind;

View File

@ -138,6 +138,10 @@ print_trans_colmode(struct transaction *trans, int cols)
pkgname = xbps_pkg_name(pkgver); pkgname = xbps_pkg_name(pkgver);
assert(pkgname); assert(pkgname);
if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
tract = "download";
}
if (strcmp(tract, "install") == 0) { if (strcmp(tract, "install") == 0) {
trans->inst_pkgcnt++; trans->inst_pkgcnt++;
} else if (strcmp(tract, "update") == 0) { } else if (strcmp(tract, "update") == 0) {
@ -147,16 +151,14 @@ print_trans_colmode(struct transaction *trans, int cols)
} else if (strcmp(tract, "configure") == 0) { } else if (strcmp(tract, "configure") == 0) {
trans->cf_pkgcnt++; trans->cf_pkgcnt++;
} }
ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname);
if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
trans->inst_pkgcnt = 0; ipkgd = NULL;
trans->up_pkgcnt = 0;
trans->rm_pkgcnt = 0;
trans->cf_pkgcnt = 0;
} }
if (dload) { if (dload) {
trans->dl_pkgcnt++; trans->dl_pkgcnt++;
} }
ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname);
if (ipkgd) { if (ipkgd) {
xbps_dictionary_get_cstring_nocopy(ipkgd, "pkgver", &ipkgver); xbps_dictionary_get_cstring_nocopy(ipkgd, "pkgver", &ipkgver);
iver = xbps_pkg_version(ipkgver); iver = xbps_pkg_version(ipkgver);

View File

@ -198,6 +198,16 @@ find_repo_deps(struct xbps_handle *xhp,
foundvpkg = true; 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 (curpkgd == NULL) {
if (errno && errno != ENOENT) { if (errno && errno != ENOENT) {
/* error */ /* error */

View File

@ -24,7 +24,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>

View File

@ -81,6 +81,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall,
} else { } else {
pkg_pkgdb = xbps_pkgdb_get_pkg(xhp, pkg); 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. * 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); xbps_dbg_printf(xhp, "%s: trans_find_pkg xbps: %d\n", __func__, rv);
if (rv == 0) { 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 */ /* a new xbps version is available, check its revdeps */
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps"); rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps");
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {

View File

@ -62,7 +62,6 @@ compute_transaction_stats(struct xbps_handle *xhp)
struct statvfs svfs; struct statvfs svfs;
uint64_t rootdir_free_size, tsize, dlsize, instsize, rmsize; uint64_t rootdir_free_size, tsize, dlsize, instsize, rmsize;
uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt, dl_pkgcnt; 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; inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = dl_pkgcnt = 0;
tsize = dlsize = instsize = rmsize = 0; tsize = dlsize = instsize = rmsize = 0;
@ -72,6 +71,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
return EINVAL; return EINVAL;
while ((obj = xbps_object_iterator_next(iter)) != NULL) { while ((obj = xbps_object_iterator_next(iter)) != NULL) {
const char *pkgver = NULL, *repo = NULL, *tract = NULL;
bool preserve = false; bool preserve = false;
/* /*
* Count number of pkgs to be removed, configured, * 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_cstring_nocopy(obj, "repository", &repo);
xbps_dictionary_get_bool(obj, "preserve", &preserve); 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) { if (strcmp(tract, "configure") == 0) {
cf_pkgcnt++; cf_pkgcnt++;
continue; continue;
@ -347,6 +361,13 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
if (all_on_hold) if (all_on_hold)
goto out; 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. * Check for packages to be replaced.
*/ */