diff --git a/Cargo.lock b/Cargo.lock index 03972b9..dde0ccc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,6 +1548,7 @@ dependencies = [ "containerd-client", "env_logger", "log", + "prost-types", "serde", "serde_json", "tokio", diff --git a/app/src/main.rs b/app/src/main.rs index 5f94c7b..57669a4 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -21,8 +21,8 @@ async fn main() -> std::io::Result<()> { HttpServer::new(move || { App::new() .app_data(web::Data::new(service.clone())) - .route("/create_container", web::post().to(create_container)) - .route("/remove_container", web::post().to(remove_container)) + .route("/create-container", web::post().to(create_container)) + .route("/remove-container", web::post().to(remove_container)) .route("/containers", web::get().to(get_container_list)) // 更多路由配置... }) diff --git a/container_spec.json b/container_spec.json new file mode 100644 index 0000000..b17221b --- /dev/null +++ b/container_spec.json @@ -0,0 +1,290 @@ + +{ + "ID": "hello", + "Labels": { + "io.containerd.image.config.stop-signal": "SIGTERM" + }, + "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 + }, + "root": { + "path": "rootfs" + }, + "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" + ] + } + ], + "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" + ] + } + } +} \ No newline at end of file diff --git a/service/Cargo.toml b/service/Cargo.toml index 41728a4..481b9a4 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -11,3 +11,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" log = "0.4" env_logger = "0.10" +prost-types = "0.13.4" \ No newline at end of file diff --git a/service/src/lib.rs b/service/src/lib.rs index df8ec02..38688d4 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -1,13 +1,15 @@ use containerd_client::{ services::v1::{ container::Runtime, Container, CreateContainerRequest, CreateTaskRequest, - DeleteContainerRequest, DeleteTaskRequest, KillRequest, ListContainersRequest, - ListTasksRequest, StartRequest, WaitRequest, + DeleteContainerRequest, DeleteTaskRequest, GetImageRequest, KillRequest, + ListContainersRequest, ListTasksRequest, StartRequest, WaitRequest, }, tonic::Request, with_namespace, Client, }; +use prost_types::Any; use std::{ + collections::HashMap, fs::{self, File}, sync::{Arc, Mutex}, time::Duration, @@ -34,6 +36,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 mut containers_client = self.client.lock().unwrap().containers(); let container = Container { id: cid.to_string(), @@ -42,7 +49,7 @@ impl Service { name: "io.containerd.runc.v2".to_string(), options: None, }), - spec: None, + // spec: Some(spec), ..Default::default() }; @@ -58,8 +65,6 @@ impl Service { .expect("Failed to create container"); println!("Container: {:?} created", cid); - - self.create_and_start_task(cid).await; } pub async fn remove_container(&self, container_id: String) { @@ -158,6 +163,25 @@ impl Service { println!("Task: {:?} started", container_id); } + pub async fn kill_task(&self, container_id: String) { + let mut tasks_client = self.client.lock().unwrap().tasks(); + let kill_request = Request::new(KillRequest { + container_id: container_id.to_string(), + signal: 15, + all: true, + ..Default::default() + }); + tasks_client + .kill(kill_request) + .await + .expect("Failed to kill task"); + } + pub async fn pause_task() { + todo!() + } + pub async fn resume_task() { + todo!() + } pub async fn delete_task(&self, container_id: &str) { let time_out = Duration::from_secs(30); let mut tc = self.client.lock().unwrap().tasks(); @@ -223,6 +247,8 @@ impl Service { .collect()) } + pub async fn get_task_list() {} + pub fn prepare_image(&self) { todo!() } @@ -233,4 +259,7 @@ impl Service { pub fn get_resolver(&self) { todo!() } + } +//容器是容器,要先启动,然后才能运行任务 +//要想删除一个正在运行的Task,必须先kill掉这个task,然后才能删除。