summaryrefslogtreecommitdiff
path: root/src/ostree/ot-admin-builtin-deploy.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2018-02-22 15:27:59 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-04-12 14:55:12 +0000
commiteb506c759c666af2461f1ba3dda4e31ea49ebc41 (patch)
treeec78dcc19982e3b14545ad2b22902a85c9a7e4ef /src/ostree/ot-admin-builtin-deploy.c
parentff50495f67a95c9b2fef5f9b84bc91469a46eb27 (diff)
downloadostree-eb506c759c666af2461f1ba3dda4e31ea49ebc41.tar.gz
Add concept of "staged" deployment
Add API to write a deployment state to `/run/ostree/staged-deployment`, along with a systemd service which runs at shutdown time. This is a big change to the ostree model for hosts, but it closes a longstanding set of bugs; many, many people have hit the "losing changes in /etc" problem. It also avoids the other problem of racing with programs that modify `/etc` such as LVM backups: https://bugzilla.redhat.com/show_bug.cgi?id=1365297 We need this in particular to go to a full-on model for automatically updated host systems where (like a dual-partition model) everything is fully prepared and the reboot can be taken asynchronously. Closes: https://github.com/ostreedev/ostree/issues/545 Closes: #1503 Approved by: jlebon
Diffstat (limited to 'src/ostree/ot-admin-builtin-deploy.c')
-rw-r--r--src/ostree/ot-admin-builtin-deploy.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c
index d9905212..f6c0c161 100644
--- a/src/ostree/ot-admin-builtin-deploy.c
+++ b/src/ostree/ot-admin-builtin-deploy.c
@@ -34,6 +34,7 @@
#include <glib/gi18n.h>
static gboolean opt_retain;
+static gboolean opt_stage;
static gboolean opt_retain_pending;
static gboolean opt_retain_rollback;
static gboolean opt_not_as_default;
@@ -50,6 +51,7 @@ static GOptionEntry options[] = {
{ "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", "FILENAME" },
{ "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Don't prune the repo when done", NULL},
{ "retain", 0, 0, G_OPTION_ARG_NONE, &opt_retain, "Do not delete previous deployments", NULL },
+ { "stage", 0, 0, G_OPTION_ARG_NONE, &opt_stage, "Complete deployment at OS shutdown", NULL },
{ "retain-pending", 0, 0, G_OPTION_ARG_NONE, &opt_retain_pending, "Do not delete pending deployments", NULL },
{ "retain-rollback", 0, 0, G_OPTION_ARG_NONE, &opt_retain_rollback, "Do not delete rollback deployments", NULL },
{ "not-as-default", 0, 0, G_OPTION_ARG_NONE, &opt_not_as_default, "Append rather than prepend new deployment", NULL },
@@ -157,31 +159,45 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat
g_autoptr(OstreeDeployment) new_deployment = NULL;
g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
- if (!ostree_sysroot_deploy_tree (sysroot, opt_osname, revision, origin, merge_deployment,
- kargs_strv, &new_deployment, cancellable, error))
- return FALSE;
-
- OstreeSysrootSimpleWriteDeploymentFlags flags = OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN;
- if (opt_retain)
- flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN;
- else
+ if (opt_stage)
{
- if (opt_retain_pending)
- flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING;
- if (opt_retain_rollback)
- flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK;
+ if (opt_retain_pending || opt_retain_rollback)
+ return glnx_throw (error, "--stage cannot currently be combined with --retain arguments");
+ if (opt_not_as_default)
+ return glnx_throw (error, "--stage cannot currently be combined with --not-as-default");
+ if (!ostree_sysroot_stage_tree (sysroot, opt_osname, revision, origin, merge_deployment,
+ kargs_strv, &new_deployment, cancellable, error))
+ return FALSE;
}
+ else
+ {
+ if (!ostree_sysroot_deploy_tree (sysroot, opt_osname, revision, origin, merge_deployment,
+ kargs_strv, &new_deployment, cancellable, error))
+ return FALSE;
- if (opt_not_as_default)
- flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT;
-
- if (!ostree_sysroot_simple_write_deployment (sysroot, opt_osname, new_deployment,
- merge_deployment, flags, cancellable, error))
- return FALSE;
+ OstreeSysrootSimpleWriteDeploymentFlags flags = OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN;
+ if (opt_retain)
+ flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN;
+ else
+ {
+ if (opt_retain_pending)
+ flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING;
+ if (opt_retain_rollback)
+ flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK;
+ }
+
+ if (opt_not_as_default)
+ flags |= OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT;
+
+ if (!ostree_sysroot_simple_write_deployment (sysroot, opt_osname, new_deployment,
+ merge_deployment, flags, cancellable, error))
+ return FALSE;
+ }
- /* And finally, cleanup of any leftover data.
+ /* And finally, cleanup of any leftover data. In stage mode, we
+ * don't do a full cleanup as we didn't touch the bootloader.
*/
- if (opt_no_prune)
+ if (opt_no_prune || opt_stage)
{
if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error))
return FALSE;