From 166caab986c5f56ef1fc79867b7c9448b72a63d6 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Fri, 27 Dec 2019 14:33:53 +0100 Subject: [PATCH] Do not silently update xbps on any install/update transaction. When there's a new xbps update, xbps-install(1) will now return EBUSY (16) and a message (if dry-run disabled) explaining how to proceed. If there's an update and transaction does not contain xbps, it will error out unless the 'xbps' pkg is the only target pkg, i.e: # xbps-install -Su # echo $? 16 To update xbps, the only way to proceed is to explicitly declare it as an update, i.e: # xbps-install -u xbps The dry-run mode will still show there's an xbps update. Modified the existing test cases to satisfy the new behaviour. Closes #166 Closes #142 --- bin/xbps-install/transaction.c | 85 +++++++++--------- include/xbps.h.in | 2 +- lib/transaction_ops.c | 12 ++- tests/xbps/libxbps/shell/install_test.sh | 20 +++++ .../xbps/libxbps/shell/update_itself_test.sh | 89 ++++--------------- 5 files changed, 90 insertions(+), 118 deletions(-) diff --git a/bin/xbps-install/transaction.c b/bin/xbps-install/transaction.c index 1f5eff3b..919712a3 100644 --- a/bin/xbps-install/transaction.c +++ b/bin/xbps-install/transaction.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2015 Juan Romero Pardines. + * Copyright (c) 2009-2019 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -229,7 +229,8 @@ out: } static bool -all_pkgs_on_hold(struct transaction *trans) { +all_pkgs_on_hold(struct transaction *trans) +{ xbps_object_t obj; const char *action = NULL; bool all_on_hold = true; @@ -252,21 +253,25 @@ dist_upgrade(struct xbps_handle *xhp, int cols, bool yes, bool drun) { int rv = 0; - if ((rv = xbps_transaction_update_packages(xhp)) != 0) { - if (rv == ENOENT) { - printf("No packages currently registered.\n"); - return 0; - } else if (rv == EEXIST) { - return 0; - } else if (rv == ENOTSUP) { - fprintf(stderr, "No repositories currently " - "registered!\n"); - return -1; + rv = xbps_transaction_update_packages(xhp); + if (rv == ENOENT) { + printf("No packages currently registered.\n"); + return 0; + } else if (rv == EBUSY) { + if (drun) { + rv = 0; } else { - fprintf(stderr, "Unexpected error %s\n", - strerror(rv)); - return -1; + printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n"); + return rv; } + } else if (rv == EEXIST) { + return 0; + } else if (rv == ENOTSUP) { + fprintf(stderr, "No repositories currently registered!\n"); + return rv; + } else if (rv != 0) { + fprintf(stderr, "Unexpected error %s\n", strerror(rv)); + return -1; } return exec_transaction(xhp, cols, yes, drun); @@ -277,42 +282,42 @@ install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall) { int rv; - if ((rv = xbps_transaction_install_pkg(xhp, pkg, reinstall)) != 0) { - if (rv == EEXIST) { - printf("Package `%s' already installed.\n", pkg); - } else if (rv == ENOENT) { - fprintf(stderr, "Unable to locate '%s' in " - "repository pool.\n", pkg); - } else if (rv == ENOTSUP) { - fprintf(stderr, "No repositories " - "currently registered!\n"); - } else if (rv == ENXIO) { - fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg); - } else { - fprintf(stderr, "Unexpected error: %s\n", - strerror(rv)); - rv = -1; - } + rv = xbps_transaction_install_pkg(xhp, pkg, reinstall); + if (rv == EEXIST) + printf("Package `%s' already installed.\n", pkg); + else if (rv == ENOENT) + fprintf(stderr, "Package '%s' not found in repository pool.\n", pkg); + else if (rv == ENOTSUP) + fprintf(stderr, "No repositories currently registered!\n"); + else if (rv == ENXIO) + fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg); + else if (rv == EBUSY) + fprintf(stderr, "The 'xbps' package must be updated, please run `xbps-install -u xbps`\n"); + else if (rv != 0) { + fprintf(stderr, "Unexpected error: %s\n", strerror(rv)); + rv = -1; } return rv; } int -update_pkg(struct xbps_handle *xhp, const char *pkgname) +update_pkg(struct xbps_handle *xhp, const char *pkg) { int rv; - rv = xbps_transaction_update_pkg(xhp, pkgname); - if (rv == EEXIST) { - printf("Package '%s' is up to date.\n", pkgname); - return EEXIST; - } else if (rv == ENOENT) - fprintf(stderr, "Package '%s' not found in " - "repository pool.\n", pkgname); + rv = xbps_transaction_update_pkg(xhp, pkg); + if (rv == EEXIST) + printf("Package '%s' is up to date.\n", pkg); + else if (rv == ENOENT) + fprintf(stderr, "Package '%s' not found in repository pool.\n", pkg); else if (rv == ENODEV) - printf("Package '%s' not installed.\n", pkgname); + fprintf(stderr, "Package '%s' not installed.\n", pkg); else if (rv == ENOTSUP) fprintf(stderr, "No repositories currently registered!\n"); + else if (rv == ENXIO) + fprintf(stderr, "Package `%s' contains invalid dependencies, exiting.\n", pkg); + else if (rv == EBUSY) + fprintf(stderr, "The 'xbps' package must be updated, please run `xbps-install -u xbps`\n"); else if (rv != 0) { fprintf(stderr, "Unexpected error: %s\n", strerror(rv)); return -1; diff --git a/include/xbps.h.in b/include/xbps.h.in index 8354b2e0..130e37df 100644 --- a/include/xbps.h.in +++ b/include/xbps.h.in @@ -50,7 +50,7 @@ * * This header documents the full API for the XBPS Library. */ -#define XBPS_API_VERSION "20190707" +#define XBPS_API_VERSION "20191227" #ifndef XBPS_VERSION #define XBPS_VERSION "UNSET" diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 2a078c25..3d3fc36a 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -297,8 +297,8 @@ xbps_transaction_update_packages(struct xbps_handle *xhp) rv = xbps_autoupdate(xhp); switch (rv) { case 1: - /* xbps needs to be updated, don't add any other package */ - return 0; + /* xbps needs to be updated, don't allow any other update */ + return EBUSY; case -1: /* error */ return EINVAL; @@ -349,7 +349,9 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg) xbps_dbg_printf(xhp, "%s: xbps_autoupdate %d\n", __func__, rv); switch (rv) { case 1: - /* xbps needs to be updated, don't add any other package */ + /* xbps needs to be updated, only allow xbps to be updated */ + if (strcmp(pkg, "xbps")) + return EBUSY; return 0; case -1: /* error */ @@ -388,7 +390,9 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, rv = xbps_autoupdate(xhp); switch (rv) { case 1: - /* xbps needs to be updated, don't add any other package */ + /* xbps needs to be updated, only allow xbps to be updated */ + if (strcmp(pkg, "xbps")) + return EBUSY; return 0; case -1: /* error */ diff --git a/tests/xbps/libxbps/shell/install_test.sh b/tests/xbps/libxbps/shell/install_test.sh index d76e7361..1e742d82 100644 --- a/tests/xbps/libxbps/shell/install_test.sh +++ b/tests/xbps/libxbps/shell/install_test.sh @@ -488,6 +488,20 @@ update_xbps_body() { set -- $out exp="$1 $2 $3 $4" atf_check_equal "$exp" "xbps-1.1_1 update noarch $(readlink -f repo)" + + xbps-install -r root --repository=repo -yu xbps + atf_check_equal $? 0 + + out=$(xbps-query -r root -p pkgver xbps) + atf_check_equal "$out" "xbps-1.1_1" + + xbps-install -r root --repository=repo -yu + atf_check_equal $? 0 + + out=$(xbps-query -r root -p pkgver B) + atf_check_equal "$out" "B-1.1_1" + out=$(xbps-query -r root -p pkgver C) + atf_check_equal "$out" "C-1.1_1" } atf_test_case update_xbps_virtual @@ -527,6 +541,12 @@ update_xbps_virtual_body() { set -- $out exp="$1 $2 $3 $4" atf_check_equal "$exp" "xbps-git-1.1_1 update noarch $(readlink -f repo)" + + xbps-install -r root --repository=repo -yu xbps + atf_check_equal $? 0 + + out=$(xbps-query -r root -p pkgver xbps-git) + atf_check_equal "$out" "xbps-git-1.1_1" } atf_test_case update_with_revdeps diff --git a/tests/xbps/libxbps/shell/update_itself_test.sh b/tests/xbps/libxbps/shell/update_itself_test.sh index 2ae42ec6..a5ba8207 100644 --- a/tests/xbps/libxbps/shell/update_itself_test.sh +++ b/tests/xbps/libxbps/shell/update_itself_test.sh @@ -30,7 +30,14 @@ update_xbps_body() { atf_check_equal $? 0 cd .. + # EBUSY xbps-install -r root --repository=$PWD/repo -yud + atf_check_equal $? 16 + + out=$(xbps-query -r root -p pkgver xbps) + atf_check_equal $out xbps-1.0_1 + + xbps-install -r root --repository=$PWD/repo -yu xbps atf_check_equal $? 0 out=$(xbps-query -r root -p pkgver xbps) @@ -40,7 +47,7 @@ update_xbps_body() { atf_test_case update_xbps_with_revdeps update_xbps_with_revdeps_head() { - atf_set "descr" "Tests for pkg updates: xbps autoupdates itself with revdeps" + atf_set "descr" "Tests for pkg updates: xbps updates itself with revdeps" } update_xbps_with_revdeps_body() { @@ -80,8 +87,11 @@ update_xbps_with_revdeps_body() { atf_check_equal $? 0 cd .. - # first time, xbps autoupdates + # first time, xbps must be updated (returns EBUSY) xbps-install -r root --repository=$PWD/repo -yud + atf_check_equal $? 16 + + xbps-install -r root --repository=$PWD/repo -yu xbps atf_check_equal $? 0 out=$(xbps-query -r root -p pkgver xbps) @@ -110,7 +120,7 @@ update_xbps_with_revdeps_body() { atf_test_case update_xbps_with_uptodate_revdeps update_xbps_with_uptodate_revdeps_head() { - atf_set "descr" "Tests for pkg updates: xbps autoupdates itself with already up-to-date revdeps" + atf_set "descr" "Tests for pkg updates: xbps updates itself with already up-to-date revdeps" } update_xbps_with_uptodate_revdeps_body() { @@ -143,6 +153,9 @@ update_xbps_with_uptodate_revdeps_body() { cd .. xbps-install -r root --repository=$PWD/repo -yud + atf_check_equal $? 16 + + xbps-install -r root --repository=$PWD/repo -yu xbps atf_check_equal $? 0 out=$(xbps-query -r root -p pkgver xbps) @@ -154,78 +167,8 @@ update_xbps_with_uptodate_revdeps_body() { atf_test_case update_xbps_on_any_op -update_xbps_on_any_op_head() { - atf_set "descr" "Tests for pkg updates: xbps autoupdates itself on any operation" -} - -update_xbps_on_any_op_body() { - mkdir -p repo xbps foo bar - touch xbps/foo foo/blah bar/baz - - cd repo - xbps-create -A noarch -n xbps-1.0_1 -s "xbps pkg" ../xbps - atf_check_equal $? 0 - xbps-create -A noarch -n foo-1.0_1 -s "foo pkg" ../foo - atf_check_equal $? 0 - xbps-create -A noarch -n bar-1.0_1 -s "bar pkg" ../bar - atf_check_equal $? 0 - xbps-rindex -d -a $PWD/*.xbps - atf_check_equal $? 0 - cd .. - - xbps-install -r root --repository=$PWD/repo -yd xbps foo - atf_check_equal $? 0 - - out=$(xbps-query -r root -p pkgver xbps) - atf_check_equal $out xbps-1.0_1 - - out=$(xbps-query -r root -p pkgver foo) - atf_check_equal $out foo-1.0_1 - - cd repo - xbps-create -A noarch -n xbps-1.1_1 -s "xbps pkg" ../xbps - atf_check_equal $? 0 - xbps-create -A noarch -n foo-1.1_1 -s "foo pkg" ../foo - atf_check_equal $? 0 - xbps-rindex -d -a $PWD/*.xbps - atf_check_equal $? 0 - cd .. - - # install an unrelated pkg, xbps autoupdates - xbps-install -r root --repository=$PWD/repo -yd bar - atf_check_equal $? 0 - - out=$(xbps-query -r root -p pkgver xbps) - atf_check_equal $out xbps-1.1_1 - - out=$(xbps-query -r root -p pkgver foo) - atf_check_equal $out foo-1.0_1 - - # ENOENT - xbps-query -r root -p pkgver bar - atf_check_equal $? 2 - - # xbps has been updated, 2nd time - xbps-install -r root --repository=$PWD/repo -yd bar - atf_check_equal $? 0 - - out=$(xbps-query -r root -p pkgver bar) - atf_check_equal $out bar-1.0_1 - - # perform a globl update - xbps-install -r root --repository=$PWD/repo -yud - atf_check_equal $? 0 - - out=$(xbps-query -r root -p pkgver xbps) - atf_check_equal $out xbps-1.1_1 - - out=$(xbps-query -r root -p pkgver foo) - atf_check_equal $out foo-1.1_1 -} - atf_init_test_cases() { atf_add_test_case update_xbps atf_add_test_case update_xbps_with_revdeps atf_add_test_case update_xbps_with_uptodate_revdeps - atf_add_test_case update_xbps_on_any_op }