Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
omertuc committed Jan 27, 2025
1 parent 9a58693 commit 88934de
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 18 deletions.
14 changes: 13 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["cli", "lib", "ostree-ext", "blockdev", "xtask", "tests-integration"]
members = ["cli", "reinstall-cli", "lib", "ostree-ext", "blockdev", "xtask", "tests-integration"]
resolver = "2"

[profile.dev]
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ all:

install:
install -D -m 0755 -t $(DESTDIR)$(prefix)/bin target/release/bootc
install -D -m 0755 -t $(DESTDIR)$(prefix)/bin target/release/bootc-reinstall
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
Expand Down
1 change: 0 additions & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ clap = { workspace = true }
tokio = { workspace = true, features = ["macros"] }
log = "0.4.21"
tracing = { workspace = true }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }

[lints]
workspace = true
19 changes: 4 additions & 15 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
//! The main entrypoint for bootc, which just performs global initialization, and then
//! calls out into the library.
use anyhow::Result;

/// The code called after we've done process global init and created
/// an async runtime.
async fn async_main() -> Result<()> {
// Don't include timestamps and such because they're not really useful and
// too verbose, and plus several log targets such as journald will already
// include timestamps.
let format = tracing_subscriber::fmt::format()
.without_time()
.with_target(false)
.compact();
// Log to stderr by default
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.event_format(format)
.with_writer(std::io::stderr)
.init();
tracing::trace!("starting");
bootc_lib::cli::tracing_util::initialize_tracing();

tracing::trace!("starting bootc");

// As you can see, the role of this file is mostly to just be a shim
// to call into the code that lives in the internal shared library.
bootc_lib::cli::run_from_iter(std::env::args()).await
Expand Down
16 changes: 16 additions & 0 deletions contrib/packaging/bootc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,30 @@ Provides: ostree-cli(ostree-container)
%description
%{summary}

%package reinstall
Summary: Utility to reinstall the current system using bootc
Requires: podman
# The reinstall subpackage intentionally does not require bootc, as it pulls in many unnecessary dependencies

%description reinstall
This package provides a utility to simplify reinstalling the current system to a given bootc image.

%prep
%autosetup -p1 -a1
%cargo_prep -v vendor

%build
# Build the main bootc binary
%if 0%{?fedora} || 0%{?rhel} >= 10
%cargo_build %{?with_rhsm:-f rhsm}
%else
%cargo_build %{?with_rhsm:--features rhsm}
%endif

# Build the bootc-reinstall binary
%global cargo_args -p bootc-reinstall
%cargo_build

%cargo_vendor_manifest
%cargo_license_summary
%{cargo_license} > LICENSE.dependencies
Expand Down Expand Up @@ -104,5 +117,8 @@ make install-ostree-hooks DESTDIR=%{?buildroot}
%{_docdir}/bootc/*
%{_mandir}/man*/bootc*

%files reinstall
%{_bindir}/bootc-reinstall

%changelog
%autochangelog
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ uuid = { version = "1.8.0", features = ["v4"] }
tini = "1.3.0"
comfy-table = "7.1.1"
thiserror = "2.0.11"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }

[dev-dependencies]
indoc = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use crate::spec::Host;
use crate::spec::ImageReference;
use crate::utils::sigpolicy_from_opt;

pub mod tracing_util;

/// Shared progress options
#[derive(Debug, Parser, PartialEq, Eq)]
pub(crate) struct ProgressOptions {
Expand Down
18 changes: 18 additions & 0 deletions lib/src/cli/tracing_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Helpers related to tracing, used by main entrypoints
/// Initialize tracing with the default configuration.
pub fn initialize_tracing() {
// Don't include timestamps and such because they're not really useful and
// too verbose, and plus several log targets such as journald will already
// include timestamps.
let format = tracing_subscriber::fmt::format()
.without_time()
.with_target(false)
.compact();
// Log to stderr by default
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.event_format(format)
.with_writer(std::io::stderr)
.init();
}
27 changes: 27 additions & 0 deletions reinstall-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "bootc-reinstall"
version = "0.1.9"
edition = "2021"
license = "MIT OR Apache-2.0"
repository = "https://github.com/containers/bootc"
readme = "README.md"
publish = false
# For now don't bump this above what is currently shipped in RHEL9.
rust-version = "1.75.0"

# See https://github.com/coreos/cargo-vendor-filterer
[package.metadata.vendor-filter]
# This list of platforms is not intended to be exclusive, feel free
# to extend it. But missing a platform will only matter for the case where
# a dependent crate is *only* built on that platform.
platforms = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", "s390x-unknown-linux-gnu", "riscv64gc-unknown-linux-gnu"]

[dependencies]
anyhow = { workspace = true }
bootc-lib = { version = "1.0", path = "../lib" }
clap = { workspace = true }
log = "0.4.21"
tracing = { workspace = true }

[lints]
workspace = true
84 changes: 84 additions & 0 deletions reinstall-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! The main entrypoint for bootc-reinstall
use std::{io::Write, process::Command};

use anyhow::{Context, Result};

fn run() -> Result<()> {
bootc_lib::cli::tracing_util::initialize_tracing();

tracing::trace!("starting bootc-reinstall");

prompt()?;

let command_and_args = [
// Rootless is not supported
"sudo",
// We use podman to run the bootc container. This might change in the future to remove the
// podman dependency.
"podman",
"run",
// The container needs to be privileged, as it heavily modifies the host
"--privileged",
// The container needs to access the host's PID namespace to mount host directories
"--pid=host",
// Since https://github.com/containers/bootc/pull/919 this mount should not be needed, but
// some reason with e.g. quay.io/fedora/fedora-bootc:41 it is still needed.
"-v",
"/var/lib/containers:/var/lib/containers",
// TODO: Get from argv
"quay.io/fedora/fedora-bootc:41",
// We're replacing the current root
"bootc",
"install",
"to-existing-root",
// The user already knows they're reinstalling their machine, that's the entire purpose of
// this binary. Since this is no longer an "arcane" bootc command, we can safely avoid this
// timed warning prompt. TODO: Discuss in https://github.com/containers/bootc/discussions/1060
"--acknowledge-destructive",
];

Command::new(command_and_args[0])
.args(&command_and_args[1..])
.status()
.context(format!(
"Failed to run the command \"{}\"",
command_and_args.join(" ")
))?;

Ok(())
}

/// Temporary safety mechanism to stop devs from running it on their dev machine. TODO: Discuss
/// final prompting UX in https://github.com/containers/bootc/discussions/1060
fn prompt() -> Result<(), anyhow::Error> {
let prompt = "This will reinstall your system. Are you sure you want to continue? (y/n) ";
let mut user_input = String::new();
loop {
print!("{}", prompt);
std::io::stdout().flush()?;
std::io::stdin().read_line(&mut user_input)?;
match user_input.trim() {
"y" => break,
"n" => {
println!("Exiting without reinstalling the system.");
return Ok(());
}
_ => {
println!("Unrecognized input. enter 'y' or 'n'.");
user_input.clear();
}
}
}
Ok(())
}

fn main() {
// In order to print the error in a custom format (with :#) our
// main simply invokes a run() where all the work is done.
// This code just captures any errors.
if let Err(e) = run() {
tracing::error!("{:#}", e);
std::process::exit(1);
}
}

0 comments on commit 88934de

Please sign in to comment.