[ostree] admin: Add an "undeploy" command
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] admin: Add an "undeploy" command
- Date: Tue, 23 Jul 2013 13:32:49 +0000 (UTC)
commit 3d7bff2d4110b7e2cd8495c3870a523faa3e7224
Author: Colin Walters <walters verbum org>
Date: Tue Jul 23 09:19:24 2013 -0400
admin: Add an "undeploy" command
Otherwise it's really easy to keep accumulating deployments. Also, we
may want to run this after rebooting, so we're back down to one
operating system.
Makefile-ostree.am | 1 +
src/ostree/ot-admin-builtin-undeploy.c | 120 ++++++++++++++++++++++++++
src/ostree/ot-admin-builtins.h | 1 +
src/ostree/ot-admin-deploy.c | 146 ++++++++++++++++++--------------
src/ostree/ot-admin-deploy.h | 7 ++
src/ostree/ot-builtin-admin.c | 1 +
tests/test-admin-deploy-1.sh | 19 ++++-
7 files changed, 231 insertions(+), 64 deletions(-)
---
diff --git a/Makefile-ostree.am b/Makefile-ostree.am
index 4c3ade9..949641e 100644
--- a/Makefile-ostree.am
+++ b/Makefile-ostree.am
@@ -48,6 +48,7 @@ ostree_SOURCES += \
src/ostree/ot-admin-builtin-init-fs.c \
src/ostree/ot-admin-builtin-diff.c \
src/ostree/ot-admin-builtin-deploy.c \
+ src/ostree/ot-admin-builtin-undeploy.c \
src/ostree/ot-admin-builtin-cleanup.c \
src/ostree/ot-admin-builtin-os-init.c \
src/ostree/ot-admin-builtin-status.c \
diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c
new file mode 100644
index 0000000..2922189
--- /dev/null
+++ b/src/ostree/ot-admin-builtin-undeploy.c
@@ -0,0 +1,120 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012,2013 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ot-admin-builtins.h"
+#include "ot-admin-functions.h"
+#include "ot-admin-deploy.h"
+#include "ot-ordered-hash.h"
+#include "ostree.h"
+
+#include <stdlib.h>
+
+static GOptionEntry options[] = {
+ { NULL }
+};
+
+gboolean
+ot_admin_builtin_undeploy (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error)
+{
+ gboolean ret = FALSE;
+ __attribute__((unused)) GCancellable *cancellable = NULL;
+ GFile *sysroot = admin_opts->sysroot;
+ GOptionContext *context;
+ const char *deploy_index_str;
+ int deploy_index;
+ int current_bootversion;
+ gs_unref_ptrarray GPtrArray *current_deployments = NULL;
+ gs_unref_ptrarray GPtrArray *new_deployments = NULL;
+ gs_free char *revision = NULL;
+ gs_unref_object OtDeployment *booted_deployment = NULL;
+ gs_unref_object OtDeployment *target_deployment = NULL;
+
+ context = g_option_context_new ("INDEX - Delete deployment INDEX");
+
+ g_option_context_add_main_entries (context, options, NULL);
+
+ if (!g_option_context_parse (context, &argc, &argv, error))
+ goto out;
+
+ if (argc < 2)
+ {
+ ot_util_usage_error (context, "INDEX must be specified", error);
+ goto out;
+ }
+
+ deploy_index_str = argv[1];
+ deploy_index = atoi (deploy_index_str);
+
+ if (!ot_admin_list_deployments (sysroot, ¤t_bootversion, ¤t_deployments,
+ cancellable, error))
+ {
+ g_prefix_error (error, "While listing deployments: ");
+ goto out;
+ }
+
+ if (!ot_admin_find_booted_deployment (sysroot, current_deployments, &booted_deployment,
+ cancellable, error))
+ goto out;
+
+ if (deploy_index < 0)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ "Invalid index %d", deploy_index);
+ goto out;
+ }
+ if (deploy_index >= current_deployments->len)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ "Out of range index %d, expected < %d", deploy_index, current_deployments->len);
+ goto out;
+ }
+
+ target_deployment = g_object_ref (current_deployments->pdata[deploy_index]);
+ if (target_deployment == booted_deployment)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ "Cannot undeploy currently booted deployment %i", deploy_index);
+ goto out;
+ }
+
+ g_ptr_array_remove_index (current_deployments, deploy_index);
+
+ if (!ot_admin_write_deployments (sysroot, current_bootversion,
+ current_bootversion ? 0 : 1, current_deployments,
+ cancellable, error))
+ goto out;
+
+ g_print ("Deleted deployment %s.%d\n", ot_deployment_get_csum (target_deployment),
+ ot_deployment_get_deployserial (target_deployment));
+
+ if (!ot_admin_cleanup (sysroot, cancellable, error))
+ {
+ g_prefix_error (error, "Performing final cleanup: ");
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ if (context)
+ g_option_context_free (context);
+ return ret;
+}
diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h
index e6dc264..440ba0f 100644
--- a/src/ostree/ot-admin-builtins.h
+++ b/src/ostree/ot-admin-builtins.h
@@ -33,6 +33,7 @@ typedef struct {
gboolean ot_admin_builtin_os_init (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
gboolean ot_admin_builtin_install (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
gboolean ot_admin_builtin_init_fs (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
+gboolean ot_admin_builtin_undeploy (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
gboolean ot_admin_builtin_deploy (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
gboolean ot_admin_builtin_cleanup (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
gboolean ot_admin_builtin_status (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error);
diff --git a/src/ostree/ot-admin-deploy.c b/src/ostree/ot-admin-deploy.c
index f77a73a..c7421b0 100644
--- a/src/ostree/ot-admin-deploy.c
+++ b/src/ostree/ot-admin-deploy.c
@@ -1000,6 +1000,86 @@ swap_bootloader (GFile *sysroot,
}
gboolean
+ot_admin_write_deployments (GFile *sysroot,
+ int current_bootversion,
+ int new_bootversion,
+ GPtrArray *new_deployments,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint i;
+ gs_unref_object OtBootloader *bootloader = NULL;
+
+ bootloader = ot_admin_query_bootloader (sysroot);
+ if (!bootloader)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No known bootloader configuration detected");
+ goto out;
+ }
+
+ if (current_bootversion == new_bootversion)
+ {
+ if (!full_system_sync (cancellable, error))
+ {
+ g_prefix_error (error, "Full sync: ");
+ goto out;
+ }
+
+ if (!swap_bootlinks (sysroot, current_bootversion,
+ new_deployments,
+ cancellable, error))
+ {
+ g_prefix_error (error, "Swapping current bootlinks: ");
+ goto out;
+ }
+ }
+ else
+ {
+ for (i = 0; i < new_deployments->len; i++)
+ {
+ OtDeployment *deployment = new_deployments->pdata[i];
+ if (!install_deployment_kernel (sysroot, new_bootversion, deployment,
+ cancellable, error))
+ {
+ g_prefix_error (error, "Installing kernel: ");
+ goto out;
+ }
+ }
+
+ /* Swap bootlinks for *new* version */
+ if (!swap_bootlinks (sysroot, new_bootversion, new_deployments,
+ cancellable, error))
+ {
+ g_prefix_error (error, "Generating new bootlinks: ");
+ goto out;
+ }
+
+ if (!full_system_sync (cancellable, error))
+ {
+ g_prefix_error (error, "Full sync: ");
+ goto out;
+ }
+
+ if (!ot_bootloader_write_config (bootloader, new_bootversion,
+ cancellable, error))
+ goto out;
+
+ if (!swap_bootloader (sysroot, current_bootversion, new_bootversion,
+ cancellable, error))
+ {
+ g_prefix_error (error, "Final bootloader swap: ");
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
ot_admin_deploy (GFile *sysroot,
int current_bootversion,
GPtrArray *current_deployments,
@@ -1019,7 +1099,6 @@ ot_admin_deploy (GFile *sysroot,
gboolean ret = FALSE;
OtDeployment *new_deployment;
gs_unref_object OtDeployment *merge_deployment = NULL;
- gs_unref_object OtBootloader *bootloader = NULL;
gs_unref_object GFile *rootfs = NULL;
gs_unref_object OstreeRepo *repo = NULL;
gs_unref_object GFile *commit_root = NULL;
@@ -1071,14 +1150,6 @@ ot_admin_deploy (GFile *sysroot,
goto out;
}
- bootloader = ot_admin_query_bootloader (sysroot);
- if (!bootloader)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No known bootloader configuration detected");
- 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.
@@ -1156,60 +1227,9 @@ ot_admin_deploy (GFile *sysroot,
ot_config_parser_set (bootconfig, "options", new_options);
}
- if (current_bootversion == new_bootversion)
- {
- if (!full_system_sync (cancellable, error))
- {
- g_prefix_error (error, "Full sync: ");
- goto out;
- }
-
- if (!swap_bootlinks (sysroot, current_bootversion,
- new_deployments,
- cancellable, error))
- {
- g_prefix_error (error, "Swapping current bootlinks: ");
- goto out;
- }
- }
- else
- {
- for (i = 0; i < new_deployments->len; i++)
- {
- OtDeployment *deployment = new_deployments->pdata[i];
- if (!install_deployment_kernel (sysroot, new_bootversion, deployment,
- cancellable, error))
- {
- g_prefix_error (error, "Installing kernel: ");
- goto out;
- }
- }
-
- /* Swap bootlinks for *new* version */
- if (!swap_bootlinks (sysroot, new_bootversion, new_deployments,
- cancellable, error))
- {
- g_prefix_error (error, "Generating new bootlinks: ");
- goto out;
- }
-
- if (!full_system_sync (cancellable, error))
- {
- g_prefix_error (error, "Full sync: ");
- goto out;
- }
-
- if (!ot_bootloader_write_config (bootloader, new_bootversion,
- cancellable, error))
- goto out;
-
- if (!swap_bootloader (sysroot, current_bootversion, new_bootversion,
- cancellable, error))
- {
- g_prefix_error (error, "Final bootloader swap: ");
- goto out;
- }
- }
+ if (!ot_admin_write_deployments (sysroot, current_bootversion, new_bootversion,
+ new_deployments, cancellable, error))
+ goto out;
g_print ("Transaction complete, performing cleanup\n");
diff --git a/src/ostree/ot-admin-deploy.h b/src/ostree/ot-admin-deploy.h
index d5dfa83..ab9f1f5 100644
--- a/src/ostree/ot-admin-deploy.h
+++ b/src/ostree/ot-admin-deploy.h
@@ -29,6 +29,13 @@
G_BEGIN_DECLS
+gboolean ot_admin_write_deployments (GFile *sysroot,
+ int current_bootversion,
+ int new_bootversion,
+ GPtrArray *new_deployments,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ot_admin_deploy (GFile *sysroot,
int current_bootversion,
GPtrArray *current_deployments,
diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c
index 4665680..c591c01 100644
--- a/src/ostree/ot-builtin-admin.c
+++ b/src/ostree/ot-builtin-admin.c
@@ -40,6 +40,7 @@ static OstreeAdminCommand admin_subcommands[] = {
{ "os-init", ot_admin_builtin_os_init },
{ "init-fs", ot_admin_builtin_init_fs },
{ "deploy", ot_admin_builtin_deploy },
+ { "undeploy", ot_admin_builtin_undeploy },
{ "upgrade", ot_admin_builtin_upgrade },
{ "cleanup", ot_admin_builtin_cleanup },
{ "status", ot_admin_builtin_status },
diff --git a/tests/test-admin-deploy-1.sh b/tests/test-admin-deploy-1.sh
index 32cca0c..0119586 100755
--- a/tests/test-admin-deploy-1.sh
+++ b/tests/test-admin-deploy-1.sh
@@ -27,7 +27,7 @@ setup_os_repository "archive-z2"
echo "ok setup"
-echo "1..7"
+echo "1..8"
ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
rev=$(ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
@@ -126,9 +126,26 @@ echo "ok upgrade bare"
os_repository_new_commit
ostree --repo=sysroot/ostree/repo remote add testos file://$(pwd)/testos-repo
testos/buildmaster/x86_64-runtime
ostree admin --sysroot=sysroot upgrade --os=testos
+origrev=${rev}
rev=${newrev}
newrev=$(ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
assert_not_streq ${rev} ${newrev}
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
echo "ok upgrade"
+
+assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
+assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.4/etc/os-release 'NAME=TestOS'
+ostree admin --sysroot=sysroot undeploy 1
+assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
+assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.4
+
+assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.3/etc/os-release 'NAME=TestOS'
+ostree admin --sysroot=sysroot undeploy 3
+assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.3
+
+assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
+ostree admin --sysroot=sysroot undeploy 0
+assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${newrev}.0
+
+echo "ok undeploy"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]