Add --path to swupd autoupdate mechanism

Signed-off-by: Karthik Prabhu Vinod <karthik.prabhu.vinod@intel.com>

Fixes #527
This commit is contained in:
Karthik Prabhu Vinod
2019-10-21 12:26:48 -07:00
committed by Otavio Pontes
parent 1c499ccaa3
commit c207c9240c
10 changed files with 154 additions and 47 deletions
+3 -2
View File
@@ -14,7 +14,7 @@ env:
- UPDATE_SUBGROUP2_TOTAL="$((UPDATE_TOTAL - UPDATE_SUBGROUP1_TOTAL))"
- UPDATE_SUBGROUP1="$(find test/functional/update -name *.bats | head -n $UPDATE_SUBGROUP1_TOTAL | tr '\n' ' ')"
- UPDATE_SUBGROUP2="$(find test/functional/update -name *.bats | tail -n $UPDATE_SUBGROUP2_TOTAL | tr '\n' ' ')"
- GROUP1="$UPDATE_SUBGROUP1 $(find test/functional/{bundleinfo,verify-legacy} -name *.bats -printf '%p ')"
- GROUP1="$UPDATE_SUBGROUP1 $(find test/functional/{autoupdate,bundleinfo,verify-legacy} -name *.bats -printf '%p ')"
- GROUP2="$UPDATE_SUBGROUP2 $(find test/functional/{checkupdate,hashdump,mirror,usability} -name *.bats \( ! -name usa-config-file.bats \) -printf '%p ')"
- GROUP3="$(find test/functional/{diagnose,search,os-install,repair} -name *.bats -printf '%p ')"
- GROUP4="$(find test/functional/{bundleadd,bundleremove,bundlelist,signature} -name *.bats -printf '%p ')"
@@ -27,7 +27,7 @@ jobs:
name: "Static Analysis & Unit Tests"
script: make compliant && make shellcheck && sudo sh -c 'umask 0022 && make unit-check' && make docs-coverage
- stage: test
name: "Functional Tests - update (group 1), bundle-info, verify-legacy"
name: "Functional Tests - update (group 1), autoupdate, bundle-info, verify-legacy"
script: env TESTS="$GROUP1" make -e check
- stage: test
name: "Functional Tests - update (group 2), checkupdate, hashdump, mirror, usability"
@@ -50,6 +50,7 @@ install:
- sudo apt-get install doxygen
- sudo apt-get install check
- sudo pip install coverxygen
- sudo ln -s /bin/systemctl /usr/bin/systemctl
# build bsdiff
- wget https://github.com/clearlinux/bsdiff/releases/download/v1.0.2/bsdiff-1.0.2.tar.xz
+1 -1
View File
@@ -165,6 +165,7 @@ BATS_LOG_DRIVER = $(tap_driver)
TESTS = $(dist_check_SCRIPTS) $(UNIT_TESTS)
BATS = \
test/functional/autoupdate/aup-basic.bats \
test/functional/bundleadd/add-alias-basic.bats \
test/functional/bundleadd/add-also-add-flag.bats \
test/functional/bundleadd/add-bad-hash.bats \
@@ -341,7 +342,6 @@ BATS = \
test/functional/verify-legacy/verify-bundle.bats \
test/functional/verify-legacy/verify-flags.bats
UNIT_TESTS = \
test/unit/test_list.test \
test/unit/test_manifest.test \
+76 -41
View File
@@ -29,56 +29,74 @@
#include "swupd.h"
static void print_help(const char *name)
static void print_help(void)
{
print("Usage:\n");
print(" swupd %s [options]\n\n", basename((char *)name));
print("Help Options:\n");
print(" -h, --help Show help options\n");
print(" swupd autoupdate [OPTION...]\n\n");
global_print_help();
print("Options:\n");
print(" --enable enable autoupdates\n");
print(" --disable disable autoupdates\n");
print("\n");
}
static int enable;
static int disable;
#define FLAG_ENABLE 2000
#define FLAG_DISABLE 2001
static bool cmdline_option_enable;
static bool cmdline_option_disable;
static const struct option prog_opts[] = {
{ "help", no_argument, 0, 'h' },
{ "enable", no_argument, &enable, 1 },
{ "disable", no_argument, &disable, 1 },
{ 0, 0, 0, 0 }
{ "enable", no_argument, 0, FLAG_ENABLE },
{ "disable", no_argument, 0, FLAG_DISABLE },
};
static bool parse_opt(int opt, UNUSED_PARAM char *optarg)
{
switch (opt) {
case 'h':
print_help();
exit(EXIT_SUCCESS);
case FLAG_ENABLE:
cmdline_option_enable = optarg_to_bool(optarg);
return true;
case FLAG_DISABLE:
cmdline_option_disable = optarg_to_bool(optarg);
return true;
default:
return false;
}
return false;
}
static const struct global_options opts = {
prog_opts,
sizeof(prog_opts) / sizeof(struct option),
parse_opt,
print_help,
};
static bool parse_options(int argc, char **argv)
{
int opt;
int ind = global_parse_options(argc, argv, &opts);
while ((opt = getopt_long(argc, argv, "h", prog_opts, NULL)) != -1) {
switch (opt) {
case '?':
print_help(argv[0]);
exit(SWUPD_INVALID_OPTION);
case 'h':
print_help(argv[0]);
exit(EXIT_SUCCESS);
case 0: /* getopt_long has set the flag */
break;
default:
error("unrecognized option\n\n");
goto err;
}
if (ind < 0) {
return false;
}
if (argc > optind) {
if (argc > ind) {
error("unexpected arguments\n\n");
goto err;
return false;
}
if (cmdline_option_enable && cmdline_option_disable) {
error("Can not use --enable and --disable options at the same time\n\n");
return false;
}
return true;
err:
print_help(argv[0]);
return false;
}
static void policy_warn(void)
@@ -89,38 +107,50 @@ static void policy_warn(void)
enum swupd_code autoupdate_main(int argc, char **argv)
{
if (!parse_options(argc, argv)) {
print_help();
return SWUPD_INVALID_OPTION;
}
if (enable && disable) {
error("Can not enable and disable at the same time\n");
return SWUPD_INVALID_OPTION;
}
if (!systemctl_active()) {
if (!globals.path_prefix && !systemctl_active()) {
error("Systemd is inactive - unable to proceed\n");
return SWUPD_SUBPROCESS_ERROR;
}
if (enable) {
if (cmdline_option_enable) {
int rc;
check_root();
info("Running systemctl to enable updates\n");
rc = systemctl_cmd("unmask", "--now", "swupd-update.service", "swupd-update.timer", NULL);
rc = systemctl_cmd_path(globals.path_prefix,
"unmask", "--now", "swupd-update.service", "swupd-update.timer", NULL);
if (rc != 0) {
return SWUPD_SUBPROCESS_ERROR;
}
rc = systemctl_restart("swupd-update.timer");
/* If globals.path_prefix is given and we have succeeded so far,
* make sense to return SWUPD_OK at this point. In that case,
* a swupd timer restart cannot be done as there is no
* system daemon to communicate for rootfs.
*/
if (globals.path_prefix) {
warn("Running autoupdate with --path will not restart swupd-update.timer. This will have to be done manually\n");
return SWUPD_OK;
}
rc = systemctl_cmd_path(globals.path_prefix, "restart", "swupd-update.timer", NULL);
if (rc != 0) {
return SWUPD_SUBPROCESS_ERROR;
}
return SWUPD_OK;
} else if (disable) {
} else if (cmdline_option_disable) {
int rc;
check_root();
policy_warn();
info("Running systemctl to disable updates\n");
rc = systemctl_cmd("mask", "--now", "swupd-update.service", "swupd-update.timer", NULL);
rc = systemctl_cmd_path(globals.path_prefix,
"mask", "--now", "swupd-update.service", "swupd-update.timer", NULL);
if (rc) {
return SWUPD_SUBPROCESS_ERROR;
}
@@ -128,8 +158,8 @@ enum swupd_code autoupdate_main(int argc, char **argv)
} else {
int rc1, rc2;
const int STATUS_UNKNOWN = 4;
rc1 = systemctl_cmd("is-enabled", "swupd-update.service", NULL);
rc2 = systemctl_cmd("is-active", "swupd-update.timer", NULL);
rc1 = systemctl_cmd_path(globals.path_prefix, "is-enabled", "swupd-update.service", NULL);
rc2 = systemctl_cmd_path(globals.path_prefix, "is-active", "swupd-update.timer", NULL);
if (rc1 == SWUPD_OK && rc2 == SWUPD_OK) {
print("Enabled\n");
return SWUPD_OK;
@@ -137,6 +167,11 @@ enum swupd_code autoupdate_main(int argc, char **argv)
/* systemctl returns 1,2, or 3 when program dead or not running */
error("Unable to determine autoupdate status\n");
return SWUPD_SUBPROCESS_ERROR;
// Swupd-service is unmasked, static but timer is inactive for --path
} else if (rc1 == SWUPD_OK && rc2 != SWUPD_OK && globals.path_prefix) {
info("Autoupdate is enabled, but the timer is not running\n");
error("Unable to determine autoupdate status with --path option\n");
return SWUPD_SUBPROCESS_ERROR;
} else {
print("Disabled\n");
return SWUPD_NO;
+6
View File
@@ -203,6 +203,12 @@ int sys_rm(const char *filename);
*/
#define systemctl_cmd(...) run_command_quiet(SYSTEMCTL, __VA_ARGS__)
/**
* @brief Run a systemctl command with the informed parameters in a path
*/
#define systemctl_cmd_path(path, ...) \
path ? run_command_quiet(SYSTEMCTL, "--root", path, __VA_ARGS__) : run_command_quiet(SYSTEMCTL, __VA_ARGS__)
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -34,7 +34,7 @@ _swupd()
opts="$global "
break;;
("autoupdate")
opts="--help --enable --disable "
opts="$global --help --enable --disable "
break;;
("check-update")
opts="$global "
+1
View File
@@ -185,6 +185,7 @@ if [[ -n "$state" ]]; then
;;
autoupdate)
local -a autoupdates; autoupdates=(
$global_opts
'(-)--enable[enable autoupdates]'
'(-)--disable[disable autoupdates]'
'(-)'{-h,--help}'[Show help options]'
+1
View File
@@ -125,6 +125,7 @@ or more of the [assertions](#assertions) provided by the test library.
| Main Business Scenarios | Commands | Group ID |
| ---------------------------------------------- | ------------- | -------- |
| Enables/Disables autoupdate | auto-update | AUT |
| Install new bundles | bundle-add | ADD |
| Uninstall bundles | bundle-remove | REM |
| List bundles | bundle-list | LST |
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bats
# Author: Karthik Prabhu Vinod
# Email: karthik.prabhu.vinod@intel.com
load "../testlib"
test_setup() {
if [ -z "$TRAVIS" ]; then
skip "This test is intended to run only in Travis (use TRAVIS=true to run it anyway)..."
fi
create_test_environment "$TEST_NAME"
}
test_teardown() {
if [ -z "$TRAVIS" ]; then
return
fi
destroy_test_environment "$TEST_NAME"
}
@test "AUT001: Basic test, Check auto-update enable" {
# perform autoupdate disable
run sudo sh -c "$SWUPD autoupdate --disable --path=$PATH_PREFIX"
assert_status_is "$SWUPD_OK"
expected_output=$(cat <<-EOM
Warning: disabling automatic updates may take you out of compliance with your IT policy
Running systemctl to disable updates
EOM
)
assert_is_output "$expected_output"
# check for files(should exist and point to /dev/null)
run sudo sh -c "test -c $PATH_PREFIX/etc/systemd/system/swupd-update.service"
assert_status_is "$SWUPD_OK"
run sudo sh -c "test -c $PATH_PREFIX/etc/systemd/system/swupd-update.timer"
assert_status_is "$SWUPD_OK"
# perform autoupdate enable
run sudo sh -c "$SWUPD autoupdate --enable $SWUPD_OPTS"
assert_status_is "$SWUPD_OK"
expected_output=$(cat <<-EOM
Running systemctl to enable updates
Warning: Running autoupdate with --path will not restart swupd-update.timer. This will have to be done manually
EOM
)
assert_is_output "$expected_output"
# check for files(should not exist)
run sudo sh -c "test -c $PATH_PREFIX/etc/systemd/system/swupd-update.service"
assert_status_is_not "$SWUPD_OK"
run sudo sh -c "test -c $PATH_PREFIX/etc/systemd/system/swupd-update.timer"
assert_status_is_not "$SWUPD_OK"
}
+1 -1
View File
@@ -5,7 +5,7 @@ FUNC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=/dev/null
source "$FUNC_DIR"/testlib.bash
declare -A groups=( ["bundleadd"]="ADD" ["bundlelist"]="LST" ["bundleremove"]="REM" \
declare -A groups=( ["autoupdate"]="AUT" ["bundleadd"]="ADD" ["bundlelist"]="LST" ["bundleremove"]="REM" \
["checkupdate"]="CHK" ["hashdump"]="HSD" ["mirror"]="MIR" ["search"]="SRH" \
["update"]="UPD" ["usability"]="USA" ["verify"]="VER" )
+1 -1
View File
@@ -3171,6 +3171,7 @@ get_next_available_id() { # swupd_function
id=$((id+1))
test_dir=$(basename "$(realpath "$test_dir")")
case "$test_dir" in
autoupdate) group=AUT;;
bundleadd) group=ADD;;
bundleremove) group=REM;;
bundlelist) group=LST;;
@@ -3184,7 +3185,6 @@ get_next_available_id() { # swupd_function
completion) group=USA;;
usability) group=USA;;
signature) group=SIG;;
autoupdate) group=AUT;;
info) group=INF;;
clean) group=CLN;;
os-install) group=INS;;