Skip to content

Commit 161bc31

Browse files
authored
Merge pull request #988 from cgwalters/add-install-base-configs
install: Add /usr/share/doc/bootc/baseimage
2 parents 9f5fa0e + 7d9a160 commit 161bc31

File tree

7 files changed

+107
-1
lines changed

7 files changed

+107
-1
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ install:
2525
fi; \
2626
done
2727
install -D -m 0644 -t $(DESTDIR)/$(prefix)/lib/systemd/system systemd/*.service systemd/*.timer systemd/*.path systemd/*.target
28+
install -D -m 0644 -t $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/usr/lib/ostree/ baseimage/base/usr/lib/ostree/prepare-root.conf
29+
install -d -m 755 $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/sysroot
30+
cp -PfT baseimage/base/ostree $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/ostree
2831

2932
# Run this to also take over the functionality of `ostree container` for example.
3033
# Only needed for OS/distros that have callers invoking `ostree container` and not bootc.

baseimage/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Recommended image content
2+
3+
The subdirectories here are recommended to be installed alongside
4+
bootc in `/usr/share/doc/bootc/baseimage` - they act as reference
5+
sources of content.
6+
7+
- [base](base): At the current time the content here is effectively
8+
a hard requirement. It's not much, just an ostree configuration
9+
enabling composefs, plus the default `sysroot` directory (which
10+
may go away in the future) and the `ostree` symlink into `sysroot`.

baseimage/base/ostree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sysroot/ostree

baseimage/base/sysroot/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# A trick to keep an empty directory in git
2+
*
3+
!.gitignore
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[composefs]
2+
enabled = true

contrib/packaging/bootc.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ BuildRequires: libzstd-devel
3232
%{_prefix}/lib/systemd/system-generators/*
3333
%{_prefix}/lib/bootc
3434
%{_unitdir}/*
35+
%{_docdir}/bootc/*
3536
%{_mandir}/man*/bootc*
3637

3738
%prep

lib/src/lints.rs

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
//! This module implements `bootc container lint`.
44
55
use std::env::consts::ARCH;
6+
use std::os::unix::ffi::OsStrExt;
67

7-
use anyhow::{bail, ensure, Result};
8+
use anyhow::{bail, ensure, Context, Result};
89
use cap_std::fs::Dir;
910
use cap_std_ext::cap_std;
1011
use cap_std_ext::dirext::CapStdExtDirExt as _;
1112
use fn_error_context::context;
1213

1314
use crate::utils::openat2_with_retry;
1415

16+
/// Reference to embedded default baseimage content that should exist.
17+
const BASEIMAGE_REF: &str = "usr/share/doc/bootc/baseimage/base";
18+
1519
/// check for the existence of the /var/run directory
1620
/// if it exists we need to check that it links to /run if not error
1721
/// if it does not exist error.
@@ -23,6 +27,7 @@ pub(crate) fn lint(root: &Dir) -> Result<()> {
2327
check_parse_kargs,
2428
check_usretc,
2529
check_utf8,
30+
check_baseimage_root,
2631
];
2732
for lint in lints {
2833
lint(&root)?;
@@ -116,6 +121,57 @@ fn check_utf8(dir: &Dir) -> Result<()> {
116121
Ok(())
117122
}
118123

124+
/// Check for a few files and directories we expect in the base image.
125+
fn check_baseimage_root_norecurse(dir: &Dir) -> Result<()> {
126+
// Check /sysroot
127+
let meta = dir.symlink_metadata_optional("sysroot")?;
128+
match meta {
129+
Some(meta) if !meta.is_dir() => {
130+
anyhow::bail!("Expected a directory for /sysroot")
131+
}
132+
None => anyhow::bail!("Missing /sysroot"),
133+
_ => {}
134+
}
135+
136+
// Check /ostree -> sysroot/ostree
137+
let Some(meta) = dir.symlink_metadata_optional("ostree")? else {
138+
anyhow::bail!("Missing ostree -> sysroot/ostree link")
139+
};
140+
if !meta.is_symlink() {
141+
anyhow::bail!("/ostree should be a symlink");
142+
}
143+
let link = dir.read_link_contents("ostree")?;
144+
let expected = "sysroot/ostree";
145+
if link.as_os_str().as_bytes() != expected.as_bytes() {
146+
anyhow::bail!("Expected /ostree -> {expected}, not {link:?}");
147+
}
148+
149+
// Check the prepare-root config
150+
let prepareroot_path = "usr/lib/ostree/prepare-root.conf";
151+
let config_data = dir
152+
.read_to_string(prepareroot_path)
153+
.context(prepareroot_path)?;
154+
let config = ostree_ext::glib::KeyFile::new();
155+
config.load_from_data(&config_data, ostree_ext::glib::KeyFileFlags::empty())?;
156+
157+
if !ostree_ext::ostree_prepareroot::overlayfs_enabled_in_config(&config)? {
158+
anyhow::bail!("{prepareroot_path} does not have composefs enabled")
159+
}
160+
161+
Ok(())
162+
}
163+
164+
/// Check ostree-related base image content.
165+
fn check_baseimage_root(dir: &Dir) -> Result<()> {
166+
check_baseimage_root_norecurse(dir)?;
167+
// If we have our own documentation with the expected root contents
168+
// embedded, then check that too! Mostly just because recursion is fun.
169+
if let Some(dir) = dir.open_dir_optional(BASEIMAGE_REF)? {
170+
check_baseimage_root_norecurse(&dir)?;
171+
}
172+
Ok(())
173+
}
174+
119175
#[cfg(test)]
120176
mod tests {
121177
use super::*;
@@ -260,4 +316,34 @@ mod tests {
260316
root.remove_file(badfile).unwrap(); // Get rid of the problem
261317
check_utf8(root).unwrap(); // Check it
262318
}
319+
320+
#[test]
321+
fn test_baseimage_root() -> Result<()> {
322+
use bootc_utils::CommandRunExt;
323+
use cap_std_ext::cmdext::CapStdExtCommandExt;
324+
use std::path::Path;
325+
326+
let td = fixture()?;
327+
328+
// An empty root should fail our test
329+
assert!(check_baseimage_root(&td).is_err());
330+
331+
// Copy our reference base image content from the source dir
332+
let manifest = std::env::var_os("CARGO_MANIFEST_PATH").unwrap();
333+
let srcdir = Path::new(&manifest)
334+
.parent()
335+
.unwrap()
336+
.join("../baseimage/base");
337+
for ent in std::fs::read_dir(srcdir)? {
338+
let ent = ent?;
339+
std::process::Command::new("cp")
340+
.cwd_dir(td.try_clone()?)
341+
.arg("-pr")
342+
.arg(ent.path())
343+
.arg(".")
344+
.run()?;
345+
}
346+
check_baseimage_root(&td).unwrap();
347+
Ok(())
348+
}
263349
}

0 commit comments

Comments
 (0)