Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composefs-run/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ rustix = { version = "1.0.0", default-features = false, features = ["fs", "proce
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = ["std"] }

[dev-dependencies]
rustix = { version = "1.0.0", default-features = false, features = ["process"] }

[lints.rust]
missing_docs = "deny"
missing_debug_implementations = "deny"
58 changes: 31 additions & 27 deletions composefs-run/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,13 @@ pub(crate) struct Cli {
#[clap(long, default_value = "true", value_parser = clap::value_parser!(SystemdMode))]
systemd: SystemdMode,

/// Use a host directory as the container rootfs instead of a composefs image
#[clap(long, conflicts_with = "image")]
rootfs: Option<PathBuf>,

/// OCI image ref name or @sha256:... digest
image: String,
#[clap(required_unless_present = "rootfs")]
image: Option<String>,

/// Command to run (overrides image entrypoint+cmd)
#[clap(last = true)]
Expand All @@ -414,13 +419,23 @@ fn main() -> Result<()> {

let cli = Cli::parse();

let repo_path = &cli.repo;

let rootless = !rustix::process::geteuid().is_root();
let container_id = format!("composefs-{}", std::process::id());

let repo = ResolvedRepo::open(repo_path)?;
let image = repo.resolve_image(&cli.image)?;
let image = if let Some(ref rootfs) = cli.rootfs {
ensure!(
rootfs.is_dir(),
"--rootfs path '{}' is not a directory",
rootfs.display()
);
ResolvedImage {
oci_config: oci_spec::image::ImageConfiguration::default(),
erofs_hex: None,
}
} else {
let repo = ResolvedRepo::open(&cli.repo)?;
repo.resolve_image(cli.image.as_deref().context("No image specified")?)?
};

let container_dir = PathBuf::from(format!("/var/tmp/cfsrun-{container_id}"));
let overlay_dir = cli
Expand All @@ -433,25 +448,14 @@ fn main() -> Result<()> {
rustix::fs::chmod(&container_dir, Mode::from_raw_mode(0o700))
.with_context(|| format!("Setting permissions on {}", container_dir.display()))?;

let result = if rootless {
run::run_rootless(
&cli,
&container_id,
&container_dir,
&overlay_dir,
&image,
repo_path,
)
} else {
run::run(
&cli,
&container_id,
&container_dir,
&overlay_dir,
&repo,
&image,
)
};
let result = run::run(
rootless,
&cli,
&container_id,
&container_dir,
&overlay_dir,
&image,
);

if result.is_err() {
let _ = std::fs::remove_dir_all(&container_dir);
Expand All @@ -460,7 +464,7 @@ fn main() -> Result<()> {
result
}

/// Wraps the algorithm-specific repo so run()/run_rootless() don't need generics.
/// Wraps the algorithm-specific repo so run() don't need generics.
pub(crate) enum ResolvedRepo {
Sha256(Repository<Sha256HashValue>),
Sha512(Repository<Sha512HashValue>),
Expand Down Expand Up @@ -513,7 +517,7 @@ impl ResolvedRepo {

pub(crate) struct ResolvedImage {
pub(crate) oci_config: oci_spec::image::ImageConfiguration,
pub(crate) erofs_hex: String,
pub(crate) erofs_hex: Option<String>,
}

fn resolve_image_typed<ObjectID: FsVerityHashValue>(
Expand All @@ -535,7 +539,7 @@ fn resolve_image_typed<ObjectID: FsVerityHashValue>(

Ok(ResolvedImage {
oci_config: config.config,
erofs_hex: erofs_id.to_hex(),
erofs_hex: Some(erofs_id.to_hex()),
})
}

Expand Down
Loading
Loading