Skip to content

Commit

Permalink
pkg-add: New builtin to layer additional packages
Browse files Browse the repository at this point in the history
This builds upon the earlier prototype in
https://github.com/cgwalters/atomic-pkglayer

The `.origin` file says for a replicated installation:

    [origin]
    refspec=local:rhel-atomic-host/7/x86_64/standard

If you then run `rpm-ostree pkg-add strace`, it will result in a new tree with:

    [origin]
    baserefspec=local:rhel-atomic-host/7/x86_64/standard

    [packages]
    requested=strace;

Work still remaining here is to teach `rpm-ostree status` and
`rpm-ostree upgrade` about this.

Closes: #289
Approved by: <try>
  • Loading branch information
cgwalters authored and rh-atomic-bot committed May 26, 2016
1 parent b1bb193 commit e72ebd3
Show file tree
Hide file tree
Showing 22 changed files with 1,650 additions and 145 deletions.
3 changes: 3 additions & 0 deletions Makefile-daemon.am
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ librpmostreed_la_SOURCES = \
src/daemon/rpmostreed-utils.c \
src/daemon/rpmostreed-sysroot.h \
src/daemon/rpmostreed-sysroot.c \
src/daemon/rpmostree-sysroot-upgrader.h \
src/daemon/rpmostree-sysroot-upgrader.c \
src/daemon/rpmostreed-errors.h \
src/daemon/rpmostreed-errors.c \
src/daemon/rpmostreed-deployment-utils.h \
Expand All @@ -39,6 +41,7 @@ librpmostreed_la_SOURCES = \
src/daemon/rpmostreed-transaction-monitor.c \
src/daemon/rpmostreed-transaction-types.h \
src/daemon/rpmostreed-transaction-types.c \
src/daemon/rpmostreed-transaction-pkg-add.c \
src/daemon/rpmostree-package-variants.h \
src/daemon/rpmostree-package-variants.c \
src/daemon/rpmostreed-os.h \
Expand Down
1 change: 1 addition & 0 deletions Makefile-rpm-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ rpm_ostree_SOURCES = src/app/main.c \
src/app/rpmostree-builtin-rollback.c \
src/app/rpmostree-builtin-deploy.c \
src/app/rpmostree-builtin-rebase.c \
src/app/rpmostree-builtin-pkgadd.c \
src/app/rpmostree-builtin-status.c \
src/app/rpmostree-builtin-internals.c \
src/app/rpmostree-builtin-container.c \
Expand Down
1 change: 1 addition & 0 deletions src/app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static RpmOstreeCommand commands[] = {
#endif
{ "db", rpmostree_builtin_db },
{ "deploy", rpmostree_builtin_deploy },
{ "pkg-add", rpmostree_builtin_pkg_add },
{ "rebase", rpmostree_builtin_rebase },
{ "rollback", rpmostree_builtin_rollback },
{ "status", rpmostree_builtin_status },
Expand Down
123 changes: 123 additions & 0 deletions src/app/rpmostree-builtin-pkgadd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2015 Colin Walters <walters@verbum.org>
*
* 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 <libglnx.h>

static char *opt_osname;
static gboolean opt_reboot;

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 },
{ NULL }
};

static GVariant *
new_floating_empty_gvariant_dict (void)
{
GVariantDict dict;
g_variant_dict_init (&dict, NULL);
return g_variant_dict_end (&dict);
}

int
rpmostree_builtin_pkg_add (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;
int i;
g_autoptr(GPtrArray) argv_and_null = g_ptr_array_new ();

context = g_option_context_new ("PACKAGE [PACKAGE...] - Download and install layered RPM packages");

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, "At least one PACKAGE must be specified", error);
goto out;
}

for (i = 1; i < argc; i++)
g_ptr_array_add (argv_and_null, argv[i]);
g_ptr_array_add (argv_and_null, NULL);

if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
cancellable, &os_proxy, error))
goto out;

if (!rpmostree_os_call_pkg_add_sync (os_proxy,
new_floating_empty_gvariant_dict (),
(const char * const*)argv_and_null->pdata,
&transaction_address,
cancellable,
error))
goto out;

if (!rpmostree_transaction_get_response_sync (sysroot_proxy,
transaction_address,
cancellable,
error))
goto out;

if (!opt_reboot)
{
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;
}
46 changes: 42 additions & 4 deletions src/app/rpmostree-builtin-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ printchar (char *s, int n)
g_print ("\n");
}

static char *
format_layered_packages_plus (char **packages)
{
guint len = g_strv_length (packages);
if (len > 0)
return g_strdup_printf (" (+%u)", len);
else
return g_strdup ("");
}

int
rpmostree_builtin_status (int argc,
char **argv,
Expand Down Expand Up @@ -126,6 +136,7 @@ rpmostree_builtin_status (int argc,
if (!opt_pretty)
{
gchar *origin_refspec = NULL; /* borrowed */
gchar **origin_packages = NULL; /* borrowed */
gchar *os_name = NULL; /* borrowed */
gchar *version_string = NULL; /* borrowed */

Expand All @@ -143,7 +154,17 @@ rpmostree_builtin_status (int argc,
max_version_len = MAX (max_version_len, strlen (version_string));

if (g_variant_dict_lookup (dict, "origin", "&s", &origin_refspec))
max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec));
{
if (g_variant_dict_lookup (dict, "packages", "^a&s", &origin_packages))
{
g_autofree gchar *origin_packages_plus =
format_layered_packages_plus (origin_packages);

max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec) + strlen (origin_packages_plus));
}
else
max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec));
}
}

g_variant_unref (child);
Expand Down Expand Up @@ -177,9 +198,11 @@ rpmostree_builtin_status (int argc,

gchar *id = NULL; /* borrowed */
gchar *origin_refspec = NULL; /* borrowed */
gchar **origin_packages = NULL; /* borrowed */
gchar *os_name = NULL; /* borrowed */
gchar *version_string = NULL; /* borrowed */
gchar *checksum = NULL; /* borrowed */
g_autofree gchar *origin_refspec_description = NULL;

guint64 t = 0;
gint serial;
Expand All @@ -194,9 +217,21 @@ rpmostree_builtin_status (int argc,
g_variant_dict_lookup (dict, "version", "s", &version_string);
g_variant_dict_lookup (dict, "timestamp", "t", &t);
g_variant_dict_lookup (dict, "origin", "s", &origin_refspec);
g_variant_dict_lookup (dict, "packages", "^a&s", &origin_packages);
signatures = g_variant_dict_lookup_value (dict, "signatures",
G_VARIANT_TYPE ("av"));

if (origin_packages)
{
g_autofree gchar *origin_packages_plus =
format_layered_packages_plus (origin_packages);
origin_refspec_description = g_strconcat (origin_refspec, origin_packages_plus, NULL);
}
else
{
origin_refspec_description = g_strdup (origin_refspec);
}

is_booted = g_strcmp0 (booted_id, id) == 0;

timestamp = g_date_time_new_from_unix_utc (t);
Expand All @@ -221,14 +256,16 @@ rpmostree_builtin_status (int argc,
g_print ("%-*s%-*s%-*s\n",
max_id_len+buffer, truncated_csum,
max_osname_len+buffer, os_name,
max_refspec_len, origin_refspec);
max_refspec_len, origin_refspec_description);
}

/* print "pretty" row info */
else
{
guint tab = 11;
char *title = NULL;
g_autofree char *packages_joined = g_strjoinv (" ", origin_packages);

if (i==0)
title = "DEFAULT ON BOOT";
else if (is_booted || n <= 2)
Expand All @@ -243,11 +280,12 @@ rpmostree_builtin_status (int argc,
if (version_string)
g_print (" %-*s%-*s\n", tab, "version", tab, version_string);

g_print (" %-*s%-*s\n %-*s%-*s.%d\n %-*s%-*s\n %-*s%-*s\n",
g_print (" %-*s%-*s\n %-*s%-*s.%d\n %-*s%-*s\n %-*s%-*s\n %-*s%-*s\n",
tab, "timestamp", tab, timestamp_string,
tab, "id", tab, checksum, serial,
tab, "osname", tab, os_name,
tab, "refspec", tab, origin_refspec);
tab, "refspec", tab, origin_refspec,
tab, "packages", tab, packages_joined);

if (signatures != NULL)
rpmostree_print_signatures (signatures, " GPG: ");
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ BUILTINPROTO(status);
BUILTINPROTO(db);
BUILTINPROTO(internals);
BUILTINPROTO(container);
BUILTINPROTO(pkg_add);

#undef BUILTINPROTO

Expand Down
24 changes: 21 additions & 3 deletions src/app/rpmostree-compose-builtin-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,9 +883,27 @@ rpmostree_compose_builtin_tree (int argc,
error))
goto out;

if (!rpmostree_commit (yumroot, repo, self->ref, metadata, gpgkey, selinux,
cancellable, error))
goto out;
{ g_autofree char *new_revision = NULL;
glnx_fd_close int rootfs_fd = -1;

if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (yumroot), TRUE,
&rootfs_fd, error))
goto out;

g_print ("Committing...\n");

if (!rpmostree_commit (rootfs_fd, repo, self->ref, metadata, gpgkey, selinux, NULL,
&new_revision,
cancellable, error))
goto out;

g_print ("%s => %s\n", ref, new_revision);

if (!g_getenv ("RPM_OSTREE_PRESERVE_ROOTFS"))
(void) glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (yumroot), cancellable, NULL);
else
g_print ("Preserved %s\n", gs_file_get_path_cached (yumroot));
}
}

if (opt_touch_if_changed)
Expand Down
7 changes: 7 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
'timestamp' (type 't')
'origin' (type 's')
'signatures' (type 'av')
'packages' (type 'as')
-->

<interface name="org.projectatomic.rpmostree1.Sysroot">
Expand Down Expand Up @@ -171,6 +172,12 @@
<arg type="s" name="transaction_address" direction="out"/>
</method>

<method name="PkgAdd">
<arg type="a{sv}" name="options" direction="in"/>
<arg type="as" name="packages"/>
<arg type="s" name="transaction_address" direction="out"/>
</method>

</interface>

<interface name="org.projectatomic.rpmostree1.Transaction">
Expand Down
Loading

0 comments on commit e72ebd3

Please sign in to comment.