mirror of
https://github.com/clearlinux/swupd-client.git
synced 2026-08-19 11:56:27 +00:00
Add --non-interactive flag
Some commands were recently added to swupd which require user interaction under certain circumstances, when this happens the user has to manually enter either Y/N to continue or abort the current process. This commit provides a --non-interactive=<yes/no> flag that can be used to avoid getting this interactive prompts. Signed-off-by: Castulo Martinez <castulo.martinez@intel.com>
This commit is contained in:
committed by
Otavio Pontes
parent
b0357b1b5a
commit
5a957cfd18
@@ -82,6 +82,9 @@
|
||||
# Wait for the post-update scripts to complete (boolean value)
|
||||
#wait_for_scripts=<true/false>
|
||||
|
||||
# Sets an automatic response to all prompts and run non-interactively (string value)
|
||||
#assume=<yes/no>
|
||||
|
||||
|
||||
#
|
||||
# The sections below contain the options that apply specifically to
|
||||
|
||||
@@ -144,6 +144,10 @@ used to modify the core behavior and resources that swupd uses.
|
||||
|
||||
Prints the swupd output as a machine readable JSON stream.
|
||||
|
||||
- ``-y, --yes``
|
||||
|
||||
Assume yes as answer to all prompts and run non-interactively.
|
||||
|
||||
- ``--allow-insecure-http``
|
||||
|
||||
For security reasons, swupd only allows system updates using
|
||||
@@ -175,6 +179,10 @@ used to modify the core behavior and resources that swupd uses.
|
||||
|
||||
Wait for the post-update scripts to complete.
|
||||
|
||||
- ``--assume={yes|no}``
|
||||
|
||||
Sets an automatic response to all prompts and run non-interactively.
|
||||
|
||||
|
||||
SUBCOMMANDS
|
||||
===========
|
||||
|
||||
@@ -166,8 +166,8 @@ static enum swupd_code validate_file_permissions(struct list *files_to_be_instal
|
||||
if (ret_code == SWUPD_NO) {
|
||||
/* the bundle has files with dangerous permissions,
|
||||
* ask the user wether to continue or not */
|
||||
info("\n");
|
||||
if (confirm_action("The 3rd-party bundle you are about to install contains files with dangerous permission", " with the installation")) {
|
||||
warn("\nThe 3rd-party bundle you are about to install contains files with dangerous permission\n");
|
||||
if (confirm_action()) {
|
||||
ret_code = SWUPD_OK;
|
||||
} else {
|
||||
ret_code = SWUPD_INVALID_FILE;
|
||||
|
||||
@@ -224,8 +224,8 @@ static enum swupd_code validate_file_permissions(struct list *files_to_be_update
|
||||
if (ret_code == SWUPD_NO) {
|
||||
/* the bundle has files with dangerous permissions,
|
||||
* ask the user wether to continue or not */
|
||||
info("\n");
|
||||
if (confirm_action("The 3rd-party update you are about to install contains files with dangerous permission", " with the update")) {
|
||||
warn("\nThe 3rd-party update you are about to install contains files with dangerous permission\n");
|
||||
if (confirm_action()) {
|
||||
ret_code = SWUPD_OK;
|
||||
} else {
|
||||
ret_code = SWUPD_INVALID_FILE;
|
||||
|
||||
@@ -42,10 +42,12 @@
|
||||
#define FLAG_DEBUG 1003
|
||||
#define FLAG_ALLOW_INSECURE_HTTP 1004
|
||||
#define FLAG_VERBOSE 1005
|
||||
#define FLAG_ASSUME 1006
|
||||
|
||||
struct globals globals = {
|
||||
.sigcheck = true,
|
||||
.timecheck = true,
|
||||
.user_interaction = INTERACTIVE,
|
||||
.max_retries = DEFAULT_MAX_RETRIES,
|
||||
.retry_delay = DEFAULT_RETRY_DELAY,
|
||||
.update_server_port = -1,
|
||||
@@ -412,6 +414,34 @@ bool set_default_urls()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_assume_option(char *option)
|
||||
{
|
||||
bool ret;
|
||||
char *option_lower = NULL;
|
||||
|
||||
if (!option) {
|
||||
error("Option shouldn't be NULL, please choose either 'yes' or 'no' as your option\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
option_lower = str_tolower(option);
|
||||
|
||||
if (strcmp(option_lower, "y") == 0 || strcmp(option_lower, "yes") == 0) {
|
||||
globals.user_interaction = NON_INTERACTIVE_ASSUME_YES;
|
||||
ret = true;
|
||||
} else if (strcmp(option_lower, "n") == 0 || strcmp(option_lower, "no") == 0) {
|
||||
globals.user_interaction = NON_INTERACTIVE_ASSUME_NO;
|
||||
ret = true;
|
||||
} else {
|
||||
error("Please choose either 'yes' or 'no' as your non interactive option\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
free_string(&option_lower);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool globals_init(void)
|
||||
{
|
||||
if (!globals.state_dir) {
|
||||
@@ -524,6 +554,8 @@ static const struct option global_opts[] = {
|
||||
{ "allow-insecure-http", no_argument, 0, FLAG_ALLOW_INSECURE_HTTP },
|
||||
{ "wait-for-scripts", no_argument, 0, FLAG_WAIT_FOR_SCRIPTS },
|
||||
{ "verbose", no_argument, 0, FLAG_VERBOSE },
|
||||
{ "assume", required_argument, 0, FLAG_ASSUME },
|
||||
{ "yes", no_argument, 0, 'y' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -613,6 +645,8 @@ static bool global_parse_opt(int opt, char *optarg)
|
||||
case 'j':
|
||||
json_format = optarg_to_bool(optarg);
|
||||
return true;
|
||||
case 'y':
|
||||
return set_assume_option("y");
|
||||
case FLAG_NO_PROGRESS:
|
||||
progress_set_enabled(!optarg_to_bool(optarg));
|
||||
return true;
|
||||
@@ -631,6 +665,8 @@ static bool global_parse_opt(int opt, char *optarg)
|
||||
case FLAG_VERBOSE:
|
||||
verbose = true;
|
||||
return true;
|
||||
case FLAG_ASSUME:
|
||||
return set_assume_option(optarg);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -683,12 +719,14 @@ void global_print_help(void)
|
||||
print(" -N, --no-scripts Do not run the post-update scripts and boot update tool\n");
|
||||
print(" -b, --no-boot-update Do not install boot files to the boot partition (containers)\n");
|
||||
print(" -j, --json-output Print all output as a JSON stream\n");
|
||||
print(" -y, --yes Assume yes as answer to all prompts and run non-interactively\n");
|
||||
print(" --allow-insecure-http Allow updates over insecure connections\n");
|
||||
print(" --quiet Quiet output. Print only important information and errors\n");
|
||||
print(" --verbose Enable verbosity for commands\n");
|
||||
print(" --debug Print extra information to help debugging problems\n");
|
||||
print(" --no-progress Don't print progress report\n");
|
||||
print(" --wait-for-scripts Wait for the post-update scripts to complete\n");
|
||||
print(" --assume=[yes|no] Sets an automatic response to all prompts and run non-interactively\n");
|
||||
print("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ extern "C" {
|
||||
|
||||
#define optarg_to_bool(_optarg) (_optarg ? strtobool(_optarg) : true)
|
||||
|
||||
enum user_interaction {
|
||||
INTERACTIVE = 0,
|
||||
NON_INTERACTIVE_ASSUME_YES,
|
||||
NON_INTERACTIVE_ASSUME_NO
|
||||
};
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
@@ -50,6 +56,7 @@ extern struct globals {
|
||||
int update_count;
|
||||
int update_server_port;
|
||||
int update_skip;
|
||||
int user_interaction;
|
||||
timelist *global_times;
|
||||
} globals;
|
||||
|
||||
|
||||
+9
-6
@@ -1201,16 +1201,19 @@ char *get_tracking_dir(void)
|
||||
return sys_path_join(globals.state_dir, "bundles");
|
||||
}
|
||||
|
||||
bool confirm_action(const char *warning_msg, const char *action)
|
||||
bool confirm_action(void)
|
||||
{
|
||||
int response;
|
||||
|
||||
if (warning_msg) {
|
||||
warn("%s\n", warning_msg);
|
||||
info("Do you want to continue? (y/N): ");
|
||||
if (globals.user_interaction == INTERACTIVE) {
|
||||
response = tolower(getchar());
|
||||
info("\n");
|
||||
} else {
|
||||
info("%s\n", globals.user_interaction == NON_INTERACTIVE_ASSUME_YES ? "y" : "N");
|
||||
info("The \"--assume=%s\" option was used\n", globals.user_interaction == NON_INTERACTIVE_ASSUME_YES ? "yes" : "no");
|
||||
response = globals.user_interaction == NON_INTERACTIVE_ASSUME_YES ? 'y' : 'n';
|
||||
}
|
||||
info("Do you want to continue%s? (y/N): ", action ? action : "");
|
||||
response = tolower(getchar());
|
||||
info("%s\n", response == 'y' ? "y" : "N");
|
||||
|
||||
return response == 'y';
|
||||
}
|
||||
|
||||
+1
-1
@@ -319,7 +319,7 @@ extern void print_header(const char *header);
|
||||
extern void prettify_size(long size_in_bytes, char **pretty_size);
|
||||
extern int link_or_rename(const char *orig, const char *dest);
|
||||
extern int create_state_dirs(const char *state_dir_path);
|
||||
extern bool confirm_action(const char *warning_msg, const char *action);
|
||||
extern bool confirm_action(void);
|
||||
|
||||
/* subscription.c */
|
||||
typedef bool (*subs_fn_t)(struct list **subs, const char *component, int recursion, bool is_optional);
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ _swupd()
|
||||
# $1 is the command being completed, $2 is the current word being expanded
|
||||
local opts IFS=$' \t\n'
|
||||
local -i i installed
|
||||
local global="--help --url --contenturl --versionurl --port --path --format --nosigcheck --ignore-time --statedir --certpath --time --no-scripts --no-boot-update --max-parallel-downloads --max-retries --retry-delay --json-output --allow-insecure-http --debug --verbose --quiet --no-progress --wait-for-scripts"
|
||||
local global="--help --url --contenturl --versionurl --port --path --format --nosigcheck --ignore-time --statedir --certpath --time --no-scripts --no-boot-update --max-parallel-downloads --max-retries --retry-delay --json-output --allow-insecure-http --debug --verbose --quiet --no-progress --wait-for-scripts --assume --yes"
|
||||
COMPREPLY=()
|
||||
for ((i=COMP_CWORD-1;i>=0;i--))
|
||||
do case "${COMP_WORDS[$i]}" in
|
||||
|
||||
@@ -143,8 +143,10 @@ local -a global_opts; global_opts=(
|
||||
'(help status -t --time)'{-t,--time}'[Show verbose time output for swupd operations]'
|
||||
'(help status -N --no-scripts)'{-N,--no-scripts}'[Do not run the post-update scripts and boot update tool]'
|
||||
'(help status -b --no-boot-update)'{-b,--no-boot-update}'[Do not install boot files to the boot partition (containers)]'
|
||||
'(help status -y --yes)'{-y,--yes}'[Assume yes as answer to all prompts and run non-interactively]'
|
||||
'(help status)--no-progress[Don`t print progress report]'
|
||||
'(help status)--wait-for-scripts[Wait for the post-update scripts to complete]'
|
||||
'(help status)--assume[Sets an automatic response to all prompts and run non-interactively]'
|
||||
)
|
||||
|
||||
# Level-1 completion for sub-command and options to swupd
|
||||
|
||||
@@ -43,7 +43,7 @@ test_setup() {
|
||||
Warning: File /bar/file_2 has dangerous permissions
|
||||
Warning: File /bar/file_3 has dangerous permissions
|
||||
Warning: The 3rd-party bundle you are about to install contains files with dangerous permission
|
||||
Do you want to continue with the installation? (y/N): y
|
||||
Do you want to continue? (y/N):$SPACE
|
||||
Installing files...
|
||||
Warning: post-update helper scripts skipped due to --no-scripts argument
|
||||
Exporting 3rd-party bundle binaries...
|
||||
@@ -76,7 +76,7 @@ test_setup() {
|
||||
Warning: File /bar/file_2 has dangerous permissions
|
||||
Warning: File /bar/file_3 has dangerous permissions
|
||||
Warning: The 3rd-party bundle you are about to install contains files with dangerous permission
|
||||
Do you want to continue with the installation? (y/N): N
|
||||
Do you want to continue? (y/N):$SPACE
|
||||
Aborting bundle installation...
|
||||
Failed to install 1 of 1 bundles
|
||||
EOM
|
||||
@@ -84,3 +84,61 @@ test_setup() {
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
}
|
||||
|
||||
@test "TPR065: Trying to add a bundle that has dangerous flags from a 3rd-party repository using --assume to run non interactively" {
|
||||
|
||||
# If a bundle from a 3rd-party repository has the setuid, setgid or sticky bit flags
|
||||
# set, then it needs to use the --force flag to be installed since those flags are
|
||||
# dangerous
|
||||
|
||||
run sudo sh -c "$SWUPD 3rd-party bundle-add $SWUPD_OPTS test-bundle1 --assume=no"
|
||||
|
||||
assert_status_is "$SWUPD_INVALID_FILE"
|
||||
expected_output=$(cat <<-EOM
|
||||
Searching for bundle test-bundle1 in the 3rd-party repositories...
|
||||
Bundle test-bundle1 found in 3rd-party repository repo1
|
||||
Bundles added from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons
|
||||
Loading required manifests...
|
||||
Validating 3rd-party bundle binaries...
|
||||
No packs need to be downloaded
|
||||
Validate downloaded files
|
||||
Starting download of remaining update content. This may take a while...
|
||||
Validating 3rd-party bundle file permissions...
|
||||
Warning: File /bar/file_2 has dangerous permissions
|
||||
Warning: File /bar/file_3 has dangerous permissions
|
||||
Warning: The 3rd-party bundle you are about to install contains files with dangerous permission
|
||||
Do you want to continue? (y/N): N
|
||||
The "--assume=no" option was used
|
||||
Aborting bundle installation...
|
||||
Failed to install 1 of 1 bundles
|
||||
EOM
|
||||
)
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
run sudo sh -c "$SWUPD 3rd-party bundle-add $SWUPD_OPTS test-bundle1 --assume=yes"
|
||||
|
||||
assert_status_is "$SWUPD_OK"
|
||||
expected_output=$(cat <<-EOM
|
||||
Searching for bundle test-bundle1 in the 3rd-party repositories...
|
||||
Bundle test-bundle1 found in 3rd-party repository repo1
|
||||
Bundles added from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons
|
||||
Loading required manifests...
|
||||
Validating 3rd-party bundle binaries...
|
||||
No packs need to be downloaded
|
||||
Validate downloaded files
|
||||
No extra files need to be downloaded
|
||||
Validating 3rd-party bundle file permissions...
|
||||
Warning: File /bar/file_2 has dangerous permissions
|
||||
Warning: File /bar/file_3 has dangerous permissions
|
||||
Warning: The 3rd-party bundle you are about to install contains files with dangerous permission
|
||||
Do you want to continue? (y/N): y
|
||||
The "--assume=yes" option was used
|
||||
Installing files...
|
||||
Warning: post-update helper scripts skipped due to --no-scripts argument
|
||||
Exporting 3rd-party bundle binaries...
|
||||
Successfully installed 1 bundle
|
||||
EOM
|
||||
)
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ test_setup() {
|
||||
Warning: The update has a new file /bar/file_4 with dangerous permissions
|
||||
Warning: The update sets dangerous permissions to file /foo/file_1
|
||||
Warning: The 3rd-party update you are about to install contains files with dangerous permission
|
||||
Do you want to continue with the update? (y/N): y
|
||||
Do you want to continue? (y/N):$SPACE
|
||||
Installing files...
|
||||
Update was applied
|
||||
Updating 3rd-party bundle binaries...
|
||||
@@ -110,7 +110,7 @@ test_setup() {
|
||||
Warning: The update has a new file /bar/file_4 with dangerous permissions
|
||||
Warning: The update sets dangerous permissions to file /foo/file_1
|
||||
Warning: The 3rd-party update you are about to install contains files with dangerous permission
|
||||
Do you want to continue with the update? (y/N): N
|
||||
Do you want to continue? (y/N):$SPACE
|
||||
Aborting update...
|
||||
Update failed
|
||||
EOM
|
||||
@@ -118,3 +118,81 @@ test_setup() {
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
}
|
||||
|
||||
@test "TPR064: Try updating a system from a 3rd-party repo when the update has files with dangerous flags using --assume to run non interactively" {
|
||||
|
||||
# the --non-interactive flag can be used to avoid getting prompots
|
||||
# from swupd
|
||||
|
||||
run sudo sh -c "$SWUPD 3rd-party update $SWUPD_OPTS --assume=no"
|
||||
|
||||
assert_status_is "$SWUPD_INVALID_FILE"
|
||||
expected_output=$(cat <<-EOM
|
||||
_______________________
|
||||
3rd-Party Repo: repo1
|
||||
_______________________
|
||||
Updates from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons
|
||||
Update started
|
||||
Preparing to update from 10 to 20
|
||||
Downloading packs for:
|
||||
- test-bundle1
|
||||
Finishing packs extraction...
|
||||
Statistics for going from version 10 to version 20:
|
||||
changed bundles : 1
|
||||
new bundles : 0
|
||||
deleted bundles : 0
|
||||
changed files : 3
|
||||
new files : 2
|
||||
deleted files : 0
|
||||
Validate downloaded files
|
||||
No extra files need to be downloaded
|
||||
Validating 3rd-party bundle file permissions...
|
||||
Warning: The update has a new file /bar/file_4 with dangerous permissions
|
||||
Warning: The update sets dangerous permissions to file /foo/file_1
|
||||
Warning: The 3rd-party update you are about to install contains files with dangerous permission
|
||||
Do you want to continue? (y/N): N
|
||||
The "--assume=no" option was used
|
||||
Aborting update...
|
||||
Update failed
|
||||
EOM
|
||||
)
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
run sudo sh -c "$SWUPD 3rd-party update $SWUPD_OPTS --yes"
|
||||
|
||||
assert_status_is "$SWUPD_OK"
|
||||
expected_output=$(cat <<-EOM
|
||||
_______________________
|
||||
3rd-Party Repo: repo1
|
||||
_______________________
|
||||
Updates from a 3rd-party repository are forced to run with the --no-scripts flag for security reasons
|
||||
Update started
|
||||
Preparing to update from 10 to 20
|
||||
Downloading packs for:
|
||||
- test-bundle1
|
||||
Finishing packs extraction...
|
||||
Statistics for going from version 10 to version 20:
|
||||
changed bundles : 1
|
||||
new bundles : 0
|
||||
deleted bundles : 0
|
||||
changed files : 3
|
||||
new files : 2
|
||||
deleted files : 0
|
||||
Validate downloaded files
|
||||
No extra files need to be downloaded
|
||||
Validating 3rd-party bundle file permissions...
|
||||
Warning: The update has a new file /bar/file_4 with dangerous permissions
|
||||
Warning: The update sets dangerous permissions to file /foo/file_1
|
||||
Warning: The 3rd-party update you are about to install contains files with dangerous permission
|
||||
Do you want to continue? (y/N): y
|
||||
The "--assume=yes" option was used
|
||||
Installing files...
|
||||
Update was applied
|
||||
Updating 3rd-party bundle binaries...
|
||||
Warning: post-update helper scripts skipped due to --no-scripts argument
|
||||
Update successful - System updated from version 10 to version 20
|
||||
EOM
|
||||
)
|
||||
assert_is_output "$expected_output"
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
FUNC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TEST_ROOT_DIR="$(pwd)"
|
||||
TEST_FILENAME=$(basename "$BATS_TEST_FILENAME")
|
||||
@@ -9,6 +7,8 @@ TEST_NAME=${TEST_FILENAME%.bats}
|
||||
THEME_DIRNAME="$BATS_TEST_DIRNAME"
|
||||
THIRD_PARTY_BUNDLES_DIR="opt/3rd-party/bundles"
|
||||
THIRD_PARTY_BIN_DIR="opt/3rd-party/bin"
|
||||
SPACE=" "
|
||||
TAB=" "
|
||||
|
||||
export TEST_NAME
|
||||
export TEST_NAME_SHORT="$TEST_NAME"
|
||||
@@ -17,6 +17,8 @@ export FUNC_DIR
|
||||
export SWUPD_DIR="$FUNC_DIR/../.."
|
||||
export THIRD_PARTY_BUNDLES_DIR
|
||||
export THIRD_PARTY_BIN_DIR
|
||||
export SPACE
|
||||
export TAB
|
||||
|
||||
# detect where the swupd binary is
|
||||
if [ -e "$SWUPD" ]; then
|
||||
|
||||
Reference in New Issue
Block a user