1
0
mirror of https://github.com/containers/bootc.git synced 2026-02-05 15:45:53 +01:00
Files
bootc/Makefile

102 lines
4.7 KiB
Makefile
Raw Permalink Normal View History

prefix ?= /usr
SOURCE_DATE_EPOCH ?= $(shell git log -1 --pretty=%ct)
# https://reproducible-builds.org/docs/archives/
TAR_REPRODUCIBLE = tar --mtime="@${SOURCE_DATE_EPOCH}" --sort=name --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime
all:
cargo build --release
install:
install -D -m 0755 -t $(DESTDIR)$(prefix)/bin target/release/bootc
cli: add `system-reinstall-bootc` binary # Background The current usage instructions for bootc involve a long podman invocation. # Issue It's hard to remember and type the long podman invocation, making the usage of bootc difficult for users. See https://issues.redhat.com/browse/BIFROST-610 and https://issues.redhat.com/browse/BIFROST-611 (Epic https://issues.redhat.com/browse/BIFROST-594) # Solution We want to make the usage of bootc easier by providing a new Fedora/RHEL subpackage that includes a new binary `system-reinstall-bootc`. This binary will simplify the usage of bootc by providing a simple command line interface (configured either through CLI flags or a configuration file) with an interactive prompt that allows users to reinstall the current system using bootc. The commandline will handle helping the user choose SSH keys / users, warn the user about the destructive nature of the operation, and eventually report issues they might run into in the various clouds (e.g. missing cloud agent on the target image) # Implementation Added new system-reinstall-bootc crate that outputs the new system-reinstall-bootc binary. This new crate depends on the existing utils crate. Refactored the tracing initialization from the bootc binary into the utils crate so that it can be reused by the new crate. The new CLI can either be configured through commandline flags or through a configuration file in a path set by the environment variable `BOOTC_REINSTALL_CONFIG`. The configuration file is a YAML file. # Limitations Only root SSH keys are supported. The multi user selection TUI is implemented, but if you choose anything other than root you will get an error. # TODO Missing docs, missing functionality. Everything is in alpha stage. User choice / SSH keys / prompt disabling should also eventually be supported to be configured through commandline arguments or the configuration file. Signed-off-by: Omer Tuchfeld <omer@tuchfeld.dev>
2025-01-25 14:20:22 +01:00
install -D -m 0755 -t $(DESTDIR)$(prefix)/bin target/release/system-reinstall-bootc
install -d -m 0755 $(DESTDIR)$(prefix)/lib/bootc/bound-images.d
install -d -m 0755 $(DESTDIR)$(prefix)/lib/bootc/kargs.d
ln -s /sysroot/ostree/bootc/storage $(DESTDIR)$(prefix)/lib/bootc/storage
install -D -m 0755 cli/bootc-generator-stub $(DESTDIR)$(prefix)/lib/systemd/system-generators/bootc-systemd-generator
install -d $(DESTDIR)$(prefix)/lib/bootc/install
# Support installing pre-generated man pages shipped in source tarball, to avoid
# a dependency on pandoc downstream. But in local builds these end up in target/man,
# so we honor that too.
for d in man target/man; do \
if test -d $$d; then \
install -D -m 0644 -t $(DESTDIR)$(prefix)/share/man/man5 $$d/*.5; \
install -D -m 0644 -t $(DESTDIR)$(prefix)/share/man/man8 $$d/*.8; \
fi; \
done
install -D -m 0644 -t $(DESTDIR)/$(prefix)/lib/systemd/system systemd/*.service systemd/*.timer systemd/*.path systemd/*.target
install -d -m 0755 $(DESTDIR)/$(prefix)/lib/systemd/system/multi-user.target.wants
ln -s ../bootc-status-updated.path $(DESTDIR)/$(prefix)/lib/systemd/system/multi-user.target.wants/bootc-status-updated.path
ln -s ../bootc-status-updated-onboot.target $(DESTDIR)/$(prefix)/lib/systemd/system/multi-user.target.wants/bootc-status-updated-onboot.target
install -D -m 0644 -t $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/usr/lib/ostree/ baseimage/base/usr/lib/ostree/prepare-root.conf
install -d -m 755 $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/sysroot
cp -PfT baseimage/base/ostree $(DESTDIR)/$(prefix)/share/doc/bootc/baseimage/base/ostree
# Ensure we've cleaned out any possibly older files
rm -vrf $(DESTDIR)$(prefix)/share/doc/bootc/baseimage/dracut
rm -vrf $(DESTDIR)$(prefix)/share/doc/bootc/baseimage/systemd
# Copy dracut and systemd config files
cp -Prf baseimage/dracut $(DESTDIR)$(prefix)/share/doc/bootc/baseimage/dracut
cp -Prf baseimage/systemd $(DESTDIR)$(prefix)/share/doc/bootc/baseimage/systemd
# Install fedora-bootc-destructive-cleanup in fedora derivatives
ID=$$(. /usr/lib/os-release && echo $$ID); \
ID_LIKE=$$(. /usr/lib/os-release && echo $$ID_LIKE); \
if [ "$$ID" = "fedora" ] || [[ "$$ID_LIKE" == *"fedora"* ]]; then \
ln -s ../bootc-destructive-cleanup.service $(DESTDIR)/$(prefix)/lib/systemd/system/multi-user.target.wants/bootc-destructive-cleanup.service; \
install -D -m 0755 -t $(DESTDIR)/$(prefix)/lib/bootc contrib/scripts/fedora-bootc-destructive-cleanup; \
fi
# Run this to also take over the functionality of `ostree container` for example.
# Only needed for OS/distros that have callers invoking `ostree container` and not bootc.
install-ostree-hooks:
install -d $(DESTDIR)$(prefix)/libexec/libostree/ext
for x in ostree-container ostree-ima-sign ostree-provisional-repair; do \
ln -sf ../../../bin/bootc $(DESTDIR)$(prefix)/libexec/libostree/ext/$$x; \
done
# Install the main binary, the ostree hooks, and the integration test suite.
install-all: install install-ostree-hooks
install -D -m 0755 target/release/tests-integration $(DESTDIR)$(prefix)/bin/bootc-integration-tests
bin-archive: all
$(MAKE) install DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) --zstd -C tmp-install -cf target/bootc.tar.zst . && rm tmp-install -rf
test-bin-archive: all
$(MAKE) install-all DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) --zstd -C tmp-install -cf target/bootc.tar.zst . && rm tmp-install -rf
test-tmt:
cargo xtask test-tmt
build: Tweak `make validate-rust` This took me some thinking and experimenting. Basically we want: - Hard deny some warnings (this is covered by the Cargo.toml workspace.lints.rust) - Gate merging to main in CI on an exact set of warnings we want to forbid, but *without* also using a blanket -Dwarning deny policy because that could break our build when the compiler revs. - A corollary to the previous: allow developing locally without killing the build just because you have an unused import or some dead code (for example). So we don't want to add `dead_code = deny` into the Cargo.toml. - Be able to easily reproduce locally what CI is gating on in an efficient way. We already had `make validate-rust` which was intending to navigate this, but what was missing was the "deny extended set of warnings" so we got code committed to git main which hit `unused_imports`. Clippy upstream docs recommend the `RUSTFLAGS = -Dwarnings` approach in e.g. https://doc.rust-lang.org/clippy/continuous_integration/github_actions.html but again I think this is a problem because it can break with updated Rust/clippy versions (unless you pin on those, but that becomes a pain in and of itself). The problem also with doing `RUSTFLAGS = -Dwarnings` *locally* is it blows out the cargo cache. So here's the solution I came to: We run `cargo clippy -A clippy:all`, and then deny some specific clippy lints *and* the core Rust warnings we want (`unused_imports` type things) at this stage. The advantage is this doesn't blow out the main Cargo cache, and I can easily reproduce locally exactly what CI would gate on. Also while we're here, add `make fix-rust` which is a handy way to use the existing `clippy --fix` to locally fix things like unused imports as well as other machine-applicable things that are in e.g. `clippy::suspicious`. Signed-off-by: Colin Walters <walters@verbum.org>
2025-03-01 12:51:56 -05:00
# This gates CI by default. Note that for clippy, we gate on
# only the clippy correctness and suspicious lints, plus a select
# set of default rustc warnings.
# We intentionally don't gate on this for local builds in cargo.toml
# because it impedes iteration speed.
CLIPPY_CONFIG = -A clippy::all -D clippy::correctness -D clippy::suspicious -Dunused_imports -Ddead_code
validate-rust:
cargo fmt -- --check -l
cargo test --no-run
(cd ostree-ext && cargo check --no-default-features)
build: Tweak `make validate-rust` This took me some thinking and experimenting. Basically we want: - Hard deny some warnings (this is covered by the Cargo.toml workspace.lints.rust) - Gate merging to main in CI on an exact set of warnings we want to forbid, but *without* also using a blanket -Dwarning deny policy because that could break our build when the compiler revs. - A corollary to the previous: allow developing locally without killing the build just because you have an unused import or some dead code (for example). So we don't want to add `dead_code = deny` into the Cargo.toml. - Be able to easily reproduce locally what CI is gating on in an efficient way. We already had `make validate-rust` which was intending to navigate this, but what was missing was the "deny extended set of warnings" so we got code committed to git main which hit `unused_imports`. Clippy upstream docs recommend the `RUSTFLAGS = -Dwarnings` approach in e.g. https://doc.rust-lang.org/clippy/continuous_integration/github_actions.html but again I think this is a problem because it can break with updated Rust/clippy versions (unless you pin on those, but that becomes a pain in and of itself). The problem also with doing `RUSTFLAGS = -Dwarnings` *locally* is it blows out the cargo cache. So here's the solution I came to: We run `cargo clippy -A clippy:all`, and then deny some specific clippy lints *and* the core Rust warnings we want (`unused_imports` type things) at this stage. The advantage is this doesn't blow out the main Cargo cache, and I can easily reproduce locally exactly what CI would gate on. Also while we're here, add `make fix-rust` which is a handy way to use the existing `clippy --fix` to locally fix things like unused imports as well as other machine-applicable things that are in e.g. `clippy::suspicious`. Signed-off-by: Colin Walters <walters@verbum.org>
2025-03-01 12:51:56 -05:00
(cd lib && cargo check --no-default-features)
cargo clippy -- $(CLIPPY_CONFIG)
env RUSTDOCFLAGS='-D warnings' cargo doc --lib
.PHONY: validate-rust
build: Tweak `make validate-rust` This took me some thinking and experimenting. Basically we want: - Hard deny some warnings (this is covered by the Cargo.toml workspace.lints.rust) - Gate merging to main in CI on an exact set of warnings we want to forbid, but *without* also using a blanket -Dwarning deny policy because that could break our build when the compiler revs. - A corollary to the previous: allow developing locally without killing the build just because you have an unused import or some dead code (for example). So we don't want to add `dead_code = deny` into the Cargo.toml. - Be able to easily reproduce locally what CI is gating on in an efficient way. We already had `make validate-rust` which was intending to navigate this, but what was missing was the "deny extended set of warnings" so we got code committed to git main which hit `unused_imports`. Clippy upstream docs recommend the `RUSTFLAGS = -Dwarnings` approach in e.g. https://doc.rust-lang.org/clippy/continuous_integration/github_actions.html but again I think this is a problem because it can break with updated Rust/clippy versions (unless you pin on those, but that becomes a pain in and of itself). The problem also with doing `RUSTFLAGS = -Dwarnings` *locally* is it blows out the cargo cache. So here's the solution I came to: We run `cargo clippy -A clippy:all`, and then deny some specific clippy lints *and* the core Rust warnings we want (`unused_imports` type things) at this stage. The advantage is this doesn't blow out the main Cargo cache, and I can easily reproduce locally exactly what CI would gate on. Also while we're here, add `make fix-rust` which is a handy way to use the existing `clippy --fix` to locally fix things like unused imports as well as other machine-applicable things that are in e.g. `clippy::suspicious`. Signed-off-by: Colin Walters <walters@verbum.org>
2025-03-01 12:51:56 -05:00
fix-rust:
cargo clippy --fix --allow-dirty -- $(CLIPPY_CONFIG)
.PHONY: fix-rust
validate: validate-rust
tests: Add pytest and nushell based tests I've been trying to keep this project in "one" programming language by writing even tests in Rust...but specifically for our integration tests it's pretty painful not just to compile them but have to deal with baking them into the base image. The tmt framework is very GHA like in that it scrapes the git source tree and copies it into the target environment, which works really well with scripts. Now, if you know me you know I am not a fan of dynamic programming languages like bash and Python. I'm one of those folks that actually tries to use Rust for things that feel like "scripts" i.e. they're *mostly* about forking external processes (see the xtask/ crate which uses "xshell"). Some of our testing code is in Rust too. However...there's a giant tension here because: - Iteration speed is very important for tests and scripts - The artifact being an architecture-dependent binary pushes us to inject it into container images; having the binary part of the bootc image under test conceptually forces us to reprovision for each test change, which is super expensive Most other people when faced with the testing challenge would just write shell scripts (or Python); that's definitely what tmt expects people to do. The podman project has a mix of a "bats" suite which is all bash based, and a Go-based framework. The thing is: bash is easy to mess up and has very little ability to do static analysis. Go (and Python) are very verbose for forking external processes. I've been using https://www.nushell.sh/ for my interactive shell for quite a while; I know just enough to get by day to day (but honestly sometimes I still type "bash" and run a few things there that I know how to express in bash but not nu) Anyways though, nushell has a lot of desirable properties for tests (which are basically scripts): - Architecture independent - Running an external process requires zero ceremony; it's the default! - But it *is* easy to e.g. scrape JSON from an external binary into a rich data structure - A decently rich standard library The downside is, it's a new language. And in the end, I'm not going to say it's the only way to write tests...maybe we do end up with some more bash. It wouldn't be the end of the world. But...after playing with this, I definitely like the result. OK, and after some debate we decided to add Python too, so this demos a pytest test. Signed-off-by: Colin Walters <walters@verbum.org>
2024-06-22 09:18:49 -04:00
ruff check
.PHONY: validate
update-generated:
cargo xtask update-generated
.PHONY: update-generated
vendor:
cargo xtask $@
.PHONY: vendor
package-rpm:
cargo xtask $@
.PHONY: package-rpm