From 976c68542b58ef791aef1a33a7c457791eec4449 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 29 May 2014 18:00:11 -0400 Subject: [PATCH] Add a "rebase" builtin This is exactly the code from "ostree admin switch", except it's called "rebase" because in the future it will also carry along any locally layered packages. --- Makefile-rpm-ostree.am | 3 + man/rpm-ostree.xml | 11 +++ src/main.c | 1 + src/rpmostree-builtin-rebase.c | 169 ++++++++++++++++++++++++++++++++ src/rpmostree-builtin-upgrade.c | 53 +--------- src/rpmostree-builtins.h | 1 + src/rpmostree-pull-progress.c | 75 ++++++++++++++ src/rpmostree-pull-progress.h | 27 +++++ 8 files changed, 289 insertions(+), 51 deletions(-) create mode 100644 src/rpmostree-builtin-rebase.c create mode 100644 src/rpmostree-pull-progress.c create mode 100644 src/rpmostree-pull-progress.h diff --git a/Makefile-rpm-ostree.am b/Makefile-rpm-ostree.am index 18066ab0..33776484 100644 --- a/Makefile-rpm-ostree.am +++ b/Makefile-rpm-ostree.am @@ -24,6 +24,8 @@ noinst_LTLIBRARIES += librpmostree.la librpmostree_la_SOURCES = \ src/rpmostree-postprocess.c \ src/rpmostree-postprocess.h \ + src/rpmostree-pull-progress.c \ + src/rpmostree-pull-progress.h \ src/rpmostree-util.c \ src/rpmostree-util.h \ src/hif-utils.c \ @@ -43,6 +45,7 @@ rpm_ostree_SOURCES = src/main.c \ src/rpmostree-builtin-compose.c \ src/rpmostree-builtin-upgrade.c \ src/rpmostree-builtin-rollback.c \ + src/rpmostree-builtin-rebase.c \ src/rpmostree-compose-builtin-tree.c \ src/rpmostree-compose-builtin-sign.c \ $(NULL) diff --git a/man/rpm-ostree.xml b/man/rpm-ostree.xml index 74c5c17e..61b5ebb7 100644 --- a/man/rpm-ostree.xml +++ b/man/rpm-ostree.xml @@ -113,6 +113,17 @@ Boston, MA 02111-1307, USA. tree the default. + + rebase + + Switch to a different remote, or a different + tree, while preserving local state in /var + and configuration in /etc. This is an + extension of upgrade which switches to a + newer version of the current current tree. + + + compose diff --git a/src/main.c b/src/main.c index 943d7699..4a1b3b76 100644 --- a/src/main.c +++ b/src/main.c @@ -34,6 +34,7 @@ static RpmOstreeCommand commands[] = { { "compose", rpmostree_builtin_compose, 0 }, { "upgrade", rpmostree_builtin_upgrade, 0 }, + { "rebase", rpmostree_builtin_rebase, 0 }, { "rollback", rpmostree_builtin_rollback, 0 }, { NULL } }; diff --git a/src/rpmostree-builtin-rebase.c b/src/rpmostree-builtin-rebase.c new file mode 100644 index 00000000..302ab601 --- /dev/null +++ b/src/rpmostree-builtin-rebase.c @@ -0,0 +1,169 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2014 Colin Walters + * + * This program 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 licence 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 +#include + +#include "rpmostree-builtins.h" +#include "rpmostree-treepkgdiff.h" +#include "rpmostree-pull-progress.h" + +#include "libgsystem.h" + +static GOptionEntry option_entries[] = { + { NULL } +}; + +gboolean +rpmostree_builtin_rebase (int argc, + char **argv, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + GOptionContext *context = g_option_context_new ("- Switch to a different tree"); + const char *new_provided_refspec; + gs_unref_object OstreeSysroot *sysroot = NULL; + gs_unref_object OstreeRepo *repo = NULL; + gs_free char *origin_refspec = NULL; + gs_free char *origin_remote = NULL; + gs_free char *origin_ref = NULL; + gs_free char *new_remote = NULL; + gs_free char *new_ref = NULL; + gs_free char *new_refspec = NULL; + gs_free char *new_revision = NULL; + gs_unref_object GFile *deployment_path = NULL; + gs_unref_object GFile *deployment_origin_path = NULL; + gs_unref_object OstreeDeployment *merge_deployment = NULL; + gs_unref_object OstreeDeployment *new_deployment = NULL; + gs_unref_object OstreeSysrootUpgrader *upgrader = NULL; + gs_unref_object OstreeAsyncProgress *progress = NULL; + gboolean changed; + GSConsole *console = NULL; + gboolean in_status_line = FALSE; + GKeyFile *old_origin; + GKeyFile *new_origin = NULL; + + g_option_context_add_main_entries (context, option_entries, NULL); + + if (!g_option_context_parse (context, &argc, &argv, error)) + goto out; + + if (argc < 2) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "REF must be specified"); + goto out; + } + + new_provided_refspec = argv[1]; + + sysroot = ostree_sysroot_new_default (); + if (!ostree_sysroot_load (sysroot, cancellable, error)) + goto out; + + upgrader = ostree_sysroot_upgrader_new_for_os (sysroot, NULL, + cancellable, error); + if (!upgrader) + goto out; + + old_origin = ostree_sysroot_upgrader_get_origin (upgrader); + origin_refspec = g_key_file_get_string (old_origin, "origin", "refspec", NULL); + + if (!ostree_parse_refspec (origin_refspec, &origin_remote, &origin_ref, error)) + goto out; + + /* Allow just switching remotes */ + if (g_str_has_suffix (new_provided_refspec, ":")) + { + new_remote = g_strdup (new_provided_refspec); + new_remote[strlen(new_remote)-1] = '\0'; + new_ref = g_strdup (origin_ref); + } + else + { + if (!ostree_parse_refspec (new_provided_refspec, &new_remote, &new_ref, error)) + goto out; + } + + if (!new_remote) + new_refspec = g_strconcat (origin_remote, ":", new_ref, NULL); + else + new_refspec = g_strconcat (new_remote, ":", new_ref, NULL); + + if (strcmp (origin_refspec, new_refspec) == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Old and new refs are equal: %s", new_refspec); + goto out; + } + + new_origin = ostree_sysroot_origin_new_from_refspec (sysroot, new_refspec); + if (!ostree_sysroot_upgrader_set_origin (upgrader, new_origin, cancellable, error)) + goto out; + + console = gs_console_get (); + if (console) + { + gs_console_begin_status_line (console, "", NULL, NULL); + progress = ostree_async_progress_new_and_connect (_rpmostree_pull_progress, console); + } + + if (in_status_line) + { + gs_console_end_status_line (console, NULL, NULL); + in_status_line = FALSE; + } + + /* Always allow older...there's not going to be a chronological + * relationship necessarily. + */ + if (!ostree_sysroot_upgrader_pull (upgrader, 0, + OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER, + progress, &changed, + cancellable, error)) + goto out; + + if (!ostree_sysroot_upgrader_deploy (upgrader, cancellable, error)) + goto out; + + if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error)) + goto out; + + if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) + goto out; + + g_print ("Deleting ref '%s:%s'\n", origin_remote, origin_ref); + ostree_repo_transaction_set_ref (repo, origin_remote, origin_ref, NULL); + + if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error)) + goto out; + +#ifdef HAVE_PATCHED_HAWKEY_AND_LIBSOLV + if (!rpmostree_print_treepkg_diff (sysroot, cancellable, error)) + goto out; +#endif + + ret = TRUE; + out: + return ret; +} diff --git a/src/rpmostree-builtin-upgrade.c b/src/rpmostree-builtin-upgrade.c index 7e6cdd52..31ae64e3 100644 --- a/src/rpmostree-builtin-upgrade.c +++ b/src/rpmostree-builtin-upgrade.c @@ -25,6 +25,7 @@ #include "rpmostree-builtins.h" #include "rpmostree-treepkgdiff.h" +#include "rpmostree-pull-progress.h" #include "libgsystem.h" @@ -37,56 +38,6 @@ static GOptionEntry option_entries[] = { { NULL } }; -static void -pull_progress (OstreeAsyncProgress *progress, - gpointer user_data) -{ - GSConsole *console = user_data; - GString *buf; - gs_free char *status = NULL; - guint outstanding_fetches; - guint outstanding_writes; - guint n_scanned_metadata; - - if (!console) - return; - - buf = g_string_new (""); - - status = ostree_async_progress_get_status (progress); - outstanding_fetches = ostree_async_progress_get_uint (progress, "outstanding-fetches"); - outstanding_writes = ostree_async_progress_get_uint (progress, "outstanding-writes"); - n_scanned_metadata = ostree_async_progress_get_uint (progress, "scanned-metadata"); - if (status) - { - g_string_append (buf, status); - } - else if (outstanding_fetches) - { - guint64 bytes_transferred = ostree_async_progress_get_uint64 (progress, "bytes-transferred"); - guint fetched = ostree_async_progress_get_uint (progress, "fetched"); - guint requested = ostree_async_progress_get_uint (progress, "requested"); - gs_free char *formatted_bytes_transferred = - g_format_size_full (bytes_transferred, 0); - - g_string_append_printf (buf, "Receiving objects: %u%% (%u/%u) %s", - (guint)((((double)fetched) / requested) * 100), - fetched, requested, formatted_bytes_transferred); - } - else if (outstanding_writes) - { - g_string_append_printf (buf, "Writing objects: %u", outstanding_writes); - } - else - { - g_string_append_printf (buf, "Scanning metadata: %u", n_scanned_metadata); - } - - gs_console_begin_status_line (console, buf->str, NULL, NULL); - - g_string_free (buf, TRUE); -} - gboolean rpmostree_builtin_upgrade (int argc, char **argv, @@ -124,7 +75,7 @@ rpmostree_builtin_upgrade (int argc, if (console) { gs_console_begin_status_line (console, "", NULL, NULL); - progress = ostree_async_progress_new_and_connect (pull_progress, console); + progress = ostree_async_progress_new_and_connect (_rpmostree_pull_progress, console); } if (opt_allow_downgrade) diff --git a/src/rpmostree-builtins.h b/src/rpmostree-builtins.h index 8cbe4706..88523c45 100644 --- a/src/rpmostree-builtins.h +++ b/src/rpmostree-builtins.h @@ -34,6 +34,7 @@ typedef struct { BUILTINPROTO(compose); BUILTINPROTO(upgrade); +BUILTINPROTO(rebase); BUILTINPROTO(rollback); #undef BUILTINPROTO diff --git a/src/rpmostree-pull-progress.c b/src/rpmostree-pull-progress.c new file mode 100644 index 00000000..9c9bdb0f --- /dev/null +++ b/src/rpmostree-pull-progress.c @@ -0,0 +1,75 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2014 Colin Walters + * + * This program 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 licence 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 "rpmostree-pull-progress.h" +#include "libgsystem.h" + +void +_rpmostree_pull_progress (OstreeAsyncProgress *progress, + gpointer user_data) +{ + GSConsole *console = user_data; + GString *buf; + gs_free char *status = NULL; + guint outstanding_fetches; + guint outstanding_writes; + guint n_scanned_metadata; + + if (!console) + return; + + buf = g_string_new (""); + + status = ostree_async_progress_get_status (progress); + outstanding_fetches = ostree_async_progress_get_uint (progress, "outstanding-fetches"); + outstanding_writes = ostree_async_progress_get_uint (progress, "outstanding-writes"); + n_scanned_metadata = ostree_async_progress_get_uint (progress, "scanned-metadata"); + if (status) + { + g_string_append (buf, status); + } + else if (outstanding_fetches) + { + guint64 bytes_transferred = ostree_async_progress_get_uint64 (progress, "bytes-transferred"); + guint fetched = ostree_async_progress_get_uint (progress, "fetched"); + guint requested = ostree_async_progress_get_uint (progress, "requested"); + gs_free char *formatted_bytes_transferred = + g_format_size_full (bytes_transferred, 0); + + g_string_append_printf (buf, "Receiving objects: %u%% (%u/%u) %s", + (guint)((((double)fetched) / requested) * 100), + fetched, requested, formatted_bytes_transferred); + } + else if (outstanding_writes) + { + g_string_append_printf (buf, "Writing objects: %u", outstanding_writes); + } + else + { + g_string_append_printf (buf, "Scanning metadata: %u", n_scanned_metadata); + } + + gs_console_begin_status_line (console, buf->str, NULL, NULL); + + g_string_free (buf, TRUE); +} + diff --git a/src/rpmostree-pull-progress.h b/src/rpmostree-pull-progress.h new file mode 100644 index 00000000..c1f2ea3c --- /dev/null +++ b/src/rpmostree-pull-progress.h @@ -0,0 +1,27 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2014 Colin Walters + * + * This program 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 licence 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. + */ + +#pragma once + +#include + +void +_rpmostree_pull_progress (OstreeAsyncProgress *progress, + gpointer user_data);