mirror of
https://github.com/containers/youki
synced 2024-05-10 09:36:13 +02:00
Support calling exec multiple times
This commit is contained in:
parent
0f36e355ec
commit
5d63f31d0e
|
@ -180,6 +180,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.20"
|
||||
|
@ -977,6 +986,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"clap",
|
||||
"dbus",
|
||||
"fastrand",
|
||||
"futures",
|
||||
"libc",
|
||||
"log",
|
||||
|
|
|
@ -28,6 +28,7 @@ oci_spec = { version = "0.1.0", path = "./oci_spec" }
|
|||
systemd = { version = "0.8", default-features = false }
|
||||
dbus = "0.9.2"
|
||||
tabwriter = "1"
|
||||
fastrand = "1.4.1"
|
||||
|
||||
[dev-dependencies]
|
||||
oci_spec = { version = "0.1.0", path = "./oci_spec", features = ["proptests"] }
|
||||
|
|
|
@ -50,7 +50,7 @@ impl InitContainerBuilder {
|
|||
.create_container_state(&container_dir)?
|
||||
.set_systemd(self.use_systemd);
|
||||
|
||||
let notify_socket: NotifyListener = NotifyListener::new( NOTIFY_FILE)?;
|
||||
let notify_socket: NotifyListener = NotifyListener::new(NOTIFY_FILE)?;
|
||||
// convert path of root file system of the container to absolute path
|
||||
let rootfs = fs::canonicalize(&spec.root.path)?;
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use anyhow::{bail, Result};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use caps::Capability;
|
||||
use nix::unistd;
|
||||
use oci_spec::{
|
||||
LinuxCapabilities, LinuxCapabilityType, LinuxNamespace, LinuxNamespaceType, Process, Spec,
|
||||
};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::TryFrom,
|
||||
ffi::{CString, OsString},
|
||||
fs::{self, File},
|
||||
fs,
|
||||
os::unix::prelude::OsStrExt,
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
|
@ -17,13 +18,15 @@ use std::{
|
|||
use crate::{
|
||||
notify_socket::{NotifyListener, NotifySocket},
|
||||
rootless::detect_rootless,
|
||||
tty,
|
||||
stdio::FileDescriptor,
|
||||
tty, utils,
|
||||
};
|
||||
|
||||
use super::{builder::ContainerBuilder, builder_impl::ContainerBuilderImpl, Container};
|
||||
|
||||
const NAMESPACE_TYPES: &[&str] = &["ipc", "uts", "net", "pid", "mnt", "cgroup"];
|
||||
pub const TENANT_SOCK: &str = "notify-exec.sock";
|
||||
const TENANT_NOTIFY: &str = "tenant-notify-";
|
||||
const TENANT_TTY: &str = "tenant-tty-";
|
||||
|
||||
/// Builder that can be used to configure the properties of a process
|
||||
/// that will join an existing container sandbox
|
||||
|
@ -95,21 +98,13 @@ impl TenantContainerBuilder {
|
|||
log::debug!("{:#?}", spec);
|
||||
|
||||
unistd::chdir(&*container_dir)?;
|
||||
let notify_socket: NotifyListener = NotifyListener::new(TENANT_SOCK)?;
|
||||
let (notify_listener, notify_path) = Self::setup_notify_listener(&container_dir)?;
|
||||
// convert path of root file system of the container to absolute path
|
||||
let rootfs = fs::canonicalize(&spec.root.path)?;
|
||||
|
||||
// if socket file path is given in commandline options,
|
||||
// get file descriptors of console socket
|
||||
let csocketfd = if let Some(console_socket) = &self.base.console_socket {
|
||||
Some(tty::setup_console_socket(
|
||||
&container_dir,
|
||||
console_socket,
|
||||
"tty-exec.sock",
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let csocketfd = self.setup_tty_socket(&container_dir)?;
|
||||
|
||||
let use_systemd = self.should_use_systemd(&container);
|
||||
let rootless = detect_rootless(&spec)?;
|
||||
|
@ -121,18 +116,18 @@ impl TenantContainerBuilder {
|
|||
root_path: self.base.root_path,
|
||||
pid_file: self.base.pid_file,
|
||||
console_socket: csocketfd,
|
||||
use_systemd: use_systemd,
|
||||
container_dir: container_dir.clone(),
|
||||
use_systemd,
|
||||
container_dir,
|
||||
spec,
|
||||
rootfs,
|
||||
rootless,
|
||||
notify_socket,
|
||||
notify_socket: notify_listener,
|
||||
container: None,
|
||||
};
|
||||
|
||||
builder_impl.create()?;
|
||||
|
||||
let mut notify_socket = NotifySocket::new(container_dir.join(TENANT_SOCK))?;
|
||||
let mut notify_socket = NotifySocket::new(notify_path);
|
||||
notify_socket.notify_container_start()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -149,7 +144,7 @@ impl TenantContainerBuilder {
|
|||
fn load_init_spec(&self, container_dir: &Path) -> Result<Spec> {
|
||||
let spec_path = container_dir.join("config.json");
|
||||
|
||||
let mut spec = oci_spec::Spec::load(spec_path)?;
|
||||
let mut spec = oci_spec::Spec::load(spec_path).context("failed to load spec")?;
|
||||
// TODO: Change Dir
|
||||
spec.canonicalize_rootfs()?;
|
||||
Ok(spec)
|
||||
|
@ -174,7 +169,7 @@ impl TenantContainerBuilder {
|
|||
self.set_working_dir(spec)?;
|
||||
self.set_args(spec)?;
|
||||
self.set_environment(spec)?;
|
||||
self.set_no_new_privileges(spec)?;
|
||||
self.set_no_new_privileges(spec);
|
||||
self.set_capabilities(spec)?;
|
||||
}
|
||||
|
||||
|
@ -196,10 +191,10 @@ impl TenantContainerBuilder {
|
|||
)
|
||||
}
|
||||
|
||||
let process = File::open(process)?;
|
||||
let process = utils::open(process)?;
|
||||
let process_spec: Process = serde_json::from_reader(process)?;
|
||||
spec.process = process_spec;
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_working_dir(&self, spec: &mut Spec) -> Result<()> {
|
||||
|
@ -238,12 +233,10 @@ impl TenantContainerBuilder {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn set_no_new_privileges(&self, spec: &mut Spec) -> Result<()> {
|
||||
fn set_no_new_privileges(&self, spec: &mut Spec) {
|
||||
if let Some(no_new_privs) = self.no_new_privs {
|
||||
spec.process.no_new_privileges = no_new_privs;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_capabilities(&self, spec: &mut Spec) -> Result<()> {
|
||||
|
@ -260,14 +253,14 @@ impl TenantContainerBuilder {
|
|||
spec_caps.bounding.append(&mut caps.clone());
|
||||
spec_caps.effective.append(&mut caps.clone());
|
||||
spec_caps.inheritable.append(&mut caps.clone());
|
||||
spec_caps.permitted.append(&mut caps.clone());
|
||||
spec_caps.permitted.append(&mut caps);
|
||||
} else {
|
||||
spec.process.capabilities = Some(LinuxCapabilities {
|
||||
ambient: caps.clone(),
|
||||
bounding: caps.clone(),
|
||||
effective: caps.clone(),
|
||||
inheritable: caps.clone(),
|
||||
permitted: caps.clone(),
|
||||
permitted: caps,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -300,6 +293,39 @@ impl TenantContainerBuilder {
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
fn setup_notify_listener(container_dir: &Path) -> Result<(NotifyListener, PathBuf)> {
|
||||
let notify_name = Self::generate_name(&container_dir, TENANT_NOTIFY);
|
||||
let socket_path = container_dir.join(¬ify_name);
|
||||
let notify_listener: NotifyListener = NotifyListener::new(¬ify_name)?;
|
||||
|
||||
Ok((notify_listener, socket_path))
|
||||
}
|
||||
|
||||
fn setup_tty_socket(&self, container_dir: &Path) -> Result<Option<FileDescriptor>> {
|
||||
let tty_name = Self::generate_name(&container_dir, TENANT_TTY);
|
||||
let csocketfd = if let Some(console_socket) = &self.base.console_socket {
|
||||
Some(tty::setup_console_socket(
|
||||
container_dir,
|
||||
console_socket,
|
||||
&tty_name,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(csocketfd)
|
||||
}
|
||||
|
||||
fn generate_name(dir: &Path, prefix: &str) -> String {
|
||||
loop {
|
||||
let rand = fastrand::i32(..);
|
||||
let name = format!("{}{:x}.sock", prefix, rand);
|
||||
if !dir.join(&name).exists() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Can be removed once https://github.com/eminence/procfs/pull/135 is available
|
||||
|
|
|
@ -60,6 +60,7 @@ impl Namespaces {
|
|||
(space, fd)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for &(space, fd) in &to_enter {
|
||||
self.command.set_ns(fd, space)?;
|
||||
unistd::close(fd)?;
|
||||
|
|
|
@ -42,10 +42,10 @@ pub struct NotifySocket {
|
|||
}
|
||||
|
||||
impl NotifySocket {
|
||||
pub fn new<P: Into<PathBuf>>(socket_path: P) -> Result<Self> {
|
||||
Ok(Self {
|
||||
pub fn new<P: Into<PathBuf>>(socket_path: P) -> Self {
|
||||
Self {
|
||||
path: socket_path.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn notify_container_start(&mut self) -> Result<()> {
|
||||
|
|
|
@ -33,7 +33,7 @@ impl Start {
|
|||
|
||||
unistd::chdir(container.root.as_os_str())?;
|
||||
|
||||
let mut notify_socket = NotifySocket::new(&container.root.join(NOTIFY_FILE))?;
|
||||
let mut notify_socket = NotifySocket::new(&container.root.join(NOTIFY_FILE));
|
||||
notify_socket.notify_container_start()?;
|
||||
|
||||
container.update_status(ContainerStatus::Running).save()?;
|
||||
|
|
|
@ -21,7 +21,8 @@ pub fn setup_console_socket(
|
|||
console_socket_path: &Path,
|
||||
socket_name: &str,
|
||||
) -> Result<FileDescriptor> {
|
||||
symlink(console_socket_path, container_dir.join(socket_name))?;
|
||||
let linked = container_dir.join(socket_name);
|
||||
symlink(console_socket_path, &linked)?;
|
||||
|
||||
let mut csocketfd = socket::socket(
|
||||
socket::AddressFamily::Unix,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::env;
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
use std::fs::{self, File};
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
@ -101,6 +101,11 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> Result<()> {
|
|||
fs::create_dir_all(path).with_context(|| format!("failed to create directory {:?}", path))
|
||||
}
|
||||
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<File> {
|
||||
let path = path.as_ref();
|
||||
File::open(path).with_context(|| format!("failed to open {:?}", path))
|
||||
}
|
||||
|
||||
pub struct TempDir {
|
||||
path: Option<PathBuf>,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue