[ostree/wip/libsysroot: 1/2] wip
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/libsysroot: 1/2] wip
- Date: Tue, 1 Oct 2013 00:43:21 +0000 (UTC)
commit a7c26b032d4cd0e0259a5032f8c6e6a4b0644ca3
Author: Colin Walters <walters verbum org>
Date: Mon Sep 16 22:37:00 2013 -0400
wip
src/libostree/ostree-sysroot-cleanup.c | 13 +-
src/libostree/ostree-sysroot-deploy.c | 406 +++++++++++---------------------
src/libostree/ostree-sysroot-private.h | 6 +
src/libostree/ostree-sysroot.c | 4 +
src/libostree/ostree-sysroot.h | 1 -
src/ostree/ot-admin-builtin-deploy.c | 11 +-
src/ostree/ot-admin-builtin-upgrade.c | 7 +-
src/ostree/ot-admin-functions.c | 47 ++++
src/ostree/ot-admin-functions.h | 9 +
9 files changed, 222 insertions(+), 282 deletions(-)
---
diff --git a/src/libostree/ostree-sysroot-cleanup.c b/src/libostree/ostree-sysroot-cleanup.c
index 186c6cb..29ff995 100644
--- a/src/libostree/ostree-sysroot-cleanup.c
+++ b/src/libostree/ostree-sysroot-cleanup.c
@@ -25,11 +25,11 @@
#include "ostree-sysroot-private.h"
-static gboolean
-list_deployment_dirs_for_os (GFile *osdir,
- GPtrArray *inout_deployments,
- GCancellable *cancellable,
- GError **error)
+gboolean
+_ostree_sysroot_list_deployment_dirs_for_os (GFile *osdir,
+ GPtrArray *inout_deployments,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret = FALSE;
const char *osname = gs_file_get_basename_cached (osdir);
@@ -136,7 +136,8 @@ list_all_deployment_directories (OstreeSysroot *self,
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
continue;
- if (!list_deployment_dirs_for_os (child, ret_deployments, cancellable, error))
+ if (!_ostree_sysroot_list_deployment_dirs_for_os (child, ret_deployments,
+ cancellable, error))
goto out;
}
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index 14136d2..2b32cf0 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -459,224 +459,6 @@ checksum_from_kernel_src (GFile *src,
return TRUE;
}
-static int
-sort_by_bootserial (gconstpointer ap, gconstpointer bp)
-{
- OstreeDeployment **a_loc = (OstreeDeployment**)ap;
- OstreeDeployment *a = *a_loc;
- OstreeDeployment **b_loc = (OstreeDeployment**)bp;
- OstreeDeployment *b = *b_loc;
-
- if (ostree_deployment_get_bootserial (a) == ostree_deployment_get_bootserial (b))
- return 0;
- else if (ostree_deployment_get_bootserial (a) < ostree_deployment_get_bootserial (b))
- return -1;
- return 1;
-}
-
-static GPtrArray *
-filter_deployments_by_bootcsum (GPtrArray *deployments,
- const char *osname,
- const char *bootcsum)
-{
- GPtrArray *ret = g_ptr_array_new ();
- guint i;
-
- for (i = 0; i < deployments->len; i++)
- {
- OstreeDeployment *deployment = deployments->pdata[i];
-
- if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
- continue;
- if (strcmp (ostree_deployment_get_bootcsum (deployment), bootcsum) != 0)
- continue;
-
- g_ptr_array_add (ret, deployment);
- }
- g_ptr_array_sort (ret, sort_by_bootserial);
-
- return ret;
-}
-
-static void
-compute_new_deployment_list (int current_bootversion,
- GPtrArray *current_deployments,
- const char *osname,
- OstreeDeployment *booted_deployment,
- OstreeDeployment *merge_deployment,
- gboolean retain,
- const char *revision,
- const char *bootcsum,
- GPtrArray **out_new_deployments)
-{
- guint i;
- int new_index;
- guint new_deployserial = 0;
- int new_bootserial = 0;
- gs_unref_object OstreeDeployment *new_deployment = NULL;
- gs_unref_ptrarray GPtrArray *matching_deployments_by_bootserial = NULL;
- OstreeDeployment *deployment_to_delete = NULL;
- gs_unref_ptrarray GPtrArray *ret_new_deployments = NULL;
-
- /* First, compute the serial for this deployment; we look
- * for other ones in this os with the same checksum.
- */
- for (i = 0; i < current_deployments->len; i++)
- {
- OstreeDeployment *deployment = current_deployments->pdata[i];
-
- if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
- continue;
- if (strcmp (ostree_deployment_get_csum (deployment), revision) != 0)
- continue;
-
- new_deployserial = MAX(new_deployserial, ostree_deployment_get_deployserial (deployment)+1);
- }
-
- /* We retain by default (well, hardcoded now) one previous
- * deployment for this OS, plus the booted deployment. Usually, we
- * have one previous, one into which we're booted, and we're
- * deploying a new one. So the old previous will get swapped out,
- * and booted becomes previous.
- *
- * But if the user then upgrades again, we will end up pruning the
- * front of the deployment list. We never delete the running
- * deployment.
- */
- if (!retain)
- {
- for (i = 0; i < current_deployments->len; i++)
- {
- OstreeDeployment *deployment = current_deployments->pdata[i];
-
- if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
- continue;
-
- // Keep both the booted and merge deployments
- if (ostree_deployment_equal (deployment, booted_deployment) ||
- ostree_deployment_equal (deployment, merge_deployment))
- continue;
-
- deployment_to_delete = deployment;
- }
- }
-
- ret_new_deployments = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-
- new_deployment = ostree_deployment_new (0, osname, revision, new_deployserial,
- bootcsum, new_bootserial);
- g_ptr_array_add (ret_new_deployments, g_object_ref (new_deployment));
- new_index = 1;
- for (i = 0; i < current_deployments->len; i++)
- {
- OstreeDeployment *orig_deployment = current_deployments->pdata[i];
- gs_unref_object OstreeDeployment *deployment_clone = NULL;
-
- if (orig_deployment == deployment_to_delete)
- continue;
-
- deployment_clone = ostree_deployment_clone (orig_deployment);
- ostree_deployment_set_index (deployment_clone, new_index);
- new_index++;
- g_ptr_array_add (ret_new_deployments, g_object_ref (deployment_clone));
- }
-
- /* Just renumber the deployments for the OS we're adding; we don't
- * handle anything else at the moment.
- */
- matching_deployments_by_bootserial = filter_deployments_by_bootcsum (ret_new_deployments,
- osname, bootcsum);
- for (i = 0; i < matching_deployments_by_bootserial->len; i++)
- {
- OstreeDeployment *deployment = matching_deployments_by_bootserial->pdata[i];
- ostree_deployment_set_bootserial (deployment, i);
- }
-
- *out_new_deployments = ret_new_deployments;
- ret_new_deployments = NULL;
-}
-
-static GHashTable *
-object_array_to_set (GPtrArray *objlist,
- GHashFunc hashfunc,
- GEqualFunc equalfunc)
-{
- GHashTable *ret = g_hash_table_new_full (hashfunc, equalfunc, g_object_unref, NULL);
- guint i;
-
- for (i = 0; i < objlist->len; i++)
- {
- GObject *obj = g_object_ref (objlist->pdata[i]);
- g_hash_table_insert (ret, obj, obj);
- }
-
- return ret;
-}
-
-static GHashTable *
-object_set_subtract (GHashTable *a, GHashTable *b)
-{
- GHashTable *ret = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
- GHashTableIter hashiter;
- gpointer hashkey, hashvalue;
-
- g_hash_table_iter_init (&hashiter, a);
- while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
- {
- if (!g_hash_table_contains (b, hashkey))
- {
- GObject *o = g_object_ref (hashkey);
- g_hash_table_insert (ret, o, o);
- }
- }
-
- return ret;
-}
-
-static void
-print_deployment_set (gboolean for_removal,
- GHashTable *set)
-{
- GHashTableIter hashiter;
- gpointer hashkey, hashvalue;
-
- if (g_hash_table_size (set) == 0)
- return;
-
- g_print ("%s\n", for_removal ? "removed:" : "added: ");
-
- g_hash_table_iter_init (&hashiter, set);
- while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
- {
- OstreeDeployment *deployment = hashkey;
-
- g_print (" %c %s %s.%d",
- for_removal ? '-' : '+', ostree_deployment_get_osname (deployment),
- ostree_deployment_get_csum (deployment),
- ostree_deployment_get_deployserial (deployment));
-
- if (!for_removal)
- g_print (" index=%d", ostree_deployment_get_index (deployment));
- g_print ("\n");
- }
-}
-
-static void
-print_deployment_diff (GPtrArray *current_deployments,
- GPtrArray *new_deployments)
-{
- gs_unref_hashtable GHashTable *curset = object_array_to_set (current_deployments, ostree_deployment_hash,
ostree_deployment_equal);
- gs_unref_hashtable GHashTable *newset = object_array_to_set (new_deployments, ostree_deployment_hash,
ostree_deployment_equal);
- gs_unref_hashtable GHashTable *removed = NULL;
- gs_unref_hashtable GHashTable *added = NULL;
-
- removed = object_set_subtract (curset, newset);
- added = object_set_subtract (newset, curset);
-
- print_deployment_set (TRUE, removed);
- print_deployment_set (FALSE, added);
-}
-
/* FIXME: We should really do individual fdatasync() on files/dirs,
* since this causes us to block on unrelated I/O. However, it's just
* safer for now.
@@ -970,7 +752,8 @@ swap_bootloader (OstreeSysroot *sysroot,
}
static GHashTable *
-bootcsum_counts_for_deployment_list (GPtrArray *deployments)
+bootcsum_counts_for_deployment_list (GPtrArray *deployments,
+ gboolean set_bootserial)
{
guint i;
GHashTable *ret =
@@ -984,7 +767,52 @@ bootcsum_counts_for_deployment_list (GPtrArray *deployments)
count = GPOINTER_TO_UINT (g_hash_table_lookup (ret, bootcsum));
g_hash_table_replace (ret, (char*)bootcsum, GUINT_TO_POINTER (count + 1));
+
+ if (set_bootserial)
+ ostree_deployment_set_bootserial (deployment, count);
+ }
+ return ret;
+}
+
+/* TEMPORARY HACK: Add a "current" symbolic link that's easy to
+ * follow inside the gnome-ostree build scripts. This isn't atomic,
+ * but that doesn't matter because it's only used by deployments
+ * done from the host.
+ */
+static gboolean
+create_current_symlinks (OstreeSysroot *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint i;
+ gs_unref_hashtable GHashTable *created_current_for_osname =
+ g_hash_table_new (g_str_hash, g_str_equal);
+
+ for (i = 0; i < self->deployments->len; i++)
+ {
+ OstreeDeployment *deployment = self->deployments->pdata[i];
+ const char *osname = ostree_deployment_get_osname (deployment);
+
+ if (!g_hash_table_lookup (created_current_for_osname, osname))
+ {
+ gs_unref_object GFile *osdir = ot_gfile_resolve_path_printf (self->path, "ostree/deploy/%s",
osname);
+ gs_unref_object GFile *os_current_path = g_file_get_child (osdir, "current");
+ gs_unref_object GFile *deployment_path = ostree_sysroot_get_deployment_directory (self,
deployment);
+ gs_free char *target = g_file_get_relative_path (osdir, deployment_path);
+
+ g_assert (target != NULL);
+
+ if (!ot_gfile_atomic_symlink_swap (os_current_path, target,
+ cancellable, error))
+ goto out;
+
+ g_hash_table_insert (created_current_for_osname, (char*)osname, GUINT_TO_POINTER (1));
+ }
}
+
+ ret = TRUE;
+ out:
return ret;
}
@@ -1007,9 +835,16 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
gboolean ret = FALSE;
guint i;
gboolean requires_new_bootversion = FALSE;
+ gboolean found_booted_deployment = FALSE;
+ gs_unref_hashtable GHashTable *new_bootcsum_to_count = NULL;
g_assert (self->loaded);
+ /* Calculate the total number of deployments per bootcsums; while we
+ * are doing this, assign a bootserial to each new deployment.
+ */
+ new_bootcsum_to_count = bootcsum_counts_for_deployment_list (new_deployments, TRUE);
+
/* Determine whether or not we need to touch the bootloader
* configuration. If we have an equal number of deployments and
* more strongly an equal number of deployments per bootcsum, then
@@ -1022,9 +857,7 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
GHashTableIter hashiter;
gpointer hkey, hvalue;
gs_unref_hashtable GHashTable *orig_bootcsum_to_count
- = bootcsum_counts_for_deployment_list (self->deployments);
- gs_unref_hashtable GHashTable *new_bootcsum_to_count
- = bootcsum_counts_for_deployment_list (new_deployments);
+ = bootcsum_counts_for_deployment_list (self->deployments, FALSE);
g_hash_table_iter_init (&hashiter, orig_bootcsum_to_count);
while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
@@ -1041,6 +874,22 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
}
}
+ for (i = 0; i < new_deployments->len; i++)
+ {
+ OstreeDeployment *deployment = new_deployments->pdata[i];
+
+ if (deployment == self->booted_deployment)
+ found_booted_deployment = TRUE;
+
+ ostree_deployment_set_index (deployment, 0);
+ }
+
+ if (self->booted_deployment && !found_booted_deployment)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Attempting to remove booted deployment");
+ goto out;
+ }
+
if (!requires_new_bootversion)
{
if (!full_system_sync (cancellable, error))
@@ -1108,6 +957,16 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
}
}
+ g_print ("Transaction complete, performing cleanup\n");
+
+ /* And finally, cleanup of any leftover data.
+ */
+ if (!ostree_sysroot_cleanup (self, cancellable, error))
+ {
+ g_prefix_error (error, "Performing final cleanup: ");
+ goto out;
+ }
+
/* Now reload from disk */
if (!ostree_sysroot_load (self, cancellable, error))
{
@@ -1115,10 +974,52 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
goto out;
}
+ if (!create_current_symlinks (self, cancellable, error))
+ goto out;
+
ret = TRUE;
out:
return ret;
}
+
+static gboolean
+allocate_deployserial (OstreeSysroot *self,
+ const char *osname,
+ const char *revision,
+ int *out_deployserial,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint i;
+ int new_deployserial = 0;
+ gs_unref_object GFile *osdir = NULL;
+ gs_unref_ptrarray GPtrArray *tmp_current_deployments =
+ g_ptr_array_new_with_free_func (g_object_unref);
+
+ osdir = ot_gfile_get_child_build_path (self->path, "ostree/deploy", osname, NULL);
+
+ if (!_ostree_sysroot_list_deployment_dirs_for_os (osdir, tmp_current_deployments,
+ cancellable, error))
+ goto out;
+
+ for (i = 0; i < tmp_current_deployments->len; i++)
+ {
+ OstreeDeployment *deployment = tmp_current_deployments->pdata[i];
+
+ if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
+ continue;
+ if (strcmp (ostree_deployment_get_csum (deployment), revision) != 0)
+ continue;
+
+ new_deployserial = MAX(new_deployserial, ostree_deployment_get_deployserial (deployment)+1);
+ }
+
+ ret = TRUE;
+ *out_deployserial = new_deployserial;
+ out:
+ return ret;
+}
/**
* ostree_sysroot_deploy_one_tree:
@@ -1127,14 +1028,13 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
* @revision: Checksum to add
* @origin: (allow-none): Origin to use for upgrades
* @add_kernel_argv: (allow-none): Append these arguments to kernel configuration
- * @retain: If %TRUE, then do not delete earlier deployment
* @provided_merge_deployment: (allow-none): Use this deployment for merge path
* @out_new_deployment: (out): The new deployment path
* @cancellable: Cancellable
* @error: Error
*
- * Add a new deployment with revision @revision; if @retain is %FALSE,
- * then an earlier deployment will be garbage collected.
+ * Check out deployment tree with revision @revision, performing a 3
+ * way merge with @provided_merge_deployment for configuration.
*/
gboolean
ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
@@ -1142,14 +1042,14 @@ ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
const char *revision,
GKeyFile *origin,
char **add_kernel_argv,
- gboolean retain,
OstreeDeployment *provided_merge_deployment,
OstreeDeployment **out_new_deployment,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
- OstreeDeployment *new_deployment;
+ gint new_deployserial;
+ gs_unref_object OstreeDeployment *new_deployment = NULL;
gs_unref_object OstreeDeployment *merge_deployment = NULL;
gs_unref_object OstreeRepo *repo = NULL;
gs_unref_object GFile *commit_root = NULL;
@@ -1158,7 +1058,6 @@ ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
gs_unref_object GFile *new_deployment_path = NULL;
gs_free char *new_bootcsum = NULL;
gs_unref_object OstreeBootconfigParser *bootconfig = NULL;
- gs_unref_ptrarray GPtrArray *new_deployments = NULL;
g_return_val_if_fail (osname != NULL || self->booted_deployment != NULL, FALSE);
@@ -1199,25 +1098,16 @@ ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
goto out;
}
- /* If we're booted into the OS into which we're deploying, then
- * merge the currently *booted* configuration, rather than the most
- * recently deployed.
- */
if (provided_merge_deployment != NULL)
merge_deployment = g_object_ref (provided_merge_deployment);
- else
- merge_deployment = ostree_sysroot_get_merge_deployment (self, osname);
-
- compute_new_deployment_list (self->bootversion,
- self->deployments, osname,
- self->booted_deployment, merge_deployment,
- retain,
- revision, new_bootcsum,
- &new_deployments);
- new_deployment = g_object_ref (new_deployments->pdata[0]);
- ostree_deployment_set_origin (new_deployment, origin);
- print_deployment_diff (self->deployments, new_deployments);
+ if (!allocate_deployserial (self, osname, revision, &new_deployserial,
+ cancellable, error))
+ goto out;
+
+ new_deployment = ostree_deployment_new (0, osname, revision, new_deployserial,
+ new_bootcsum, 0);
+ ostree_deployment_set_origin (new_deployment, origin);
/* Check out the userspace tree onto the filesystem */
if (!checkout_deployment_tree (self, repo, new_deployment, &new_deployment_path,
@@ -1274,34 +1164,6 @@ ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
ostree_bootconfig_parser_set (bootconfig, "options", new_options);
}
- if (!ostree_sysroot_write_deployments (self, new_deployments, cancellable, error))
- goto out;
-
- g_print ("Transaction complete, performing cleanup\n");
-
- /* TEMPORARY HACK: Add a "current" symbolic link that's easy to
- * follow inside the gnome-ostree build scripts. This isn't atomic,
- * but that doesn't matter because it's only used by deployments
- * done from the host.
- */
- {
- gs_unref_object GFile *osdir = ot_gfile_resolve_path_printf (self->path, "ostree/deploy/%s",
ostree_deployment_get_osname (new_deployment));
- gs_unref_object GFile *os_current_path = g_file_get_child (osdir, "current");
- gs_free char *target = g_file_get_relative_path (osdir, new_deployment_path);
- g_assert (target != NULL);
- if (!ot_gfile_atomic_symlink_swap (os_current_path, target,
- cancellable, error))
- goto out;
- }
-
- /* And finally, cleanup of any leftover data.
- */
- if (!ostree_sysroot_cleanup (self, cancellable, error))
- {
- g_prefix_error (error, "Performing final cleanup: ");
- goto out;
- }
-
ret = TRUE;
ot_transfer_out_value (out_new_deployment, &new_deployment);
out:
diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h
index 864d3cd..ce79fb8 100644
--- a/src/libostree/ostree-sysroot-private.h
+++ b/src/libostree/ostree-sysroot-private.h
@@ -61,6 +61,12 @@ _ostree_sysroot_parse_deploy_path_name (const char *name,
GError **error);
gboolean
+_ostree_sysroot_list_deployment_dirs_for_os (GFile *osdir,
+ GPtrArray *inout_deployments,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean
_ostree_sysroot_get_devino (GFile *path,
guint32 *out_device,
guint64 *out_inode,
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index bf064d5..92d7b03 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -1070,6 +1070,10 @@ ostree_sysroot_get_merge_deployment (OstreeSysroot *self,
if (osname == NULL)
osname = ostree_deployment_get_osname (self->booted_deployment);
+ /* If we're booted into the OS into which we're deploying, then
+ * merge the currently *booted* configuration, rather than the most
+ * recently deployed.
+ */
if (self->booted_deployment &&
g_strcmp0 (ostree_deployment_get_osname (self->booted_deployment), osname) == 0)
{
diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h
index d8959c4..a61f491 100644
--- a/src/libostree/ostree-sysroot.h
+++ b/src/libostree/ostree-sysroot.h
@@ -76,7 +76,6 @@ gboolean ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
const char *revision,
GKeyFile *origin,
char **add_kernel_argv,
- gboolean retain,
OstreeDeployment *provided_merge_deployment,
OstreeDeployment **out_new_deployment,
GCancellable *cancellable,
diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c
index 9761f86..efe543b 100644
--- a/src/ostree/ot-admin-builtin-deploy.c
+++ b/src/ostree/ot-admin-builtin-deploy.c
@@ -54,6 +54,7 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell
gs_unref_object OstreeRepo *repo = NULL;
gs_unref_ptrarray GPtrArray *new_deployments = NULL;
gs_unref_object OstreeDeployment *new_deployment = NULL;
+ gs_unref_object OstreeDeployment *merge_deployment = NULL;
gs_free char *revision = NULL;
context = g_option_context_new ("REFSPEC - Checkout revision REFSPEC as the new default deployment");
@@ -102,14 +103,20 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell
if (!ostree_repo_resolve_rev (repo, refspec, FALSE, &revision, error))
goto out;
+ merge_deployment = ostree_sysroot_get_merge_deployment (sysroot, opt_osname);
+
if (!ostree_sysroot_deploy_one_tree (sysroot,
opt_osname, revision, origin,
- opt_kernel_argv, opt_retain,
- NULL,
+ opt_kernel_argv, merge_deployment,
&new_deployment,
cancellable, error))
goto out;
+ if (!ot_admin_complete_deploy_one (sysroot, opt_osname,
+ new_deployment, merge_deployment, opt_retain,
+ cancellable, error))
+ goto out;
+
ret = TRUE;
out:
if (origin)
diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c
index 73b1bf5..8654e65 100644
--- a/src/ostree/ot-admin-builtin-upgrade.c
+++ b/src/ostree/ot-admin-builtin-upgrade.c
@@ -127,12 +127,17 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancel
gs_unref_object GFile *real_sysroot = g_file_new_for_path ("/");
if (!ostree_sysroot_deploy_one_tree (sysroot,
opt_osname, new_revision, origin,
- NULL, FALSE,
+ NULL,
merge_deployment,
&new_deployment,
cancellable, error))
goto out;
+ if (!ot_admin_complete_deploy_one (sysroot, opt_osname,
+ new_deployment, merge_deployment, FALSE,
+ cancellable, error))
+ goto out;
+
if (opt_reboot && g_file_equal (ostree_sysroot_get_path (sysroot), real_sysroot))
{
gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c
index 90f3a4e..bf9364d 100644
--- a/src/ostree/ot-admin-functions.c
+++ b/src/ostree/ot-admin-functions.c
@@ -56,3 +56,50 @@ ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot,
out:
return ret;
}
+
+gboolean
+ot_admin_complete_deploy_one (OstreeSysroot *sysroot,
+ const char *osname,
+ OstreeDeployment *new_deployment,
+ OstreeDeployment *merge_deployment,
+ gboolean opt_retain,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint i;
+ OstreeDeployment *booted_deployment = NULL;
+ gs_unref_ptrarray GPtrArray *deployments = NULL;
+ gs_unref_ptrarray GPtrArray *new_deployments = g_ptr_array_new_with_free_func (g_object_unref);
+
+ deployments = ostree_sysroot_get_deployments (sysroot);
+ booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
+
+ g_ptr_array_add (new_deployments, g_object_ref (new_deployment));
+
+ for (i = 0; i < deployments->len; i++)
+ {
+ OstreeDeployment *deployment = deployments->pdata[i];
+
+ /* Keep deployments with different osnames, as well as the
+ * booted and merge deployments
+ */
+ if (opt_retain ||
+ strcmp (ostree_deployment_get_osname (deployment), osname) != 0 ||
+ ostree_deployment_equal (deployment, booted_deployment) ||
+ ostree_deployment_equal (deployment, merge_deployment))
+ {
+ g_ptr_array_add (new_deployments, g_object_ref (deployment));
+ }
+ }
+
+ if (!ostree_sysroot_write_deployments (sysroot, new_deployments, cancellable, error))
+ goto out;
+
+ if (!ostree_sysroot_cleanup (sysroot, cancellable, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
diff --git a/src/ostree/ot-admin-functions.h b/src/ostree/ot-admin-functions.h
index 8b9758d..e0a824d 100644
--- a/src/ostree/ot-admin-functions.h
+++ b/src/ostree/ot-admin-functions.h
@@ -35,5 +35,14 @@ ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error);
+gboolean
+ot_admin_complete_deploy_one (OstreeSysroot *sysroot,
+ const char *osname,
+ OstreeDeployment *new_deployment,
+ OstreeDeployment *merge_deployment,
+ gboolean opt_retain,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]