diff --git a/src/app/libmain.cxx b/src/app/libmain.cxx index 45653d0cb8..dfbb9269ef 100644 --- a/src/app/libmain.cxx +++ b/src/app/libmain.cxx @@ -143,7 +143,6 @@ static RpmOstreeCommand commands[] = { }; static gboolean opt_version; -static gboolean opt_force_peer; static char *opt_sysroot; static gchar **opt_install; static gchar **opt_uninstall; @@ -153,9 +152,8 @@ static GOptionEntry global_entries[] = { { NULL } }; -static GOptionEntry daemon_entries[] = { +static GOptionEntry mux_entries[] = { { "sysroot", 0, 0, G_OPTION_ARG_STRING, &opt_sysroot, "Use system root SYSROOT (default: /)", "SYSROOT" }, - { "peer", 0, 0, G_OPTION_ARG_NONE, &opt_force_peer, "Force a peer-to-peer connection instead of using the system message bus", NULL }, { NULL } }; @@ -219,13 +217,15 @@ rpmostree_option_context_parse (GOptionContext *context, GCancellable *cancellable, const char *const* *out_install_pkgs, const char *const* *out_uninstall_pkgs, + /* eventually, we'll just have out_mux here */ RPMOSTreeSysroot **out_sysroot_proxy, + RpmOstreeMux **out_mux, GError **error) { /* with --version there's no command, don't require a daemon for it */ const RpmOstreeBuiltinFlags flags = invocation ? invocation->command->flags : RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD; - gboolean use_daemon = ((flags & RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD) == 0); + gboolean use_mux = ((flags & RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD) == 0); if (invocation && invocation->command->description != NULL) { @@ -240,8 +240,8 @@ rpmostree_option_context_parse (GOptionContext *context, if (main_entries != NULL) g_option_context_add_main_entries (context, main_entries, NULL); - if (use_daemon) - g_option_context_add_main_entries (context, daemon_entries, NULL); + if (use_mux) + g_option_context_add_main_entries (context, mux_entries, NULL); if ((flags & RPM_OSTREE_BUILTIN_FLAG_SUPPORTS_PKG_INSTALLS) > 0) g_option_context_add_main_entries (context, pkg_entries, NULL); @@ -276,13 +276,15 @@ rpmostree_option_context_parse (GOptionContext *context, if ((flags & RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT) > 0) rpmostreecxx::client_require_root(); - if (use_daemon) + const char *sysroot_path = opt_sysroot ?: g_getenv ("RPMOSTREE_SYSROOT"); + + if (use_mux) { /* More gracefully handle the case where * no --sysroot option was specified and we're not booted via ostree * https://github.com/projectatomic/rpm-ostree/issues/1537 */ - if (!opt_sysroot) + if (!sysroot_path) { if (!glnx_fstatat_allow_noent (AT_FDCWD, "/run/ostree-booted", NULL, 0, error)) return FALSE; @@ -301,10 +303,21 @@ rpmostree_option_context_parse (GOptionContext *context, /* ignore errors; we print out a warning if we fail to spawn pkttyagent */ (void)rpmostree_polkit_agent_open (); - if (!rpmostree_load_sysroot (cancellable, - out_sysroot_proxy, - error)) - return FALSE; + /* Eventually we'll always load the mux here. See also comment in that + * function. For now, we only use it if the caller is opted in. */ + if (out_mux) + { + g_assert_null (out_sysroot_proxy); + *out_mux = rpmostree_mux_new (sysroot_path, cancellable, error); + if (!*out_mux) + return FALSE; + } + else + { + g_assert_nonnull (out_sysroot_proxy); + if (!rpmostree_load_sysroot (cancellable, out_sysroot_proxy, error)) + return FALSE; + } } if (out_install_pkgs) @@ -389,7 +402,7 @@ rpmostree_handle_subcommand (int argc, char **argv, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); if (subcommand_name == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -504,7 +517,7 @@ rpmostree_main_inner (const rust::Slice args) /* This will not return for some options (e.g. --version). */ (void) rpmostree_option_context_parse (context, NULL, &argc, &argv, NULL, NULL, NULL, NULL, NULL, - NULL); + NULL, NULL); g_autofree char *help = g_option_context_get_help (context, FALSE, NULL); g_printerr ("%s", help); if (command_name == NULL) diff --git a/src/app/rpmostree-builtin-cancel.cxx b/src/app/rpmostree-builtin-cancel.cxx index 36ae8f0407..141c0c6eb8 100644 --- a/src/app/rpmostree-builtin-cancel.cxx +++ b/src/app/rpmostree-builtin-cancel.cxx @@ -72,7 +72,7 @@ rpmostree_builtin_cancel (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-cleanup.cxx b/src/app/rpmostree-builtin-cleanup.cxx index e400534709..8e6df9ac74 100644 --- a/src/app/rpmostree-builtin-cleanup.cxx +++ b/src/app/rpmostree-builtin-cleanup.cxx @@ -64,7 +64,7 @@ rpmostree_builtin_cleanup (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-db.cxx b/src/app/rpmostree-builtin-db.cxx index 6a7d1f55fc..ffab0a52a5 100644 --- a/src/app/rpmostree-builtin-db.cxx +++ b/src/app/rpmostree-builtin-db.cxx @@ -61,7 +61,7 @@ rpmostree_db_option_context_parse (GOptionContext *context, argc, argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-deploy.cxx b/src/app/rpmostree-builtin-deploy.cxx index d8306b77dd..6e4b3c8afe 100644 --- a/src/app/rpmostree-builtin-deploy.cxx +++ b/src/app/rpmostree-builtin-deploy.cxx @@ -85,7 +85,7 @@ rpmostree_builtin_deploy (int argc, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; @@ -226,7 +226,8 @@ rpmostree_builtin_deploy (int argc, } else if (!opt_reboot) { - if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) { if (opt_unchanged_exit_77) invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; diff --git a/src/app/rpmostree-builtin-finalize-deployment.cxx b/src/app/rpmostree-builtin-finalize-deployment.cxx index 2ac9f1b37e..817836a881 100644 --- a/src/app/rpmostree-builtin-finalize-deployment.cxx +++ b/src/app/rpmostree-builtin-finalize-deployment.cxx @@ -48,7 +48,7 @@ rpmostree_builtin_finalize_deployment (int argc, glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, cancellable, NULL, NULL, - &sysroot_proxy, error)) + &sysroot_proxy, NULL, error)) return FALSE; const char *checksum = NULL; diff --git a/src/app/rpmostree-builtin-initramfs-etc.cxx b/src/app/rpmostree-builtin-initramfs-etc.cxx index d678ac9586..3d58416dfa 100644 --- a/src/app/rpmostree-builtin-initramfs-etc.cxx +++ b/src/app/rpmostree-builtin-initramfs-etc.cxx @@ -58,25 +58,24 @@ rpmostree_ex_builtin_initramfs_etc (int argc, GCancellable *cancellable, GError **error) { + g_autoptr(RpmOstreeMux) mux = NULL; g_autoptr(GOptionContext) context = g_option_context_new (""); - - glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + NULL, &mux, error)) return FALSE; - glnx_unref_object RPMOSTreeOS *os_proxy = NULL; - if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, - cancellable, &os_proxy, error)) + if (!rpmostree_mux_load_os (mux, opt_osname, cancellable, error)) return FALSE; - g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy); + g_autoptr(GVariant) previous_deployment = rpmostree_mux_get_default_deployment (mux, error); + if (!previous_deployment) + return FALSE; if (!(opt_track || opt_untrack || opt_untrack_all || opt_force_sync)) { @@ -84,7 +83,10 @@ rpmostree_ex_builtin_initramfs_etc (int argc, return glnx_throw (error, "Cannot use ---reboot without --track, --untrack, --untrack-all, or --force-sync"); g_autofree char **files = NULL; - g_autoptr(GVariant) deployments = rpmostree_sysroot_dup_deployments (sysroot_proxy); + g_autoptr(GVariant) deployments = rpmostree_mux_get_deployments (mux, error); + if (!deployments) + return FALSE; + if (g_variant_n_children (deployments) > 0) { g_autoptr(GVariant) pending = g_variant_get_child_value (deployments, 0); @@ -112,41 +114,37 @@ rpmostree_ex_builtin_initramfs_etc (int argc, if (!opt_untrack) opt_untrack = empty_strv; - GVariantDict dict; + g_auto(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_variant_dict_insert (&dict, "lock-finalization", "b", opt_lock_finalization); - g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict)); - - g_autofree char *transaction_address = NULL; - if (!rpmostree_os_call_initramfs_etc_sync (os_proxy, - (const char *const*)opt_track, - (const char *const*)opt_untrack, - opt_untrack_all, - opt_force_sync, - options, - &transaction_address, - cancellable, - error)) - return FALSE; - if (!rpmostree_transaction_get_response_sync (sysroot_proxy, - transaction_address, - cancellable, - error)) + if (!rpmostree_mux_call_initramfs_etc (mux, + (const char *const*)opt_track, + (const char *const*)opt_untrack, + opt_untrack_all, + opt_force_sync, + &dict, + cancellable, + error)) return FALSE; if (!opt_reboot) { - if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_autoptr(GVariant) new_deployment = rpmostree_mux_get_default_deployment (mux, error); + if (!new_deployment) + return FALSE; + + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) { if (opt_unchanged_exit_77) invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; return TRUE; } - g_print ("Run \"systemctl reboot\" to start a reboot\n"); + if (rpmostree_mux_is_dbus (mux)) + g_print ("Run \"systemctl reboot\" to start a reboot\n"); } return TRUE; diff --git a/src/app/rpmostree-builtin-initramfs.cxx b/src/app/rpmostree-builtin-initramfs.cxx index 4a8e69bc29..55ee5246b8 100644 --- a/src/app/rpmostree-builtin-initramfs.cxx +++ b/src/app/rpmostree-builtin-initramfs.cxx @@ -62,7 +62,7 @@ rpmostree_builtin_initramfs (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-kargs.cxx b/src/app/rpmostree-builtin-kargs.cxx index 270a84f0d7..1864a25f7e 100644 --- a/src/app/rpmostree-builtin-kargs.cxx +++ b/src/app/rpmostree-builtin-kargs.cxx @@ -180,7 +180,7 @@ rpmostree_builtin_kargs (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; @@ -357,7 +357,8 @@ rpmostree_builtin_kargs (int argc, error)) return FALSE; - if (rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) g_print("Kernel arguments updated.\nRun \"systemctl reboot\" to start a reboot\n"); else if (opt_unchanged_exit_77) invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; diff --git a/src/app/rpmostree-builtin-rebase.cxx b/src/app/rpmostree-builtin-rebase.cxx index f943507b33..b3a6ab032c 100644 --- a/src/app/rpmostree-builtin-rebase.cxx +++ b/src/app/rpmostree-builtin-rebase.cxx @@ -90,7 +90,7 @@ rpmostree_builtin_rebase (int argc, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-refresh-md.cxx b/src/app/rpmostree-builtin-refresh-md.cxx index de4d21660f..340f63b54b 100644 --- a/src/app/rpmostree-builtin-refresh-md.cxx +++ b/src/app/rpmostree-builtin-refresh-md.cxx @@ -64,7 +64,7 @@ rpmostree_builtin_refresh_md (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-reload.cxx b/src/app/rpmostree-builtin-reload.cxx index 51998dea26..50535a64e7 100644 --- a/src/app/rpmostree-builtin-reload.cxx +++ b/src/app/rpmostree-builtin-reload.cxx @@ -49,7 +49,7 @@ rpmostree_builtin_reload (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-reset.cxx b/src/app/rpmostree-builtin-reset.cxx index eeb7af8b59..74cf4d92af 100644 --- a/src/app/rpmostree-builtin-reset.cxx +++ b/src/app/rpmostree-builtin-reset.cxx @@ -67,7 +67,7 @@ rpmostree_builtin_reset (int argc, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-rollback.cxx b/src/app/rpmostree-builtin-rollback.cxx index 01f1942a71..7824a8316b 100644 --- a/src/app/rpmostree-builtin-rollback.cxx +++ b/src/app/rpmostree-builtin-rollback.cxx @@ -65,7 +65,7 @@ rpmostree_builtin_rollback (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-status.cxx b/src/app/rpmostree-builtin-status.cxx index 56aafa2ec0..0a04957009 100644 --- a/src/app/rpmostree-builtin-status.cxx +++ b/src/app/rpmostree-builtin-status.cxx @@ -1089,17 +1089,15 @@ rpmostree_builtin_status (int argc, GCancellable *cancellable, GError **error) { + g_autoptr(RpmOstreeMux) mux = NULL; g_autoptr(GOptionContext) context = g_option_context_new (""); - glnx_unref_object RPMOSTreeOS *os_proxy = NULL; - glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; - if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + NULL, &mux, error)) return FALSE; @@ -1110,13 +1108,18 @@ rpmostree_builtin_status (int argc, return FALSE; } - if (!rpmostree_load_os_proxy (sysroot_proxy, NULL, cancellable, &os_proxy, error)) + if (!rpmostree_mux_load_os (mux, NULL, cancellable, error)) return FALSE; - g_autoptr(GVariant) deployments = rpmostree_sysroot_dup_deployments (sysroot_proxy); + RPMOSTreeOS *os_proxy = rpmostree_mux_get_os_proxy (mux);; + RPMOSTreeSysroot *sysroot_proxy = rpmostree_mux_get_sysroot_proxy (mux);; + + g_autoptr(GVariant) deployments = rpmostree_mux_get_deployments (mux, error); + if (!deployments) + return FALSE; g_assert (deployments); g_autoptr(GVariant) cached_update = NULL; - if (rpmostree_os_get_has_cached_update_rpm_diff (os_proxy)) + if (os_proxy && rpmostree_os_get_has_cached_update_rpm_diff (os_proxy)) cached_update = rpmostree_os_dup_cached_update (os_proxy); g_autoptr(GVariant) driver_info = NULL; if (!get_driver_g_variant (&driver_info, error)) @@ -1130,7 +1133,7 @@ rpmostree_builtin_status (int argc, json_builder_set_member_name (builder, "deployments"); json_builder_add_value (builder, json_gvariant_serialize (deployments)); json_builder_set_member_name (builder, "transaction"); - GVariant *txn = get_active_txn (sysroot_proxy); + GVariant *txn = sysroot_proxy ? get_active_txn (sysroot_proxy) : NULL; JsonNode *txn_node = txn ? json_gvariant_serialize (txn) : json_node_new (JSON_NODE_NULL); json_builder_add_value (builder, txn_node); @@ -1174,22 +1177,28 @@ rpmostree_builtin_status (int argc, } else { - if (!print_daemon_state (sysroot_proxy, cancellable, error)) - return FALSE; + if (sysroot_proxy) + { + if (!print_daemon_state (sysroot_proxy, cancellable, error)) + return FALSE; + } gboolean printed_cached_update = FALSE; if (!print_deployments (sysroot_proxy, deployments, cached_update, &printed_cached_update, cancellable, error)) return FALSE; - const char *policy = rpmostree_sysroot_get_automatic_update_policy (sysroot_proxy); - gboolean auto_updates_enabled = (!g_str_equal (policy, "none")); - if (cached_update && !printed_cached_update && auto_updates_enabled) + if (sysroot_proxy) { - g_print ("\n"); - if (!rpmostree_print_cached_update (cached_update, opt_verbose, - opt_verbose_advisories, cancellable, error)) - return FALSE; + const char *policy = rpmostree_sysroot_get_automatic_update_policy (sysroot_proxy); + gboolean auto_updates_enabled = (!g_str_equal (policy, "none")); + if (cached_update && !printed_cached_update && auto_updates_enabled) + { + g_print ("\n"); + if (!rpmostree_print_cached_update (cached_update, opt_verbose, + opt_verbose_advisories, cancellable, error)) + return FALSE; + } } } @@ -1361,7 +1370,7 @@ rpmostree_ex_builtin_history (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtin-upgrade.cxx b/src/app/rpmostree-builtin-upgrade.cxx index aaf0fc8c20..ee771e1a65 100644 --- a/src/app/rpmostree-builtin-upgrade.cxx +++ b/src/app/rpmostree-builtin-upgrade.cxx @@ -84,7 +84,7 @@ rpmostree_builtin_upgrade (int argc, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; @@ -234,7 +234,8 @@ rpmostree_builtin_upgrade (int argc, } else if (!opt_reboot) { - if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) { if (opt_upgrade_unchanged_exit_77 || opt_unchanged_exit_77) invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; diff --git a/src/app/rpmostree-builtin-usroverlay.cxx b/src/app/rpmostree-builtin-usroverlay.cxx index 5973022cce..7a4dc45f1b 100644 --- a/src/app/rpmostree-builtin-usroverlay.cxx +++ b/src/app/rpmostree-builtin-usroverlay.cxx @@ -49,7 +49,7 @@ rpmostree_builtin_usroverlay (int argc, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-builtins.h b/src/app/rpmostree-builtins.h index 9b8d4dd966..69705ad188 100644 --- a/src/app/rpmostree-builtins.h +++ b/src/app/rpmostree-builtins.h @@ -72,6 +72,7 @@ rpmostree_option_context_parse (GOptionContext *context, const char *const* *out_install_pkgs, const char *const* *out_uninstall_pkgs, RPMOSTreeSysroot **out_sysroot_proxy, + RpmOstreeMux **out_mux, GError **error); int diff --git a/src/app/rpmostree-clientlib.cxx b/src/app/rpmostree-clientlib.cxx index d96f652b48..fba6a5b73b 100644 --- a/src/app/rpmostree-clientlib.cxx +++ b/src/app/rpmostree-clientlib.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,10 @@ #include "rpmostree-util.h" #include "rpmostree-rpm-util.h" #include "rpmostree-cxxrs.h" + +/* XXX: should move things we need from there into libpriv */ #include "rpmostreed-transaction-types.h" +#include "rpmostreed-deployment-utils.h" static gboolean impl_transaction_get_response_sync (GDBusConnection *connection, @@ -286,7 +290,7 @@ rpmostree_load_os_proxies (RPMOSTreeSysroot *sysroot_proxy, gboolean rpmostree_load_os_proxy (RPMOSTreeSysroot *sysroot_proxy, - gchar *opt_osname, + const char *opt_osname, GCancellable *cancellable, RPMOSTreeOS **out_os_proxy, GError **error) @@ -792,28 +796,16 @@ rpmostree_transaction_get_response_sync (RPMOSTreeSysroot *sysroot_proxy, return TRUE; } -/* Handles client-side processing for most command line tools - * after a transaction has been started. Wraps invocation - * of rpmostree_transaction_get_response_sync(). - */ -gboolean -rpmostree_transaction_client_run (RpmOstreeCommandInvocation *invocation, - RPMOSTreeSysroot *sysroot_proxy, - RPMOSTreeOS *os_proxy, - GVariant *options, - gboolean exit_unchanged_77, - const char *transaction_address, - GVariant *previous_deployment, - GCancellable *cancellable, - GError **error) +static gboolean +transaction_handle_options_and_diff (RpmOstreeCommandInvocation *invocation, + GVariant *options, + gboolean exit_unchanged_77, + const char *sysroot_path, + GVariant *previous_deployment, + GVariant *new_deployment, + GCancellable *cancellable, + GError **error) { - /* Wait for the txn to complete */ - if (!rpmostree_transaction_get_response_sync (sysroot_proxy, transaction_address, - cancellable, error)) - return FALSE; - - /* Process the result of the txn and our options */ - g_auto(GVariantDict) optdict = G_VARIANT_DICT_INIT (options); /* Parse back the options variant */ gboolean opt_reboot = FALSE; @@ -829,7 +821,7 @@ rpmostree_transaction_client_run (RpmOstreeCommandInvocation *invocation, } else if (!opt_reboot) { - if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) { if (exit_unchanged_77) invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED; @@ -838,14 +830,12 @@ rpmostree_transaction_client_run (RpmOstreeCommandInvocation *invocation, else if (!opt_apply_live) { /* do diff without dbus: https://github.com/projectatomic/rpm-ostree/pull/116 */ - const char *sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); rpmostreecxx::print_treepkg_diff_from_sysroot_path (rust::Str(sysroot_path), RPMOSTREE_DIFF_PRINT_FORMAT_FULL_MULTILINE, 0, cancellable); g_print ("Changes queued for next boot. Run \"systemctl reboot\" to start a reboot\n"); } else if (opt_apply_live) { - const char *sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path); g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_file); if (!ostree_sysroot_load (sysroot, cancellable, error)) @@ -859,6 +849,36 @@ rpmostree_transaction_client_run (RpmOstreeCommandInvocation *invocation, return TRUE; } +/* Handles client-side processing for most command line tools + * after a transaction has been started. Wraps invocation + * of rpmostree_transaction_get_response_sync(). + * + * XXX: Eventually once everything is migrated, this will be a private function + * of RpmOstreeMux. + */ +gboolean +rpmostree_transaction_client_run (RpmOstreeCommandInvocation *invocation, + RPMOSTreeSysroot *sysroot_proxy, + RPMOSTreeOS *os_proxy, + GVariant *options, + gboolean exit_unchanged_77, + const char *transaction_address, + GVariant *previous_deployment, + GCancellable *cancellable, + GError **error) +{ + /* Wait for the txn to complete */ + if (!rpmostree_transaction_get_response_sync (sysroot_proxy, transaction_address, + cancellable, error)) + return FALSE; + + const char *sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); + g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); + return transaction_handle_options_and_diff (invocation, options, exit_unchanged_77, + sysroot_path, previous_deployment, + new_deployment, cancellable, error); +} + static void rpmostree_print_signatures (GVariant *variant, const gchar *sep, @@ -1150,6 +1170,7 @@ get_modifiers_variant (const char *set_refspec, return TRUE; } +/* XXX: nuke once everything has migrated to mux */ gboolean rpmostree_update_deployment (RPMOSTreeOS *os_proxy, const char *set_refspec, @@ -1688,3 +1709,344 @@ error_if_driver_registered (RPMOSTreeSysroot *sysroot_proxy, return TRUE; } + +typedef enum { + SELECTOR_DIRECT, + SELECTOR_DBUS, +} RpmOstreeMuxSelector; + +struct RpmOstreeMux { + RpmOstreeMuxSelector selector; + + OstreeSysroot *sysroot; + char *osname; + + RPMOSTreeSysroot *sysroot_proxy; + RPMOSTreeOS *os_proxy; +}; + +/* Right now, as we transition from unconditionally using daemon mode, we only + * use the mux in some situations. Eventually, we'll always use the mux, so this + * function will become only used in `rpmostree_mux_new()`. + * */ +gboolean +rpmostree_mux_should_direct (const char *sysroot_path) +{ + if (g_getenv ("RPMOSTREE_FORCE_DIRECT")) + return TRUE; + + if (sd_booted () <= 0) + return TRUE; + + if (sysroot_path && !g_str_equal (sysroot_path, "/")) + return TRUE; + + return FALSE; +} + +RpmOstreeMux* +rpmostree_mux_new (const char *sysroot_path, + GCancellable *cancellable, + GError **error) +{ + RpmOstreeMuxSelector selector = SELECTOR_DBUS; + if (rpmostree_mux_should_direct (sysroot_path)) + selector = SELECTOR_DIRECT; + + g_autoptr(OstreeSysroot) sysroot = NULL; + glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; + if (selector == SELECTOR_DBUS) + { + if (!rpmostree_load_sysroot (cancellable, &sysroot_proxy, error)) + return FALSE; + } + else + { + g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path); + sysroot = ostree_sysroot_new (sysroot_file); + if (!ostree_sysroot_load (sysroot, cancellable, error)) + return FALSE; + } + + g_autoptr(RpmOstreeMux) mux = g_new0 (RpmOstreeMux, 1); + mux->selector = selector; + mux->sysroot_proxy = util::move_nullify (sysroot_proxy); + mux->sysroot = util::move_nullify (sysroot); + return util::move_nullify (mux); +} + +void +rpmostree_mux_free (RpmOstreeMux *mux) +{ + g_clear_pointer (&mux->sysroot, g_object_unref); + g_clear_pointer (&mux->osname, g_free); + g_clear_pointer (&mux->sysroot_proxy, g_object_unref); + g_clear_pointer (&mux->os_proxy, g_object_unref); + g_free (mux); +} + +gboolean +rpmostree_mux_is_dbus (RpmOstreeMux *mux) +{ + return mux->selector == SELECTOR_DBUS; +} + +RPMOSTreeSysroot* +rpmostree_mux_get_sysroot_proxy (RpmOstreeMux *mux) +{ + return mux->sysroot_proxy; +} + +RPMOSTreeOS* +rpmostree_mux_get_os_proxy (RpmOstreeMux *mux) +{ + return mux->os_proxy; +} + +static char* +matching_osname_or_null (OstreeSysroot *sysroot) +{ + const char *last_osname = NULL; + g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot); + for (guint i = 0; deployments != NULL && i < deployments->len; i++) + { + auto deployment = static_cast(deployments->pdata[i]); + const char *osname = ostree_deployment_get_osname (deployment); + if (!last_osname) + last_osname = osname; + else if (!g_str_equal (last_osname, osname)) + return NULL; + } + /* NB: implicitly returns NULL if no deployments */ + return g_strdup (last_osname); +} + +gboolean +rpmostree_mux_load_os (RpmOstreeMux *mux, + const char *osname, + GCancellable *cancellable, + GError **error) +{ + if (mux->selector == SELECTOR_DIRECT) + { + /* as a convenience so that users don't have to pass in --os, we + * auto-detect if there's only one kind; if so, assume that */ + if (!osname) + mux->osname = matching_osname_or_null (mux->sysroot); + else + mux->osname = g_strdup (osname); + } + else + { + glnx_unref_object RPMOSTreeOS *os_proxy = NULL; + if (!rpmostree_load_os_proxy (mux->sysroot_proxy, osname, + cancellable, &os_proxy, error)) + return FALSE; + + mux->os_proxy = util::move_nullify (os_proxy); + } + + return TRUE; +} + +/* One might ask: why not just have clients always use OstreeSysroot locally for + * read-only operations? The answer is that there would then be no + * synchronization between daemon modifications and the object. A lot of work + * went into making sure that e.g. the sysroot is reloaded when needed and + * properties are up-to-date etc... */ + +GVariant* +rpmostree_mux_get_default_deployment (RpmOstreeMux *mux, + GError **error) +{ + if (mux->selector == SELECTOR_DBUS) + return rpmostree_os_dup_default_deployment (mux->os_proxy); + + g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (mux->sysroot); + if (deployments->len == 0) + return (GVariant*)glnx_null_throw (error, "No deployments found for OS '%s'", mux->osname); + + OstreeDeployment *deployment = (OstreeDeployment*)deployments->pdata[0]; + g_autoptr(GVariant) ret = rpmostreed_deployment_generate_variant (mux->sysroot, deployment, + ostree_sysroot_repo (mux->sysroot), TRUE, + error); + if (!ret) + return FALSE; + return g_variant_ref_sink (util::move_nullify (ret)); +} + +GVariant* +rpmostree_mux_get_deployments (RpmOstreeMux *mux, + GError **error) +{ + if (mux->selector == SELECTOR_DBUS) + return rpmostree_sysroot_dup_deployments (mux->sysroot_proxy); + + g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (mux->sysroot); + if (deployments->len == 0) + return (GVariant*)glnx_null_throw (error, "No deployments found for OS '%s'", mux->osname); + + /* For the purposes of rpmostreed_deployment_generate_variant(), we don't want to directly + * use the sysroot's repo because it won't be able to find the remotes. Ideally, we'd be + * able to transiently set the remotes dir on the repo, but currently it requires setting + * at construction time, so we hack around this by using a separate repo object. + * */ + g_autoptr(OstreeRepo) repo = NULL; + { + OstreeDeployment *deployment = (OstreeDeployment*)deployments->pdata[0]; + g_autofree char *deployment_root = rpmostree_get_deployment_root (mux->sysroot, deployment); + g_autofree char *remotes_dir = g_build_filename (deployment_root, "etc/ostree/remotes.d", NULL); + repo = (OstreeRepo*)g_object_new (OSTREE_TYPE_REPO, + "path", ostree_repo_get_path (ostree_sysroot_repo (mux->sysroot)), + "remotes-config-dir", remotes_dir, NULL); + if (!ostree_repo_open (repo, NULL, error)) + return FALSE; + } + + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + for (guint i = 0; deployments != NULL && i < deployments->len; i++) + { + auto deployment = static_cast(deployments->pdata[i]); + GVariant *variant = + rpmostreed_deployment_generate_variant (mux->sysroot, deployment, + repo, TRUE, error); + if (!variant) + return (GVariant*)glnx_prefix_error_null (error, "Reading deployment %u", i); + + g_variant_builder_add_value (&builder, variant); + } + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +gboolean +rpmostree_mux_call_initramfs_etc (RpmOstreeMux *mux, + const char *const *arg_track, + const char *const *arg_untrack, + gboolean arg_untrack_all, + gboolean arg_force_sync, + GVariantDict *arg_options, + GCancellable *cancellable, + GError **error) +{ + switch (mux->selector) + { + case SELECTOR_DBUS: + { + g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (arg_options)); + + g_autofree char *transaction_address = NULL; + if (!rpmostree_os_call_initramfs_etc_sync (mux->os_proxy, + (const char *const*)arg_track, + (const char *const*)arg_untrack, + arg_untrack_all, + arg_force_sync, + options, + &transaction_address, + cancellable, + error)) + return FALSE; + + return rpmostree_transaction_get_response_sync (mux->sysroot_proxy, + transaction_address, + cancellable, + error); + } + case SELECTOR_DIRECT: + return rpmostree_callimpl_initramfs_etc (mux->sysroot, + mux->osname, + (char**)arg_track, + (char**)arg_untrack, + arg_untrack_all, + arg_force_sync, + arg_options, + NULL, + cancellable, + error); + default: + g_assert_not_reached (); + } +} + +gboolean +rpmostree_mux_call_update_deployment (RpmOstreeMux *mux, + RpmOstreeCommandInvocation *invocation, + const char *set_refspec, + const char *set_revision, + const char *const* install_pkgs, + const char *const* uninstall_pkgs, + const char *const* override_replace_pkgs, + const char *const* override_remove_pkgs, + const char *const* override_reset_pkgs, + const char *local_repo_remote, + GVariant *options, + gboolean unchanged_exit_77, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GVariant) modifiers = NULL; + glnx_unref_object GUnixFDList *fd_list = NULL; + if (!get_modifiers_variant (set_refspec, set_revision, + install_pkgs, uninstall_pkgs, + override_replace_pkgs, + override_remove_pkgs, + override_reset_pkgs, + local_repo_remote, + &modifiers, &fd_list, error)) + return FALSE; + + g_autoptr(GVariant) previous_deployment = rpmostree_mux_get_default_deployment (mux, error); + if (!previous_deployment) + return FALSE; + + switch (mux->selector) + { + case SELECTOR_DBUS: + { + g_autofree char *transaction_address = NULL; + if (!rpmostree_os_call_update_deployment_sync (mux->os_proxy, + modifiers, + options, + fd_list, + &transaction_address, + NULL, + cancellable, + error)) + return FALSE; + + return rpmostree_transaction_client_run (invocation, + mux->sysroot_proxy, + mux->os_proxy, + options, + unchanged_exit_77, + transaction_address, + previous_deployment, + cancellable, error); + } + case SELECTOR_DIRECT: + { + if (!rpmostree_callimpl_update_deployment (mux->sysroot, + mux->osname, + static_cast(0), + options, + modifiers, + fd_list, + NULL, + cancellable, + error)) + return FALSE; + + g_autoptr(GVariant) new_deployment = rpmostree_mux_get_default_deployment (mux, error); + if (!new_deployment) + return FALSE; + + const char *sysroot_path = gs_file_get_path_cached (ostree_sysroot_get_path (mux->sysroot)); + return transaction_handle_options_and_diff (invocation, options, unchanged_exit_77, + sysroot_path, previous_deployment, + new_deployment, cancellable, error); + } + default: + g_assert_not_reached (); + } +} diff --git a/src/app/rpmostree-clientlib.h b/src/app/rpmostree-clientlib.h index 6a703989d1..b1c63d9fe2 100644 --- a/src/app/rpmostree-clientlib.h +++ b/src/app/rpmostree-clientlib.h @@ -67,7 +67,7 @@ rpmostree_load_sysroot (GCancellable *cancellable, gboolean rpmostree_load_os_proxy (RPMOSTreeSysroot *sysroot_proxy, - gchar *opt_osname, + const char *opt_osname, GCancellable *cancellable, RPMOSTreeOS **out_os_proxy, GError **error); @@ -167,4 +167,68 @@ error_if_driver_registered (RPMOSTreeSysroot *sysroot_proxy, GCancellable *cancellable, GError **error); +typedef struct RpmOstreeMux RpmOstreeMux; + +gboolean +rpmostree_mux_should_direct (const char *sysroot_path); + +RpmOstreeMux* +rpmostree_mux_new (const char *sysroot_path, + GCancellable *cancellable, + GError **error); + +void +rpmostree_mux_free (RpmOstreeMux *mux); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(RpmOstreeMux, rpmostree_mux_free); + +gboolean +rpmostree_mux_is_dbus (RpmOstreeMux *mux); + +RPMOSTreeSysroot* +rpmostree_mux_get_sysroot_proxy (RpmOstreeMux *mux); + +RPMOSTreeOS* +rpmostree_mux_get_os_proxy (RpmOstreeMux *mux); + +gboolean +rpmostree_mux_load_os (RpmOstreeMux *mux, + const char *osname, + GCancellable *cancellable, + GError **error); + +GVariant* +rpmostree_mux_get_default_deployment (RpmOstreeMux *mux, + GError **error); + +GVariant* +rpmostree_mux_get_deployments (RpmOstreeMux *mux, + GError **error); + +gboolean +rpmostree_mux_call_initramfs_etc (RpmOstreeMux *mux, + const char *const *arg_track, + const char *const *arg_untrack, + gboolean arg_untrack_all, + gboolean arg_force_sync, + GVariantDict *arg_options, + GCancellable *cancellable, + GError **error); + +gboolean +rpmostree_mux_call_update_deployment (RpmOstreeMux *mux, + RpmOstreeCommandInvocation *invocation, + const char *set_refspec, + const char *set_revision, + const char *const* install_pkgs, + const char *const* uninstall_pkgs, + const char *const* override_replace_pkgs, + const char *const* override_remove_pkgs, + const char *const* override_reset_pkgs, + const char *local_repo_remote, + GVariant *options, + gboolean unchanged_exit_77, + GCancellable *cancellable, + GError **error); + G_END_DECLS diff --git a/src/app/rpmostree-compose-builtin-tree.cxx b/src/app/rpmostree-compose-builtin-tree.cxx index 32763b5d68..b81968a394 100644 --- a/src/app/rpmostree-compose-builtin-tree.cxx +++ b/src/app/rpmostree-compose-builtin-tree.cxx @@ -1187,7 +1187,7 @@ rpmostree_compose_builtin_install (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; @@ -1260,7 +1260,7 @@ rpmostree_compose_builtin_postprocess (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; @@ -1323,7 +1323,7 @@ rpmostree_compose_builtin_commit (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; @@ -1369,7 +1369,7 @@ rpmostree_compose_builtin_tree (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; @@ -1439,7 +1439,7 @@ rpmostree_compose_builtin_extensions (int argc, &argc, &argv, invocation, cancellable, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-libbuiltin.cxx b/src/app/rpmostree-libbuiltin.cxx index 1ea9cd4c25..b0b6852620 100644 --- a/src/app/rpmostree-libbuiltin.cxx +++ b/src/app/rpmostree-libbuiltin.cxx @@ -69,11 +69,9 @@ get_id_from_deployment_variant (GVariant *deployment) } gboolean -rpmostree_has_new_default_deployment (RPMOSTreeOS *os_proxy, - GVariant *previous_deployment) +rpmostree_has_new_default_deployment (GVariant *previous_deployment, + GVariant *new_deployment) { - g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); - /* trivial case */ if (g_variant_equal (previous_deployment, new_deployment)) return FALSE; diff --git a/src/app/rpmostree-libbuiltin.h b/src/app/rpmostree-libbuiltin.h index 27a9e75dc5..c6e888d3cc 100644 --- a/src/app/rpmostree-libbuiltin.h +++ b/src/app/rpmostree-libbuiltin.h @@ -60,8 +60,8 @@ rpmostree_usage_error (GOptionContext *context, GError **error); gboolean -rpmostree_has_new_default_deployment (RPMOSTreeOS *os_proxy, - GVariant *previous_deployment); +rpmostree_has_new_default_deployment (GVariant *previous_deployment, + GVariant *new_deployment); namespace rpmostreecxx { diff --git a/src/app/rpmostree-override-builtins.cxx b/src/app/rpmostree-override-builtins.cxx index e187d5ad36..18a4e68953 100644 --- a/src/app/rpmostree-override-builtins.cxx +++ b/src/app/rpmostree-override-builtins.cxx @@ -119,7 +119,8 @@ handle_override (RPMOSTreeSysroot *sysroot_proxy, else if (!opt_reboot) { /* only print diff if a new deployment was laid down (e.g. reset --all may not) */ - if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment)) + g_autoptr(GVariant) new_deployment = rpmostree_os_dup_default_deployment (os_proxy); + if (!rpmostree_has_new_default_deployment (previous_deployment, new_deployment)) return TRUE; const char *sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); @@ -155,7 +156,7 @@ rpmostree_override_builtin_replace (int argc, char **argv, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; @@ -196,7 +197,7 @@ rpmostree_override_builtin_remove (int argc, char **argv, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; @@ -237,7 +238,7 @@ rpmostree_override_builtin_reset (int argc, char **argv, cancellable, &install_pkgs, &uninstall_pkgs, - &sysroot_proxy, + &sysroot_proxy, NULL, error)) return FALSE; diff --git a/src/app/rpmostree-pkg-builtins.cxx b/src/app/rpmostree-pkg-builtins.cxx index 69216468dc..e8527a7349 100644 --- a/src/app/rpmostree-pkg-builtins.cxx +++ b/src/app/rpmostree-pkg-builtins.cxx @@ -70,7 +70,7 @@ static GOptionEntry install_option_entry[] = { static gboolean pkg_change (RpmOstreeCommandInvocation *invocation, - RPMOSTreeSysroot *sysroot_proxy, + RpmOstreeMux *mux, const char *const* packages_to_add, const char *const* packages_to_remove, GCancellable *cancellable, @@ -83,13 +83,9 @@ pkg_change (RpmOstreeCommandInvocation *invocation, if (!packages_to_remove) packages_to_remove = strv_empty; - glnx_unref_object RPMOSTreeOS *os_proxy = NULL; - if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, - cancellable, &os_proxy, error)) + if (!rpmostree_mux_load_os (mux, opt_osname, cancellable, error)) return FALSE; - g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy); - GVariantDict dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); @@ -112,26 +108,31 @@ pkg_change (RpmOstreeCommandInvocation *invocation, /* Use newer D-Bus API only if we have to. */ g_autofree char *transaction_address = NULL; - if (met_local_pkg || opt_apply_live) + if (met_local_pkg || opt_apply_live || !rpmostree_mux_is_dbus (mux)) { - if (!rpmostree_update_deployment (os_proxy, - NULL, /* refspec */ - NULL, /* revision */ - packages_to_add, - packages_to_remove, - NULL, /* override replace */ - NULL, /* override remove */ - NULL, /* override reset */ - NULL, /* local_repo_remote */ - options, - &transaction_address, - cancellable, - error)) + if (!rpmostree_mux_call_update_deployment (mux, + invocation, + NULL, /* refspec */ + NULL, /* revision */ + packages_to_add, + packages_to_remove, + NULL, /* override replace */ + NULL, /* override remove */ + NULL, /* override reset */ + NULL, /* local_repo_remote */ + options, + opt_unchanged_exit_77, + cancellable, + error)) return FALSE; } else { - if (!rpmostree_os_call_pkg_change_sync (os_proxy, + g_autoptr(GVariant) previous_deployment = rpmostree_mux_get_default_deployment (mux, error); + if (!previous_deployment) + return FALSE; + + if (!rpmostree_os_call_pkg_change_sync (rpmostree_mux_get_os_proxy (mux), options, packages_to_add, packages_to_remove, @@ -141,13 +142,18 @@ pkg_change (RpmOstreeCommandInvocation *invocation, cancellable, error)) return FALSE; + + if (!rpmostree_transaction_client_run (invocation, + rpmostree_mux_get_sysroot_proxy (mux), + rpmostree_mux_get_os_proxy (mux), + options, opt_unchanged_exit_77, + transaction_address, + previous_deployment, + cancellable, error)) + return FALSE; } - return rpmostree_transaction_client_run (invocation, sysroot_proxy, os_proxy, - options, opt_unchanged_exit_77, - transaction_address, - previous_deployment, - cancellable, error); + return TRUE; } gboolean @@ -157,20 +163,17 @@ rpmostree_builtin_install (int argc, GCancellable *cancellable, GError **error) { - GOptionContext *context; - glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; - - context = g_option_context_new ("PACKAGE [PACKAGE...]"); - + GOptionContext *context = g_option_context_new ("PACKAGE [PACKAGE...]"); g_option_context_add_main_entries (context, install_option_entry, NULL); + g_autoptr(RpmOstreeMux) mux = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + NULL, &mux, error)) return FALSE; @@ -185,7 +188,7 @@ rpmostree_builtin_install (int argc, argv++; argc--; argv[argc] = NULL; - return pkg_change (invocation, sysroot_proxy, + return pkg_change (invocation, mux, (const char *const*)argv, (const char *const*)opt_uninstall, cancellable, error); @@ -198,20 +201,17 @@ rpmostree_builtin_uninstall (int argc, GCancellable *cancellable, GError **error) { - GOptionContext *context; - glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; - - context = g_option_context_new ("PACKAGE [PACKAGE...]"); - + GOptionContext *context = g_option_context_new ("PACKAGE [PACKAGE...]"); g_option_context_add_main_entries (context, uninstall_option_entry, NULL); + g_autoptr(RpmOstreeMux) mux = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, cancellable, NULL, NULL, - &sysroot_proxy, + NULL, &mux, error)) return FALSE; @@ -231,7 +231,7 @@ rpmostree_builtin_uninstall (int argc, if (!opt_install) opt_cache_only = TRUE; - return pkg_change (invocation, sysroot_proxy, + return pkg_change (invocation, mux, (const char *const*)opt_install, (const char *const*)argv, cancellable, error); diff --git a/src/daemon/rpmostree-sysroot-upgrader.cxx b/src/daemon/rpmostree-sysroot-upgrader.cxx index 57d4162109..3457cb37f5 100644 --- a/src/daemon/rpmostree-sysroot-upgrader.cxx +++ b/src/daemon/rpmostree-sysroot-upgrader.cxx @@ -517,9 +517,6 @@ rpmostree_sysroot_upgrader_pull_base (RpmOstreeSysrootUpgrader *self, if (!ostree_repo_pull_with_options (self->repo, origin_remote, opts, progress, cancellable, error)) return glnx_prefix_error (error, "While pulling %s", override_commit ?: origin_ref); - - if (progress) - ostree_async_progress_finish (progress); } if (override_commit) @@ -1259,7 +1256,7 @@ write_history (RpmOstreeSysrootUpgrader *self, GError **error) { g_autoptr(GVariant) deployment_variant = - rpmostreed_deployment_generate_variant (self->sysroot, new_deployment, NULL, + rpmostreed_deployment_generate_variant (self->sysroot, new_deployment, self->repo, FALSE, error); if (!deployment_variant) return FALSE; diff --git a/src/daemon/rpmostreed-daemon.cxx b/src/daemon/rpmostreed-daemon.cxx index 5558c127b2..b3e076098e 100644 --- a/src/daemon/rpmostreed-daemon.cxx +++ b/src/daemon/rpmostreed-daemon.cxx @@ -799,14 +799,21 @@ idle_initiate_reboot (void *_unused) void rpmostreed_daemon_reboot (RpmostreedDaemon *self) { - g_assert (!self->rebooting); - self->rebooting = TRUE; - /* Queue actually starting the reboot until we return to the client, so - * that they get a success message for the transaction. Otherwise - * if the daemon gets killed via SIGTERM they just see the bus connection - * broken and may spuriously error out. - */ - g_idle_add_full (G_PRIORITY_LOW, idle_initiate_reboot, NULL, NULL); + if (self) + { + g_assert (!self->rebooting); + self->rebooting = TRUE; + /* Queue actually starting the reboot until we return to the client, so + * that they get a success message for the transaction. Otherwise + * if the daemon gets killed via SIGTERM they just see the bus connection + * broken and may spuriously error out. + */ + g_idle_add_full (G_PRIORITY_LOW, idle_initiate_reboot, NULL, NULL); + } + else + { + (void)idle_initiate_reboot (NULL); + } } gboolean diff --git a/src/daemon/rpmostreed-deployment-utils.cxx b/src/daemon/rpmostreed-deployment-utils.cxx index bec7563ba1..3cae80ddf9 100644 --- a/src/daemon/rpmostreed-deployment-utils.cxx +++ b/src/daemon/rpmostreed-deployment-utils.cxx @@ -228,7 +228,6 @@ filter_commit_meta (GVariant *commit_meta) GVariant* rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot, OstreeDeployment *deployment, - const char *booted_id, OstreeRepo *repo, gboolean filter, GError **error) diff --git a/src/daemon/rpmostreed-deployment-utils.h b/src/daemon/rpmostreed-deployment-utils.h index 18d7609d43..8860efc292 100644 --- a/src/daemon/rpmostreed-deployment-utils.h +++ b/src/daemon/rpmostreed-deployment-utils.h @@ -39,7 +39,6 @@ GVariant * rpmostreed_deployment_generate_blank_variant (void); GVariant * rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot, OstreeDeployment *deployment, - const char *booted_id, OstreeRepo *repo, gboolean filter, GError **error); diff --git a/src/daemon/rpmostreed-os.cxx b/src/daemon/rpmostreed-os.cxx index 2bfe67e44d..95a788767b 100644 --- a/src/daemon/rpmostreed-os.cxx +++ b/src/daemon/rpmostreed-os.cxx @@ -1809,7 +1809,7 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error) booted_variant = g_variant_ref_sink ( rpmostreed_deployment_generate_variant (ot_sysroot, booted_deployment, - booted_id, ot_repo, TRUE, error)); + ot_repo, TRUE, error)); if (!booted_variant) return FALSE; auto bootedid_v = rpmostreecxx::deployment_generate_id(*booted_deployment); @@ -1831,7 +1831,6 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error) default_variant = g_variant_ref_sink (rpmostreed_deployment_generate_variant (ot_sysroot, pending_deployment, - booted_id, ot_repo, TRUE, error)); if (!default_variant) return FALSE; @@ -1844,7 +1843,7 @@ rpmostreed_os_load_internals (RpmostreedOS *self, GError **error) if (rollback_deployment) { rollback_variant = - rpmostreed_deployment_generate_variant (ot_sysroot, rollback_deployment, booted_id, + rpmostreed_deployment_generate_variant (ot_sysroot, rollback_deployment, ot_repo, TRUE, error); if (!rollback_variant) return FALSE; diff --git a/src/daemon/rpmostreed-sysroot.cxx b/src/daemon/rpmostreed-sysroot.cxx index ce084a48b3..acf472c2f0 100644 --- a/src/daemon/rpmostreed-sysroot.cxx +++ b/src/daemon/rpmostreed-sysroot.cxx @@ -290,7 +290,7 @@ sysroot_populate_deployments_unlocked (RpmostreedSysroot *self, auto deployment = static_cast(deployments->pdata[i]); GVariant *variant = rpmostreed_deployment_generate_variant (self->ot_sysroot, deployment, - booted_id, self->repo, TRUE, error); + self->repo, TRUE, error); if (!variant) return glnx_prefix_error (error, "Reading deployment %u", i); diff --git a/src/daemon/rpmostreed-transaction-types.cxx b/src/daemon/rpmostreed-transaction-types.cxx index cca2e4dc63..10304b7860 100644 --- a/src/daemon/rpmostreed-transaction-types.cxx +++ b/src/daemon/rpmostreed-transaction-types.cxx @@ -356,6 +356,7 @@ package_diff_transaction_execute (RpmostreedTransaction *transaction, self->revision, cancellable, error)) return FALSE; rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + ostree_async_progress_finish (progress); } else if (upgrading) { @@ -377,6 +378,7 @@ package_diff_transaction_execute (RpmostreedTransaction *transaction, cancellable, error)) return FALSE; rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + ostree_async_progress_finish (progress); } if (!changed) @@ -592,20 +594,11 @@ rpmostreed_transaction_new_rollback (GDBusMethodInvocation *invocation, typedef struct { RpmostreedTransaction parent; - RpmOstreeTransactionDeployFlags flags; + RpmOstreeTransactionDeployFlags default_flags; char *osname; - GVariantDict *options; - GVariantDict *modifiers; - char *refspec; /* NULL for non-rebases */ - const char *revision; /* NULL for upgrade; owned by @options */ - char **install_pkgs; /* strv but strings owned by modifiers */ - GUnixFDList *install_local_pkgs; - char **uninstall_pkgs; /* strv but strings owned by modifiers */ - char **override_replace_pkgs; /* strv but strings owned by modifiers */ - GUnixFDList *override_replace_local_pkgs; - char **override_remove_pkgs; /* strv but strings owned by modifiers */ - char **override_reset_pkgs; /* strv but strings owned by modifiers */ - int local_repo_remote_dfd; + GVariant *options; + GVariant *modifiers; + GUnixFDList *fd_list; } DeployTransaction; typedef RpmostreedTransactionClass DeployTransactionClass; @@ -624,17 +617,9 @@ deploy_transaction_finalize (GObject *object) self = (DeployTransaction *) object; g_free (self->osname); - g_clear_pointer (&self->options, g_variant_dict_unref); - g_clear_pointer (&self->modifiers, g_variant_dict_unref); - g_free (self->refspec); - g_free (self->install_pkgs); - g_clear_pointer (&self->install_local_pkgs, g_object_unref); - g_free (self->uninstall_pkgs); - g_free (self->override_replace_pkgs); - g_clear_pointer (&self->override_replace_local_pkgs, g_object_unref); - g_free (self->override_remove_pkgs); - g_free (self->override_reset_pkgs); - glnx_close_fd (&self->local_repo_remote_dfd); + g_clear_pointer (&self->options, g_variant_unref); + g_clear_pointer (&self->modifiers, g_variant_unref); + g_clear_pointer (&self->fd_list, g_object_unref); G_OBJECT_CLASS (deploy_transaction_parent_class)->finalize (object); } @@ -779,17 +764,17 @@ get_sack_for_booted (OstreeSysroot *sysroot, } static gboolean -deploy_has_bool_option (DeployTransaction *self, - const char *option) +dict_has_bool_option (GVariantDict *dict, + const char *option) { - return vardict_lookup_bool (self->options, option, FALSE); + return vardict_lookup_bool (dict, option, FALSE); } static const char * -deploy_has_string_option (DeployTransaction *self, - const char *option) +dict_has_string_option (GVariantDict *dict, + const char *option) { - return static_cast(vardict_lookup_ptr (self->options, option, "s")); + return static_cast(vardict_lookup_ptr (dict, option, "s")); } /* Write a state file which records information about the agent that is "driving" updates */ @@ -882,38 +867,92 @@ get_driver_info (char **name, return TRUE; } -static gboolean -deploy_transaction_execute (RpmostreedTransaction *transaction, - GCancellable *cancellable, - GError **error) +/* See canonical version of this in ot-builtin-pull.c */ +static void +noninteractive_console_progress_changed (OstreeAsyncProgress *progress, + gpointer user_data) { - DeployTransaction *self = (DeployTransaction *) transaction; - OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); + /* We do nothing here - we just want the final status */ +} + +typedef struct { + char *set_refspec; + char *set_revision; + char **install_pkgs; + char **uninstall_pkgs; + GUnixFDList *install_local_pkgs; + char **override_replace_pkgs; + GUnixFDList *override_replace_local_pkgs; + char **override_remove_pkgs; + char **override_reset_pkgs; + int local_repo_remote_dfd; + RpmOstreeTransactionDeployFlags flags; +} UpdateDeploymentCtx; + +static void +update_deployment_ctx_free (UpdateDeploymentCtx *ctx) +{ + g_free (ctx->set_refspec); + g_free (ctx->install_pkgs); + g_free (ctx->uninstall_pkgs); + g_clear_pointer (&ctx->install_local_pkgs, g_object_unref); + g_free (ctx->override_replace_pkgs); + g_clear_pointer (&ctx->override_replace_local_pkgs, g_object_unref); + g_free (ctx->override_remove_pkgs); + g_free (ctx->override_reset_pkgs); + glnx_close_fd (&ctx->local_repo_remote_dfd); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(UpdateDeploymentCtx, update_deployment_ctx_free); + +static UpdateDeploymentCtx* +update_deployment_ctx (RpmOstreeTransactionDeployFlags default_flags, + GVariantDict *options, + GVariantDict *modifiers, + GUnixFDList *fd_list, + GError **error); + +gboolean +rpmostree_callimpl_update_deployment (OstreeSysroot *sysroot, + char *osname, + RpmOstreeTransactionDeployFlags default_flags, + GVariant *options_v, + GVariant *modifiers_v, + GUnixFDList *fd_list, + RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GVariantDict) options = g_variant_dict_new (options_v); + g_autoptr(GVariantDict) modifiers = g_variant_dict_new (modifiers_v); + g_autoptr(UpdateDeploymentCtx) ctx = update_deployment_ctx (default_flags, options, modifiers, fd_list, error); + if (!ctx) + return FALSE; const gboolean dry_run = - ((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN) > 0); - const gboolean no_overrides = deploy_has_bool_option (self, "no-overrides"); - const gboolean no_layering = deploy_has_bool_option (self, "no-layering"); - const gboolean no_initramfs = deploy_has_bool_option (self, "no-initramfs"); - const gboolean cache_only = deploy_has_bool_option (self, "cache-only"); - const gboolean idempotent_layering = deploy_has_bool_option (self, "idempotent-layering"); + ((ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN) > 0); + const gboolean no_overrides = dict_has_bool_option (options, "no-overrides"); + const gboolean no_layering = dict_has_bool_option (options, "no-layering"); + const gboolean no_initramfs = dict_has_bool_option (options, "no-initramfs"); + const gboolean cache_only = dict_has_bool_option (options, "cache-only"); + const gboolean idempotent_layering = dict_has_bool_option (options, "idempotent-layering"); const gboolean download_only = - ((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_ONLY) > 0); + ((ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_ONLY) > 0); /* Mainly for the `install` and `override` commands */ const gboolean no_pull_base = - ((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE) > 0); + ((ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_NO_PULL_BASE) > 0); /* Used to background check for updates; this essentially means downloading the minimum * amount of metadata only to check if there's an upgrade */ const gboolean download_metadata_only = - ((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_METADATA_ONLY) > 0); - const gboolean allow_inactive = deploy_has_bool_option (self, "allow-inactive"); - g_autofree const char *update_driver = deploy_has_string_option (self, "register-driver"); + ((ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_METADATA_ONLY) > 0); + const gboolean allow_inactive = dict_has_bool_option (options, "allow-inactive"); + g_autofree const char *update_driver = dict_has_string_option (options, "register-driver"); gboolean is_install = FALSE; gboolean is_uninstall = FALSE; gboolean is_override = FALSE; - if (deploy_has_bool_option (self, "apply-live") && deploy_has_bool_option (self, "reboot")) + if (dict_has_bool_option (options, "apply-live") && dict_has_bool_option (options, "reboot")) return glnx_throw (error, "Cannot specify `apply-live` and `reboot`"); /* In practice today */ @@ -921,14 +960,14 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, { /* this is a heuristic; by the end, once the proper switches are added, the two * commands can look indistinguishable at the D-Bus level */ - is_override = (self->override_reset_pkgs || - self->override_remove_pkgs || - self->override_replace_pkgs || - self->override_replace_local_pkgs || + is_override = (ctx->override_reset_pkgs || + ctx->override_remove_pkgs || + ctx->override_replace_pkgs || + ctx->override_replace_local_pkgs || no_overrides); if (!is_override) { - if (self->install_pkgs || self->install_local_pkgs) + if (ctx->install_pkgs || ctx->install_local_pkgs) is_install = TRUE; else is_uninstall = TRUE; @@ -936,15 +975,15 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, } auto command_line = (const char *) - vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); + vardict_lookup_ptr (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); + const gboolean is_upgrade = (!no_pull_base && !ctx->set_refspec && !ctx->set_revision); /* Now set the transaction title before doing any work. * https://github.com/projectatomic/rpm-ostree/issues/454 */ - if (command_line) + if (command_line && transaction) { /* special-case the automatic one, otherwise just use verbatim as title */ const char *title = command_line; @@ -952,7 +991,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, title = download_metadata_only ? "automatic (check)" : "automatic (stage)"; rpmostree_transaction_set_title (RPMOSTREE_TRANSACTION (transaction), title); } - else + else if (transaction) { g_autoptr(GString) txn_title = g_string_new (""); if (is_install) @@ -961,9 +1000,9 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, g_string_append (txn_title, "uninstall"); else if (is_override) g_string_append (txn_title, "override"); - else if (self->refspec) + else if (ctx->set_refspec) g_string_append (txn_title, "rebase"); - else if (self->revision) + else if (ctx->set_revision) g_string_append (txn_title, "deploy"); else g_string_append (txn_title, "upgrade"); @@ -976,27 +1015,27 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, else if (download_only) g_string_append (txn_title, " (download only)"); - if (self->uninstall_pkgs) + if (ctx->uninstall_pkgs) g_string_append_printf (txn_title, "; uninstall: %u", - g_strv_length (self->uninstall_pkgs)); - if (self->install_pkgs) + g_strv_length (ctx->uninstall_pkgs)); + if (ctx->install_pkgs) g_string_append_printf (txn_title, "; install: %u", - g_strv_length (self->install_pkgs)); - if (self->install_local_pkgs) + g_strv_length (ctx->install_pkgs)); + if (ctx->install_local_pkgs) g_string_append_printf (txn_title, "; localinstall: %u", - g_unix_fd_list_get_length (self->install_local_pkgs)); + g_unix_fd_list_get_length (ctx->install_local_pkgs)); rpmostree_transaction_set_title (RPMOSTREE_TRANSACTION (transaction), txn_title->str); } - if (update_driver) + if (update_driver && transaction) { if (!record_driver_info (transaction, update_driver, cancellable, error)) return FALSE; /* If revision is an empty string, we interpret this to mean that the invocation * was called solely for the purpose of registering the update driver. Exit early without * doing any further work. */ - if (self->revision && self->revision[0] == '\0') + if (ctx->set_revision && ctx->set_revision[0] == '\0') { rpmostree_output_message ("Empty string revision found; registering update driver only"); return TRUE; @@ -1004,11 +1043,11 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, } int upgrader_flags = 0; - if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE) + if (ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE) upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER; if (dry_run) upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_DRY_RUN; - if (deploy_has_bool_option (self, "lock-finalization")) + if (dict_has_bool_option (options, "lock-finalization")) upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_LOCK_FINALIZATION; /* DOWNLOAD_METADATA_ONLY isn't directly exposed at the D-Bus API level, so we shouldn't @@ -1029,13 +1068,13 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, if (no_overrides) { - g_assert (self->override_replace_pkgs == NULL); - g_assert (self->override_replace_local_pkgs == NULL); - g_assert (self->override_remove_pkgs == NULL); - g_assert (self->override_reset_pkgs == NULL); + g_assert (ctx->override_replace_pkgs == NULL); + g_assert (ctx->override_replace_local_pkgs == NULL); + g_assert (ctx->override_remove_pkgs == NULL); + g_assert (ctx->override_reset_pkgs == NULL); } - if (self->refspec) + if (ctx->set_refspec) { /* When rebasing, we should be able to switch to a different tree even if * the current origin is unconfigured */ @@ -1048,7 +1087,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return FALSE; g_autoptr(RpmOstreeSysrootUpgrader) upgrader = - rpmostree_sysroot_upgrader_new (sysroot, self->osname, (RpmOstreeSysrootUpgraderFlags)upgrader_flags, + rpmostree_sysroot_upgrader_new (sysroot, osname, (RpmOstreeSysrootUpgraderFlags)upgrader_flags, cancellable, error); if (upgrader == NULL) return FALSE; @@ -1059,62 +1098,105 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, /* Handle local repo remotes immediately; the idea is that the remote is "transient" * (otherwise, one should set up a proper file:/// remote), so we only support rebasing to * a checksum. We don't want to import a ref. */ - if (self->local_repo_remote_dfd != -1) + if (ctx->local_repo_remote_dfd != -1) { - /* self->refspec is the rev in the other local repo we'll rebase to */ - g_assert (self->refspec); + /* set_refspec is the rev in the other local repo we'll rebase to */ + g_assert (ctx->set_refspec); RpmOstreeRefspecType refspectype; - if (!rpmostree_refspec_classify (self->refspec, &refspectype, error)) + if (!rpmostree_refspec_classify (ctx->set_refspec, &refspectype, error)) return FALSE; g_autoptr(OstreeRepo) local_repo_remote = - ostree_repo_open_at (self->local_repo_remote_dfd, ".", cancellable, error); + ostree_repo_open_at (ctx->local_repo_remote_dfd, ".", cancellable, error); if (!local_repo_remote) return glnx_prefix_error (error, "Failed to open local repo"); g_autofree char *rev = NULL; - if (!ostree_repo_resolve_rev (local_repo_remote, self->refspec, FALSE, &rev, error)) + if (!ostree_repo_resolve_rev (local_repo_remote, ctx->set_refspec, FALSE, &rev, error)) return FALSE; + // XXX: fold into rpmostree_output API g_autoptr(OstreeAsyncProgress) progress = ostree_async_progress_new (); - rpmostreed_transaction_connect_download_progress (transaction, progress); + g_auto(GLnxConsoleRef) console = { 0, }; + if (transaction) + rpmostreed_transaction_connect_download_progress (transaction, progress); + else + { + glnx_console_lock (&console); + g_signal_connect (progress, "changed", G_CALLBACK (console.is_tty + ? ostree_repo_pull_default_console_progress_changed + : noninteractive_console_progress_changed), &console); + } /* pull-local into the system repo */ const char *refs_to_fetch[] = { rev, NULL }; g_autofree char *local_repo_uri = - g_strdup_printf ("file:///proc/self/fd/%d", self->local_repo_remote_dfd); + g_strdup_printf ("file:///proc/self/fd/%d", ctx->local_repo_remote_dfd); if (!ostree_repo_pull (repo, local_repo_uri, (char**)refs_to_fetch, OSTREE_REPO_PULL_FLAGS_NONE, progress, cancellable, error)) return glnx_prefix_error (error, "Pulling commit %s from local repo", rev); + if (!transaction) + { + if (!console.is_tty) + { + const char *status = ostree_async_progress_get_status (progress); + if (status) + g_print ("%s\n", status); + } + } + else + rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); ostree_async_progress_finish (progress); - rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); /* as far as the rest of the code is concerned, we're rebasing to :SHA256 now */ - g_clear_pointer (&self->refspec, g_free); - self->refspec = g_strdup_printf (":%s", rev); - glnx_close_fd (&self->local_repo_remote_dfd); + g_clear_pointer (&ctx->set_refspec, g_free); + ctx->set_refspec = g_strdup_printf (":%s", rev); + glnx_close_fd (&ctx->local_repo_remote_dfd); } g_autofree gchar *new_refspec = NULL; g_autofree gchar *old_refspec = NULL; - if (self->refspec) + if (ctx->set_refspec) { - if (!change_origin_refspec (self->options, sysroot, origin, self->refspec, cancellable, + if (!change_origin_refspec (options, sysroot, origin, ctx->set_refspec, cancellable, &old_refspec, &new_refspec, error)) return FALSE; } - rpmostreed_transaction_connect_signature_progress (transaction, repo); + if (transaction) + rpmostreed_transaction_connect_signature_progress (transaction, repo); - if (self->revision) + if (ctx->set_revision) { + // XXX: fold into rpmostree_output API g_autoptr(OstreeAsyncProgress) progress = ostree_async_progress_new (); - rpmostreed_transaction_connect_download_progress (transaction, progress); + g_auto(GLnxConsoleRef) console = { 0, }; + if (transaction) + rpmostreed_transaction_connect_download_progress (transaction, progress); + else + { + glnx_console_lock (&console); + g_signal_connect (progress, "changed", G_CALLBACK (console.is_tty + ? ostree_repo_pull_default_console_progress_changed + : noninteractive_console_progress_changed), &console); + } + if (!apply_revision_override (transaction, repo, progress, origin, - deploy_has_bool_option (self, "skip-branch-check"), - self->revision, cancellable, error)) + dict_has_bool_option (options, "skip-branch-check"), + ctx->set_revision, cancellable, error)) return FALSE; - rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + if (transaction) + { + if (!console.is_tty) + { + const char *status = ostree_async_progress_get_status (progress); + if (status) + g_print ("%s\n", status); + } + } + else + rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + ostree_async_progress_finish (progress); } else { @@ -1134,7 +1216,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, // Handle the --ex-cliwrap option { gboolean cliwrap = FALSE; - if (g_variant_dict_lookup (self->options, "ex-cliwrap", "b", &cliwrap)) + if (g_variant_dict_lookup (options, "ex-cliwrap", "b", &cliwrap)) { rpmostree_origin_set_cliwrap (origin, cliwrap); changed = TRUE; @@ -1147,9 +1229,9 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, if (!rpmostree_origin_remove_all_packages (origin, &remove_changed, error)) return FALSE; } - else if (self->uninstall_pkgs) + else if (ctx->uninstall_pkgs) { - if (!rpmostree_origin_remove_packages (origin, self->uninstall_pkgs, + if (!rpmostree_origin_remove_packages (origin, ctx->uninstall_pkgs, idempotent_layering, &remove_changed, error)) return FALSE; } @@ -1162,7 +1244,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, /* lazily loaded cache that's used in a few conditional blocks */ g_autoptr(RpmOstreeRefSack) base_rsack = NULL; - if (self->install_pkgs) + if (ctx->install_pkgs) { /* we run a special check here; let's just not allow trying to install a pkg that will * right away become inactive because it's already installed */ @@ -1175,7 +1257,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return FALSE; } - for (char **it = self->install_pkgs; it && *it; it++) + for (char **it = ctx->install_pkgs; it && *it; it++) { const char *pkg = *it; g_autoptr(GPtrArray) pkgs = @@ -1195,17 +1277,17 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, } gboolean add_changed = FALSE; - if (!rpmostree_origin_add_packages (origin, self->install_pkgs, FALSE, + if (!rpmostree_origin_add_packages (origin, ctx->install_pkgs, FALSE, idempotent_layering, &add_changed, error)) return FALSE; changed = changed || add_changed; } - if (self->install_local_pkgs != NULL) + if (ctx->install_local_pkgs != NULL) { g_autoptr(GPtrArray) pkgs = NULL; - if (!import_many_local_rpms (repo, self->install_local_pkgs, &pkgs, + if (!import_many_local_rpms (repo, ctx->install_local_pkgs, &pkgs, cancellable, error)) return FALSE; @@ -1230,7 +1312,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, changed = changed || overrides_changed; } - else if (self->override_reset_pkgs || self->override_replace_local_pkgs) + else if (ctx->override_reset_pkgs || ctx->override_replace_local_pkgs) { /* The origin stores removal overrides as pkgnames and replacement overrides as nevra. * To be nice, we support both name & nevra and do the translation here by just @@ -1284,7 +1366,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, g_ptr_array_add (names_to_free, g_steal_pointer (&name)); } - for (char **it = self->override_reset_pkgs; it && *it; it++) + for (char **it = ctx->override_reset_pkgs; it && *it; it++) { const char *name_or_nevra = *it; auto name = static_cast(g_hash_table_lookup (nevra_to_name, name_or_nevra)); @@ -1319,10 +1401,10 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return glnx_throw (error, "No overrides for package '%s'", name_or_nevra); } - if (self->override_replace_local_pkgs) + if (ctx->override_replace_local_pkgs) { g_autoptr(GPtrArray) pkgs = NULL; - if (!import_many_local_rpms (repo, self->override_replace_local_pkgs, &pkgs, + if (!import_many_local_rpms (repo, ctx->override_replace_local_pkgs, &pkgs, cancellable, error)) return FALSE; @@ -1367,12 +1449,34 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, if (download_metadata_only) flags |= OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY; + // XXX: fold into rpmostree_output API g_autoptr(OstreeAsyncProgress) progress = ostree_async_progress_new (); - rpmostreed_transaction_connect_download_progress (transaction, progress); + g_auto(GLnxConsoleRef) console = { 0, }; + if (transaction) + rpmostreed_transaction_connect_download_progress (transaction, progress); + else + { + glnx_console_lock (&console); + g_signal_connect (progress, "changed", G_CALLBACK (console.is_tty + ? ostree_repo_pull_default_console_progress_changed + : noninteractive_console_progress_changed), &console); + } + if (!rpmostree_sysroot_upgrader_pull_base (upgrader, NULL, (OstreeRepoPullFlags)flags, progress, &base_changed, cancellable, error)) return FALSE; - rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + if (!transaction) + { + if (!console.is_tty) + { + const char *status = ostree_async_progress_get_status (progress); + if (status) + g_print ("%s\n", status); + } + } + else + rpmostree_transaction_emit_progress_end (RPMOSTREE_TRANSACTION (transaction)); + ostree_async_progress_finish (progress); if (base_changed) changed = TRUE; @@ -1396,7 +1500,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, * anyway in the common case even if there's an error with the overrides, * users will fix it and try again, so the second pull will be a no-op */ - if (self->override_remove_pkgs) + if (ctx->override_remove_pkgs) { if (!base_rsack) { @@ -1408,7 +1512,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, /* NB: the strings are owned by the sack pool */ g_autoptr(GPtrArray) pkgnames = g_ptr_array_new (); - for (char **it = self->override_remove_pkgs; it && *it; it++) + for (char **it = ctx->override_remove_pkgs; it && *it; it++) { const char *pkg = *it; g_autoptr(GPtrArray) pkgs = @@ -1456,9 +1560,9 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, /* this is checked in AutomaticUpdateTrigger, but check here too to be safe */ if (!booted_deployment || - !g_str_equal (self->osname, ostree_deployment_get_osname (booted_deployment))) + !g_str_equal (osname, ostree_deployment_get_osname (booted_deployment))) return glnx_throw (error, "Refusing to download rpm-md for offline OS '%s'", - self->osname); + osname); g_autoptr(DnfSack) sack = NULL; if (g_hash_table_size (rpmostree_origin_get_packages (origin)) > 0) @@ -1493,15 +1597,15 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return FALSE; } - rpmostree_sysroot_upgrader_set_caller_info (upgrader, command_line, - rpmostreed_transaction_get_agent_id (RPMOSTREED_TRANSACTION(self)), - rpmostreed_transaction_get_sd_unit (RPMOSTREED_TRANSACTION(self))); + rpmostree_sysroot_upgrader_set_caller_info (upgrader, command_line, + transaction ? rpmostreed_transaction_get_agent_id (transaction) : NULL, + transaction ? rpmostreed_transaction_get_sd_unit (transaction) : NULL); /* TODO - better logic for "changed" based on deployments */ - if (changed || self->refspec) + if (changed) { /* Note early return; we stop short of actually writing the deployment */ - if (self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_ONLY) + if (ctx->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_ONLY) { /* XXX: improve msg here; e.g. cache will be blown on next operation? */ if (changed) @@ -1517,7 +1621,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return FALSE; /* Are we rebasing? May want to delete the previous ref */ - if (self->refspec && !(deploy_has_bool_option (self, "skip-purge"))) + if (ctx->set_refspec && !(dict_has_bool_option (options, "skip-purge"))) { g_autofree char *remote = NULL; g_autofree char *ref = NULL; @@ -1547,13 +1651,13 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return FALSE; } - if (deploy_has_bool_option (self, "apply-live")) + if (dict_has_bool_option (options, "apply-live")) { g_autoptr(GVariantDict) dictv = g_variant_dict_new (NULL); g_autoptr(GVariant) live_opts = g_variant_ref_sink (g_variant_dict_end (dictv)); rpmostreecxx::transaction_apply_live(*sysroot, *live_opts); } - else if (deploy_has_bool_option (self, "reboot")) + else if (dict_has_bool_option (options, "reboot")) { if (!check_sd_inhibitor_locks (cancellable, error)) return FALSE; @@ -1583,6 +1687,24 @@ deploy_transaction_execute (RpmostreedTransaction *transaction, return TRUE; } +static gboolean +deploy_transaction_execute (RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error) +{ + DeployTransaction *self = (DeployTransaction *) transaction; + OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); + return rpmostree_callimpl_update_deployment (sysroot, + self->osname, + self->default_flags, + self->options, + self->modifiers, + self->fd_list, + transaction, + cancellable, + error); +} + static void deploy_transaction_class_init (DeployTransactionClass *clazz) { @@ -1597,7 +1719,6 @@ deploy_transaction_class_init (DeployTransactionClass *clazz) static void deploy_transaction_init (DeployTransaction *self) { - self->local_repo_remote_dfd = -1; } static char ** @@ -1738,37 +1859,52 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation, */ self->osname = g_strdup (osname); - self->options = g_variant_dict_ref (options_dict); - self->modifiers = g_variant_dict_new (modifiers); + self->options = g_variant_ref (options); + self->modifiers = g_variant_ref (modifiers); - self->flags = deploy_flags_from_options (self->options, default_flags); + self->default_flags = default_flags; + self->fd_list = (GUnixFDList*)g_object_ref (fd_list); + return (RpmostreedTransaction *) util::move_nullify (self); +} - auto refspec = (const char *)vardict_lookup_ptr (self->modifiers, "set-refspec", "&s"); +static UpdateDeploymentCtx* +update_deployment_ctx (RpmOstreeTransactionDeployFlags default_flags, + GVariantDict *options, + GVariantDict *modifiers, + GUnixFDList *fd_list, + GError **error) +{ + UpdateDeploymentCtx *self = g_new0 (UpdateDeploymentCtx, 1); + self->local_repo_remote_dfd = -1; + + self->flags = deploy_flags_from_options (options, default_flags); + + auto refspec = (const char *)vardict_lookup_ptr (modifiers, "set-refspec", "&s"); if (refspec) - self->refspec = g_strdup (refspec); + self->set_refspec = g_strdup (refspec); - const gboolean refspec_or_revision = (self->refspec != NULL || self->revision != NULL); + self->set_revision = (char*)vardict_lookup_ptr (modifiers, "set-revision", "&s"); + self->install_pkgs = vardict_lookup_strv_canonical (modifiers, "install-packages"); + self->uninstall_pkgs = vardict_lookup_strv_canonical (modifiers, "uninstall-packages"); + self->override_replace_pkgs = vardict_lookup_strv_canonical (modifiers, "override-replace-packages"); + self->override_remove_pkgs = vardict_lookup_strv_canonical (modifiers, "override-remove-packages"); + self->override_reset_pkgs = vardict_lookup_strv_canonical (modifiers, "override-reset-packages"); - self->revision = (char*)vardict_lookup_ptr (self->modifiers, "set-revision", "&s"); - self->install_pkgs = vardict_lookup_strv_canonical (self->modifiers, "install-packages"); - self->uninstall_pkgs = vardict_lookup_strv_canonical (self->modifiers, "uninstall-packages"); - self->override_replace_pkgs = vardict_lookup_strv_canonical (self->modifiers, "override-replace-packages"); - self->override_remove_pkgs = vardict_lookup_strv_canonical (self->modifiers, "override-remove-packages"); - self->override_reset_pkgs = vardict_lookup_strv_canonical (self->modifiers, "override-reset-packages"); + const gboolean refspec_or_revision = (self->set_refspec != NULL || self->set_revision != NULL); /* default to allowing downgrades for rebases & deploys (without --disallow-downgrade) */ - if (vardict_lookup_bool (self->options, "allow-downgrade", refspec_or_revision)) - self->flags = static_cast(self-> flags | RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE); + if (vardict_lookup_bool (options, "allow-downgrade", refspec_or_revision)) + self->flags = static_cast(self->flags | RPMOSTREE_TRANSACTION_DEPLOY_FLAG_ALLOW_DOWNGRADE); g_autoptr(GVariant) install_local_pkgs_idxs = - g_variant_dict_lookup_value (self->modifiers, "install-local-packages", + g_variant_dict_lookup_value (modifiers, "install-local-packages", G_VARIANT_TYPE("ah")); g_autoptr(GVariant) override_replace_local_pkgs_idxs = - g_variant_dict_lookup_value (self->modifiers, "override-replace-local-packages", + g_variant_dict_lookup_value (modifiers, "override-replace-local-packages", G_VARIANT_TYPE("ah")); int local_repo_remote_idx = -1; /* See related blurb in get_modifiers_variant() */ - g_variant_dict_lookup (self->modifiers, "ex-local-repo-remote", "h", &local_repo_remote_idx); + g_variant_dict_lookup (modifiers, "ex-local-repo-remote", "h", &local_repo_remote_idx); /* First in the fd list is local RPM fds, which are relevant in the * `install foo.rpm` case and the `override replace foo.rpm` case. Let's make sure that @@ -1791,7 +1927,7 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation, actual_fdn = g_unix_fd_list_get_length (fd_list); if (expected_fdn != actual_fdn) - return (RpmostreedTransaction*)glnx_null_throw (error, "Expected %u fds but received %u", + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Expected %u fds but received %u", expected_fdn, actual_fdn); /* split into two fd lists to make it easier for deploy_transaction_execute */ @@ -1824,33 +1960,33 @@ rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation, /* Also check for conflicting options -- this is after all a public API. */ - if (!self->refspec && vardict_lookup_bool (self->options, "skip-purge", FALSE)) - return (RpmostreedTransaction*)glnx_null_throw (error, "Can't specify skip-purge if not setting a " + if (!self->set_refspec && vardict_lookup_bool (options, "skip-purge", FALSE)) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Can't specify skip-purge if not setting a " "new refspec"); if (refspec_or_revision && - vardict_lookup_bool (self->options, "no-pull-base", FALSE)) - return (RpmostreedTransaction*)glnx_null_throw (error, "Can't specify no-pull-base if setting a " + vardict_lookup_bool (options, "no-pull-base", FALSE)) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Can't specify no-pull-base if setting a " "new refspec or revision"); - if (vardict_lookup_bool (self->options, "cache-only", FALSE) && - vardict_lookup_bool (self->options, "download-only", FALSE)) - return (RpmostreedTransaction*)glnx_null_throw (error, "Can't specify cache-only and download-only"); - if (vardict_lookup_bool (self->options, "dry-run", FALSE) && - vardict_lookup_bool (self->options, "download-only", FALSE)) - return (RpmostreedTransaction*)glnx_null_throw (error, "Can't specify dry-run and download-only"); + if (vardict_lookup_bool (options, "cache-only", FALSE) && + vardict_lookup_bool (options, "download-only", FALSE)) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Can't specify cache-only and download-only"); + if (vardict_lookup_bool (options, "dry-run", FALSE) && + vardict_lookup_bool (options, "download-only", FALSE)) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Can't specify dry-run and download-only"); if (self->override_replace_pkgs) - return (RpmostreedTransaction*)glnx_null_throw (error, "Non-local replacement overrides not implemented yet"); + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Non-local replacement overrides not implemented yet"); - if (vardict_lookup_bool (self->options, "no-overrides", FALSE) && + if (vardict_lookup_bool (options, "no-overrides", FALSE) && (self->override_remove_pkgs || self->override_reset_pkgs || self->override_replace_pkgs || override_replace_local_pkgs_idxs)) - return (RpmostreedTransaction*)glnx_null_throw (error, "Can't specify no-overrides if setting " + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Can't specify no-overrides if setting " "override modifiers"); - if (!self->refspec && self->local_repo_remote_dfd != -1) - return (RpmostreedTransaction*)glnx_null_throw (error, "Missing ref for transient local rebases"); - if (self->revision && self->local_repo_remote_dfd != -1) - return (RpmostreedTransaction*)glnx_null_throw (error, "Revision overrides for transient local rebases not implemented yet"); + if (!self->set_refspec && self->local_repo_remote_dfd != -1) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Missing ref for transient local rebases"); + if (self->set_revision && self->local_repo_remote_dfd != -1) + return (UpdateDeploymentCtx*)glnx_null_throw (error, "Revision overrides for transient local rebases not implemented yet"); - return (RpmostreedTransaction *) util::move_nullify (self); + return (UpdateDeploymentCtx *) util::move_nullify (self); } /* ================================ InitramfsEtc ================================ */ @@ -1887,52 +2023,59 @@ initramfs_etc_transaction_finalize (GObject *object) G_OBJECT_CLASS (initramfs_etc_transaction_parent_class)->finalize (object); } -static gboolean -initramfs_etc_transaction_execute (RpmostreedTransaction *transaction, - GCancellable *cancellable, - GError **error) +/* XXX: should be in a separate file */ +gboolean +rpmostree_callimpl_initramfs_etc (OstreeSysroot *sysroot, + char *osname, + char **track, + char **untrack, + gboolean untrack_all, + gboolean force_sync, + GVariantDict *options, + RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error) { - InitramfsEtcTransaction *self = (InitramfsEtcTransaction *) transaction; - OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); auto command_line = (const char *) - vardict_lookup_ptr (self->options, "initiating-command-line", "&s"); + vardict_lookup_ptr (options, "initiating-command-line", "&s"); int upgrader_flags = 0; - if (vardict_lookup_bool (self->options, "lock-finalization", FALSE)) + if (vardict_lookup_bool (options, "lock-finalization", FALSE)) upgrader_flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_LOCK_FINALIZATION; g_autoptr(RpmOstreeSysrootUpgrader) upgrader = - rpmostree_sysroot_upgrader_new (sysroot, self->osname, static_cast(upgrader_flags), cancellable, error); + rpmostree_sysroot_upgrader_new (sysroot, osname, + static_cast(upgrader_flags), cancellable, error); if (upgrader == NULL) return FALSE; - rpmostree_sysroot_upgrader_set_caller_info (upgrader, command_line, - rpmostreed_transaction_get_agent_id (RPMOSTREED_TRANSACTION(self)), - rpmostreed_transaction_get_sd_unit (RPMOSTREED_TRANSACTION(self))); + rpmostree_sysroot_upgrader_set_caller_info (upgrader, command_line, + transaction ? rpmostreed_transaction_get_agent_id (transaction) : NULL, + transaction ? rpmostreed_transaction_get_sd_unit (transaction) : NULL); g_autoptr(RpmOstreeOrigin) origin = rpmostree_sysroot_upgrader_dup_origin (upgrader); gboolean changed = FALSE; - if (self->untrack_all) + if (untrack_all) { gboolean subchanged = FALSE; rpmostree_origin_initramfs_etc_files_untrack_all (origin, &subchanged); changed = changed || subchanged; } - else if (self->untrack) + else if (untrack) { gboolean subchanged = FALSE; - rpmostree_origin_initramfs_etc_files_untrack (origin, self->untrack, &subchanged); + rpmostree_origin_initramfs_etc_files_untrack (origin, untrack, &subchanged); changed = changed || subchanged; } - if (self->track) + if (track) { gboolean subchanged = FALSE; - rpmostree_origin_initramfs_etc_files_track (origin, self->track, &subchanged); + rpmostree_origin_initramfs_etc_files_track (origin, track, &subchanged); changed = changed || subchanged; } - if (!changed && !self->force_sync) + if (!changed && !force_sync) { rpmostree_output_message ("No changes."); return TRUE; /* Note early return */ @@ -1950,7 +2093,7 @@ initramfs_etc_transaction_execute (RpmostreedTransaction *transaction, if (!rpmostree_sysroot_upgrader_deploy (upgrader, NULL, cancellable, error)) return FALSE; - if (vardict_lookup_bool (self->options, "reboot", FALSE)) + if (vardict_lookup_bool (options, "reboot", FALSE)) { if (!check_sd_inhibitor_locks (cancellable, error)) return FALSE; @@ -1960,6 +2103,25 @@ initramfs_etc_transaction_execute (RpmostreedTransaction *transaction, return TRUE; } +static gboolean +initramfs_etc_transaction_execute (RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error) +{ + InitramfsEtcTransaction *self = (InitramfsEtcTransaction *) transaction; + OstreeSysroot *sysroot = rpmostreed_transaction_get_sysroot (transaction); + return rpmostree_callimpl_initramfs_etc (sysroot, + self->osname, + self->track, + self->untrack, + self->untrack_all, + self->force_sync, + self->options, + transaction, + cancellable, + error); +} + static void initramfs_etc_transaction_class_init (InitramfsEtcTransactionClass *clazz) { diff --git a/src/daemon/rpmostreed-transaction-types.h b/src/daemon/rpmostreed-transaction-types.h index f67f5e2bb7..177ba1c8ab 100644 --- a/src/daemon/rpmostreed-transaction-types.h +++ b/src/daemon/rpmostreed-transaction-types.h @@ -59,6 +59,16 @@ typedef enum { RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DOWNLOAD_METADATA_ONLY = (1 << 9), } RpmOstreeTransactionDeployFlags; +gboolean +rpmostree_callimpl_update_deployment (OstreeSysroot *sysroot, + char *osname, + RpmOstreeTransactionDeployFlags default_flags, + GVariant *options_v, + GVariant *modifiers_v, + GUnixFDList *fd_list, + RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error); RpmostreedTransaction * rpmostreed_transaction_new_deploy (GDBusMethodInvocation *invocation, @@ -79,6 +89,20 @@ rpmostreed_transaction_new_finalize_deployment (GDBusMethodInvocation *invocatio GCancellable *cancellable, GError **error); + +/* XXX: this method should go in a different file */ +gboolean +rpmostree_callimpl_initramfs_etc (OstreeSysroot *sysroot, + char *osname, + char **track, + char **untrack, + gboolean untrack_all, + gboolean force_sync, + GVariantDict *options, + RpmostreedTransaction *transaction, + GCancellable *cancellable, + GError **error); + RpmostreedTransaction * rpmostreed_transaction_new_initramfs_etc (GDBusMethodInvocation *invocation, OstreeSysroot *sysroot, diff --git a/src/daemon/rpmostreed-utils.cxx b/src/daemon/rpmostreed-utils.cxx index a9ca0caba5..7bd2521587 100644 --- a/src/daemon/rpmostreed-utils.cxx +++ b/src/daemon/rpmostreed-utils.cxx @@ -291,9 +291,6 @@ rpmostreed_repo_pull_ancestry (OstreeRepo *repo, g_variant_dict_end (&options), progress, cancellable, error)) goto out; - - if (progress) - ostree_async_progress_finish (progress); } /* First pass only. Now we can resolve the ref to a checksum. */ @@ -618,7 +615,19 @@ gboolean check_sd_inhibitor_locks (GCancellable *cancellable, GError **error) { - GDBusConnection *connection = rpmostreed_daemon_connection (); + if (!rpmostreed_daemon_get ()) + return TRUE; + + g_autoptr(GDBusConnection) connection = NULL; + if (rpmostreed_daemon_get ()) + connection = (GDBusConnection*)g_object_ref (rpmostreed_daemon_connection ()); + else + { + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); + if (!connection) + return FALSE; + } + // https://www.freedesktop.org/software/systemd/man/org.freedesktop.login1.html g_autoptr(GVariant) inhibitors_array_tuple = g_dbus_connection_call_sync (connection, "org.freedesktop.login1", "/org/freedesktop/login1",