diff --git a/daemon/.gitignore b/daemon/.gitignore new file mode 100644 index 0000000..596b9e4 --- /dev/null +++ b/daemon/.gitignore @@ -0,0 +1,3 @@ +target/ + +Cargo.lock \ No newline at end of file diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml new file mode 100644 index 0000000..bef63de --- /dev/null +++ b/daemon/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "daemon" +version = "0.1.0" +edition = "2024" + +[dependencies] +clap = { version = "4.5.47", features = ["derive"] } +containerd-client = "0.8.0" +tokio = { version = "1.45.1", features = ["macros", "rt-multi-thread"] } diff --git a/daemon/Makefile b/daemon/Makefile index e69de29..a9b9853 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -0,0 +1,13 @@ +.PHONY: rebuild +rebuild: + cargo clean + cargo build + +.PHONY: rebuild-release +rebuild-release: + cargo clean + cargo build -r + +.PHONY: run +run: + sudo ./target/debug/daemon diff --git a/daemon/src/actions/mod.rs b/daemon/src/actions/mod.rs new file mode 100644 index 0000000..6f65dd5 --- /dev/null +++ b/daemon/src/actions/mod.rs @@ -0,0 +1 @@ +mod pull; diff --git a/daemon/src/actions/pull.rs b/daemon/src/actions/pull.rs new file mode 100644 index 0000000..e69de29 diff --git a/daemon/src/config/default.json b/daemon/src/config/default.json new file mode 100644 index 0000000..8e29c7e --- /dev/null +++ b/daemon/src/config/default.json @@ -0,0 +1,8 @@ +{ + "images": [ + { + "id": "", + "image": "" + } + ] +} \ No newline at end of file diff --git a/daemon/src/config/mod.rs b/daemon/src/config/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/daemon/src/main.rs b/daemon/src/main.rs new file mode 100644 index 0000000..66c6511 --- /dev/null +++ b/daemon/src/main.rs @@ -0,0 +1,89 @@ +mod actions; +mod config; + +use clap::Parser; +use containerd_client::tonic::Request; +use containerd_client::{ + connect, + services::v1::{transfer_client::TransferClient, TransferOptions, TransferRequest}, + to_any, + types::transfer::OciRegistry, + types::transfer::{ImageStore, UnpackConfiguration}, + types::Platform, + with_namespace, +}; +use std::env::consts; + +#[derive(Parser, Debug)] +struct Args { + /// containerd namespace + #[arg(short, long, default_value = "nocturne")] + namespace: String, + + /// containerd socket + #[arg(short, long, default_value = "/run/containerd/containerd.sock")] + socket: String, +} + +const IMAGE: &str = "docker.io/library/alpine:latest"; + +#[tokio::main] +async fn main() { + let args = Args::parse(); + + let arch = match consts::ARCH { + "x86_64" => "amd64", + "aarch64" => "arm64", + _ => consts::ARCH, + }; + + dbg!(&args); + + let channel = connect(&args.socket).await.expect("failed to bind socket"); + let mut client = TransferClient::new(channel.clone()); + + let registry = OciRegistry { + reference: IMAGE.to_string(), + resolver: Default::default(), + }; + + let platform = Platform { + os: "linux".to_string(), + architecture: arch.to_string(), + variant: "".to_string(), + os_version: "".to_string(), + }; + + let destination = ImageStore { + name: IMAGE.to_string(), + platforms: vec![platform.clone()], + unpacks: vec![UnpackConfiguration { + platform: Some(platform), + ..Default::default() + }], + ..Default::default() + }; + + let anys = to_any(®istry); + let anyd = to_any(&destination); + + println!( + "Pulling image for linux/{} from source: {:?}", + arch, registry + ); + + let request = TransferRequest { + source: Some(anys), + destination: Some(anyd), + options: Some(TransferOptions { + ..Default::default() + }), + }; + // let request = Request::new(request); + let req = with_namespace!(request, args.namespace); + + client + .transfer(req) + .await + .expect("unable to transfer image"); +}