Skip to content

Commit

Permalink
Add suggestion for LABEL containers.bootc 1
Browse files Browse the repository at this point in the history
As we aim to slowly move away from ostree, let's add a bootc label
that we expect to be used.  For now, this is just a warning.

I will change rpm-ostree to add this by default if we take this.

But this one is also an important step for if we ever add the
flow of simply deriving from an existing application base image.

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Feb 5, 2024
1 parent 8558c96 commit b766db8
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 0 deletions.
10 changes: 10 additions & 0 deletions docs/bootc-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ The requirement for both methods is that your initial treefile/manifest
However, the ostree usage is an implementation detail
and the requirement on this will be lifted in the future.

## Standard metadata for bootc compatible images

It is strongly recommended to do:

```dockerfile
LABEL containers.bootc 1
```

This will signal that this image is intended to be usable with `bootc`.

# Deriving from existing base images

It's important to emphasize that from one
Expand Down
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ gvariant = "0.4.0"
indicatif = "0.17.0"
libc = "^0.2"
liboverdrop = "0.1.0"
libsystemd = "0.7"
once_cell = "1.9"
openssl = "^0.10"
# TODO drop this in favor of rustix
Expand Down
1 change: 1 addition & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
println!("No changes in: {}", imgref);
}
PrepareResult::Ready(r) => {
crate::deploy::check_bootc_label(&r.config);
println!("Update available for: {}", imgref);
if let Some(version) = r.version() {
println!(" Version: {version}");
Expand Down
28 changes: 28 additions & 0 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use ostree_ext::sysroot::SysrootLock;

use crate::spec::HostSpec;
use crate::spec::ImageReference;
use crate::status::labels_of_config;

// TODO use https://github.com/ostreedev/ostree-rs-ext/pull/493/commits/afc1837ff383681b947de30c0cefc70080a4f87a
const BASE_IMAGE_PREFIX: &str = "ostree/container/baseimage/bootc";
Expand Down Expand Up @@ -84,6 +85,32 @@ pub(crate) async fn new_importer(
Ok(imp)
}

pub(crate) fn check_bootc_label(config: &ostree_ext::oci_spec::image::ImageConfiguration) {
if let Some(label) =
labels_of_config(config).and_then(|labels| labels.get(crate::metadata::BOOTC_COMPAT_LABEL))
{
match label.as_str() {
crate::metadata::COMPAT_LABEL_V1 => {}
o => crate::journal::journal_print(
libsystemd::logging::Priority::Warning,
&format!(
"notice: Unknown {} value {}",
crate::metadata::BOOTC_COMPAT_LABEL,
o
),
),
}
} else {
crate::journal::journal_print(
libsystemd::logging::Priority::Warning,
&format!(
"notice: Image is missing label: {}",
crate::metadata::BOOTC_COMPAT_LABEL
),
)
}
}

/// Wrapper for pulling a container image, wiring up status output.
#[context("Pulling")]
pub(crate) async fn pull(
Expand All @@ -101,6 +128,7 @@ pub(crate) async fn pull(
}
PrepareResult::Ready(p) => p,
};
check_bootc_label(&prep.config);
if let Some(warning) = prep.deprecated_warning() {
ostree_ext::cli::print_deprecated_warning(warning).await;
}
Expand Down
36 changes: 36 additions & 0 deletions lib/src/journal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Thin wrapper for systemd journaling; these APIs are no-ops
//! when not running under systemd. Only use them when
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};

/// Set to true if we failed to write to the journal once
static EMITTED_JOURNAL_ERROR: AtomicBool = AtomicBool::new(false);

/// Wrapper for structured logging which is an explicit no-op
/// when systemd is not in use (e.g. in a container).
pub(crate) fn journal_send<K, V>(
priority: libsystemd::logging::Priority,
msg: &str,
vars: impl Iterator<Item = (K, V)>,
) where
K: AsRef<str>,
V: AsRef<str>,
{
if !libsystemd::daemon::booted() {
return;
}
if let Err(e) = libsystemd::logging::journal_send(priority, msg, vars) {
if !EMITTED_JOURNAL_ERROR.swap(true, Ordering::SeqCst) {
eprintln!("failed to write to journal: {e}");
}
}
}

/// Wrapper for writing to systemd journal which is an explicit no-op
/// when systemd is not in use (e.g. in a container).
#[allow(dead_code)]
pub(crate) fn journal_print(priority: libsystemd::logging::Priority, msg: &str) {
let vars: HashMap<&str, &str> = HashMap::new();
journal_send(priority, msg, vars.into_iter())
}
2 changes: 2 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

pub mod cli;
pub(crate) mod deploy;
pub(crate) mod journal;
mod lsm;
pub(crate) mod metadata;
mod reboot;
mod reexec;
mod status;
Expand Down
4 changes: 4 additions & 0 deletions lib/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/// This label is expected to be present on compatible base images.
pub(crate) const BOOTC_COMPAT_LABEL: &str = "containers.bootc";
/// The current single well-known value for the label.
pub(crate) const COMPAT_LABEL_V1: &str = "1";

0 comments on commit b766db8

Please sign in to comment.