Skip to content

Commit

Permalink
Add a "apply" (reboot) automatic update strategy
Browse files Browse the repository at this point in the history
This is aiming to help replace the hacky systemd unit
created in coreos/fedora-coreos-docs#540

And to also be useful in other contexts (i.e. not coreos/ignition).

Closes: coreos#2843
  • Loading branch information
cgwalters authored and lukewarmtemp committed Jun 7, 2023
1 parent cd7494b commit 8f3bdbe
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
13 changes: 10 additions & 3 deletions man/rpm-ostreed.conf.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,22 @@ Boston, MA 02111-1307, USA.
<term><varname>AutomaticUpdatePolicy=</varname></term>

<listitem>
<para>Controls the automatic update policy. Currently "none", "check", or "stage".
<para>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 <command>rpm-ostree status</command>. Defaults to
"none". The <citerefentry><refentrytitle>rpm-ostreed-automatic.timer</refentrytitle><manvolnum>8</manvolnum></citerefentry>
unit determines the actual frequency of updates.</para>
<para>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
<para>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 <literal>ostree-finalize-staged.service</literal> systemd unit.
</para>
<para>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 <literal>systemd-inhibit bash</literal>; exiting the shell will lift the inhibitor.
</para>
</listitem>
</varlistentry>
<varlistentry>
Expand Down
20 changes: 13 additions & 7 deletions src/daemon/rpmostreed-os.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,13 @@ 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. */
Expand All @@ -744,17 +751,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,
Expand Down
1 change: 1 addition & 0 deletions src/libpriv/rpmostree-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/libpriv/rpmostree-util.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down
17 changes: 13 additions & 4 deletions tests/kolainst/destructive/container-image
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,20 @@ 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
timeout 5m skopeo copy containers-storage:localhost/fcos ${image}:derived
/tmp/autopkgtest-reboot-prepare 4
cursor=$(journalctl -o json -n 1 | jq -r '.["__CURSOR"]')
systemctl start --no-block rpm-ostreed-automatic.service
echo "Blocking for reboot initiation"
journalctl --after-cursor="$cursor" -f -u rpm-ostreed
;;
4)
# This should carry over
Expand All @@ -198,7 +207,7 @@ EOF
fatal "found $p"
fi
done
rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:latest\""
rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:derived\""
;;
*) echo "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}"; exit 1;;
esac

0 comments on commit 8f3bdbe

Please sign in to comment.