Skip to content

Commit 0bffcce

Browse files
committed
Split out a hostexec module
We'll use this even in cases where we don't have the `install` feature. Signed-off-by: Colin Walters <[email protected]>
1 parent b101d9d commit 0bffcce

File tree

6 files changed

+38
-29
lines changed

6 files changed

+38
-29
lines changed

lib/src/blockdev.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::install::run_in_host_mountns;
1+
use crate::hostexec::run_in_host_mountns;
22
use crate::task::Task;
33
use anyhow::{anyhow, Context, Result};
44
use camino::Utf8Path;

lib/src/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
459459
Opt::InstallToFilesystem(opts) => crate::install::install_to_filesystem(opts).await,
460460
#[cfg(feature = "install")]
461461
Opt::ExecInHostMountNamespace(args) => {
462-
crate::install::exec_in_host_mountns(args.as_slice())
462+
crate::hostexec::exec_in_host_mountns(args.as_slice())
463463
}
464464
Opt::Status(opts) => super::status::status(opts).await,
465465
#[cfg(feature = "internal-testing-api")]

lib/src/hostexec.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//! Run a command in the host mount namespace
2+
3+
use std::os::fd::AsFd;
4+
use std::os::unix::process::CommandExt;
5+
use std::process::Command;
6+
7+
use anyhow::{Context, Result};
8+
use camino::Utf8Path;
9+
use fn_error_context::context;
10+
11+
/// Run a command in the host mount namespace
12+
pub(crate) fn run_in_host_mountns(cmd: &str) -> Command {
13+
let mut c = Command::new("/proc/self/exe");
14+
c.args(["exec-in-host-mount-namespace", cmd]);
15+
c
16+
}
17+
18+
#[context("Re-exec in host mountns")]
19+
pub(crate) fn exec_in_host_mountns(args: &[std::ffi::OsString]) -> Result<()> {
20+
let (cmd, args) = args[1..]
21+
.split_first()
22+
.ok_or_else(|| anyhow::anyhow!("Missing command"))?;
23+
let pid1mountns = std::fs::File::open("/proc/1/ns/mnt")?;
24+
nix::sched::setns(pid1mountns.as_fd(), nix::sched::CloneFlags::CLONE_NEWNS).context("setns")?;
25+
rustix::process::chdir("/")?;
26+
// Work around supermin doing chroot() and not pivot_root
27+
// https://github.com/libguestfs/supermin/blob/5230e2c3cd07e82bd6431e871e239f7056bf25ad/init/init.c#L288
28+
if !Utf8Path::new("/usr").try_exists()? && Utf8Path::new("/root/usr").try_exists()? {
29+
tracing::debug!("Using supermin workaround");
30+
rustix::process::chroot("/root")?;
31+
}
32+
Err(Command::new(cmd).args(args).exec())?
33+
}

lib/src/install.rs

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ mod baseline;
1111
use std::io::BufWriter;
1212
use std::io::Write;
1313
use std::os::fd::AsFd;
14-
use std::os::unix::process::CommandExt;
15-
use std::process::Command;
1614
use std::str::FromStr;
1715
use std::sync::Arc;
1816

@@ -38,6 +36,7 @@ use serde::{Deserialize, Serialize};
3836

3937
use self::baseline::InstallBlockDeviceOpts;
4038
use crate::containerenv::ContainerExecutionInfo;
39+
use crate::hostexec::run_in_host_mountns;
4140
use crate::task::Task;
4241

4342
/// The default "stateroot" or "osname"; see https://github.com/ostreedev/ostree/issues/2794
@@ -663,30 +662,6 @@ fn copy_to_oci(
663662
Ok(dest_imageref)
664663
}
665664

666-
/// Run a command in the host mount namespace
667-
pub(crate) fn run_in_host_mountns(cmd: &str) -> Command {
668-
let mut c = Command::new("/proc/self/exe");
669-
c.args(["exec-in-host-mount-namespace", cmd]);
670-
c
671-
}
672-
673-
#[context("Re-exec in host mountns")]
674-
pub(crate) fn exec_in_host_mountns(args: &[std::ffi::OsString]) -> Result<()> {
675-
let (cmd, args) = args[1..]
676-
.split_first()
677-
.ok_or_else(|| anyhow::anyhow!("Missing command"))?;
678-
let pid1mountns = std::fs::File::open("/proc/1/ns/mnt")?;
679-
nix::sched::setns(pid1mountns.as_fd(), nix::sched::CloneFlags::CLONE_NEWNS).context("setns")?;
680-
rustix::process::chdir("/")?;
681-
// Work around supermin doing chroot() and not pivot_root
682-
// https://github.com/libguestfs/supermin/blob/5230e2c3cd07e82bd6431e871e239f7056bf25ad/init/init.c#L288
683-
if !Utf8Path::new("/usr").try_exists()? && Utf8Path::new("/root/usr").try_exists()? {
684-
tracing::debug!("Using supermin workaround");
685-
rustix::process::chroot("/root")?;
686-
}
687-
Err(Command::new(cmd).args(args).exec())?
688-
}
689-
690665
#[context("Querying skopeo version")]
691666
fn skopeo_supports_containers_storage() -> Result<bool> {
692667
let o = run_in_host_mountns("skopeo").arg("--version").output()?;

lib/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
pub mod cli;
1717
pub(crate) mod deploy;
18+
pub(crate) mod hostexec;
1819
mod lsm;
1920
mod reboot;
2021
mod reexec;

lib/src/podman.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{anyhow, Result};
22
use serde::Deserialize;
33

4-
use crate::install::run_in_host_mountns;
4+
use crate::hostexec::run_in_host_mountns;
55

66
#[derive(Deserialize)]
77
#[serde(rename_all = "PascalCase")]

0 commit comments

Comments
 (0)