mirror of
https://github.com/containers/youki
synced 2024-05-10 09:36:13 +02:00
add rootless option for spec
This commit is contained in:
parent
6cb89fcdfa
commit
5714615b80
|
@ -948,6 +948,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "path-clean"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd"
|
||||
|
||||
[[package]]
|
||||
name = "pentacle"
|
||||
version = "1.0.0"
|
||||
|
@ -1529,6 +1535,7 @@ dependencies = [
|
|||
"nix",
|
||||
"oci-spec",
|
||||
"once_cell",
|
||||
"path-clean",
|
||||
"pentacle",
|
||||
"prctl",
|
||||
"procfs",
|
||||
|
|
|
@ -51,6 +51,7 @@ fastrand = "1.4.1"
|
|||
crossbeam-channel = "0.5"
|
||||
seccomp = { version = "0.1.0", path = "./seccomp" }
|
||||
pentacle = "1.0.0"
|
||||
path-clean = "0.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
# TODO: Fetch from crate.io instead of git when next release oci-spec-rs
|
||||
|
|
|
@ -1,18 +1,106 @@
|
|||
use anyhow::Result;
|
||||
use clap::Clap;
|
||||
use oci_spec::runtime::Spec;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nix;
|
||||
use oci_spec::runtime::{
|
||||
LinuxBuilder, LinuxIdMappingBuilder, LinuxNamespaceBuilder, LinuxNamespaceType, MountBuilder,
|
||||
Spec, SpecBuilder,
|
||||
};
|
||||
use path_clean;
|
||||
use serde_json::to_writer_pretty;
|
||||
use std::fs::File;
|
||||
|
||||
/// Create a new runtime specification
|
||||
/// Command generates a config.json
|
||||
#[derive(Clap, Debug)]
|
||||
pub struct SpecJson;
|
||||
pub struct SpecJson {
|
||||
/// Generate a configuration for a rootless container
|
||||
#[clap(long)]
|
||||
pub rootless: bool,
|
||||
}
|
||||
|
||||
pub fn set_for_rootless(spec: &Spec) -> Result<Spec> {
|
||||
let uid = nix::unistd::geteuid().as_raw();
|
||||
let gid = nix::unistd::getegid().as_raw();
|
||||
|
||||
// Remove network from the default spec
|
||||
let mut namespaces = vec![];
|
||||
for ns in spec
|
||||
.linux()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.namespaces()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
{
|
||||
if ns.typ() != LinuxNamespaceType::Network && ns.typ() != LinuxNamespaceType::User {
|
||||
namespaces.push(ns.clone());
|
||||
}
|
||||
}
|
||||
// Add user namespace
|
||||
namespaces.push(
|
||||
LinuxNamespaceBuilder::default()
|
||||
.typ(LinuxNamespaceType::User)
|
||||
.build()?,
|
||||
);
|
||||
let linux_builder = LinuxBuilder::default()
|
||||
.namespaces(namespaces)
|
||||
.uid_mappings(vec![LinuxIdMappingBuilder::default()
|
||||
.host_id(uid)
|
||||
.container_id(0_u32)
|
||||
.size(1_u32)
|
||||
.build()?])
|
||||
.gid_mappings(vec![LinuxIdMappingBuilder::default()
|
||||
.host_id(gid)
|
||||
.container_id(0_u32)
|
||||
.size(1_u32)
|
||||
.build()?]);
|
||||
|
||||
// Fix the mounts
|
||||
let mut mounts = vec![];
|
||||
for mount in spec.mounts().as_ref().unwrap().iter() {
|
||||
let dest = mount.destination().clone();
|
||||
if path_clean::clean(dest.as_path().to_str().unwrap()) == "/sys" {
|
||||
let mount = MountBuilder::default()
|
||||
.destination(PathBuf::from("/sys"))
|
||||
.source(PathBuf::from("/sys"))
|
||||
.typ("none".to_string())
|
||||
.options(vec![
|
||||
"rbind".to_string(),
|
||||
"nosuid".to_string(),
|
||||
"noexec".to_string(),
|
||||
"nodev".to_string(),
|
||||
"ro".to_string(),
|
||||
])
|
||||
.build()?;
|
||||
mounts.push(mount);
|
||||
} else {
|
||||
let options: Vec<String> = mount
|
||||
.options()
|
||||
.as_ref()
|
||||
.unwrap_or(&vec![])
|
||||
.iter()
|
||||
.filter(|&o| !o.starts_with("gid=") && !o.starts_with("uid="))
|
||||
.map(|o| o.to_string())
|
||||
.collect();
|
||||
let mount_builder = MountBuilder::default().options(options);
|
||||
mounts.push(mount_builder.build()?);
|
||||
}
|
||||
}
|
||||
let spec_builder = SpecBuilder::default()
|
||||
.linux(linux_builder.build()?)
|
||||
.mounts(mounts);
|
||||
Ok(spec_builder.build()?)
|
||||
}
|
||||
|
||||
/// spec Cli command
|
||||
impl SpecJson {
|
||||
pub fn exec(&self) -> Result<()> {
|
||||
// get default values for Spec
|
||||
let default_json: Spec = Default::default();
|
||||
let mut default_json: Spec = Default::default();
|
||||
if self.rootless {
|
||||
default_json = set_for_rootless(&default_json)?
|
||||
};
|
||||
// write data to config.json
|
||||
to_writer_pretty(&File::create("config.json")?, &default_json)?;
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in New Issue