Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new ex initramfs-etc command #2170

Merged
merged 1 commit into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile-rpm-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ rpm_ostree_SOURCES = src/app/main.c \
src/app/rpmostree-builtin-cliwrap.c \
src/app/rpmostree-builtin-cleanup.c \
src/app/rpmostree-builtin-initramfs.c \
src/app/rpmostree-builtin-initramfs-etc.c \
src/app/rpmostree-builtin-livefs.c \
src/app/rpmostree-builtin-usroverlay.c \
src/app/rpmostree-builtin-override.c \
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ LIBS="$save_LIBS"
# Remember to update AM_CPPFLAGS in Makefile.am when bumping GIO req.
PKG_CHECK_MODULES(PKGDEP_GIO_UNIX, [gio-unix-2.0])
PKG_CHECK_MODULES(PKGDEP_RPMOSTREE, [gio-unix-2.0 >= 2.50.0 json-glib-1.0
ostree-1 >= 2020.1
ostree-1 >= 2020.7
libsystemd
polkit-gobject-1
rpm librepo libsolv
Expand Down
30 changes: 30 additions & 0 deletions man/rpm-ostree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,36 @@ Boston, MA 02111-1307, USA.
</listitem>
</varlistentry>

<varlistentry>
<term><command>ex initramfs-etc</command></term>

<listitem>
<para>
Experimental feature; subject to change.
</para>

<para>
Add configuration (<literal>/etc</literal>) files into the initramfs without
regenerating the entire initramfs. This is useful to be able to configure
services backing the root block device as well as early-boot services like
systemd and journald.
</para>

<para>
Use <command>--track</command> to start tracking a specific file. Can be
specified multiple times. A new deployment will be generated. Use
<command>--untrack</command> or <command>--untrack-all</command> to stop
tracking files.
</para>

<para>
When there are tracked files, any future created deployment (e.g. when doing an
upgrade) will ensure that they are synced. You can additionally use
<command>--force-sync</command> to simply generate a new deployment with the
latest versions of tracked files without upgrading.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
2 changes: 1 addition & 1 deletion packaging/rpm-ostree.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ BuildRequires: gnome-common
BuildRequires: /usr/bin/g-ir-scanner
# Core requirements
# One way to check this: `objdump -p /path/to/rpm-ostree | grep LIBOSTREE` and pick the highest (though that might miss e.g. new struct members)
BuildRequires: pkgconfig(ostree-1) >= 2019.2
BuildRequires: pkgconfig(ostree-1) >= 2020.7
BuildRequires: pkgconfig(polkit-gobject-1)
BuildRequires: pkgconfig(json-glib-1.0)
BuildRequires: pkgconfig(rpm)
Expand Down
2 changes: 2 additions & 0 deletions src/app/rpmostree-builtin-ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ static RpmOstreeCommand ex_subcommands[] = {
#endif
{ "history", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
"Inspect rpm-ostree history of the system", rpmostree_ex_builtin_history },
{ "initramfs-etc", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
"Track initramfs configuration files", rpmostree_ex_builtin_initramfs_etc },
{ NULL, 0, NULL, NULL }
};

Expand Down
156 changes: 156 additions & 0 deletions src/app/rpmostree-builtin-initramfs-etc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2020 Jonathan Lebon <jonathan@jlebon.com>
*
* 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 <string.h>
#include <glib-unix.h>

#include "rpmostree-ex-builtins.h"
#include "rpmostree-libbuiltin.h"
#include "rpmostree-dbus-helpers.h"

#include <libglnx.h>

static char *opt_osname;
static gboolean opt_force_sync;
static char **opt_track;
static char **opt_untrack;
static gboolean opt_untrack_all;
static gboolean opt_reboot;
static gboolean opt_lock_finalization;
static gboolean opt_unchanged_exit_77;

static GOptionEntry option_entries[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
{ "force-sync", 0, 0, G_OPTION_ARG_NONE, &opt_force_sync, "Deploy a new tree with the latest tracked /etc files", NULL },
{ "track", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_track, "Track root /etc file", "FILE" },
{ "untrack", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_untrack, "Untrack root /etc file", "FILE" },
{ "untrack-all", 0, 0, G_OPTION_ARG_NONE, &opt_untrack_all, "Untrack all root /etc files", NULL },
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after operation is complete", NULL },
{ "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL },
{ "unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_unchanged_exit_77, "If no new deployment made, exit 77", NULL },

{ NULL }
};

gboolean
rpmostree_ex_builtin_initramfs_etc (int argc,
char **argv,
RpmOstreeCommandInvocation *invocation,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GOptionContext) context = g_option_context_new ("");

_cleanup_peer_ GPid peer_pid = 0;
glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
if (!rpmostree_option_context_parse (context,
option_entries,
&argc, &argv,
invocation,
cancellable,
NULL, NULL,
&sysroot_proxy,
&peer_pid,
NULL,
error))
return FALSE;

glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
cancellable, &os_proxy, error))
return FALSE;

g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy);

if (!(opt_track || opt_untrack || opt_untrack_all || opt_force_sync))
{
if (opt_reboot)
return glnx_throw (error, "Cannot use ---reboot without --track, --untrack, --untrack-all, or --force-sync");

g_autofree char **files = NULL;
g_autoptr(GVariant) deployments = rpmostree_sysroot_dup_deployments (sysroot_proxy);
if (g_variant_n_children (deployments) > 0)
{
g_autoptr(GVariant) pending = g_variant_get_child_value (deployments, 0);
g_auto(GVariantDict) dict;
g_variant_dict_init (&dict, pending);

g_variant_dict_lookup (&dict, "initramfs-etc", "^a&s", &files);
}

if (!files || !*files)
g_print ("No tracked files.\n");
else
{
g_print ("Tracked files:\n");
for (char **it = files; it && *it; it++)
g_print (" %s\n", *it);
}

return TRUE; /* note early return */
}

char *empty_strv[] = {NULL};
if (!opt_track)
opt_track = empty_strv;
if (!opt_untrack)
opt_untrack = empty_strv;

GVariantDict dict;
g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "reboot", "b", opt_reboot);
g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line);
g_variant_dict_insert (&dict, "lock-finalization", "b", opt_lock_finalization);
g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict));

g_autofree char *transaction_address = NULL;
if (!rpmostree_os_call_initramfs_etc_sync (os_proxy,
(const char *const*)opt_track,
(const char *const*)opt_untrack,
opt_untrack_all,
opt_force_sync,
options,
&transaction_address,
cancellable,
error))
return FALSE;

if (!rpmostree_transaction_get_response_sync (sysroot_proxy,
transaction_address,
cancellable,
error))
return FALSE;

if (!opt_reboot)
{
if (!rpmostree_has_new_default_deployment (os_proxy, previous_deployment))
{
if (opt_unchanged_exit_77)
invocation->exit_code = RPM_OSTREE_EXIT_UNCHANGED;
return TRUE;
}

g_print ("Run \"systemctl reboot\" to start a reboot\n");
}

return TRUE;
}
2 changes: 1 addition & 1 deletion src/app/rpmostree-builtin-reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static GOptionEntry option_entries[] = {
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after transaction is complete", NULL },
{ "overlays", 'l', 0, G_OPTION_ARG_NONE, &opt_overlays, "Remove all overlayed packages", NULL },
{ "overrides", 'o', 0, G_OPTION_ARG_NONE, &opt_overrides, "Remove all overrides", NULL },
{ "initramfs", 'i', 0, G_OPTION_ARG_NONE, &opt_initramfs, "Stop regenerating initramfs", NULL },
{ "initramfs", 'i', 0, G_OPTION_ARG_NONE, &opt_initramfs, "Stop regenerating initramfs or tracking files", NULL },
{ "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL },
{ NULL }
};
Expand Down
7 changes: 7 additions & 0 deletions src/app/rpmostree-builtin-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,13 @@ print_one_deployment (RPMOSTreeSysroot *sysroot_proxy,
g_string_append (buf, "regenerate");
rpmostree_print_kv ("Initramfs", max_key_len, buf->str);
}

g_autofree char **initramfs_etc_files = NULL;
g_variant_dict_lookup (dict, "initramfs-etc", "^a&s", &initramfs_etc_files);
if (initramfs_etc_files && *initramfs_etc_files)
/* XXX: not really packages but it works... should just rename that function */
print_packages ("InitramfsEtc", max_key_len, (const char**)initramfs_etc_files, NULL);

gboolean pinned = FALSE;
g_variant_dict_lookup (dict, "pinned", "b", &pinned);
if (pinned)
Expand Down
1 change: 1 addition & 0 deletions src/app/rpmostree-ex-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ BUILTINPROTO(commit2rojig);
BUILTINPROTO(rojig2commit);
#endif
BUILTINPROTO(history);
BUILTINPROTO(initramfs_etc);

#undef BUILTINPROTO

Expand Down
9 changes: 9 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@
<arg type="s" name="transaction_address" direction="out"/>
</method>

<method name="InitramfsEtc">
<arg type="as" name="track" direction="in"/>
<arg type="as" name="untrack" direction="in"/>
<arg type="b" name="untrack_all" direction="in"/>
<arg type="b" name="force_sync" direction="in"/>
<arg type="a{sv}" name="options" direction="in"/>
<arg type="s" name="transaction_address" direction="out"/>
</method>

<!-- Available options:
"reboot" (type 'b')
-->
Expand Down
Loading