Skip to content

Commit

Permalink
Copy used command-line and set as transaction title
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jlebon authored and rh-atomic-bot committed May 8, 2019
1 parent 01fbaa7 commit 4c99cc7
Show file tree
Hide file tree
Showing 24 changed files with 155 additions and 45 deletions.
23 changes: 22 additions & 1 deletion src/app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <unistd.h>
#include <locale.h>

#include "rpmostree-util.h"
#include "rpmostree-builtins.h"
#include "rpmostree-polkit-agent.h"

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-deploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-finalize-deployment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-initramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-kargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtin-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct RpmOstreeCommand {
*/
struct RpmOstreeCommandInvocation {
RpmOstreeCommand *command;
const char *command_line;
int exit_code;
};
G_END_DECLS
Expand Down
2 changes: 2 additions & 0 deletions src/app/rpmostree-builtin-upgrade.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ())
Expand Down Expand Up @@ -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. */
Expand Down
8 changes: 5 additions & 3 deletions src/app/rpmostree-override-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions src/app/rpmostree-pkg-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
-->
<method name="UpdateDeployment">
<arg type="a{sv}" name="modifiers" direction="in"/>
Expand Down
4 changes: 4 additions & 0 deletions src/daemon/rpmostree-sysroot-upgrader.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct RpmOstreeSysrootUpgrader {
OstreeRepo *repo;
char *osname;
RpmOstreeSysrootUpgraderFlags flags;
char *command_line;

OstreeDeployment *cfg_merge_deployment;
OstreeDeployment *origin_merge_deployment;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
9 changes: 5 additions & 4 deletions src/daemon/rpmostree-sysroot-upgrader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
97 changes: 60 additions & 37 deletions src/daemon/rpmostreed-transaction-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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))
Expand Down
Loading

0 comments on commit 4c99cc7

Please sign in to comment.