From f9484e9bab5d559e96ecd6ae48f6f411b8760be2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 16 May 2013 08:29:20 -0400 Subject: [PATCH] admin: Add -r option to upgrade to initiate a reboot if tree changes $ ostree admin upgrade -r is convenient to fire off inside a VM and come back to it later. --- src/ostree/ot-admin-builtin-pull-deploy.c | 35 ++--------------- src/ostree/ot-admin-builtin-upgrade.c | 46 +++++++++++++++++++--- src/ostree/ot-admin-functions.c | 48 +++++++++++++++++++++-- src/ostree/ot-admin-functions.h | 17 ++++++++ 4 files changed, 105 insertions(+), 41 deletions(-) diff --git a/src/ostree/ot-admin-builtin-pull-deploy.c b/src/ostree/ot-admin-builtin-pull-deploy.c index 08d39583..cfdd9e64 100644 --- a/src/ostree/ot-admin-builtin-pull-deploy.c +++ b/src/ostree/ot-admin-builtin-pull-deploy.c @@ -35,21 +35,6 @@ static GOptionEntry options[] = { { NULL } }; -static char * -parse_deploy_name_from_path (GFile *osdir, - GFile *path) -{ - ot_lfree char *relpath = g_file_get_relative_path (osdir, path); - const char *last_dash; - - g_assert (relpath); - last_dash = strrchr (relpath, '-'); - if (!last_dash) - g_error ("Failed to parse deployment name %s", relpath); - - return g_strndup (relpath, last_dash - relpath); -} - static gboolean ensure_remote_branch (OstreeRepo *repo, const char *remote, @@ -116,7 +101,6 @@ ot_admin_builtin_pull_deploy (int argc, char **argv, OtAdminBuiltinOpts *admin_o ot_lobj GFile *current_deployment = NULL; ot_lfree char *deploy_name = NULL; ot_lobj GFile *deploy_dir = NULL; - ot_lobj GFile *os_dir = NULL; ot_lfree char *remote_name = NULL; ot_lptrarray GPtrArray *subproc_args = NULL; __attribute__((unused)) GCancellable *cancellable = NULL; @@ -142,9 +126,6 @@ ot_admin_builtin_pull_deploy (int argc, char **argv, OtAdminBuiltinOpts *admin_o if (!ostree_repo_check (repo, error)) goto out; - deploy_dir = g_file_get_child (ostree_dir, "deploy"); - os_dir = g_file_get_child (deploy_dir, osname); - if (argc > 2) { target = argv[2]; @@ -167,20 +148,12 @@ ot_admin_builtin_pull_deploy (int argc, char **argv, OtAdminBuiltinOpts *admin_o goto out; } - deploy_name = parse_deploy_name_from_path (os_dir, current_deployment); + ot_admin_parse_deploy_name (ostree_dir, osname, current_deployment, + &deploy_name, NULL); } - { - ot_lfree char *repo_arg = g_strconcat ("--repo=", - gs_file_get_path_cached (repo_path), - NULL); - - if (!gs_subprocess_simple_run_sync (gs_file_get_path_cached (ostree_dir), - GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT, - cancellable, error, - "ostree", "pull", repo_arg, osname, NULL)) - goto out; - } + if (!ot_admin_pull (ostree_dir, osname, cancellable, error)) + goto out; { ot_lfree char *opt_ostree_dir_arg = g_strconcat ("--ostree-dir=", diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c index 60def832..b060fbb9 100644 --- a/src/ostree/ot-admin-builtin-upgrade.c +++ b/src/ostree/ot-admin-builtin-upgrade.c @@ -24,13 +24,17 @@ #include "ot-admin-builtins.h" #include "ot-admin-functions.h" +#include "ostree.h" #include "otutil.h" #include #include #include +static gboolean opt_reboot; + static GOptionEntry options[] = { + { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after a successful upgrade", NULL }, { NULL } }; @@ -42,6 +46,12 @@ ot_admin_builtin_upgrade (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GFile *ostree_dir = admin_opts->ostree_dir; gs_free char *booted_osname = NULL; const char *osname = NULL; + gs_unref_object GFile *deployment = NULL; + gs_unref_object GFile *repo_path = NULL; + gs_unref_object OstreeRepo *repo = NULL; + gs_free char *deploy_name = NULL; + gs_free char *current_rev = NULL; + gs_free char *new_rev = NULL; gs_free char *ostree_dir_arg = NULL; __attribute__((unused)) GCancellable *cancellable = NULL; @@ -57,7 +67,8 @@ ot_admin_builtin_upgrade (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, } else { - if (!ot_admin_get_active_deployment (NULL, &booted_osname, NULL, cancellable, error)) + if (!ot_admin_get_booted_os (&booted_osname, NULL, + cancellable, error)) goto out; if (booted_osname == NULL) { @@ -67,15 +78,18 @@ ot_admin_builtin_upgrade (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, } osname = booted_osname; } + + if (!ot_admin_get_current_deployment (ostree_dir, osname, &deployment, + cancellable, error)) + goto out; + + ot_admin_parse_deploy_name (ostree_dir, osname, deployment, &deploy_name, ¤t_rev); ostree_dir_arg = g_strconcat ("--ostree-dir=", gs_file_get_path_cached (ostree_dir), NULL); - - if (!gs_subprocess_simple_run_sync (gs_file_get_path_cached (ostree_dir), - GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT, - cancellable, error, - "ostree", "admin", ostree_dir_arg, "pull-deploy", osname, NULL)) + + if (!ot_admin_pull (ostree_dir, osname, cancellable, error)) goto out; if (!gs_subprocess_simple_run_sync (gs_file_get_path_cached (ostree_dir), @@ -84,6 +98,26 @@ ot_admin_builtin_upgrade (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, "ostree", "admin", ostree_dir_arg, "prune", osname, NULL)) goto out; + if (opt_reboot) + { + repo_path = g_file_get_child (ostree_dir, "repo"); + + repo = ostree_repo_new (repo_path); + if (!ostree_repo_check (repo, error)) + goto out; + + if (!ostree_repo_resolve_rev (repo, deploy_name, TRUE, &new_rev, + error)) + goto out; + + if (strcmp (current_rev, new_rev) != 0 && opt_reboot) + { + gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT, + cancellable, error, + "systemctl", "reboot", NULL); + } + } + ret = TRUE; out: if (context) diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c index cc0d3b39..736c230d 100644 --- a/src/ostree/ot-admin-functions.c +++ b/src/ostree/ot-admin-functions.c @@ -313,11 +313,11 @@ ot_admin_list_deployments (GFile *ostree_dir, return ret; } -static gboolean -ot_admin_get_booted_os (char **out_osname, - char **out_tree, +gboolean +ot_admin_get_booted_os (char **out_osname, + char **out_tree, GCancellable *cancellable, - GError **error) + GError **error) { gboolean ret = FALSE; gs_free char *ret_osname = NULL; @@ -467,3 +467,43 @@ ot_admin_get_default_ostree_dir (GFile **out_ostree_dir, ot_transfer_out_value (out_ostree_dir, &ret_ostree_dir); return ret; } + +gboolean +ot_admin_pull (GFile *ostree_dir, + const char *osname, + GCancellable *cancellable, + GError **error) +{ + gs_unref_object GFile *repo_path = g_file_get_child (ostree_dir, "repo"); + gs_free char *repo_arg = g_strconcat ("--repo=", + gs_file_get_path_cached (repo_path), + NULL); + + return gs_subprocess_simple_run_sync (gs_file_get_path_cached (ostree_dir), + GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT, + cancellable, error, + "ostree", "pull", repo_arg, osname, NULL); +} + +void +ot_admin_parse_deploy_name (GFile *ostree_dir, + const char *osname, + GFile *deployment, + char **out_name, + char **out_rev) +{ + gs_unref_object GFile *deploy_dir = g_file_get_child (ostree_dir, "deploy"); + gs_unref_object GFile *os_dir = g_file_get_child (deploy_dir, osname); + gs_free char *relpath = g_file_get_relative_path (os_dir, deployment); + const char *last_dash; + + g_assert (relpath); + last_dash = strrchr (relpath, '-'); + if (!last_dash) + g_error ("Failed to parse deployment name %s", relpath); + + if (out_name) + *out_name = g_strndup (relpath, last_dash - relpath); + if (out_rev) + *out_rev = g_strdup (last_dash + 1); +} diff --git a/src/ostree/ot-admin-functions.h b/src/ostree/ot-admin-functions.h index d74d768b..a03ef59d 100644 --- a/src/ostree/ot-admin-functions.h +++ b/src/ostree/ot-admin-functions.h @@ -31,6 +31,11 @@ gboolean ot_admin_ensure_initialized (GFile *ostree_dir, GCancellable *cancellable, GError **error); +gboolean ot_admin_get_booted_os (char **out_osname, + char **out_tree, + GCancellable *cancellable, + GError **error); + gboolean ot_admin_get_current_deployment (GFile *ostree_dir, const char *osname, GFile **out_deployment, @@ -58,6 +63,18 @@ gboolean ot_admin_get_default_ostree_dir (GFile **out_ostree_dir, GCancellable *cancellable, GError **error); +gboolean ot_admin_pull (GFile *ostree_dir, + const char *osname, + GCancellable *cancellable, + GError **error); + +void +ot_admin_parse_deploy_name (GFile *ostree_dir, + const char *osname, + GFile *deployment, + char **out_name, + char **out_rev); + G_END_DECLS #endif