diff --git a/Makefile-rpm-ostree.am b/Makefile-rpm-ostree.am index 694b962e..f983d509 100644 --- a/Makefile-rpm-ostree.am +++ b/Makefile-rpm-ostree.am @@ -25,6 +25,7 @@ rpm_ostree_SOURCES = src/app/main.c \ src/app/rpmostree-compose-builtins.h \ src/app/rpmostree-builtin-upgrade.c \ src/app/rpmostree-builtin-rollback.c \ + src/app/rpmostree-builtin-deploy.c \ src/app/rpmostree-builtin-rebase.c \ src/app/rpmostree-builtin-status.c \ src/app/rpmostree-builtin-db.c \ diff --git a/man/rpm-ostree.xml b/man/rpm-ostree.xml index 02cfcb58..695a0aa8 100644 --- a/man/rpm-ostree.xml +++ b/man/rpm-ostree.xml @@ -151,6 +151,29 @@ Boston, MA 02111-1307, USA. + + deploy + + + + Similar to upgrade, but download a specific + version of the current tree which may be newer or older than your + running filesystem tree. The tree to download can be specified by + its SHA256 checksum, or by its "version" metadata value. + + + + or to initiate a + reboot after the downloaded tree is prepared. + + + + to download only /usr/share/rpm in + order to preview the package changes with the current tree. + + + + compose diff --git a/src/app/main.c b/src/app/main.c index b461fbe8..c0b73845 100644 --- a/src/app/main.c +++ b/src/app/main.c @@ -38,6 +38,7 @@ static RpmOstreeCommand commands[] = { { "compose", rpmostree_builtin_compose }, #endif { "db", rpmostree_builtin_db }, + { "deploy", rpmostree_builtin_deploy }, { "rebase", rpmostree_builtin_rebase }, { "rollback", rpmostree_builtin_rollback }, { "status", rpmostree_builtin_status }, diff --git a/src/app/rpmostree-builtin-deploy.c b/src/app/rpmostree-builtin-deploy.c new file mode 100644 index 00000000..f5f392d1 --- /dev/null +++ b/src/app/rpmostree-builtin-deploy.c @@ -0,0 +1,171 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2015 Red Hat, Inc. + * + * 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-builtins.h" +#include "rpmostree-libbuiltin.h" +#include "rpmostree-rpm-util.h" +#include "rpmostree-dbus-helpers.h" + +#include + +static char *opt_osname; +static gboolean opt_reboot; +static gboolean opt_preview; + +static GOptionEntry option_entries[] = { + { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" }, + { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after upgrade is prepared", NULL }, + /* XXX As much as I dislike the inconsistency with "rpm-ostree upgrade", + * calling this option --check-diff doesn't really make sense here. + * A --preview option would work for both commands if we wanted to + * deprecate --check-diff. */ + { "preview", 0, 0, G_OPTION_ARG_NONE, &opt_preview, "Just preview package differences", NULL }, + { NULL } +}; + +static GVariant * +get_args_variant (void) +{ + GVariantDict dict; + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "reboot", "b", opt_reboot); + + return g_variant_dict_end (&dict); +} + +static void +default_deployment_changed_cb (GObject *object, + GParamSpec *pspec, + GVariant **value) +{ + g_object_get (object, pspec->name, value, NULL); +} + +int +rpmostree_builtin_deploy (int argc, + char **argv, + GCancellable *cancellable, + GError **error) +{ + int exit_status = EXIT_FAILURE; + GOptionContext *context; + glnx_unref_object RPMOSTreeOS *os_proxy = NULL; + glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; + g_autoptr(GVariant) default_deployment = NULL; + g_autofree char *transaction_address = NULL; + const char * const packages[] = { NULL }; + const char *revision; + + context = g_option_context_new ("REVISION - Deploy a specific commit"); + + if (!rpmostree_option_context_parse (context, + option_entries, + &argc, &argv, + RPM_OSTREE_BUILTIN_FLAG_NONE, + cancellable, + &sysroot_proxy, + error)) + goto out; + + if (argc < 2) + { + rpmostree_usage_error (context, "REVISION must be specified", error); + goto out; + } + + revision = argv[1]; + + if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, + cancellable, &os_proxy, error)) + goto out; + + if (opt_preview) + { + if (!rpmostree_os_call_download_deploy_rpm_diff_sync (os_proxy, + revision, + packages, + &transaction_address, + cancellable, + error)) + goto out; + } + else + { + /* This will set the GVariant if the default deployment changes. */ + g_signal_connect (os_proxy, "notify::default-deployment", + G_CALLBACK (default_deployment_changed_cb), + &default_deployment); + + if (!rpmostree_os_call_deploy_sync (os_proxy, + revision, + get_args_variant (), + &transaction_address, + cancellable, + error)) + goto out; + } + + if (!rpmostree_transaction_get_response_sync (sysroot_proxy, + transaction_address, + cancellable, + error)) + goto out; + + if (opt_preview) + { + g_autoptr(GVariant) result = NULL; + g_autoptr(GVariant) details = NULL; + + if (!rpmostree_os_call_get_cached_deploy_rpm_diff_sync (os_proxy, + revision, + packages, + &result, + &details, + cancellable, + error)) + goto out; + + rpmostree_print_package_diffs (result); + } + else if (!opt_reboot && default_deployment != NULL) + { + const char *sysroot_path; + + sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy); + + if (!rpmostree_print_treepkg_diff_from_sysroot_path (sysroot_path, + cancellable, + error)) + goto out; + + g_print ("Run \"systemctl reboot\" to start a reboot\n"); + } + + exit_status = EXIT_SUCCESS; + +out: + /* Does nothing if using the message bus. */ + rpmostree_cleanup_peer (); + + return exit_status; +} diff --git a/src/app/rpmostree-builtins.h b/src/app/rpmostree-builtins.h index d0654ae0..95df63cc 100644 --- a/src/app/rpmostree-builtins.h +++ b/src/app/rpmostree-builtins.h @@ -39,6 +39,7 @@ typedef struct { BUILTINPROTO(compose); BUILTINPROTO(upgrade); +BUILTINPROTO(deploy); BUILTINPROTO(rebase); BUILTINPROTO(rollback); BUILTINPROTO(status);