diff --git a/container_spec.json b/container_spec.json index b17221b..ea26e4f 100644 --- a/container_spec.json +++ b/container_spec.json @@ -1,290 +1,158 @@ - { - "ID": "hello", - "Labels": { - "io.containerd.image.config.stop-signal": "SIGTERM" + "ociVersion": "1.0.0-rc2-dev", + "platform": { + "os": "linux", + "arch": "amd64" }, - "Image": "docker.io/library/hello-world:latest", - "Runtime": { - "Name": "io.containerd.runc.v2", - "Options": { - "type_url": "containerd.runc.v1.Options" - }susu - }, - "SnapshotKey": "hello", - "Snapshotter": "overlayfs", - "CreatedAt": "2025-01-25T10:08:43.259272017Z", - "UpdatedAt": "2025-01-25T10:08:43.259272017Z", - "Extensions": {}, - "SandboxID": "", - "Spec": { - "ociVersion": "1.1.0", - "process": { - "user": { - "uid": 0, - "gid": 0, - "additionalGids": [ - 0 - ] - }, - "args": [ - "/hello" - ], - "env": [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - ], - "cwd": "/", - "capabilities": { - "bounding": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE" - ], - "effective": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE" - ], - "permitted": [ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE" - ] - }, - "rlimits": [ - { - "type": "RLIMIT_NOFILE", - "hard": 1024, - "soft": 1024 - } - ], - "noNewPrivileges": true + "process": { + "terminal": false, + "consoleSize": { + "height": 0, + "width": 0 }, - "root": { - "path": "rootfs" + "user": { + "uid": 0, + "gid": 0 }, - "mounts": [ - { - "destination": "/proc", - "type": "proc", - "source": "proc", - "options": [ - "nosuid", - "noexec", - "nodev" - ] - }, - { - "destination": "/dev", - "type": "tmpfs", - "source": "tmpfs", - "options": [ - "nosuid", - "strictatime", - "mode=755", - "size=65536k" - ] - }, - { - "destination": "/dev/pts", - "type": "devpts", - "source": "devpts", - "options": [ - "nosuid", - "noexec", - "newinstance", - "ptmxmode=0666", - "mode=0620", - "gid=5" - ] - }, - { - "destination": "/dev/shm", - "type": "tmpfs", - "source": "shm", - "options": [ - "nosuid", - "noexec", - "nodev", - "mode=1777", - "size=65536k" - ] - }, - { - "destination": "/dev/mqueue", - "type": "mqueue", - "source": "mqueue", - "options": [ - "nosuid", - "noexec", - "nodev" - ] - }, - { - "destination": "/sys", - "type": "sysfs", - "source": "sysfs", - "options": [ - "nosuid", - "noexec", - "nodev", - "ro" - ] - }, - { - "destination": "/run", - "type": "tmpfs", - "source": "tmpfs", - "options": [ - "nosuid", - "strictatime", - "mode=755", - "size=65536k" - ] - } + "args": [ "echo", "$OUTPUT" ], + "env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM=xterm" ], - "linux": { - "resources": { - "devices": [ - { - "allow": false, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 1, - "minor": 3, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 1, - "minor": 8, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 1, - "minor": 7, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 5, - "minor": 0, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 1, - "minor": 5, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 1, - "minor": 9, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 5, - "minor": 1, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 136, - "access": "rwm" - }, - { - "allow": true, - "type": "c", - "major": 5, - "minor": 2, - "access": "rwm" - } - ] - }, - "cgroupsPath": "/default/hello", - "namespaces": [ - { - "type": "pid" - }, - { - "type": "ipc" - }, - { - "type": "uts" - }, - { - "type": "mount" - }, - { - "type": "network" - } - ], - "maskedPaths": [ - "/proc/acpi", - "/proc/asound", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", - "/proc/timer_list", - "/proc/timer_stats", - "/proc/sched_debug", - "/sys/firmware", - "/sys/devices/virtual/powercap", - "/proc/scsi" - ], - "readonlyPaths": [ - "/proc/bus", - "/proc/fs", - "/proc/irq", - "/proc/sys", - "/proc/sysrq-trigger" + "cwd": "/", + "rlimits": [{ + "type": "RLIMIT_NOFILE", + "hard": 1024, + "soft": 1024 + }], + "noNewPrivileges": true + }, + "root": { + "path": "$ROOTFS", + "readonly": false + }, + "hostname": "test", + "mounts": [{ + "destination": "/proc", + "type": "proc", + "source": "proc" + }, + { + "destination": "/dev", + "type": "tmpfs", + "source": "tmpfs", + "options": [ + "nosuid", + "strictatime", + "mode=755", + "size=65536k" + ] + }, + { + "destination": "/dev/pts", + "type": "devpts", + "source": "devpts", + "options": [ + "nosuid", + "noexec", + "newinstance", + "ptmxmode=0666", + "mode=0620", + "gid=5" + ] + }, + { + "destination": "/dev/shm", + "type": "tmpfs", + "source": "shm", + "options": [ + "nosuid", + "noexec", + "nodev", + "mode=1777", + "size=65536k" + ] + }, + { + "destination": "/dev/mqueue", + "type": "mqueue", + "source": "mqueue", + "options": [ + "nosuid", + "noexec", + "nodev" + ] + }, + { + "destination": "/sys", + "type": "sysfs", + "source": "sysfs", + "options": [ + "nosuid", + "noexec", + "nodev", + "ro" + ] + }, + { + "destination": "/sys/fs/cgroup", + "type": "cgroup", + "source": "cgroup", + "options": [ + "nosuid", + "noexec", + "nodev", + "relatime", + "ro" ] } + ], + "hooks": {}, + "linux": { + "devices": [], + "cgroupsPath": "kata/vfiotest", + "resources": { + "devices": [ + {"allow":false,"access":"rwm"}, + {"allow":true,"type":"c","major":1,"minor":3,"access":"rwm"}, + {"allow":true,"type":"c","major":1,"minor":5,"access":"rwm"}, + {"allow":true,"type":"c","major":1,"minor":8,"access":"rwm"}, + {"allow":true,"type":"c","major":1,"minor":9,"access":"rwm"}, + {"allow":true,"type":"c","major":5,"minor":0,"access":"rwm"}, + {"allow":true,"type":"c","major":5,"minor":1,"access":"rwm"} + ] + }, + "namespaces": [{ + "type": "pid" + }, + { + "type": "network" + }, + { + "type": "ipc" + }, + { + "type": "uts" + }, + { + "type": "mount" + } + ], + "maskedPaths": [ + "/proc/kcore", + "/proc/latency_stats", + "/proc/timer_list", + "/proc/timer_stats", + "/proc/sched_debug", + "/sys/firmware" + ], + "readonlyPaths": [ + "/proc/asound", + "/proc/bus", + "/proc/fs", + "/proc/irq", + "/proc/sys", + "/proc/sysrq-trigger" + ] } } \ No newline at end of file diff --git a/service/src/lib.rs b/service/src/lib.rs index 38688d4..f63c7a5 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -1,3 +1,5 @@ +pub mod spec; + use containerd_client::{ services::v1::{ container::Runtime, Container, CreateContainerRequest, CreateTaskRequest, @@ -36,11 +38,11 @@ impl Service { } pub async fn create_container(&self, image: String, cid: String) { - // let spec = include_str!("../../container_spec.json").to_string(); - // let spec = Any { - // type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(), - // value: spec.into_bytes(), - // }; + let spec = include_str!("../../container_spec.json").to_string(); + let spec = Any { + type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(), + value: spec.into_bytes(), + }; let mut containers_client = self.client.lock().unwrap().containers(); let container = Container { id: cid.to_string(), @@ -49,7 +51,7 @@ impl Service { name: "io.containerd.runc.v2".to_string(), options: None, }), - // spec: Some(spec), + spec: Some(spec), ..Default::default() }; @@ -259,7 +261,6 @@ impl Service { pub fn get_resolver(&self) { todo!() } - } //容器是容器,要先启动,然后才能运行任务 //要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。 diff --git a/service/src/spec.rs b/service/src/spec.rs new file mode 100644 index 0000000..0cc482b --- /dev/null +++ b/service/src/spec.rs @@ -0,0 +1,297 @@ +use serde::{Deserialize, Serialize}; +use std::fs::File; + +// 定义版本的常量 +const VERSION_MAJOR: u32 = 1; +const VERSION_MINOR: u32 = 1; +const VERSION_PATCH: u32 = 0; +const VERSION_DEV: &str = ""; // 对应开发分支 + +const RWM: &str = "rwm"; +const DEFAULT_ROOTFS_PATH: &str = "rootfs"; + +const DEFAULT_UNIX_ENV:&str="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; + +const PID_NAMESPACE: &str = "pid"; +const NETWORK_NAMESPACE: &str = "network"; +const MOUNT_NAMESPACE: &str = "mount"; +const IPC_NAMESPACE: &str = "ipc"; +const UTS_NAMESPACE: &str = "uts"; +const USER_NAMESPACE: &str = "user"; +const CGROUP_NAMESPACE: &str = "cgroup"; +const TIME_NAMESPACE: &str = "time"; + + +#[derive(Serialize, Deserialize, Debug)] +struct Spec { + ociVersion: String, + root: Root, + process: Process, + linux: Linux, + mounts: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Root { + path: String, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Process { + cwd: String, + noNewPrivileges: bool, + user: User, + capabilities: LinuxCapabilities, + rlimits: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct User { + uid: u32, + gid: u32, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Mount { + destination: String, + type_: String, + source: String, + options: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct LinuxCapabilities { + bounding: Vec, + permitted: Vec, + effective: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct POSIXRlimit { + #[serde(rename = "type")] + type_: String, + hard: u64, + soft: u64, +} + +#[derive(Serialize, Deserialize, Debug)] +struct Linux { + masked_paths: Vec, + readonly_paths: Vec, + cgroups_path: String, + resources: LinuxResources, + namespaces: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct LinuxResources { + devices: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +struct LinuxDeviceCgroup { + allow: bool, + access: String, +} + +#[derive(Serialize, Deserialize, Debug)] +struct LinuxNamespace { + #[serde(rename = "type")] + type_: String, +} + +pub fn default_unix_caps() -> Vec { + vec![ + String::from("CAP_CHOWN"), + String::from("CAP_DAC_OVERRIDE"), + String::from("CAP_FSETID"), + String::from("CAP_FOWNER"), + String::from("CAP_MKNOD"), + String::from("CAP_NET_RAW"), + String::from("CAP_SETGID"), + String::from("CAP_SETUID"), + String::from("CAP_SETFCAP"), + String::from("CAP_SETPCAP"), + String::from("CAP_NET_BIND_SERVICE"), + String::from("CAP_SYS_CHROOT"), + String::from("CAP_KILL"), + String::from("CAP_AUDIT_WRITE"), + ] +} + +fn default_masked_parhs() -> Vec { + vec![ + String::from("/proc/acpi"), + String::from("/proc/asound"), + String::from("/proc/kcore"), + String::from("/proc/keys"), + String::from("/proc/latency_stats"), + String::from("/proc/timer_list"), + String::from("/proc/timer_stats"), + String::from("/proc/sched_debug"), + String::from("/proc/scsi"), + String::from("/sys/firmware"), + String::from("/sys/devices/virtual/powercap"), + ] +} + +fn default_readonly_paths() -> Vec { + vec![ + String::from("/proc/bus"), + String::from("/proc/fs"), + String::from("/proc/irq"), + String::from("/proc/sys"), + String::from("/proc/sysrq-trigger"), + ] +} + +fn default_unix_namespaces() -> Vec { + vec![ + LinuxNamespace { + type_: String::from(PID_NAMESPACE), + }, + LinuxNamespace { + type_: String::from(IPC_NAMESPACE), + }, + LinuxNamespace { + type_: String::from(UTS_NAMESPACE), + }, + LinuxNamespace { + type_: String::from(MOUNT_NAMESPACE), + }, + LinuxNamespace { + type_: String::from(NETWORK_NAMESPACE), + }, + ] +} + +fn default_mounts() -> Vec { + vec![ + Mount { + destination: "/proc".to_string(), + type_: "proc".to_string(), + source: "proc".to_string(), + options: vec![], + }, + Mount { + destination: "/dev".to_string(), + type_: "tmpfs".to_string(), + source: "tmpfs".to_string(), + options: vec![ + "nosuid".to_string(), + "strictatime".to_string(), + "mode=755".to_string(), + "size=65536k".to_string(), + ], + }, + Mount { + destination: "/dev/pts".to_string(), + type_: "devpts".to_string(), + source: "devpts".to_string(), + options: vec![ + "nosuid".to_string(), + "noexec".to_string(), + "newinstance".to_string(), + "ptmxmode=0666".to_string(), + "mode=0620".to_string(), + "gid=5".to_string(), + ], + }, + Mount { + destination: "/dev/shm".to_string(), + type_: "tmpfs".to_string(), + source: "shm".to_string(), + options: vec![ + "nosuid".to_string(), + "noexec".to_string(), + "nodev".to_string(), + "mode=1777".to_string(), + "size=65536k".to_string(), + ], + }, + Mount { + destination: "/dev/mqueue".to_string(), + type_: "mqueue".to_string(), + source: "mqueue".to_string(), + options: vec![ + "nosuid".to_string(), + "noexec".to_string(), + "nodev".to_string(), + ], + }, + Mount { + destination: "/sys".to_string(), + type_: "sysfs".to_string(), + source: "sysfs".to_string(), + options: vec![ + "nosuid".to_string(), + "noexec".to_string(), + "nodev".to_string(), + "ro".to_string(), + ], + }, + Mount { + destination: "/sys/fs/cgroup".to_string(), + type_: "cgroup".to_string(), + source: "cgroup".to_string(), + options: vec![ + "nosuid".to_string(), + "noexec".to_string(), + "nodev".to_string(), + "relatime".to_string(), + "ro".to_string(), + ], + }, + ] +} + +fn get_version() -> String { + format!( + "{}.{}.{}{}", + VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_DEV + ) +} + +fn populate_default_unix_spec(id: &str, ns: &str) -> Spec { + Spec { + ociVersion: get_version(), + root: Root { + path: DEFAULT_ROOTFS_PATH.to_string(), + }, + process: Process { + cwd: String::from("/"), + noNewPrivileges: true, + user: User { uid: 0, gid: 0 }, + capabilities: LinuxCapabilities { + bounding: default_unix_caps(), + permitted: default_unix_caps(), + effective: default_unix_caps(), + }, + rlimits: vec![POSIXRlimit { + type_: String::from("RLIMIT_NOFILE"), + hard: 1024, + soft: 1024, + }], + }, + linux: Linux { + masked_paths: default_masked_parhs(), + readonly_paths: default_readonly_paths(), + cgroups_path: format!("{}/{}", ns, id), + resources: LinuxResources { + devices: vec![LinuxDeviceCgroup { + allow: false, + access: String::from("rwm"), + }], + }, + namespaces: default_unix_namespaces(), + }, + mounts: default_mounts(), + } +} + +fn save_spec_to_file(spec: &Spec, path: &str) -> Result<(), std::io::Error> { + let file = File::create(path)?; + serde_json::to_writer(file, spec)?; + Ok(()) +} +