Skip to content

Commit

Permalink
Add rpm-ostree ex rebuild command
Browse files Browse the repository at this point in the history
This command reads treefile dropins in `/etc` and applies it to the
system. Only the OSTree container flow is supported for now. For the
client-side flow, see #2326.

In the container flow, only `packages` is currently supported. But this
paves the way for supporting more derivation fields as well as making
currently "base" fields only become valid derivation fields too (by
promoting it from the `BaseComposeConfigFields` struct to
`TreeComposeConfig`).

What we're doing here is providing a "container" backend for derivation
treefiles, but #2326 will provide a "client" backend which uses the core
more fully. But the inputs themselves are the exact same, hence
providing symmetry between the two flows. (See also discussions about
this in coreos/fedora-coreos-tracker#1054).

This will also allow us to drop the `microdnf` dependency which will be
done in a following patch.
  • Loading branch information
jlebon authored and cgwalters committed Jan 22, 2022
1 parent 1707622 commit 826b470
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile-libpriv.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ librpmostreepriv_sources = \
src/libpriv/rpmostree-types.h \
src/libpriv/rpmostree-refts.h \
src/libpriv/rpmostree-refts.cxx \
src/libpriv/rpmostree-container.cxx \
src/libpriv/rpmostree-container.h \
src/libpriv/rpmostree-core.cxx \
src/libpriv/rpmostree-core.h \
src/libpriv/rpmostree-core-private.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 @@ -59,6 +59,7 @@ librpmostreeinternals_la_SOURCES = \
src/app/rpmostree-composeutil.cxx \
src/app/rpmostree-composeutil.h \
src/app/rpmostree-builtin-compose.cxx \
src/app/rpmostree-builtin-rebuild.cxx \
$(librpmostreed_sources) \
$(librpmostreepriv_sources) \
$(librpmostree_1_la_SOURCES) \
Expand Down
1 change: 1 addition & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ pub mod ffi {
) -> Result<Box<Treefile>>;
fn treefile_new_client(filename: &str, basearch: &str) -> Result<Box<Treefile>>;
fn treefile_new_client_from_etc(basearch: &str) -> Result<Box<Treefile>>;
fn treefile_delete_client_etc() -> Result<()>;

fn get_workdir(&self) -> i32;
fn get_passwd_fd(&mut self) -> i32;
Expand Down
8 changes: 8 additions & 0 deletions rust/src/treefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,3 +2305,11 @@ pub(crate) fn treefile_new_client_from_etc(basearch: &str) -> CxxResult<Box<Tree
r.error_if_base()?;
Ok(Box::new(r))
}

pub(crate) fn treefile_delete_client_etc() -> CxxResult<()> {
// To be nice we don't delete the directory itself; just matching files.
for tf in iter_etc_treefiles()? {
std::fs::remove_file(&tf?)?;
}
Ok(())
}
4 changes: 4 additions & 0 deletions src/app/rpmostree-builtin-ex.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ static RpmOstreeCommand ex_subcommands[] = {
"Inspect rpm-ostree history of the system", rpmostree_ex_builtin_history },
{ "initramfs-etc", (RpmOstreeBuiltinFlags)0,
"Track initramfs configuration files", rpmostree_ex_builtin_initramfs_etc },
/* This is currently only for CoreOS layering; so hide it to not confuse
* users. */
{ "rebuild", (RpmOstreeBuiltinFlags)(RPM_OSTREE_BUILTIN_FLAG_HIDDEN),
"Rebuild system based on configuration", rpmostree_ex_builtin_rebuild },
/* To graduate out of experimental, simply revert:
* https://github.com/coreos/rpm-ostree/pull/3078 */
{ "module", static_cast<RpmOstreeBuiltinFlags>(0),
Expand Down
83 changes: 83 additions & 0 deletions src/app/rpmostree-builtin-rebuild.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2022 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 <string.h>
#include <glib-unix.h>

#include "rpmostree-ex-builtins.h"
#include "rpmostree-libbuiltin.h"
#include "rpmostree-clientlib.h"
#include "rpmostree-container.h"

#include <libglnx.h>

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

if (!rpmostree_option_context_parse (context,
NULL,
&argc, &argv,
invocation,
cancellable,
NULL, NULL, NULL,
error))
return FALSE;

bool in_container = false;
if (rpmostreecxx::running_in_container())
{
auto is_ostree_container = CXX_TRY_VAL(is_ostree_container(), error);
if (!is_ostree_container)
return glnx_throw (error, "This command can only run in an OSTree container.");
in_container = true;
}

auto basearch = rpmostreecxx::get_rpm_basearch();
auto treefile = CXX_TRY_VAL(treefile_new_client_from_etc (basearch), error);

/* This is the big switch: we support running this command in two modes:
* "client containers", where the effect takes place in the active rootfs, and
* possibly eventually "client host systems", where the effect takes place in
* a new deployment. */
if (in_container)
{
if (!rpmostree_container_rebuild (*treefile, cancellable, error))
return FALSE;

/* In the container flow, we effectively "consume" the treefiles after
* modifying the rootfs. */
CXX_TRY(treefile_delete_client_etc (), error);
}
else
{
return glnx_throw (error, "This command is not yet supported on host systems. "
"See https://github.com/coreos/rpm-ostree/issues/2326.");
}

return TRUE;
}
1 change: 1 addition & 0 deletions src/app/rpmostree-ex-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ BUILTINPROTO(apply_live);
BUILTINPROTO(history);
BUILTINPROTO(initramfs_etc);
BUILTINPROTO(module);
BUILTINPROTO(rebuild);

#undef BUILTINPROTO

Expand Down
62 changes: 62 additions & 0 deletions src/libpriv/rpmostree-container.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2022 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 <string.h>
#include <glib-unix.h>

#include "rpmostree-core.h"
#include "rpmostree-container.h"

#include <libglnx.h>

gboolean
rpmostree_container_rebuild (rpmostreecxx::Treefile &treefile,
GCancellable *cancellable,
GError **error)
{
auto packages = treefile.get_packages();

/* for now, we only support package installs */
if (packages.empty())
return TRUE;

g_autoptr(RpmOstreeContext) ctx = rpmostree_context_new_container ();
rpmostree_context_set_treefile (ctx, treefile);

if (!rpmostree_context_setup (ctx, "/", "/", cancellable, error))
return FALSE;

if (!rpmostree_context_prepare (ctx, cancellable, error))
return FALSE;

if (!rpmostree_context_download (ctx, cancellable, error))
return FALSE;

DnfContext *dnfctx = rpmostree_context_get_dnf (ctx);

/* can't use cancellable here because it wants to re-set it on the state,
* which will trigger an assertion; XXX: tweak libdnf */
if (!dnf_context_run (dnfctx, NULL, error))
return FALSE;

return TRUE;
}
30 changes: 30 additions & 0 deletions src/libpriv/rpmostree-container.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2022 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.
*/

#pragma once

G_BEGIN_DECLS

gboolean
rpmostree_container_rebuild (rpmostreecxx::Treefile &treefile,
GCancellable *cancellable,
GError **error);

G_END_DECLS
9 changes: 9 additions & 0 deletions tests/kolainst/destructive/container-image
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,19 @@ case "${AUTOPKGTEST_REBOOT_MARK:-}" in
[local]
gpgcheck=0
baseurl=http://127.0.0.1
EOF
cat >baz.yaml << 'EOF'
packages:
- baz
EOF
cat > Dockerfile << 'EOF'
FROM localhost/fcos
RUN rm -rf /etc/yum.repos.d/* # Ensure we work offline
ADD local.repo /etc/yum.repos.d/
RUN rpm-ostree install bar
RUN mkdir -p /etc/rpm-ostree/origin.d
ADD baz.yaml /etc/rpm-ostree/origin.d/
RUN rpm-ostree ex rebuild
RUN echo some config file > /etc/someconfig.conf
RUN echo somedata > /usr/share/somenewdata
EOF
Expand All @@ -132,6 +139,8 @@ EOF
grep -qF somedata /usr/share/somenewdata || (echo missing somenewdata; exit 1)
assert_streq $(rpm -q bar) bar-1.0-1.${arch}
test -f /usr/bin/bar
assert_streq $(rpm -q baz) baz-1.0-1.${arch}
test -f /usr/bin/baz
rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:derived\""
;;
*) echo "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}"; exit 1;;
Expand Down
1 change: 1 addition & 0 deletions tests/kolainst/kolainst-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mkdir ${test_tmpdir}/rpm-repos/${repover}
# The obligatory `foo` and `bar` packages
build_rpm foo version 1.2 release 3
build_rpm bar
build_rpm baz
# And from here we lose our creativity and name things starting
# with `testpkg` and grow more content.
# This one has various files in /etc
Expand Down

0 comments on commit 826b470

Please sign in to comment.