Skip to content

Commit

Permalink
Basic image pulling and dvs file experiments
Browse files Browse the repository at this point in the history
  • Loading branch information
harmless-tech committed Sep 17, 2023
1 parent 4a02ef7 commit c64d937
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 81 deletions.
69 changes: 67 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ dialoguer = "0.10.4"
directories = "5.0.1"
indicatif = "0.17.6"
mimalloc = { version = "0.1.39", optional = true }
phf = { version = "0.11.2", features = ["macros"] }
serde = { version = "1.0.188", features = ["derive"] }
thiserror = "1.0.48"
toml = { version = "0.8.0", features = ["display", "parse"] }

[features]
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ msrv:
--mount type=bind,source=$HOME/.cargo/registry,target=/usr/local/cargo/registry \
-w /project \
rust:latest \
bash -c 'cargo install cargo-msrv --version 0.16.0-beta.14 --profile=dev && cargo msrv -- cargo check --verbose --locked'
bash -c 'cargo install cargo-msrv --version 0.15.1 --profile=dev && cargo msrv -- cargo check --verbose --locked'
84 changes: 9 additions & 75 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,91 +1,25 @@
use clap::{Parser, Subcommand};
use std::ffi::OsString;

#[derive(Debug, Parser)]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Args {
#[command(subcommand)]
subcommand: ArgCommand,
pub subcommand: ArgCommand,
// TODO: Top level config stuff, like --config=$PATH
}

#[derive(Debug, Subcommand)]
pub enum ArgCommand {
/// Deals with virtual system bases
Img {
#[command(subcommand)]
subcommand: ArgImgCommand,
},
/// List virtual systems and their statuses
List,
/// Runs a virtual system
Create {
/// Temporary system that must be removed on exit.
/// Can use multiple of these at a time.
#[arg(short, long)]
temp: bool,
/// Do not remove on exit
#[arg(short, long)]
no_remove: bool,
/// Do not attach STDIO
#[arg(short, long)]
detach: bool,
/// Name to be given to the virtual system
name: String,
/// Base of the virtual system
base: String,
/// Command to exec, otherwise base command will be used
#[arg(last = true)]
cmd: Option<OsString>,
},
/// Runs a command in the virtual system
Exec {
/// Do not attach STDIO
#[arg(short, long)]
detach: bool,
/// Name of the virtual system
name: String,
/// Command to exec, otherwise base command will be used
#[arg(last = true)]
cmd: Option<OsString>,
},
/// Start a virtual system
Start {
/// Name of the virtual system
name: String,
},
/// Stop a virtual system
Stop {
/// Name of the virtual system
name: String,
},
}

#[derive(Debug, Subcommand)]
pub enum ArgImgCommand {
/// Create a new image
/// (TODO) Persist
Create,
/// Download an image definition from a url
Download,
/// Edit an image
Edit, // TODO: This should allow people to open stuff like the config and Dockerfile in VSCODE
/// Bundle an image for use in
Bundle,
/// List images
List,
/// Get info about an image
Info,
/// (Re)Builds base image, removing the old image and any containers that use it
Build {
/// Do not rebuild image if it already exists
#[arg(short, long)]
no_rebuild: bool,
/// Use build cache if possible
#[arg(short, long)]
use_cache: bool,
/// TODO
base_name: String,
/// (TODO) Temp
Run {
/// Id of the dvs
id: String,
},
/// (TODO) Edit and manage dvs'
Img,
}

#[test]
Expand Down
13 changes: 13 additions & 0 deletions src/driver/docker.rs
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
use crate::driver::Driver;

pub struct DockerDriver {}
impl DockerDriver {
pub fn new() -> Self {
Self {}
}
}
impl Driver for DockerDriver {
// TODO: Support --platform
fn pull_image(&self, image: &str) -> String {
format!("docker pull {image}")
}
}
13 changes: 13 additions & 0 deletions src/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
use crate::driver::docker::DockerDriver;

mod docker;
mod podman;

pub trait Driver {
fn pull_image(&self, image: &str) -> String;
}

pub fn get_bundled(item: &str) -> Option<Box<dyn Driver>> {
match item {
"bundled-docker" => Some(Box::new(DockerDriver::new())),
_ => None,
}
}
8 changes: 8 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use thiserror::Error;

#[allow(dead_code)] // TODO: Remove
#[derive(Debug, Error)]
pub enum CommandError {
#[error("The child process exited with code `{0}`")]
ExitCode(i32),
}
30 changes: 30 additions & 0 deletions src/image/bundled/rust.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[info]
id = "rust" # dvs id

[container]
workspace = "/project" # -w
mount_pwd = "/project" # --mount type=bind,source="$(pwd)",target=/project
mounts = ["$HOME/.cargo/registry:/usr/local/cargo/registry"] # --mount type=bind,source=$HOME/.cargo/registry,target=/usr/local/cargo/registry
env = ["CARGO_TARGET_DIR=/target"] # -e CARGO_TARGET_DIR=/target

[image]
default = "latest"
versions = [
"latest",
"alpine",
"bookworm",
"bullseye",
"buster",
"slim",
"slim-bookworm",
"slim-bullseye",
"slim-buster",
]
pull = "rust" # Applies to all image unless overridden
pull_updates = true
entrypoint = "/bin/sh"
cmd = "-c /bin/bash"

[image.alpine]
entrypoint = "/bin/sh"
cmd = "-c /bin/sh"
9 changes: 9 additions & 0 deletions src/image/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use phf::phf_map;

static BUNDLED_MAP: phf::Map<&'static str, &'static str> = phf_map! {
"rust" => include_str!("./bundled/rust.toml")
};

pub fn get_bundled(item: &str) -> Option<&&'static str> {
BUNDLED_MAP.get(item)
}
68 changes: 65 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,74 @@
use crate::cli::ArgCommand;
use clap::Parser;
use std::{ffi::OsString, process::Command};
use toml::Table;

mod cli;
mod driver;
mod errors;
mod image;

#[cfg(target_family = "wasm")]
compile_error!("Wasm is not a supported target!");

fn main() {
let _args = cli::Args::parse();
let args = cli::Args::parse();
#[cfg(debug_assertions)]
dbg!(_args);
dbg!(&args);

// TODO: Get config here!
let driver = driver::get_bundled("bundled-docker").unwrap();

match &args.subcommand {
ArgCommand::Run { id } => {
let image = image::get_bundled(id).unwrap();
let image = image.parse::<Table>().unwrap();

let pull_img = image["image"]["pull"].as_str().unwrap();
let pull_img_default = image["image"]["default"].as_str().unwrap();
let pull_img = if !pull_img.contains(':') {
format!("{pull_img}:{pull_img_default}")
}
else {
pull_img.to_string()
};

dbg!(&pull_img);

let cmd = driver.pull_image(&pull_img);
run_cmd(&cmd, None).expect("FFF");
}
_ => todo!(),
}
}

fn run_cmd(cmd: &str, end: Option<OsString>) -> Result<(), String> {
#[cfg(target_family = "unix")]
let mut command = Command::new("sh");
#[cfg(target_family = "unix")]
command.arg("-c");

#[cfg(target_family = "windows")]
let mut command = Command::new("cmd");
#[cfg(target_family = "windows")]
command.arg("/C");

command.arg(cmd);
if let Some(str) = end {
command.arg(str);
}

dbg!(&command);

// let out = command.status().expect("exec failed");

let child = command.spawn().expect("Could not spawn child process.");
let _out = child.wait_with_output();

// match command.spawn().and_then(|mut child| child.wait()) {
// Ok(status) => std::process::exit(status.code().unwrap_or(1)),
// Err(error) => die!("fatal: {}", error),
// };

println!("Hello, world!");
Ok(())
}

0 comments on commit c64d937

Please sign in to comment.