Skip to content
Closed
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
2 changes: 2 additions & 0 deletions Makefile-daemon.am
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,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-livefs.c \
src/daemon/rpmostree-package-variants.h \
src/daemon/rpmostree-package-variants.c \
src/daemon/rpmostreed-os.h \
Expand All @@ -56,6 +57,7 @@ librpmostreed_la_CFLAGS = \
$(AM_CFLAGS) \
$(PKGDEP_RPMOSTREE_CFLAGS) \
-DG_LOG_DOMAIN=\"rpm-ostreed\" \
-D_RPMOSTREE_EXTERN= \
-I$(srcdir)/src/daemon \
-I$(srcdir)/src/lib \
-I$(srcdir)/src/libpriv \
Expand Down
1 change: 1 addition & 0 deletions Makefile-rpm-ostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ rpm_ostree_SOURCES = src/app/main.c \
src/app/rpmostree-builtin-rebase.c \
src/app/rpmostree-builtin-cleanup.c \
src/app/rpmostree-builtin-initramfs.c \
src/app/rpmostree-builtin-livefs.c \
src/app/rpmostree-pkg-builtins.c \
src/app/rpmostree-builtin-status.c \
src/app/rpmostree-builtin-ex.c \
Expand Down
1 change: 1 addition & 0 deletions Makefile-tests.am
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ testpackages = \
tests/common/compose/yum/repo/packages/x86_64/nonrootcap-1.0-1.x86_64.rpm \
tests/common/compose/yum/repo/packages/x86_64/test-post-rofiles-violation-1.0-1.x86_64.rpm \
tests/common/compose/yum/repo/packages/x86_64/test-opt-1.0-1.x86_64.rpm \
tests/common/compose/yum/repo/packages/x86_64/test-livefs-with-etc-1.0-1.x86_64.rpm \
$(NULL)

# Create a rule for each testpkg with their respective spec file as dep.
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 @@ -25,6 +25,8 @@
#include "rpmostree-rpm-util.h"

static RpmOstreeCommand ex_subcommands[] = {
{ "livefs", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
rpmostree_ex_builtin_livefs },
{ "unpack", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
rpmostree_ex_builtin_unpack },
{ "container", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
Expand Down
96 changes: 96 additions & 0 deletions src/app/rpmostree-builtin-livefs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2017 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 <string.h>
#include <glib-unix.h>

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

#include <libglnx.h>

static gboolean opt_dry_run;
static gboolean opt_replace;

static GOptionEntry option_entries[] = {
{ "dry-run", 'n', 0, G_OPTION_ARG_NONE, &opt_dry_run, "Only perform analysis, do not make changes", NULL },
{ "replace", 0, 0, G_OPTION_ARG_NONE, &opt_replace, "Completely replace all files in /usr", NULL },
{ NULL }
};

static GVariant *
get_args_variant (void)
{
GVariantDict dict;

g_variant_dict_init (&dict, NULL);
g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run);
g_variant_dict_insert (&dict, "replace", "b", opt_replace);

return g_variant_dict_end (&dict);
}

int
rpmostree_ex_builtin_livefs (int argc,
char **argv,
RpmOstreeCommandInvocation *invocation,
GCancellable *cancellable,
GError **error)
{
_cleanup_peer_ GPid peer_pid = 0;
glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
g_autoptr(GOptionContext) context = g_option_context_new ("- Apply pending deployment changes to booted deployment");
if (!rpmostree_option_context_parse (context,
option_entries,
&argc, &argv,
invocation,
cancellable,
NULL, NULL,
&sysroot_proxy,
&peer_pid,
error))
return EXIT_FAILURE;

glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
glnx_unref_object RPMOSTreeOSExperimental *osexperimental_proxy = NULL;
if (!rpmostree_load_os_proxies (sysroot_proxy, NULL,
cancellable, &os_proxy,
&osexperimental_proxy, error))
return EXIT_FAILURE;

g_autofree char *transaction_address = NULL;
if (!rpmostree_osexperimental_call_live_fs_sync (osexperimental_proxy,
get_args_variant (),
&transaction_address,
cancellable,
error))
return EXIT_FAILURE;

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

return EXIT_SUCCESS;
}
69 changes: 65 additions & 4 deletions src/app/rpmostree-builtin-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,29 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
const char *red_suffix = is_tty ? "\x1b[22m" : "";
GVariant* txn = get_active_txn (sysroot_proxy);

/* First, gather global state */
gboolean have_any_live_overlay = FALSE;
g_variant_iter_init (&iter, deployments);
while (TRUE)
{
g_autoptr(GVariant) child = g_variant_iter_next_value (&iter);

if (!child)
break;

g_autoptr(GVariantDict) dict = g_variant_dict_new (child);

const gchar *live_inprogress;
if (!g_variant_dict_lookup (dict, "live-inprogress", "&s", &live_inprogress))
live_inprogress = NULL;
const gchar *live_replaced;
if (!g_variant_dict_lookup (dict, "live-replaced", "&s", &live_replaced))
live_replaced = NULL;
const gboolean have_live_changes = live_inprogress || live_replaced;

have_any_live_overlay = have_any_live_overlay || have_live_changes;
}

if (txn)
{
const char *method, *sender, *path;
Expand All @@ -179,13 +202,16 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
const gchar *checksum;
const gchar *version_string;
const gchar *unlocked;
const gchar *live_inprogress;
const gchar *live_replaced;
gboolean gpg_enabled;
gboolean regenerate_initramfs;
guint64 t = 0;
int serial;
gboolean is_booted;
const gboolean was_first = first;
const guint max_key_len = strlen ("PendingBaseVersion");
/* Add the long keys here */
const guint max_key_len = MAX (strlen ("PendingBaseVersion"), strlen ("InterruptedLiveCommit"));
g_autoptr(GVariant) signatures = NULL;
g_autofree char *timestamp_string = NULL;

Expand Down Expand Up @@ -267,10 +293,45 @@ status_generic (RPMOSTreeSysroot *sysroot_proxy,
print_kv ("Timestamp", max_key_len, timestamp_string);
}

if (!g_variant_dict_lookup (dict, "live-inprogress", "&s", &live_inprogress))
live_inprogress = NULL;
if (!g_variant_dict_lookup (dict, "live-replaced", "&s", &live_replaced))
live_replaced = NULL;
const gboolean have_live_changes = live_inprogress || live_replaced;

if (is_locally_assembled)
print_kv ("BaseCommit", max_key_len, base_checksum);
if (opt_verbose || !is_locally_assembled)
print_kv ("Commit", max_key_len, checksum);
{
if (have_live_changes)
print_kv ("BootedBaseCommit", max_key_len, base_checksum);
else
print_kv ("BaseCommit", max_key_len, base_checksum);
if (opt_verbose || have_any_live_overlay)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the rationale for adding || have_any_live_overlay? Is it to make it easier to cross-reference with the deployment that has a live overlay? Can we instead print it only for the deployments that are referenced by a live deployment? Basically changing have_any_live_overlay to e.g. a hash table of checksums.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I agree that'd be more accurate, but I think it'd be better to add the notion of "deployment referencing" to the core?

print_kv ("Commit", max_key_len, checksum);
}
else
{
if (have_live_changes)
print_kv ("BootedCommit", max_key_len, checksum);
if (!have_live_changes || opt_verbose)
print_kv ("Commit", max_key_len, checksum);
}

if (live_inprogress)
{
if (is_booted)
g_print ("%s%s", red_prefix, bold_prefix);
print_kv ("InterruptedLiveCommit", max_key_len, live_inprogress);
if (is_booted)
g_print ("%s%s", bold_suffix, red_suffix);
}
if (live_replaced)
{
if (is_booted)
g_print ("%s%s", red_prefix, bold_prefix);
print_kv ("LiveCommit", max_key_len, live_replaced);
if (is_booted)
g_print ("%s%s", bold_suffix, red_suffix);
}

/* Show any difference between the baseref vs head, but only for the
booted commit, and only if there isn't a pending deployment. Otherwise
Expand Down
9 changes: 8 additions & 1 deletion src/app/rpmostree-ex-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@

G_BEGIN_DECLS

gboolean rpmostree_ex_builtin_unpack (int argc, char **argv, RpmOstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error);
#define BUILTINPROTO(name) gboolean rpmostree_ex_builtin_ ## name (int argc, char **argv, \
RpmOstreeCommandInvocation *invocation, \
GCancellable *cancellable, GError **error)

BUILTINPROTO(unpack);
BUILTINPROTO(livefs);

#undef BUILTINPROTO

G_END_DECLS

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

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

</interface>

<interface name="org.projectatomic.rpmostree1.Transaction">
Expand Down
56 changes: 53 additions & 3 deletions src/daemon/rpmostree-sysroot-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "rpmostree-util.h"

#include "rpmostree-sysroot-upgrader.h"
#include "rpmostree-sysroot-core.h"
#include "rpmostree-core.h"
#include "rpmostree-origin.h"
#include "rpmostree-kernel.h"
Expand Down Expand Up @@ -333,7 +334,8 @@ GPtrArray *
rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
OstreeDeployment *new_deployment,
OstreeDeployment *merge_deployment,
gboolean pushing_rollback)
gboolean pushing_rollback,
GError **error)
{
OstreeDeployment *booted_deployment = NULL;
g_autoptr(GPtrArray) deployments = NULL;
Expand All @@ -343,6 +345,7 @@ rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
gboolean added_new = FALSE;
/* Keep track of whether we're looking at a deployment before or after the booted */
gboolean before_booted = TRUE;
gboolean booted_is_live = FALSE;

deployments = ostree_sysroot_get_deployments (sysroot);
booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
Expand All @@ -363,14 +366,23 @@ rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
const gboolean is_last = (i == (deployments->len - 1));

if (is_booted)
before_booted = FALSE;
{
before_booted = FALSE;
if (!rpmostree_syscore_deployment_is_live (sysroot, deployment, -1,
&booted_is_live, error))
return NULL;
}

/* Retain deployment if:
* - The deployment is for another osname
* - We're pushing a rollback and this is a pending deployment
* - It's the merge or booted deployment
* - The booted deployment is live, this is a rollback
*/
if (!osname_matches || (pushing_rollback && before_booted) || is_merge_or_booted)
if (!osname_matches
|| (pushing_rollback && before_booted)
|| is_merge_or_booted
|| (!before_booted && booted_is_live))
g_ptr_array_add (new_deployments, g_object_ref (deployment));

/* Insert new rollback right after the booted */
Expand Down Expand Up @@ -510,3 +522,41 @@ rpmostree_syscore_write_deployments (OstreeSysroot *sysroot,

return TRUE;
}

/* Load the checksums that describe the "livefs" state of the given
* deployment.
*/
gboolean
rpmostree_syscore_deployment_get_live (OstreeSysroot *sysroot,
OstreeDeployment *deployment,
int deployment_dfd,
char **out_inprogress_checksum,
char **out_livereplaced_checksum,
GError **error)
{
g_autoptr(RpmOstreeOrigin) origin = rpmostree_origin_parse_deployment (deployment, error);
if (!origin)
return FALSE;
rpmostree_origin_get_live_state (origin, out_inprogress_checksum, out_livereplaced_checksum);
return TRUE;
}

/* Set @out_is_live to %TRUE if the deployment is live-modified */
gboolean
rpmostree_syscore_deployment_is_live (OstreeSysroot *sysroot,
OstreeDeployment *deployment,
int deployment_dfd,
gboolean *out_is_live,
GError **error)
{
g_autofree char *inprogress_checksum = NULL;
g_autofree char *livereplaced_checksum = NULL;

if (!rpmostree_syscore_deployment_get_live (sysroot, deployment, deployment_dfd,
&inprogress_checksum, &livereplaced_checksum,
error))
return FALSE;

*out_is_live = (inprogress_checksum != NULL || livereplaced_checksum != NULL);
return TRUE;
}
21 changes: 20 additions & 1 deletion src/daemon/rpmostree-sysroot-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,29 @@ OstreeDeployment *rpmostree_syscore_get_origin_merge_deployment (OstreeSysroot *

gboolean rpmostree_syscore_bump_mtime (OstreeSysroot *self, GError **error);



#define RPMOSTREE_LIVE_INPROGRESS_XATTR "user.rpmostree-live-inprogress"
#define RPMOSTREE_LIVE_REPLACED_XATTR "user.rpmostree-live-replaced"

gboolean rpmostree_syscore_deployment_get_live (OstreeSysroot *sysroot,
OstreeDeployment *deployment,
int deployment_dfd,
char **out_inprogress_checksum,
char **out_livereplaced_checksum,
GError **error);

gboolean rpmostree_syscore_deployment_is_live (OstreeSysroot *sysroot,
OstreeDeployment *deployment,
int deployment_dfd,
gboolean *out_is_live,
GError **error);

GPtrArray *rpmostree_syscore_add_deployment (OstreeSysroot *sysroot,
OstreeDeployment *new_deployment,
OstreeDeployment *merge_deployment,
gboolean pushing_rollback);
gboolean pushing_rollback,
GError **error);

void rpmostree_syscore_query_deployments (OstreeSysroot *sysroot,
const char *osname,
Expand Down
Loading