diff --git a/man/rpm-ostreed.conf.xml b/man/rpm-ostreed.conf.xml
index f06e83bb39..418c60abf4 100644
--- a/man/rpm-ostreed.conf.xml
+++ b/man/rpm-ostreed.conf.xml
@@ -71,15 +71,22 @@ Boston, MA 02111-1307, USA.
AutomaticUpdatePolicy=
- Controls the automatic update policy. Currently "none", "check", or "stage".
+ Controls the automatic update policy. Currently "none", "check", "stage", "apply".
"none" disables automatic updates. "check" downloads just enough metadata to check
for updates and display them in rpm-ostree status. Defaults to
"none". The rpm-ostreed-automatic.timer8
unit determines the actual frequency of updates.
- Finally, the "stage" policy downloads and unpacks the update, performing
- any package layering. Only a small amount of work is left to be performed at
+ The "stage" policy downloads and unpacks the update, queuing it for the next boot.
+ This leaves initiating a reboot to other automation tools.
+ Only a small amount of work is left to be performed at
shutdown time via the ostree-finalize-staged.service systemd unit.
+ Finally, the "apply" policy will currently always initiate a reboot. However,
+ in the future it may apply userspace-only fixes without a physical reboot.
+ Any reboots initiated via rpm-ostree will default to honoring active systemd inhibitors.
+ For example, to temporarily suppress automatic "apply" updates while debugging a system,
+ you can use systemd-inhibit bash; exiting the shell will lift the inhibitor.
+
diff --git a/src/daemon/rpmostreed-os.cxx b/src/daemon/rpmostreed-os.cxx
index 8b15159ba4..76bb4abee7 100644
--- a/src/daemon/rpmostreed-os.cxx
+++ b/src/daemon/rpmostreed-os.cxx
@@ -725,6 +725,14 @@ os_handle_automatic_update_trigger (RPMOSTreeOS *interface, GDBusMethodInvocatio
}
}
+ /* if output-to-self is not explicitly set, default to TRUE */
+ g_autoptr (GVariant) arg_options_owned = NULL;
+ if (!g_variant_dict_contains (&dict, "output-to-self"))
+ {
+ g_variant_dict_insert (&dict, "output-to-self", "b", TRUE);
+ }
+
+
/* Now we translate policy into flags the deploy transaction understands. But avoid
* starting it at all if we're not even on. The benefit of this approach is that we keep
* the Deploy transaction simpler. */
@@ -744,17 +752,16 @@ os_handle_automatic_update_trigger (RPMOSTreeOS *interface, GDBusMethodInvocatio
break;
case RPMOSTREED_AUTOMATIC_UPDATE_POLICY_STAGE:
break;
+ case RPMOSTREED_AUTOMATIC_UPDATE_POLICY_APPLY:
+ // For now, we always reboot for any change. In the future, we may start e.g. detecting
+ // the case where there are no kernel changes, and doing a fast userspace apply via systemd.
+ g_variant_dict_insert (&dict, "reboot", "b", TRUE);
+ break;
default:
g_assert_not_reached ();
}
- /* if output-to-self is not explicitly set, default to TRUE */
- g_autoptr (GVariant) arg_options_owned = NULL;
- if (!g_variant_dict_contains (&dict, "output-to-self"))
- {
- g_variant_dict_insert (&dict, "output-to-self", "b", TRUE);
- arg_options = arg_options_owned = g_variant_ref_sink (g_variant_dict_end (&dict));
- }
+ arg_options = arg_options_owned = g_variant_ref_sink (g_variant_dict_end (&dict));
(void)arg_options_owned; /* Pacify static analysis */
return os_merge_or_start_deployment_txn (interface, invocation, dfault, arg_options, NULL, NULL,
diff --git a/src/libpriv/rpmostree-types.h b/src/libpriv/rpmostree-types.h
index 903fddd6ff..5c400f2ab3 100644
--- a/src/libpriv/rpmostree-types.h
+++ b/src/libpriv/rpmostree-types.h
@@ -34,6 +34,7 @@ typedef enum
RPMOSTREED_AUTOMATIC_UPDATE_POLICY_NONE,
RPMOSTREED_AUTOMATIC_UPDATE_POLICY_CHECK,
RPMOSTREED_AUTOMATIC_UPDATE_POLICY_STAGE,
+ RPMOSTREED_AUTOMATIC_UPDATE_POLICY_APPLY,
} RpmostreedAutomaticUpdatePolicy;
typedef enum
diff --git a/src/libpriv/rpmostree-util.cxx b/src/libpriv/rpmostree-util.cxx
index 8ee6943d7c..7aa2a84f20 100644
--- a/src/libpriv/rpmostree-util.cxx
+++ b/src/libpriv/rpmostree-util.cxx
@@ -1031,6 +1031,8 @@ rpmostree_auto_update_policy_to_str (RpmostreedAutomaticUpdatePolicy policy, GEr
return "check";
case RPMOSTREED_AUTOMATIC_UPDATE_POLICY_STAGE:
return "stage";
+ case RPMOSTREED_AUTOMATIC_UPDATE_POLICY_APPLY:
+ return "apply";
default:
return (char *)glnx_null_throw (error, "Invalid policy value %u", policy);
}
@@ -1047,6 +1049,8 @@ rpmostree_str_to_auto_update_policy (const char *str, RpmostreedAutomaticUpdateP
*out_policy = RPMOSTREED_AUTOMATIC_UPDATE_POLICY_CHECK;
else if (g_str_equal (str, "stage") || g_str_equal (str, "ex-stage") /* backcompat */)
*out_policy = RPMOSTREED_AUTOMATIC_UPDATE_POLICY_STAGE;
+ else if (g_str_equal (str, "apply"))
+ *out_policy = RPMOSTREED_AUTOMATIC_UPDATE_POLICY_APPLY;
else
return glnx_throw (error, "Invalid value for AutomaticUpdatePolicy: '%s'", str);
return TRUE;
diff --git a/tests/kolainst/destructive/container-image b/tests/kolainst/destructive/container-image
index 598fbef52a..0d87e10a42 100755
--- a/tests/kolainst/destructive/container-image
+++ b/tests/kolainst/destructive/container-image
@@ -183,11 +183,19 @@ EOF
! rpm -q nano
rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:derived\""
+ # We'll test the "apply" automatic updates policy here
+ systemctl stop rpm-ostreed
+ cp /usr/etc/rpm-ostreed.conf /etc
+ echo -e "[Daemon]\nAutomaticUpdatePolicy=apply" > /etc/rpm-ostreed.conf
+ rpm-ostree reload
+
# Now revert back to the base image, but keep our layered package foo
rm "${image_dir}" -rf
skopeo copy containers-storage:localhost/fcos ${image}:latest
- rpm-ostree rebase ostree-unverified-image:${image}:latest
- /tmp/autopkgtest-reboot 4
+ /tmp/autopkgtest-reboot-prepare 4
+ systemctl start rpm-ostreed-automatic.service
+ echo "Blocking for reboot initiation"
+ sleep infinity
;;
4)
# This should carry over