Skip to content

Commit 481fbb0

Browse files
dustymabejlebon
andcommitted
treefile: Add no-initramfs: knob
In the work to rebase FCOS/RHCOS to fedora-bootc/rhel-bootc, we want to run postprocess scripts for CoreOS specific changes to the rootfs, but we want changes made in those postprocess scripts to affect the initramfs generation too. The new experimental `no-initramfs` knob will allow us to disable the generation of the initramfs via dracut in the initial compose of the rootfs. Then we can run our postprocess scripts on the rootfs and later run dracut to generate the initramfs. This came from discussion in https://gitlab.com/fedora/bootc/base-images/-/merge_requests/315 where it was decided to not add a `--postprocess` argument to bootc-base-imagectl. Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
1 parent 77c12a0 commit 481fbb0

File tree

8 files changed

+94
-38
lines changed

8 files changed

+94
-38
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: 10 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

@@ -5625,6 +5629,12 @@ Treefile::merge_treefile (::rust::Str treefile)
56255629
return ::std::move (return$.value);
56265630
}
56275631

5632+
bool
5633+
Treefile::get_no_initramfs () const noexcept
5634+
{
5635+
return rpmostreecxx$cxxbridge1$Treefile$get_no_initramfs (*this);
5636+
}
5637+
56285638
::std::size_t
56295639
RepoPackage::layout::size () noexcept
56305640
{

rpmostree-cxxrs.h

Lines changed: 1 addition & 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:

rust/src/lib.rs

Lines changed: 1 addition & 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)

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: 47 additions & 34 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,14 @@ 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.
218-
*/
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-
}
243+
if (!treefile.get_no_initramfs ())
244+
{
245+
if (!run_dracut (rootfs_dfd, treefile, &initramfs_tmpf, kver, cancellable, error))
246+
return FALSE;
247+
}
235248

236249
/* We always tell rpmostree_finalize_kernel() to skip /boot, since we'll do a
237250
* 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)