app/upgrade: Do not upgrade if updates driver registered
Do not perform an upgrade if detected that an updates driver has been registered. Add --bypass-driver option to force an upgrade regardless of whether an updates driver has been registered.
This commit is contained in:
parent
261b9cbb87
commit
626d021edb
@ -28,6 +28,7 @@
|
||||
#include "rpmostree-libbuiltin.h"
|
||||
#include "rpmostree-rpm-util.h"
|
||||
#include "rpmostree-dbus-helpers.h"
|
||||
#include "rpmostreed-transaction-types.h"
|
||||
|
||||
#include <libglnx.h>
|
||||
|
||||
@ -42,6 +43,7 @@ static gboolean opt_cache_only;
|
||||
static gboolean opt_download_only;
|
||||
static char *opt_automatic;
|
||||
static gboolean opt_lock_finalization;
|
||||
static gboolean opt_bypass_driver;
|
||||
|
||||
/* "check-diff" is deprecated, replaced by "preview" */
|
||||
static GOptionEntry option_entries[] = {
|
||||
@ -58,9 +60,41 @@ static GOptionEntry option_entries[] = {
|
||||
{ "unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_unchanged_exit_77, "If no new deployment made, exit 77", NULL },
|
||||
{ "trigger-automatic-update-policy", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_automatic, "For automated use only; triggered by automatic timer", NULL },
|
||||
{ "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL },
|
||||
{ "bypass-driver", 0, 0, G_OPTION_ARG_NONE, &opt_bypass_driver, "Force an upgrade even if an updates driver is registered.", NULL},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* Get the `Documentation` property `update_driver_sd_unit`. Documentation is returned
|
||||
* as a string array GVariant in `unit_doc_array`. */
|
||||
static gboolean
|
||||
get_update_driver_doc (GDBusConnection *connection,
|
||||
const char *update_driver_sd_unit,
|
||||
GVariant **unit_doc_array,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
const char *update_driver_objpath = NULL;
|
||||
if (!get_sd_unit_objpath (connection, update_driver_sd_unit, &update_driver_objpath,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* Look up `Documentation` property of update driver's systemd unit. */
|
||||
g_autoptr(GDBusProxy) update_driver_unit_obj_proxy =
|
||||
g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, NULL,
|
||||
"org.freedesktop.systemd1", update_driver_objpath,
|
||||
"org.freedesktop.systemd1.Unit", cancellable, error);
|
||||
if (!update_driver_unit_obj_proxy)
|
||||
return FALSE;
|
||||
|
||||
*unit_doc_array =
|
||||
g_dbus_proxy_get_cached_property (update_driver_unit_obj_proxy, "Documentation");
|
||||
if (!*unit_doc_array)
|
||||
return glnx_throw (error, "Documentation property not found in proxy's cache (%s)",
|
||||
update_driver_objpath);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_builtin_upgrade (int argc,
|
||||
char **argv,
|
||||
@ -76,6 +110,7 @@ rpmostree_builtin_upgrade (int argc,
|
||||
const char *const *install_pkgs = NULL;
|
||||
const char *const *uninstall_pkgs = NULL;
|
||||
|
||||
GBusType bus_type;
|
||||
if (!rpmostree_option_context_parse (context,
|
||||
option_entries,
|
||||
&argc, &argv,
|
||||
@ -84,7 +119,7 @@ rpmostree_builtin_upgrade (int argc,
|
||||
&install_pkgs,
|
||||
&uninstall_pkgs,
|
||||
&sysroot_proxy,
|
||||
&peer_pid, NULL,
|
||||
&peer_pid, &bus_type,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
@ -129,6 +164,58 @@ rpmostree_builtin_upgrade (int argc,
|
||||
g_print ("note: automatic updates (%s) are enabled\n", policy);
|
||||
}
|
||||
|
||||
if (!opt_bypass_driver)
|
||||
{
|
||||
g_autofree char *update_driver_sd_unit = NULL;
|
||||
g_autofree char *update_driver_name = NULL;
|
||||
if (!get_driver_info (&update_driver_name, &update_driver_sd_unit, error))
|
||||
return FALSE;
|
||||
|
||||
/* Notify user that an updates driver is registered and upgrades should be
|
||||
* done through the driver. */
|
||||
if (update_driver_sd_unit && update_driver_name)
|
||||
{
|
||||
g_autoptr(GString) error_msg = g_string_new(NULL);
|
||||
g_string_printf (error_msg, "Updates are driven by %s (%s)\n",
|
||||
update_driver_name, update_driver_sd_unit);
|
||||
/* only try to get unit's `Documentation` if we're on the system bus */
|
||||
if (bus_type == G_BUS_TYPE_SYSTEM)
|
||||
{
|
||||
g_autoptr(GVariant) update_driver_docs_array = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
GDBusConnection *connection =
|
||||
g_dbus_proxy_get_connection (G_DBUS_PROXY (sysroot_proxy));
|
||||
if (!get_update_driver_doc (connection, update_driver_sd_unit, &update_driver_docs_array,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
g_printerr ("%s", local_error->message);
|
||||
}
|
||||
else if (update_driver_docs_array)
|
||||
{
|
||||
g_string_append_printf (error_msg, "See %s's documentation", update_driver_name);
|
||||
gsize docs_len;
|
||||
g_autofree const char **update_driver_docs =
|
||||
g_variant_get_strv (update_driver_docs_array, &docs_len);
|
||||
if (docs_len > 0)
|
||||
{
|
||||
g_string_append_printf (error_msg, " at ");
|
||||
for (guint i = 0; i < docs_len; i++)
|
||||
g_string_append_printf (error_msg, "%s%s", update_driver_docs[i],
|
||||
i < docs_len - 1 ? ", " : "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (error_msg, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_string_append_printf (error_msg, "Use --bypass-driver to bypass %s and force an upgrade anyway",
|
||||
update_driver_name);
|
||||
return glnx_throw (error, "%s", error_msg->str);
|
||||
}
|
||||
}
|
||||
|
||||
g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy);
|
||||
|
||||
const gboolean check_or_preview = (opt_check || opt_preview);
|
||||
|
@ -44,12 +44,11 @@ assert_streq "$(vm_get_booted_csum)" "${booted_csum}"
|
||||
vm_assert_journal_has_content $cursor 'Not finalizing; found /run/ostree/staged-deployment-locked'
|
||||
echo "ok locked rebase staging"
|
||||
|
||||
# This also now tests custom client IDs in the journal and the `deploy --register-driver` option.
|
||||
# This also now tests custom client IDs in the journal.
|
||||
cursor=$(vm_get_journal_cursor)
|
||||
vm_cmd env RPMOSTREE_CLIENT_ID=testing-agent-id \
|
||||
rpm-ostree deploy revision="${commit}" \
|
||||
--lock-finalization --register-driver TestDriver
|
||||
vm_cmd test -f /run/rpm-ostree/update-driver.gv
|
||||
--lock-finalization
|
||||
vm_cmd test -f /run/ostree/staged-deployment-locked
|
||||
if vm_rpmostree finalize-deployment; then
|
||||
assert_not_reached "finalized without expected checksum"
|
||||
@ -60,30 +59,11 @@ vm_cmd journalctl --after-cursor "'$cursor'" -u rpm-ostreed -o json | jq -r '.AG
|
||||
assert_file_has_content agent.txt testing-agent-id
|
||||
vm_cmd journalctl --after-cursor "'$cursor'" -u rpm-ostreed -o json | jq -r '.AGENT_SD_UNIT//""' > agent_sd_unit.txt
|
||||
assert_file_has_content agent_sd_unit.txt sshd.service
|
||||
vm_cmd rpm-ostree status > status.txt
|
||||
assert_file_has_content status.txt 'AutomaticUpdatesDriver: TestDriver'
|
||||
vm_cmd rpm-ostree status -v > verbose_status.txt
|
||||
assert_file_has_content verbose_status.txt 'AutomaticUpdatesDriver: TestDriver (sshd.service)'
|
||||
assert_file_has_content verbose_status.txt ' DriverState: active'
|
||||
vm_assert_status_jq ".\"update-driver\"[\"driver-name\"] == \"TestDriver\"" \
|
||||
".\"update-driver\"[\"driver-sd-unit\"] == \"sshd.service\""
|
||||
vm_reboot_cmd rpm-ostree finalize-deployment "${commit}"
|
||||
assert_streq "$(vm_get_booted_csum)" "${commit}"
|
||||
vm_assert_journal_has_content $cursor "Finalized deployment; rebooting into ${commit}"
|
||||
echo "ok finalize-deployment"
|
||||
|
||||
# Test `deploy --register-driver` option with empty string as revision.
|
||||
vm_cmd rpm-ostree deploy \'\' \
|
||||
--register-driver=OtherTestDriver
|
||||
vm_cmd test -f /run/rpm-ostree/update-driver.gv
|
||||
vm_cmd rpm-ostree status > status.txt
|
||||
assert_file_has_content status.txt 'AutomaticUpdatesDriver: OtherTestDriver'
|
||||
vm_cmd rpm-ostree status -v > verbose_status.txt
|
||||
assert_file_has_content verbose_status.txt 'AutomaticUpdatesDriver: OtherTestDriver (sshd.service)'
|
||||
vm_assert_status_jq ".\"update-driver\"[\"driver-name\"] == \"OtherTestDriver\"" \
|
||||
".\"update-driver\"[\"driver-sd-unit\"] == \"sshd.service\""
|
||||
echo "ok deploy --register-driver with empty string revision"
|
||||
|
||||
# Custom origin and local repo rebases. This is essentially the RHCOS workflow.
|
||||
# https://github.com/projectatomic/rpm-ostree/pull/1406
|
||||
# https://github.com/projectatomic/rpm-ostree/pull/1732
|
||||
@ -308,3 +288,26 @@ vm_rpmostree status > status.txt
|
||||
assert_file_has_content status.txt "failed to finalize previous deployment"
|
||||
assert_file_has_content status.txt "error: opendir"
|
||||
echo "ok previous staged failure in status"
|
||||
|
||||
# Test `deploy --register-driver` option.
|
||||
vm_cmd rpm-ostree deploy \'\' \
|
||||
--register-driver=TestDriver
|
||||
vm_cmd test -f /run/rpm-ostree/update-driver.gv
|
||||
vm_cmd rpm-ostree status > status.txt
|
||||
assert_file_has_content status.txt 'AutomaticUpdatesDriver: TestDriver'
|
||||
vm_cmd rpm-ostree status -v > verbose_status.txt
|
||||
assert_file_has_content verbose_status.txt 'AutomaticUpdatesDriver: TestDriver (sshd.service)'
|
||||
vm_assert_status_jq ".\"update-driver\"[\"driver-name\"] == \"TestDriver\"" \
|
||||
".\"update-driver\"[\"driver-sd-unit\"] == \"sshd.service\""
|
||||
echo "ok deploy --register-driver with empty string revision"
|
||||
|
||||
# Ensure that we are prevented from upgrading when an updates driver is registered
|
||||
if vm_rpmostree upgrade 2>err.txt; then
|
||||
assert_not_reached "Upgrade with updates driver registered unexpected succeeded"
|
||||
fi
|
||||
assert_file_has_content err.txt 'Updates are driven by TestDriver'
|
||||
# Bypass updates driver to force an upgrade
|
||||
vm_rpmostree upgrade --bypass-driver 2>err.txt
|
||||
assert_not_file_has_content err.txt 'Updates are driven by TestDriver'
|
||||
vm_rpmostree cleanup -p
|
||||
echo "ok upgrade when updates driver is registered"
|
||||
|
Loading…
Reference in New Issue
Block a user