Skip to content

Commit

Permalink
WIP rhsm
Browse files Browse the repository at this point in the history
  • Loading branch information
jeckersb committed Dec 9, 2024
1 parent af4d43f commit 93afefe
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ install:
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
install -D -m 0644 -t $(DESTDIR)/$(prefix)/lib/systemd/system systemd/*.service systemd/*.timer systemd/*.path systemd/*.target

# 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.
Expand Down
3 changes: 3 additions & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ static_assertions = { workspace = true }
default = ["install"]
# This feature enables `bootc install`. Disable if you always want to use an external installer.
install = []
# This featuares enables `bootc rhsm-facts-publish` to integrate with
# Red Hat Subscription Manager
rhsm = []
# Implementation detail of man page generation.
docgen = ["clap_mangen"]

Expand Down
6 changes: 6 additions & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,8 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
}
}
if changed {
sysroot.update_mtime()?;

if opts.apply {
crate::reboot::reboot()?;
}
Expand Down Expand Up @@ -799,6 +801,8 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
let stateroot = booted_deployment.osname();
crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec).await?;

sysroot.update_mtime()?;

if opts.apply {
crate::reboot::reboot()?;
}
Expand Down Expand Up @@ -852,6 +856,8 @@ async fn edit(opts: EditOpts) -> Result<()> {
let stateroot = booted_deployment.osname();
crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec).await?;

sysroot.update_mtime()?;

Ok(())
}

Expand Down
3 changes: 3 additions & 0 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ pub(crate) async fn rollback(sysroot: &Storage) -> Result<()> {
} else {
println!("Next boot: rollback deployment");
}

sysroot.update_mtime()?;

Ok(())
}

Expand Down
24 changes: 15 additions & 9 deletions lib/src/imgstorage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::sync::Arc;

use anyhow::{Context, Result};
use bootc_utils::{AsyncCommandRunExt, CommandRunExt, ExitStatusExt};
use camino::Utf8Path;
use camino::Utf8PathBuf;
use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::Dir;
use cap_std_ext::cap_tempfile::TempDir;
Expand All @@ -35,8 +35,8 @@ pub(crate) const STORAGE_ALIAS_DIR: &str = "/run/bootc/storage";
/// We pass this via /proc/self/fd to the child process.
const STORAGE_RUN_FD: i32 = 3;

/// The path to the storage, relative to the physical system root.
pub(crate) const SUBPATH: &str = "ostree/bootc/storage";
/// The path to the image storage, relative to the bootc root directory.
pub(crate) const SUBPATH: &str = "storage";
/// The path to the "runroot" with transient runtime state; this is
/// relative to the /run directory
const RUNROOT: &str = "bootc/storage";
Expand Down Expand Up @@ -139,14 +139,15 @@ impl Storage {
#[context("Creating imgstorage")]
pub(crate) fn create(sysroot: &Dir, run: &Dir) -> Result<Self> {
Self::init_globals()?;
let subpath = Utf8Path::new(SUBPATH);
let subpath = Self::subpath();

// SAFETY: We know there's a parent
let parent = subpath.parent().unwrap();
if !sysroot
.try_exists(subpath)
.try_exists(&subpath)
.with_context(|| format!("Querying {subpath}"))?
{
let tmp = format!("{SUBPATH}.tmp");
let tmp = format!("{subpath}.tmp");
sysroot.remove_all_optional(&tmp).context("Removing tmp")?;
sysroot
.create_dir_all(parent)
Expand All @@ -163,7 +164,7 @@ impl Storage {
.context("Initializing images")?;
drop(storage_root);
sysroot
.rename(&tmp, sysroot, subpath)
.rename(&tmp, sysroot, &subpath)
.context("Renaming tmpdir")?;
tracing::debug!("Created image store");
}
Expand All @@ -174,9 +175,10 @@ impl Storage {
pub(crate) fn open(sysroot: &Dir, run: &Dir) -> Result<Self> {
tracing::trace!("Opening container image store");
Self::init_globals()?;
let subpath = Self::subpath();
let storage_root = sysroot
.open_dir(SUBPATH)
.with_context(|| format!("Opening {SUBPATH}"))?;
.open_dir(&subpath)
.with_context(|| format!("Opening {subpath}"))?;
// Always auto-create this if missing
run.create_dir_all(RUNROOT)
.with_context(|| format!("Creating {RUNROOT}"))?;
Expand Down Expand Up @@ -303,6 +305,10 @@ impl Storage {
temp_runroot.close()?;
Ok(())
}

fn subpath() -> Utf8PathBuf {
[crate::store::BOOTC_ROOT, SUBPATH].iter().collect()
}
}

#[cfg(test)]
Expand Down
27 changes: 25 additions & 2 deletions lib/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use std::cell::OnceCell;
use std::env;
use std::ops::Deref;

use anyhow::Result;
use cap_std_ext::cap_std::fs::Dir;
use anyhow::{Context, Result};
use cap_std_ext::{cap_primitives, cap_std::fs::Dir};
use clap::ValueEnum;
use fn_error_context::context;

use ostree_ext::container::OstreeImageReference;
use ostree_ext::keyfileext::KeyFileExt;
Expand All @@ -15,6 +16,10 @@ use crate::spec::ImageStatus;

mod ostree_container;

/// The path to the bootc root directory, relative to the physical
/// system root
pub(crate) const BOOTC_ROOT: &str = "ostree/bootc";

pub(crate) struct Storage {
pub sysroot: SysrootLock,
run: Dir,
Expand Down Expand Up @@ -82,6 +87,24 @@ impl Storage {
let imgstore = crate::imgstorage::Storage::create(&sysroot_dir, &self.run)?;
Ok(self.imgstore.get_or_init(|| imgstore))
}

/// Update the mtime on the storage root directory
/// This triggers the bootc-status-updated.path systemd unit
#[context("Updating storage root mtime")]
pub(crate) fn update_mtime(&self) -> Result<()> {
let sysroot_dir = Dir::reopen_dir(&crate::utils::sysroot_fd(&self.sysroot))
.context("Reopen sysroot directory")?
.into_std_file();

cap_primitives::fs::set_times(
&sysroot_dir,
std::path::Path::new(BOOTC_ROOT),
Some(cap_primitives::fs::SystemTimeSpec::SymbolicNow),
Some(cap_primitives::fs::SystemTimeSpec::SymbolicNow),
)
.context("set_times")
.map_err(Into::into)
}
}

impl ContainerImageStore for ostree::Deployment {
Expand Down
11 changes: 11 additions & 0 deletions systemd/bootc-rhsm-facts-publish.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Publish bootc facts to Red Hat Subscription Manager
Documentation=man:bootc(8)
ConditionPathExists=/etc/rhsm

[Service]
Type=oneshot
ExecStart=/usr/bin/bootc rhsm-facts-publish

[Install]
WantedBy=bootc-status-modified.target
10 changes: 10 additions & 0 deletions systemd/bootc-status-updated.path
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Monitor bootc for status changes
Documentation=man:bootc(8)

[Path]
PathChanged=/ostree/bootc
Unit=bootc-status-updated.target

[Install]
WantedBy=multi-user.target
4 changes: 4 additions & 0 deletions systemd/bootc-status-updated.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[Unit]
Description=Target for bootc status changes
Documentation=man:bootc(8)
StopWhenUnneeded=true

0 comments on commit 93afefe

Please sign in to comment.