Skip to content

Commit f7767cc

Browse files
authored
Merge pull request #5529 from dustymabe/dusty-no-initramfs
treefile: Add `no-initramfs:` knob
2 parents 77c12a0 + 989ff9e commit f7767cc

File tree

10 files changed

+124
-39
lines changed

10 files changed

+124
-39
lines changed

docs/treefile.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ version of `rpm-ostree`.
561561
- `var`: `/opt` and `/usr/local` are symlinks to subdirectories in `/var`
562562
and are purely machine-local state.
563563
- `root`: These are plain directories; only use this with composefs enabled!
564+
* `no-initramfs`: boolean, optional: If `true` don't run dracut to generate an
565+
initramfs. Defaults to `false`.
564566

565567
### Kickstarts
566568

rpmostree-cxxrs.cxx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,7 @@ struct Treefile final : public ::rust::Opaque
18761876
bool may_require_local_assembly () const noexcept;
18771877
bool has_any_packages () const noexcept;
18781878
bool merge_treefile (::rust::Str treefile);
1879+
bool get_no_initramfs () const noexcept;
18791880
~Treefile () = delete;
18801881

18811882
private:
@@ -2835,6 +2836,9 @@ extern "C"
28352836
::rust::repr::PtrLen
28362837
rpmostreecxx$cxxbridge1$Treefile$merge_treefile (::rpmostreecxx::Treefile &self,
28372838
::rust::Str treefile, bool *return$) noexcept;
2839+
2840+
bool
2841+
rpmostreecxx$cxxbridge1$Treefile$get_no_initramfs (::rpmostreecxx::Treefile const &self) noexcept;
28382842
::std::size_t rpmostreecxx$cxxbridge1$RepoPackage$operator$sizeof () noexcept;
28392843
::std::size_t rpmostreecxx$cxxbridge1$RepoPackage$operator$alignof () noexcept;
28402844

@@ -2885,6 +2889,9 @@ extern "C"
28852889
rpmostreecxx$cxxbridge1$transaction_apply_live (::rpmostreecxx::OstreeSysroot const &sysroot,
28862890
::rpmostreecxx::GVariant const &target) noexcept;
28872891

2892+
::rust::repr::PtrLen
2893+
rpmostreecxx$cxxbridge1$normalize_etc_shadow (::std::int32_t rootfs_dfd) noexcept;
2894+
28882895
::rust::repr::PtrLen rpmostreecxx$cxxbridge1$prepare_rpm_layering (
28892896
::std::int32_t rootfs, ::std::int32_t merge_passwd_dir, bool *return$) noexcept;
28902897

@@ -5625,6 +5632,12 @@ Treefile::merge_treefile (::rust::Str treefile)
56255632
return ::std::move (return$.value);
56265633
}
56275634

5635+
bool
5636+
Treefile::get_no_initramfs () const noexcept
5637+
{
5638+
return rpmostreecxx$cxxbridge1$Treefile$get_no_initramfs (*this);
5639+
}
5640+
56285641
::std::size_t
56295642
RepoPackage::layout::size () noexcept
56305643
{
@@ -5770,6 +5783,16 @@ transaction_apply_live (::rpmostreecxx::OstreeSysroot const &sysroot,
57705783
}
57715784
}
57725785

5786+
void
5787+
normalize_etc_shadow (::std::int32_t rootfs_dfd)
5788+
{
5789+
::rust::repr::PtrLen error$ = rpmostreecxx$cxxbridge1$normalize_etc_shadow (rootfs_dfd);
5790+
if (error$.ptr)
5791+
{
5792+
throw ::rust::impl<::rust::Error>::error (error$);
5793+
}
5794+
}
5795+
57735796
bool
57745797
prepare_rpm_layering (::std::int32_t rootfs, ::std::int32_t merge_passwd_dir)
57755798
{

rpmostree-cxxrs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,7 @@ struct Treefile final : public ::rust::Opaque
16531653
bool may_require_local_assembly () const noexcept;
16541654
bool has_any_packages () const noexcept;
16551655
bool merge_treefile (::rust::Str treefile);
1656+
bool get_no_initramfs () const noexcept;
16561657
~Treefile () = delete;
16571658

16581659
private:
@@ -2083,6 +2084,8 @@ void applylive_sync_ref (::rpmostreecxx::OstreeSysroot const &sysroot);
20832084
void transaction_apply_live (::rpmostreecxx::OstreeSysroot const &sysroot,
20842085
::rpmostreecxx::GVariant const &target);
20852086

2087+
void normalize_etc_shadow (::std::int32_t rootfs_dfd);
2088+
20862089
bool prepare_rpm_layering (::std::int32_t rootfs, ::std::int32_t merge_passwd_dir);
20872090

20882091
void complete_rpm_layering (::std::int32_t rootfs);

rust/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ pub mod ffi {
690690
fn may_require_local_assembly(&self) -> bool;
691691
fn has_any_packages(&self) -> bool;
692692
fn merge_treefile(&mut self, treefile: &str) -> Result<bool>;
693+
fn get_no_initramfs(&self) -> bool;
693694
}
694695

695696
// treefile.rs (split out from above to make &self nice to use)
@@ -738,6 +739,11 @@ pub mod ffi {
738739
fn transaction_apply_live(sysroot: &OstreeSysroot, target: &GVariant) -> Result<()>;
739740
}
740741

742+
// normalization.rs
743+
extern "Rust" {
744+
fn normalize_etc_shadow(rootfs_dfd: i32) -> Result<()>;
745+
}
746+
741747
// passwd.rs
742748
extern "Rust" {
743749
fn prepare_rpm_layering(rootfs: i32, merge_passwd_dir: i32) -> Result<bool>;
@@ -1018,6 +1024,7 @@ mod live;
10181024
pub(crate) use self::live::*;
10191025
mod nameservice;
10201026
mod normalization;
1027+
use normalization::*;
10211028
mod origin;
10221029
mod ostree_prepareroot;
10231030
pub(crate) use self::origin::*;

rust/src/normalization.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// SPDX-License-Identifier: Apache-2.0 OR MIT
77

88
use crate::bwrap::Bubblewrap;
9+
use crate::cxxrsutil::*;
10+
use crate::ffiutil;
911
use crate::nameservice::shadow::parse_shadow_content;
1012
use anyhow::{anyhow, Context, Result};
1113
use cap_std::fs::OpenOptionsExt;
@@ -30,7 +32,8 @@ pub(crate) fn source_date_epoch_raw() -> Option<String> {
3032
}
3133

3234
#[context("Rewriting /etc/shadow to remove lstchg field")]
33-
pub(crate) fn normalize_etc_shadow(rootfs: &Dir) -> Result<()> {
35+
pub(crate) fn normalize_etc_shadow(rootfs_dfd: i32) -> CxxResult<()> {
36+
let rootfs = unsafe { ffiutil::ffi_dirfd(rootfs_dfd)? };
3437
// Read in existing entries.
3538
let mut openopts = OpenOptions::new();
3639
openopts.create(true).read(true).write(true).mode(0o400);

rust/src/passwd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub fn complete_rpm_layering(rootfs_dfd: i32) -> CxxResult<()> {
8989
// /etc/shadow ends up with a timestamp in it thanks to the `lstchg`
9090
// field. This can be made empty safely, especially for accounts that
9191
// are locked.
92-
normalization::normalize_etc_shadow(&rootfs)?;
92+
normalization::normalize_etc_shadow(rootfs_dfd)?;
9393

9494
Ok(())
9595
}

rust/src/treefile.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
482482
check_passwd,
483483
check_groups,
484484
postprocess_script,
485-
rpmdb_normalize
485+
rpmdb_normalize,
486+
no_initramfs
486487
);
487488
merge_hashsets!(ignore_removed_groups, ignore_removed_users);
488489
merge_maps!(add_commit_metadata, variables, metadata, repovars);
@@ -1856,6 +1857,10 @@ impl Treefile {
18561857
derived
18571858
}
18581859

1860+
pub(crate) fn get_no_initramfs(&self) -> bool {
1861+
self.parsed.base.no_initramfs.unwrap_or_default()
1862+
}
1863+
18591864
pub(crate) fn set_initramfs_regenerate(&mut self, enabled: bool, args: Vec<String>) {
18601865
if !enabled {
18611866
// implicitly leaves empty if already empty
@@ -2609,6 +2614,8 @@ pub(crate) struct BaseComposeConfigFields {
26092614
#[serde(skip_serializing_if = "Option::is_none")]
26102615
pub(crate) initramfs_args: Option<Vec<String>>,
26112616
#[serde(skip_serializing_if = "Option::is_none")]
2617+
pub(crate) no_initramfs: Option<bool>,
2618+
#[serde(skip_serializing_if = "Option::is_none")]
26122619
pub(crate) readonly_executables: Option<bool>,
26132620

26142621
// Tree layout options

src/libpriv/rpmostree-kernel.cxx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,17 @@ rpmostree_finalize_kernel (int rootfs_dfd, const char *bootdir, const char *kver
398398
}
399399
else
400400
{
401-
/* we're not replacing the initramfs; use built-in one */
402-
if (!_rpmostree_util_update_checksum_from_file (boot_checksum, rootfs_dfd,
403-
initramfs_modules_path, cancellable, error))
401+
/* We're not replacing the initramfs; use built-in one if it exists */
402+
if (!glnx_fstatat_allow_noent (rootfs_dfd, initramfs_modules_path, NULL, AT_SYMLINK_NOFOLLOW,
403+
error))
404404
return FALSE;
405+
if (errno == 0)
406+
{
407+
/* It exists, update the checksum */
408+
if (!_rpmostree_util_update_checksum_from_file (
409+
boot_checksum, rootfs_dfd, initramfs_modules_path, cancellable, error))
410+
return FALSE;
411+
}
405412
}
406413

407414
const char *boot_checksum_str = g_checksum_get_string (boot_checksum);

src/libpriv/rpmostree-postprocess.cxx

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,48 @@ rename_if_exists (int src_dfd, const char *from, int dest_dfd, const char *to, G
8080
return TRUE;
8181
}
8282

83+
static gboolean
84+
run_dracut (int rootfs_dfd, rpmostreecxx::Treefile &treefile, GLnxTmpfile *initramfs_tmpf,
85+
const char *kver, GCancellable *cancellable, GError **error)
86+
{
87+
/* Run dracut with our chosen arguments (commonly at least --no-hostonly) */
88+
g_autoptr (GPtrArray) dracut_argv = g_ptr_array_new ();
89+
rust::Vec<rust::String> initramfs_args = treefile.get_initramfs_args ();
90+
if (!initramfs_args.empty ())
91+
{
92+
for (auto &arg : initramfs_args)
93+
g_ptr_array_add (dracut_argv, (void *)arg.c_str ());
94+
}
95+
else
96+
{
97+
/* Default to this for treecomposes */
98+
g_ptr_array_add (dracut_argv, (char *)"--no-hostonly");
99+
}
100+
g_ptr_array_add (dracut_argv, NULL);
101+
102+
/* We use a tmpdir under the target root since dracut currently tries to copy
103+
* xattrs, including e.g. user.ostreemeta, which can't be copied to tmpfs.
104+
*/
105+
{
106+
g_auto (GLnxTmpDir) dracut_host_tmpd = {
107+
0,
108+
};
109+
if (!glnx_mkdtempat (rootfs_dfd, "rpmostree-dracut.XXXXXX", 0700, &dracut_host_tmpd, error))
110+
return FALSE;
111+
if (!rpmostree_run_dracut (rootfs_dfd, (const char *const *)dracut_argv->pdata, kver, NULL,
112+
FALSE, &dracut_host_tmpd, initramfs_tmpf, cancellable, error))
113+
return FALSE;
114+
/* No reason to have the initramfs not be world-readable since
115+
* it's server-side generated and shouldn't contain any secrets.
116+
* https://github.com/coreos/coreos-assembler/pull/372#issuecomment-467620937
117+
*/
118+
if (!glnx_fchmod (initramfs_tmpf->fd, 0644, error))
119+
return FALSE;
120+
}
121+
122+
return TRUE;
123+
}
124+
83125
/* Handle the kernel/initramfs, which can be in at least 2 different places:
84126
* - /boot (CentOS, Fedora treecompose before we suppressed kernel.spec's %posttrans)
85127
* - /usr/lib/modules (Fedora treecompose without kernel.spec's %posttrans)
@@ -195,43 +237,19 @@ process_kernel_and_initramfs (int rootfs_dfd, rpmostreecxx::Treefile &treefile,
195237
(void)unlinkat (rootfs_dfd, "usr/etc/machine-id", 0);
196238
}
197239

198-
/* Run dracut with our chosen arguments (commonly at least --no-hostonly) */
199-
g_autoptr (GPtrArray) dracut_argv = g_ptr_array_new ();
200-
rust::Vec<rust::String> initramfs_args = treefile.get_initramfs_args ();
201-
if (!initramfs_args.empty ())
202-
{
203-
for (auto &arg : initramfs_args)
204-
g_ptr_array_add (dracut_argv, (void *)arg.c_str ());
205-
}
206-
else
207-
{
208-
/* Default to this for treecomposes */
209-
g_ptr_array_add (dracut_argv, (char *)"--no-hostonly");
210-
}
211-
g_ptr_array_add (dracut_argv, NULL);
212-
213240
g_auto (GLnxTmpfile) initramfs_tmpf = {
214241
0,
215242
};
216-
/* We use a tmpdir under the target root since dracut currently tries to copy
217-
* xattrs, including e.g. user.ostreemeta, which can't be copied to tmpfs.
243+
if (!treefile.get_no_initramfs ())
244+
{
245+
if (!run_dracut (rootfs_dfd, treefile, &initramfs_tmpf, kver, cancellable, error))
246+
return FALSE;
247+
}
248+
249+
/* Always normalize etc shadow. If we called run_dracut this may
250+
* have already been done but it's OK since it's idempotent.
218251
*/
219-
{
220-
g_auto (GLnxTmpDir) dracut_host_tmpd = {
221-
0,
222-
};
223-
if (!glnx_mkdtempat (rootfs_dfd, "rpmostree-dracut.XXXXXX", 0700, &dracut_host_tmpd, error))
224-
return FALSE;
225-
if (!rpmostree_run_dracut (rootfs_dfd, (const char *const *)dracut_argv->pdata, kver, NULL,
226-
FALSE, &dracut_host_tmpd, &initramfs_tmpf, cancellable, error))
227-
return FALSE;
228-
/* No reason to have the initramfs not be world-readable since
229-
* it's server-side generated and shouldn't contain any secrets.
230-
* https://github.com/coreos/coreos-assembler/pull/372#issuecomment-467620937
231-
*/
232-
if (!glnx_fchmod (initramfs_tmpf.fd, 0644, error))
233-
return FALSE;
234-
}
252+
ROSCXX_TRY (normalize_etc_shadow (rootfs_dfd), error);
235253

236254
/* We always tell rpmostree_finalize_kernel() to skip /boot, since we'll do a
237255
* full hardlink pass if needed after that for the kernel + bootloader data.

tests/compose/test-no-initramfs.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
set -xeuo pipefail
3+
4+
dn=$(cd "$(dirname "$0")" && pwd)
5+
# shellcheck source=libcomposetest.sh
6+
. "${dn}/libcomposetest.sh"
7+
8+
treefile_set "no-initramfs" 'True'
9+
runcompose
10+
echo "ok compose"
11+
12+
commit=$(jq -r '.["ostree-commit"]' < compose.json)
13+
ostree --repo=${repo:?} ls -R ${commit} usr/lib/modules > ls.txt
14+
assert_not_file_has_content ls.txt '/usr/lib/modules/.*/initramfs.img$'
15+
echo "ok no initramfs"

0 commit comments

Comments
 (0)