From 6246b990a9917808c887e17e7077125293efed53 Mon Sep 17 00:00:00 2001 From: "Rafael G. Ruiz" Date: Mon, 26 Apr 2021 04:18:31 +0200 Subject: [PATCH] kargs: Add CLI switch --unchanged-exit-77 The new switch will rise an exit code 77 if kernel args are unchanged Closes: #1802 Signed-off-by: Rafael G. Ruiz --- src/app/rpmostree-builtin-kargs.cxx | 15 ++++- src/daemon/rpmostreed-transaction-types.cxx | 64 ++++++++++----------- tests/vmcheck/test-kernel-args.sh | 14 +++++ 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/app/rpmostree-builtin-kargs.cxx b/src/app/rpmostree-builtin-kargs.cxx index 9b8e8b65..11ccc351 100644 --- a/src/app/rpmostree-builtin-kargs.cxx +++ b/src/app/rpmostree-builtin-kargs.cxx @@ -38,6 +38,7 @@ static char **opt_kernel_replace_strings; static char *opt_osname; static char *opt_deploy_index; static gboolean opt_lock_finalization; +static gboolean opt_unchanged_exit_77; static GOptionEntry option_entries[] = { { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operation on provided OSNAME", "OSNAME" }, @@ -48,6 +49,7 @@ static GOptionEntry option_entries[] = { { "delete", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_delete_strings, "Delete a specific kernel argument key/val pair or an entire argument with a single key/value pair", "KEY=VALUE"}, { "append-if-missing", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_append_if_missing_strings, "Like --append, but does nothing if the key is already present", "KEY=VALUE" }, { "delete-if-present", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_delete_if_present_strings, "Like --delete, but does nothing if the key is already missing", "KEY=VALUE" }, + { "unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_unchanged_exit_77, "If no kernel args changed, exit 77", NULL }, { "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_import_proc_cmdline, "Instead of modifying old kernel arguments, we modify args from current /proc/cmdline (the booted deployment)", NULL }, { "editor", 0, 0, G_OPTION_ARG_NONE, &opt_editor, "Use an editor to modify the kernel arguments", NULL }, { "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL }, @@ -277,6 +279,7 @@ rpmostree_builtin_kargs (int argc, if (opt_kernel_delete_if_present_strings && *opt_kernel_delete_if_present_strings) g_variant_dict_insert (&dict, "delete-if-present", "^as", opt_kernel_delete_if_present_strings); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); + g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy); if (opt_editor) { @@ -355,7 +358,17 @@ rpmostree_builtin_kargs (int argc, error)) return FALSE; - g_print("Kernel arguments updated.\nRun \"systemctl reboot\" to start a reboot\n"); + if (opt_unchanged_exit_77) + { + if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + { + invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; + return TRUE; + } + } + + if (rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_print("Kernel arguments updated.\nRun \"systemctl reboot\" to start a reboot\n"); return TRUE; } diff --git a/src/daemon/rpmostreed-transaction-types.cxx b/src/daemon/rpmostreed-transaction-types.cxx index 7b97093c..89b61651 100644 --- a/src/daemon/rpmostreed-transaction-types.cxx +++ b/src/daemon/rpmostreed-transaction-types.cxx @@ -2705,6 +2705,7 @@ kernel_arg_transaction_execute (RpmostreedTransaction *transaction, auto command_line = static_cast(vardict_lookup_ptr (self->options, "initiating-command-line", "&s")); g_autofree char **append_if_missing = static_cast(vardict_lookup_strv_canonical (self->options, "append-if-missing")); g_autofree char **delete_if_present = static_cast(vardict_lookup_strv_canonical (self->options, "delete-if-present")); + gboolean changed = FALSE; /* don't want to pull new content for this */ upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL; @@ -2728,56 +2729,55 @@ kernel_arg_transaction_execute (RpmostreedTransaction *transaction, if (upgrader == NULL) return FALSE; - if (self->kernel_args_deleted) - { /* Delete all the entries included in the kernel args */ - for (char **iter = self->kernel_args_deleted; iter && *iter; iter++) - { - const char* arg = *iter; - if (!ostree_kernel_args_delete (kargs, arg, error)) - return FALSE; - } + for (char **iter = self->kernel_args_deleted; iter && *iter; iter++) + { + const char* arg = *iter; + if (!ostree_kernel_args_delete (kargs, arg, error)) + return FALSE; + changed = TRUE; } - if (self->kernel_args_replaced) + for (char **iter = self->kernel_args_replaced; iter && *iter; iter++) { - for (char **iter = self->kernel_args_replaced; iter && *iter; iter++) - { - const char *arg = *iter; - if (!ostree_kernel_args_new_replace (kargs, arg, error)) - return FALSE; - } + const char *arg = *iter; + if (!ostree_kernel_args_new_replace (kargs, arg, error)) + return FALSE; + changed = TRUE; } if (self->kernel_args_added) { ostree_kernel_args_append_argv (kargs, self->kernel_args_added); + changed = TRUE; } - if (append_if_missing) + for (char **iter = append_if_missing; iter && *iter; iter++) { - for (char **iter = append_if_missing; iter && *iter; iter++) + const char *arg = *iter; + if (!g_strv_contains (existing_kargs, arg)) { - const char *arg = *iter; - if (!g_strv_contains (existing_kargs, arg)) - { - ostree_kernel_args_append (kargs, arg); - } - + ostree_kernel_args_append (kargs, arg); + changed = TRUE; } } - if (delete_if_present) + + for (char **iter = delete_if_present; iter && *iter; iter++) { - for (char **iter = delete_if_present; iter && *iter; iter++) + const char *arg = *iter; + if (g_strv_contains (existing_kargs, arg)) { - const char *arg = *iter; - if (g_strv_contains (existing_kargs, arg)) - { - if (!ostree_kernel_args_delete (kargs, arg, error)) - return FALSE; - } + if (!ostree_kernel_args_delete (kargs, arg, error)) + return FALSE; + changed = TRUE; } - } + } + + if (!changed) + { + rpmostree_output_message ("No changes."); + return TRUE; + } /* After all the arguments are processed earlier, we convert it to a string list*/ g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs); diff --git a/tests/vmcheck/test-kernel-args.sh b/tests/vmcheck/test-kernel-args.sh index ebdbe2c7..6b4e3f73 100755 --- a/tests/vmcheck/test-kernel-args.sh +++ b/tests/vmcheck/test-kernel-args.sh @@ -167,6 +167,20 @@ vm_rpmostree kargs > if_not_present.txt diff kargs.txt if_not_present.txt echo "ok kargs deleted with delete-if-present only if present" +#Test for rpm-ostree kargs unchanged-exit-77 +rc=0 +vm_rpmostree kargs --append-if-missing=PACKAGE3=TEST3 --unchanged-exit-77 || rc=$? +assert_streq $rc 0 +vm_rpmostree kargs --append-if-missing=PACKAGE3=TEST3 --unchanged-exit-77 || rc=$? +assert_streq $rc 77 +rc=0 +vm_rpmostree kargs --delete-if-present=PACKAGE3=TEST3 --unchanged-exit-77 || rc=$? +assert_streq $rc 0 +vm_rpmostree kargs --delete-if-present=PACKAGE3=TEST3 --unchanged-exit-77 || rc=$? +assert_streq $rc 77 +echo "ok exit 77 when unchanged kargs with unchanged-exit-77" + + # XXX: uncomment this when we migrate CI to FCOS # # And reset this bit # vm_cmd ostree config --repo /sysroot/ostree/repo set sysroot.readonly false