From 4c99cc765f81a95e87e875af01c5aa60093dcd0b Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 1 May 2019 10:07:31 -0400 Subject: [PATCH] Copy used command-line and set as transaction title In the app, rebuild the exact command-line that the client used and pass that to the daemon to be used as the transaction title. Especially in transactions like `UpdateDeployment()`, we can avoid reverse-engineering what the original command used was. This will be used by the upcoming history feature to record the command-line used in the journal. Closes: #1824 Approved by: rfairley --- src/app/main.c | 23 ++++- src/app/rpmostree-builtin-deploy.c | 1 + .../rpmostree-builtin-finalize-deployment.c | 1 + src/app/rpmostree-builtin-initramfs.c | 1 + src/app/rpmostree-builtin-kargs.c | 1 + src/app/rpmostree-builtin-rebase.c | 1 + src/app/rpmostree-builtin-reset.c | 1 + src/app/rpmostree-builtin-types.h | 1 + src/app/rpmostree-builtin-upgrade.c | 2 + src/app/rpmostree-override-builtins.c | 8 +- src/app/rpmostree-pkg-builtins.c | 1 + src/daemon/org.projectatomic.rpmostree1.xml | 3 + src/daemon/rpmostree-sysroot-upgrader.c | 4 + src/daemon/rpmostree-sysroot-upgrader.h | 9 +- src/daemon/rpmostreed-transaction-types.c | 97 ++++++++++++------- tests/common/libvm.sh | 21 ++++ tests/vmcheck/test-initramfs.sh | 2 + tests/vmcheck/test-kernel-args.sh | 2 + tests/vmcheck/test-layering-basic-1.sh | 2 + tests/vmcheck/test-layering-unified.sh | 10 ++ tests/vmcheck/test-override-local-replace.sh | 2 + tests/vmcheck/test-override-remove.sh | 2 + tests/vmcheck/test-override-replace-2.sh | 3 + tests/vmcheck/test-reset.sh | 2 + 24 files changed, 155 insertions(+), 45 deletions(-) diff --git a/src/app/main.c b/src/app/main.c index be9fd8bcdd..0252c7bedc 100644 --- a/src/app/main.c +++ b/src/app/main.c @@ -29,6 +29,7 @@ #include #include +#include "rpmostree-util.h" #include "rpmostree-builtins.h" #include "rpmostree-polkit-agent.h" @@ -382,13 +383,30 @@ rpmostree_handle_subcommand (int argc, char **argv, /* We need a new sub-invocation with the new command, which also carries a new * exit code, but we'll proxy the latter. */ - RpmOstreeCommandInvocation sub_invocation = { .command = subcommand, .exit_code = -1 }; + RpmOstreeCommandInvocation sub_invocation = { .command = subcommand, + .command_line = invocation->command_line, + .exit_code = -1 }; gboolean ret = subcommand->fn (argc, argv, &sub_invocation, cancellable, error); /* Proxy the exit code */ invocation->exit_code = sub_invocation.exit_code; return ret; } +static char* +rebuild_command_line (int argc, + char **argv) +{ + /* be nice and quote args as needed instead of just g_strjoinv() */ + g_autoptr(GString) command = g_string_new (NULL); + for (int i = 1; i < argc; i++) + { + g_autofree char *quoted = rpmostree_maybe_shell_quote (argv[i]); + g_string_append (command, quoted ?: argv[i]); + g_string_append_c (command, ' '); + } + return g_string_free (g_steal_pointer (&command), FALSE); +} + int main (int argc, char **argv) @@ -420,6 +438,8 @@ main (int argc, GCancellable *cancellable = g_cancellable_new (); + g_autofree char *command_line = rebuild_command_line (argc, argv); + /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through @@ -460,6 +480,7 @@ main (int argc, g_set_prgname (prgname); RpmOstreeCommandInvocation invocation = { .command = command, + .command_line = command_line, .exit_code = -1 }; exit_statusp = &(invocation.exit_code); if (!command->fn (argc, argv, &invocation, cancellable, &local_error)) diff --git a/src/app/rpmostree-builtin-deploy.c b/src/app/rpmostree-builtin-deploy.c index 42f4dccff7..45dd8fc927 100644 --- a/src/app/rpmostree-builtin-deploy.c +++ b/src/app/rpmostree-builtin-deploy.c @@ -117,6 +117,7 @@ rpmostree_builtin_deploy (int argc, g_variant_dict_insert (&dict, "allow-downgrade", "b", TRUE); g_variant_dict_insert (&dict, "cache-only", "b", opt_cache_only); g_variant_dict_insert (&dict, "download-only", "b", opt_download_only); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); /* Use newer D-Bus API only if we have to so we maintain coverage. */ diff --git a/src/app/rpmostree-builtin-finalize-deployment.c b/src/app/rpmostree-builtin-finalize-deployment.c index aa7c34bfc1..cdb269ba3b 100644 --- a/src/app/rpmostree-builtin-finalize-deployment.c +++ b/src/app/rpmostree-builtin-finalize-deployment.c @@ -82,6 +82,7 @@ rpmostree_builtin_finalize_deployment (int argc, g_variant_dict_insert (&dict, "checksum", "s", checksum); g_variant_dict_insert (&dict, "allow-missing-checksum", "b", opt_allow_missing); g_variant_dict_insert (&dict, "allow-unlocked", "b", opt_allow_unlocked); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); g_autofree char *transaction_address = NULL; diff --git a/src/app/rpmostree-builtin-initramfs.c b/src/app/rpmostree-builtin-initramfs.c index 6fc44094db..d0d4952c85 100644 --- a/src/app/rpmostree-builtin-initramfs.c +++ b/src/app/rpmostree-builtin-initramfs.c @@ -135,6 +135,7 @@ rpmostree_builtin_initramfs (int argc, GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); g_autofree char *transaction_address = NULL; diff --git a/src/app/rpmostree-builtin-kargs.c b/src/app/rpmostree-builtin-kargs.c index 447174c866..078920d389 100644 --- a/src/app/rpmostree-builtin-kargs.c +++ b/src/app/rpmostree-builtin-kargs.c @@ -272,6 +272,7 @@ rpmostree_builtin_kargs (int argc, GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); if (opt_editor) diff --git a/src/app/rpmostree-builtin-rebase.c b/src/app/rpmostree-builtin-rebase.c index 9f38915a5b..d7ec4a8159 100644 --- a/src/app/rpmostree-builtin-rebase.c +++ b/src/app/rpmostree-builtin-rebase.c @@ -167,6 +167,7 @@ rpmostree_builtin_rebase (int argc, g_variant_dict_insert (&dict, "cache-only", "b", opt_cache_only); g_variant_dict_insert (&dict, "download-only", "b", opt_download_only); g_variant_dict_insert (&dict, "skip-purge", "b", opt_skip_purge); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); if (opt_custom_origin_url) { if (!opt_custom_origin_description) diff --git a/src/app/rpmostree-builtin-reset.c b/src/app/rpmostree-builtin-reset.c index 18b13f122b..7122687559 100644 --- a/src/app/rpmostree-builtin-reset.c +++ b/src/app/rpmostree-builtin-reset.c @@ -100,6 +100,7 @@ rpmostree_builtin_reset (int argc, g_variant_dict_insert (&dict, "no-overrides", "b", opt_overrides); g_variant_dict_insert (&dict, "no-initramfs", "b", opt_initramfs); g_variant_dict_insert (&dict, "cache-only", "b", cache_only); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); if (!rpmostree_update_deployment (os_proxy, NULL, NULL, install_pkgs, uninstall_pkgs, diff --git a/src/app/rpmostree-builtin-types.h b/src/app/rpmostree-builtin-types.h index cfde72ee6c..7f54ea4636 100644 --- a/src/app/rpmostree-builtin-types.h +++ b/src/app/rpmostree-builtin-types.h @@ -54,6 +54,7 @@ struct RpmOstreeCommand { */ struct RpmOstreeCommandInvocation { RpmOstreeCommand *command; + const char *command_line; int exit_code; }; G_END_DECLS diff --git a/src/app/rpmostree-builtin-upgrade.c b/src/app/rpmostree-builtin-upgrade.c index 730db62d4e..22cfea8975 100644 --- a/src/app/rpmostree-builtin-upgrade.c +++ b/src/app/rpmostree-builtin-upgrade.c @@ -134,6 +134,7 @@ rpmostree_builtin_upgrade (int argc, GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "mode", "s", check_or_preview ? "check" : "auto"); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); /* override default of TRUE if we're handling --check/--preview for backcompat, * or we're *are* handling --trigger-automatic-update-policy, but on a tty */ if (check_or_preview || glnx_stdout_is_tty ()) @@ -165,6 +166,7 @@ rpmostree_builtin_upgrade (int argc, g_variant_dict_insert (&dict, "cache-only", "b", opt_cache_only); g_variant_dict_insert (&dict, "download-only", "b", opt_download_only); g_variant_dict_insert (&dict, "lock-finalization", "b", opt_lock_finalization); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); /* Use newer D-Bus API only if we have to. */ diff --git a/src/app/rpmostree-override-builtins.c b/src/app/rpmostree-override-builtins.c index 436fe283df..50e132e928 100644 --- a/src/app/rpmostree-override-builtins.c +++ b/src/app/rpmostree-override-builtins.c @@ -58,6 +58,7 @@ static GOptionEntry remove_option_entries[] = { static gboolean handle_override (RPMOSTreeSysroot *sysroot_proxy, + RpmOstreeCommandInvocation *invocation, const char *const *override_remove, const char *const *override_replace, const char *const *override_reset, @@ -81,6 +82,7 @@ handle_override (RPMOSTreeSysroot *sysroot_proxy, g_variant_dict_insert (&dict, "no-pull-base", "b", TRUE); g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run); g_variant_dict_insert (&dict, "no-overrides", "b", opt_reset_all); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); 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); @@ -166,7 +168,7 @@ rpmostree_override_builtin_replace (int argc, char **argv, argv++; argc--; argv[argc] = NULL; - return handle_override (sysroot_proxy, + return handle_override (sysroot_proxy, invocation, opt_remove_pkgs, (const char *const*)argv, NULL, cancellable, error); } @@ -209,7 +211,7 @@ rpmostree_override_builtin_remove (int argc, char **argv, argv++; argc--; argv[argc] = NULL; - return handle_override (sysroot_proxy, + return handle_override (sysroot_proxy, invocation, (const char *const*)argv, opt_replace_pkgs, NULL, cancellable, error); } @@ -258,7 +260,7 @@ rpmostree_override_builtin_reset (int argc, char **argv, argv++; argc--; argv[argc] = NULL; - return handle_override (sysroot_proxy, + return handle_override (sysroot_proxy, invocation, NULL, NULL, (const char *const*)argv, cancellable, error); } diff --git a/src/app/rpmostree-pkg-builtins.c b/src/app/rpmostree-pkg-builtins.c index 2e1274f6d8..623ab96cda 100644 --- a/src/app/rpmostree-pkg-builtins.c +++ b/src/app/rpmostree-pkg-builtins.c @@ -96,6 +96,7 @@ pkg_change (RpmOstreeCommandInvocation *invocation, g_variant_dict_insert (&dict, "allow-inactive", "b", opt_allow_inactive); g_variant_dict_insert (&dict, "no-layering", "b", opt_uninstall_all); g_variant_dict_insert (&dict, "idempotent-layering", "b", opt_idempotent); + g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line); g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); gboolean met_local_pkg = FALSE; diff --git a/src/daemon/org.projectatomic.rpmostree1.xml b/src/daemon/org.projectatomic.rpmostree1.xml index 2d45737e82..2d55dfa61f 100644 --- a/src/daemon/org.projectatomic.rpmostree1.xml +++ b/src/daemon/org.projectatomic.rpmostree1.xml @@ -343,6 +343,9 @@ Prevent automatic deployment finalization on shutdown. Clients must manually call FinalizeDeployment() when ready to apply the update and reboot. + "initiating-command-line" (type 's') + Mark the transaction as being initiated by the given command. + This is used for the transaction title and journal entries. --> diff --git a/src/daemon/rpmostree-sysroot-upgrader.c b/src/daemon/rpmostree-sysroot-upgrader.c index 9898fbd35f..fc25e1fac7 100644 --- a/src/daemon/rpmostree-sysroot-upgrader.c +++ b/src/daemon/rpmostree-sysroot-upgrader.c @@ -59,6 +59,7 @@ struct RpmOstreeSysrootUpgrader { OstreeRepo *repo; char *osname; RpmOstreeSysrootUpgraderFlags flags; + char *command_line; OstreeDeployment *cfg_merge_deployment; OstreeDeployment *origin_merge_deployment; @@ -204,6 +205,7 @@ rpmostree_sysroot_upgrader_finalize (GObject *object) g_clear_object (&self->sysroot); g_clear_object (&self->repo); g_free (self->osname); + g_free (self->command_line); g_clear_object (&self->cfg_merge_deployment); g_clear_object (&self->origin_merge_deployment); @@ -1227,6 +1229,7 @@ rpmostree_sysroot_upgrader_set_kargs (RpmOstreeSysrootUpgrader *self, /** * rpmostree_sysroot_upgrader_deploy: * @self: Self + * @initiating_command_line (nullable): command-line that initiated the deployment * @out_deployment: (out) (optional): return location for new deployment * @cancellable: Cancellable * @error: Error @@ -1236,6 +1239,7 @@ rpmostree_sysroot_upgrader_set_kargs (RpmOstreeSysrootUpgrader *self, */ gboolean rpmostree_sysroot_upgrader_deploy (RpmOstreeSysrootUpgrader *self, + const char *initiating_command_line, OstreeDeployment **out_deployment, GCancellable *cancellable, GError **error) diff --git a/src/daemon/rpmostree-sysroot-upgrader.h b/src/daemon/rpmostree-sysroot-upgrader.h index 10bf4fbe2f..a8fc5630aa 100644 --- a/src/daemon/rpmostree-sysroot-upgrader.h +++ b/src/daemon/rpmostree-sysroot-upgrader.h @@ -127,10 +127,11 @@ rpmostree_sysroot_upgrader_pull_repos (RpmOstreeSysrootUpgrader *self, gboolean -rpmostree_sysroot_upgrader_deploy (RpmOstreeSysrootUpgrader *self, - OstreeDeployment **out_deployment, - GCancellable *cancellable, - GError **error); +rpmostree_sysroot_upgrader_deploy (RpmOstreeSysrootUpgrader *self, + const char *initiating_command_line, + OstreeDeployment **out_deployment, + GCancellable *cancellable, + GError **error); void rpmostree_sysroot_upgrader_set_kargs (RpmOstreeSysrootUpgrader *self, diff --git a/src/daemon/rpmostreed-transaction-types.c b/src/daemon/rpmostreed-transaction-types.c index c81434ed6b..af2b9274ff 100644 --- a/src/daemon/rpmostreed-transaction-types.c +++ b/src/daemon/rpmostreed-transaction-types.c @@ -835,45 +835,59 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, } } + const char *command_line = + vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); + /* If we're not actively holding back pulling a new update and we're staying on the same * ref, then by definition we're upgrading. */ const gboolean is_upgrade = (!no_pull_base && !self->refspec && !self->revision); /* Now set the transaction title before doing any work. * https://github.com/projectatomic/rpm-ostree/issues/454 */ - g_autoptr(GString) txn_title = g_string_new (""); - if (is_install) - g_string_append (txn_title, "install"); - else if (is_uninstall) - g_string_append (txn_title, "uninstall"); - else if (is_override) - g_string_append (txn_title, "override"); - else if (self->refspec) - g_string_append (txn_title, "rebase"); - else if (self->revision) - g_string_append (txn_title, "deploy"); + if (command_line) + { + /* special-case the automatic one, otherwise just use verbatim as title */ + const char *title = command_line; + if (strstr (command_line, "--trigger-automatic-update-policy")) + title = download_metadata_only ? "automatic (check)" : "automatic (stage)"; + rpmostree_transaction_set_title (RPMOSTREE_TRANSACTION (transaction), title); + } else - g_string_append (txn_title, "upgrade"); - - /* so users know we were probably fired by the automated timer when looking at status */ - if (cache_only) - g_string_append (txn_title, " (cache only)"); - else if (download_metadata_only) - g_string_append (txn_title, " (check only)"); - else if (download_only) - g_string_append (txn_title, " (download only)"); - - if (self->uninstall_pkgs) - g_string_append_printf (txn_title, "; uninstall: %u", - g_strv_length (self->uninstall_pkgs)); - if (self->install_pkgs) - g_string_append_printf (txn_title, "; install: %u", - g_strv_length (self->install_pkgs)); - if (self->install_local_pkgs) - g_string_append_printf (txn_title, "; localinstall: %u", - g_unix_fd_list_get_length (self->install_local_pkgs)); - - rpmostree_transaction_set_title (RPMOSTREE_TRANSACTION (transaction), txn_title->str); + { + g_autoptr(GString) txn_title = g_string_new (""); + if (is_install) + g_string_append (txn_title, "install"); + else if (is_uninstall) + g_string_append (txn_title, "uninstall"); + else if (is_override) + g_string_append (txn_title, "override"); + else if (self->refspec) + g_string_append (txn_title, "rebase"); + else if (self->revision) + g_string_append (txn_title, "deploy"); + else + g_string_append (txn_title, "upgrade"); + + /* so users know we were probably fired by the automated timer when looking at status */ + if (cache_only) + g_string_append (txn_title, " (cache only)"); + else if (download_metadata_only) + g_string_append (txn_title, " (check only)"); + else if (download_only) + g_string_append (txn_title, " (download only)"); + + if (self->uninstall_pkgs) + g_string_append_printf (txn_title, "; uninstall: %u", + g_strv_length (self->uninstall_pkgs)); + if (self->install_pkgs) + g_string_append_printf (txn_title, "; install: %u", + g_strv_length (self->install_pkgs)); + if (self->install_local_pkgs) + g_string_append_printf (txn_title, "; localinstall: %u", + g_unix_fd_list_get_length (self->install_local_pkgs)); + + rpmostree_transaction_set_title (RPMOSTREE_TRANSACTION (transaction), txn_title->str); + } RpmOstreeSysrootUpgraderFlags upgrader_flags = 0; if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE) @@ -1340,7 +1354,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, } g_autoptr(OstreeDeployment) new_deployment = NULL; - if (!rpmostree_sysroot_upgrader_deploy (upgrader, &new_deployment, + if (!rpmostree_sysroot_upgrader_deploy (upgrader, command_line, &new_deployment, cancellable, error)) return FALSE; @@ -1702,8 +1716,10 @@ initramfs_state_transaction_execute (RpmostreedTransaction *transaction, InitramfsStateTransaction *self = (InitramfsStateTransaction *) transaction; OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); + const char *command_line = + vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); - rpmostree_transaction_set_title ((RPMOSTreeTransaction*)self, "initramfs"); + rpmostree_transaction_set_title ((RPMOSTreeTransaction*)self, command_line ?: "initramfs"); g_autoptr(RpmOstreeSysrootUpgrader) upgrader = rpmostree_sysroot_upgrader_new (sysroot, self->osname, 0, cancellable, error); @@ -1731,7 +1747,7 @@ initramfs_state_transaction_execute (RpmostreedTransaction *transaction, rpmostree_origin_set_regenerate_initramfs (origin, self->regenerate, self->args); rpmostree_sysroot_upgrader_set_origin (upgrader, origin); - if (!rpmostree_sysroot_upgrader_deploy (upgrader, NULL, cancellable, error)) + if (!rpmostree_sysroot_upgrader_deploy (upgrader, command_line, NULL, cancellable, error)) return FALSE; if (vardict_lookup_bool (self->options, "reboot", FALSE)) @@ -2251,6 +2267,11 @@ finalize_deployment_transaction_execute (RpmostreedTransaction *transaction, OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); OstreeRepo *repo = ostree_sysroot_repo (sysroot); + const char *command_line = + vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); + + rpmostree_transaction_set_title ((RPMOSTreeTransaction*)self, command_line ?: "finalize-deployment"); + g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); if (deployments->len == 0) return glnx_throw (error, "No deployments found"); @@ -2380,12 +2401,14 @@ kernel_arg_transaction_execute (RpmostreedTransaction *transaction, KernelArgTransaction *self = (KernelArgTransaction *) transaction; OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); RpmOstreeSysrootUpgraderFlags upgrader_flags = 0; + const char *command_line = + vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); /* don't want to pull new content for this */ upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_SYNTHETIC_PULL; upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGCACHE_ONLY; - rpmostree_transaction_set_title ((RPMOSTreeTransaction*)self, "kargs"); + rpmostree_transaction_set_title ((RPMOSTreeTransaction*)self, command_line ?: "kargs"); /* Read in the existing kernel args and convert those to an #OstreeKernelArg instance for API usage */ __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = _ostree_kernel_args_from_string (self->existing_kernel_args); @@ -2427,7 +2450,7 @@ kernel_arg_transaction_execute (RpmostreedTransaction *transaction, g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs); rpmostree_sysroot_upgrader_set_kargs (upgrader, kargs_strv); - if (!rpmostree_sysroot_upgrader_deploy (upgrader, NULL, cancellable, error)) + if (!rpmostree_sysroot_upgrader_deploy (upgrader, command_line, NULL, cancellable, error)) return FALSE; if (vardict_lookup_bool (self->options, "reboot", FALSE)) diff --git a/tests/common/libvm.sh b/tests/common/libvm.sh index 8b5b1aca3e..829830d084 100644 --- a/tests/common/libvm.sh +++ b/tests/common/libvm.sh @@ -621,3 +621,24 @@ vm_ostree_repo_commit_layered_as_base() { vm_ostree_commit_layered_as_base() { vm_ostree_repo_commit_layered_as_base /ostree/repo "$@" } + +vm_status_watch_start() { + rm -rf status-watch.txt + while sleep 1; do + vm_rpmostree status >> status-watch.txt + done & + _status_watch_pid=$! + # NB: the EXIT trap is used by libtest, but not the ERR trap + trap "kill $_status_watch_pid" ERR + set -E # inherit trap +} + +vm_status_watch_check() { + [ -n "${_status_watch_pid:-}" ] + kill $_status_watch_pid + _status_watch_pid= + set +E + [ -f status-watch.txt ] + assert_file_has_content_literal status-watch.txt "$@" + rm -rf status-watch.txt +} diff --git a/tests/vmcheck/test-initramfs.sh b/tests/vmcheck/test-initramfs.sh index 9f77afd3fb..73c9bff003 100755 --- a/tests/vmcheck/test-initramfs.sh +++ b/tests/vmcheck/test-initramfs.sh @@ -46,7 +46,9 @@ fi assert_file_has_content err.txt "arg.*used with.*enable" echo "ok initramfs state" +vm_status_watch_start vm_rpmostree initramfs --enable > initramfs.txt +vm_status_watch_check "Transaction: initramfs --enable" assert_file_has_content initramfs.txt "Initramfs regeneration.*enabled" vm_rpmostree initramfs > initramfs.txt assert_file_has_content initramfs.txt "Initramfs regeneration.*enabled" diff --git a/tests/vmcheck/test-kernel-args.sh b/tests/vmcheck/test-kernel-args.sh index 166b8596f2..570d986acb 100755 --- a/tests/vmcheck/test-kernel-args.sh +++ b/tests/vmcheck/test-kernel-args.sh @@ -67,7 +67,9 @@ assert_file_has_content tmp_conf.txt 'APPENDARG=2NDAPPEND' echo "ok delete a single key/value pair from multi valued key pairs" # Test for rpm-ostree kargs replace +vm_status_watch_start vm_rpmostree kargs --append=REPLACE_TEST=TEST --append=REPLACE_MULTI_TEST=TEST --append=REPLACE_MULTI_TEST=NUMBERTWO +vm_status_watch_check "Transaction: kargs --append=REPLACE_TEST=TEST --append=REPLACE_MULTI_TEST=TEST --append=REPLACE_MULTI_TEST=NUMBERTWO" # Test for replacing key/value pair with only one value vm_rpmostree kargs --replace=REPLACE_TEST=HELLO diff --git a/tests/vmcheck/test-layering-basic-1.sh b/tests/vmcheck/test-layering-basic-1.sh index 8dd7281660..2d08319ebb 100755 --- a/tests/vmcheck/test-layering-basic-1.sh +++ b/tests/vmcheck/test-layering-basic-1.sh @@ -122,7 +122,9 @@ vm_rpmostree install foo-1.0 --idempotent assert_streq $old_pending $(vm_get_pending_csum) echo "ok idempotent install" +vm_status_watch_start vm_rpmostree uninstall foo-1.0 +vm_status_watch_check "Transaction: uninstall foo-1.0" # Test idempotent uninstall old_pending=$(vm_get_pending_csum) diff --git a/tests/vmcheck/test-layering-unified.sh b/tests/vmcheck/test-layering-unified.sh index ad81841253..14003af724 100755 --- a/tests/vmcheck/test-layering-unified.sh +++ b/tests/vmcheck/test-layering-unified.sh @@ -39,7 +39,9 @@ bar_rpm=/var/tmp/vmcheck/yumrepo/packages/x86_64/bar-1.0-1.x86_64.rpm # UPGRADE commit=$(vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck) +vm_status_watch_start vm_rpmostree upgrade --install bar --install $foo_rpm +vm_status_watch_check "Transaction: upgrade --install bar --install $foo_rpm" vm_assert_status_jq \ ".deployments[0][\"base-checksum\"] == \"${commit}\"" \ '.deployments[0]["packages"]|length == 1' \ @@ -54,7 +56,9 @@ echo "ok upgrade with bar and local foo" commit=$(vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck \ --add-metadata-string=version=SUPADUPAVERSION) +vm_status_watch_start vm_rpmostree deploy SUPADUPAVERSION --install foo --install $bar_rpm +vm_status_watch_check "Transaction: deploy SUPADUPAVERSION --install foo --install $bar_rpm" vm_assert_status_jq \ ".deployments[0][\"base-checksum\"] == \"${commit}\"" \ '.deployments[0]["version"] == "SUPADUPAVERSION"' \ @@ -70,8 +74,10 @@ echo "ok deploy with foo and local bar" commit=$(vm_cmd ostree commit -b vmcheck_tmp/rebase \ --tree=ref=vmcheck --add-metadata-string=version=SUPADUPAVERSION) +vm_status_watch_start vm_rpmostree rebase vmcheck_tmp/rebase SUPADUPAVERSION \ --install bar --install $foo_rpm +vm_status_watch_check "Transaction: rebase vmcheck_tmp/rebase SUPADUPAVERSION --install bar --install $foo_rpm" vm_assert_status_jq \ ".deployments[0][\"base-checksum\"] == \"${commit}\"" \ '.deployments[0]["origin"] == "vmcheck_tmp/rebase"' \ @@ -86,12 +92,16 @@ echo "ok rebase with bar and local foo" # PKG CHANGES +vm_status_watch_start vm_rpmostree install $foo_rpm +vm_status_watch_check "Transaction: install $foo_rpm" vm_assert_status_jq \ '.deployments[0]["packages"]|length == 0' \ '.deployments[0]["requested-local-packages"]|length == 1' \ '.deployments[0]["requested-local-packages"]|index("foo-1.0-1.x86_64") >= 0' +vm_status_watch_start vm_rpmostree uninstall foo-1.0-1.x86_64 --install bar +vm_status_watch_check "Transaction: uninstall foo-1.0-1.x86_64 --install bar" vm_assert_status_jq \ '.deployments[0]["packages"]|length == 1' \ '.deployments[0]["packages"]|index("bar") >= 0' \ diff --git a/tests/vmcheck/test-override-local-replace.sh b/tests/vmcheck/test-override-local-replace.sh index 2d64aba75a..f330eeac05 100755 --- a/tests/vmcheck/test-override-local-replace.sh +++ b/tests/vmcheck/test-override-local-replace.sh @@ -125,7 +125,9 @@ assert_replaced_local_pkg bar-1.0-1.x86_64 bar-0.9-1.x86_64 echo "ok override replacements carried through upgrade" # try to reset pkgs using both name and nevra +vm_status_watch_start vm_rpmostree override reset foo fooext-2.0-1.x86_64 +vm_status_watch_check "Transaction: override reset foo fooext-2.0-1.x86_64" vm_assert_status_jq \ '.deployments[0]["base-local-replacements"]|length == 1' \ '.deployments[0]["requested-base-local-replacements"]|length == 1' diff --git a/tests/vmcheck/test-override-remove.sh b/tests/vmcheck/test-override-remove.sh index 9626afe6cd..2eeb876ef4 100755 --- a/tests/vmcheck/test-override-remove.sh +++ b/tests/vmcheck/test-override-remove.sh @@ -219,6 +219,8 @@ vm_rpmostree cleanup -p echo "ok override remove base dep to layered pkg fails" vm_build_rpm boo +vm_status_watch_start vm_rpmostree override remove foo --install boo +vm_status_watch_check "Transaction: override remove foo --install boo" vm_rpmostree cleanup -p echo "ok remove and --install at the same time" diff --git a/tests/vmcheck/test-override-replace-2.sh b/tests/vmcheck/test-override-replace-2.sh index 4ed3425726..118ba8c2b9 100755 --- a/tests/vmcheck/test-override-replace-2.sh +++ b/tests/vmcheck/test-override-replace-2.sh @@ -77,7 +77,10 @@ build_rpms() { } build_rpms +vm_status_watch_start vm_rpmostree install {foo,bar}-ext-{1,2} +vm_status_watch_check "Transaction: install foo-ext-1 foo-ext-2 bar-ext-1 bar-ext-2" + vm_cmd ostree refs $(vm_get_deployment_info 0 checksum) \ --create vmcheck_tmp/with_foo_and_bar vm_rpmostree cleanup -p diff --git a/tests/vmcheck/test-reset.sh b/tests/vmcheck/test-reset.sh index 96a7349497..78c03ce2d1 100755 --- a/tests/vmcheck/test-reset.sh +++ b/tests/vmcheck/test-reset.sh @@ -97,7 +97,9 @@ echo "ok reset EVERYTHING" # reset everything and overlay at the same time vm_build_rpm a-new-package +vm_status_watch_start vm_rpmostree reset --install a-new-package +vm_status_watch_check "Transaction: reset --install a-new-package" vm_assert_status_jq \ '.deployments[0]["packages"]|length == 1' \ '.deployments[0]["packages"]|index("a-new-package") >= 0' \