From 6d172b12e0118371c889ff2f1e9c015b228d2a17 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Tue, 25 Apr 2023 23:45:01 -0500 Subject: [PATCH 01/14] Refactor quadlet file into its own type New struct `quadlet::File` handles `Display` impl Prepares for the addition of other types that can be converted to a quadlet file --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cli.rs | 78 ++++----- src/cli/container.rs | 67 +++----- src/cli/container/podman.rs | 4 +- src/cli/container/quadlet.rs | 229 ++++++++------------------ src/cli/container/security_opt.rs | 75 ++++----- src/cli/install.rs | 29 ++-- src/cli/kube.rs | 60 ++++--- src/cli/network.rs | 74 +++------ src/cli/service.rs | 4 +- src/cli/unit.rs | 4 +- src/cli/volume.rs | 56 +++---- src/main.rs | 1 + src/quadlet.rs | 117 ++++++++++++++ src/quadlet/container.rs | 259 ++++++++++++++++++++++++++++++ src/quadlet/install.rs | 25 +++ src/quadlet/kube.rs | 44 +++++ src/quadlet/network.rs | 70 ++++++++ src/quadlet/volume.rs | 50 ++++++ 20 files changed, 817 insertions(+), 433 deletions(-) create mode 100644 src/quadlet.rs create mode 100644 src/quadlet/container.rs create mode 100644 src/quadlet/install.rs create mode 100644 src/quadlet/kube.rs create mode 100644 src/quadlet/network.rs create mode 100644 src/quadlet/volume.rs diff --git a/Cargo.lock b/Cargo.lock index ad4510b..7b445a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -754,7 +754,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "podlet" -version = "0.2.0-alpha.1" +version = "0.2.0-alpha.2" dependencies = [ "clap", "color-eyre", diff --git a/Cargo.toml b/Cargo.toml index 0bf1f89..a2557eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "podlet" -version = "0.2.0-alpha.1" +version = "0.2.0-alpha.2" authors = ["Paul Nettleton "] edition = "2021" description = "Podlet generates podman quadlet (systemd-like) files from a podman command." diff --git a/src/cli.rs b/src/cli.rs index bc0a641..53ca82f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,8 +2,8 @@ mod container; mod install; mod kube; mod network; -mod service; -mod unit; +pub mod service; +pub mod unit; mod volume; #[cfg(unix)] @@ -13,7 +13,6 @@ use std::{ borrow::Cow, env, ffi::OsStr, - fmt::Display, fs::File, io::{self, Write}, path::{Path, PathBuf}, @@ -25,6 +24,8 @@ use color_eyre::{ Help, Report, }; +use crate::quadlet; + use self::{ container::Container, install::Install, kube::Kube, network::Network, service::Service, unit::Unit, volume::Volume, @@ -101,28 +102,24 @@ pub struct Cli { command: Commands, } -impl Display for Cli { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if !self.unit.is_empty() { - writeln!(f, "{}", &self.unit)?; - } - - let Commands::Podman { command } = &self.command; - write!(f, "{command}")?; - - if self.install.install { - write!(f, "\n{}", &self.install)?; +impl From for quadlet::File { + fn from(value: Cli) -> Self { + let Commands::Podman { command } = value.command; + let service = command.service().cloned(); + Self { + unit: (!value.unit.is_empty()).then_some(value.unit), + resource: command.into(), + service, + install: value.install.install.then(|| value.install.into()), } - - Ok(()) } } impl Cli { - pub fn print_or_write_file(&self) -> eyre::Result<()> { + pub fn print_or_write_file(self) -> eyre::Result<()> { if self.unit_directory || self.file.is_some() { let path = self.file_path()?; - let path_display = path.display(); + let path_display = path.display().to_string(); let mut file = File::options() .write(true) .create_new(!self.overwrite) @@ -140,12 +137,12 @@ impl Cli { and you have write permissions for the file", ), })?; - write!(file, "{self}") + write!(file, "{}", quadlet::File::from(self)) .wrap_err_with(|| format!("Failed to write to file: {path_display}"))?; println!("Wrote to file: {path_display}"); Ok(()) } else { - print!("{self}"); + print!("{}", quadlet::File::from(self)); Ok(()) } } @@ -278,24 +275,25 @@ enum PodmanCommands { }, } -impl Display for PodmanCommands { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Run { container, service } => { - write!(f, "{container}")?; - if !service.is_empty() { - write!(f, "\n{service}")?; - } - Ok(()) - } - Self::Kube { kube } => write!(f, "{kube}"), - Self::Network { network } => write!(f, "{network}"), - Self::Volume { volume } => write!(f, "{volume}"), +impl From for quadlet::Resource { + fn from(value: PodmanCommands) -> Self { + match value { + PodmanCommands::Run { container, .. } => (*container).into(), + PodmanCommands::Kube { kube } => kube.into(), + PodmanCommands::Network { network } => network.into(), + PodmanCommands::Volume { volume } => volume.into(), } } } impl PodmanCommands { + fn service(&self) -> Option<&Service> { + match self { + Self::Run { service, .. } => (!service.is_empty()).then_some(service), + _ => None, + } + } + /// Returns the name that should be used for the generated file fn name(&self) -> &str { match self { @@ -329,20 +327,6 @@ impl PodmanCommands { } } -fn escape_spaces_join<'a>(words: impl IntoIterator) -> String { - words - .into_iter() - .map(|word| { - if word.contains(' ') { - format!("\"{word}\"").into() - } else { - word.into() - } - }) - .collect::>>() - .join(" ") -} - #[cfg(test)] mod tests { use clap::CommandFactory; diff --git a/src/cli/container.rs b/src/cli/container.rs index 770da19..209053b 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -2,8 +2,6 @@ mod podman; mod quadlet; mod security_opt; -use std::fmt::{self, Display, Formatter}; - use clap::Args; use self::{podman::PodmanArgs, quadlet::QuadletOptions, security_opt::SecurityOpt}; @@ -39,29 +37,37 @@ pub struct Container { command: Vec, } -impl Display for Container { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - writeln!(f, "[Container]")?; - writeln!(f, "Image={}", self.image)?; - - write!(f, "{}", self.quadlet_options)?; - - let mut podman_args = self.podman_args.to_string(); +impl From for crate::quadlet::Container { + fn from(value: Container) -> Self { + let mut podman_args = value.podman_args.to_string(); - for output in self.security_opt.iter().map(Output::from) { - output.write_or_add_arg("--security-opt", f, &mut podman_args)?; + let mut security_options = security_opt::QuadletOptions::default(); + for security_opt in value.security_opt { + security_options.add_security_opt(security_opt); } - - if !podman_args.is_empty() { - writeln!(f, "PodmanArgs={}", podman_args.trim())?; + for arg in security_options.podman_args { + podman_args += &format!(" --security-opt {arg}"); } - if !self.command.is_empty() { - let command = shlex::join(self.command.iter().map(String::as_str)); - writeln!(f, "Exec={command}")?; + Self { + image: value.image, + no_new_privileges: security_options.no_new_privileges, + seccomp_profile: security_options.seccomp_profile, + security_label_disable: security_options.security_label_disable, + security_label_file_type: security_options.security_label_file_type, + security_label_level: security_options.security_label_level, + security_label_type: security_options.security_label_type, + podman_args: (!podman_args.is_empty()).then(|| podman_args.trim().to_string()), + exec: (!value.command.is_empty()) + .then(|| shlex::join(value.command.iter().map(String::as_str))), + ..value.quadlet_options.into() } + } +} - Ok(()) +impl From for crate::quadlet::Resource { + fn from(value: Container) -> Self { + crate::quadlet::Container::from(value).into() } } @@ -79,29 +85,6 @@ impl Container { } } -#[derive(Debug, Clone, PartialEq)] -enum Output { - QuadletOptions(String), - PodmanArg(String), -} - -impl Output { - fn write_or_add_arg( - &self, - arg: &str, - f: &mut Formatter, - args: &mut String, - ) -> Result<(), fmt::Error> { - match self { - Output::QuadletOptions(options) => writeln!(f, "{options}"), - Output::PodmanArg(arg_value) => { - *args += &format!(" {arg} {arg_value}"); - Ok(()) - } - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/cli/container/podman.rs b/src/cli/container/podman.rs index c0b8f91..58ce867 100644 --- a/src/cli/container/podman.rs +++ b/src/cli/container/podman.rs @@ -1,5 +1,5 @@ use std::{ - fmt::Display, + fmt::{self, Display, Formatter}, path::{Path, PathBuf}, }; @@ -547,7 +547,7 @@ where impl Display for PodmanArgs { #[allow(clippy::similar_names, clippy::too_many_lines)] - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { let mut args = Vec::with_capacity(self.args_len()); extend_args(&mut args, "--add-host", &self.add_host); diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index 68b9c75..e4f432a 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -1,9 +1,10 @@ -use std::{fmt::Display, path::PathBuf}; +use std::{ + net::{Ipv4Addr, Ipv6Addr}, + path::PathBuf, +}; use clap::{Args, ValueEnum}; -use crate::cli::escape_spaces_join; - #[allow(clippy::module_name_repetitions)] #[derive(Args, Default, Debug, Clone, PartialEq)] pub struct QuadletOptions { @@ -149,13 +150,13 @@ pub struct QuadletOptions { /// /// Converts to "IP=IPV4" #[arg(long, value_name = "IPV4")] - ip: Option, + ip: Option, /// Specify a static IPv6 address for the container /// /// Converts to "IP6=IPV6" #[arg(long, value_name = "IPV6")] - ip6: Option, + ip6: Option, /// Set one or more OCI labels on the container /// @@ -282,167 +283,73 @@ impl Default for Notify { } } -impl Display for QuadletOptions { - #[allow(clippy::too_many_lines)] - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if !self.cap_add.is_empty() { - writeln!(f, "AddCapability={}", self.cap_add.join(" "))?; - } - - for device in &self.device { - writeln!(f, "AddDevice={device}")?; - } - - if !self.annotation.is_empty() { - writeln!(f, "Annotation={}", escape_spaces_join(&self.annotation))?; - } - - if let Some(name) = &self.name { - writeln!(f, "ContainerName={name}")?; - } - - if !self.cap_drop.is_empty() { - writeln!(f, "DropCapability={}", self.cap_drop.join(" "))?; - } - - if !self.env.is_empty() { - writeln!(f, "Environment={}", escape_spaces_join(&self.env))?; - } - - for file in &self.env_file { - writeln!(f, "EnvironmentFile={}", file.display())?; - } - - if self.env_host { - writeln!(f, "EnvironmentHost=true")?; - } - - for port in &self.expose { - writeln!(f, "ExposeHostPort={port}")?; - } - - if let Some(command) = &self.health_cmd { - writeln!(f, "HealthCmd={command}")?; - } - - if let Some(interval) = &self.health_interval { - writeln!(f, "HealthInterval={interval}")?; - } - - if let Some(action) = &self.health_on_failure { - writeln!(f, "HealthOnFailure={action}")?; - } - - if let Some(retries) = &self.health_retries { - writeln!(f, "HealthRetries={retries}")?; - } - - if let Some(period) = &self.health_start_period { - writeln!(f, "HealthStartPeriod={period}")?; - } - - if let Some(command) = &self.health_startup_cmd { - writeln!(f, "HealthStartupCmd={command}")?; - } - - if let Some(interval) = &self.health_startup_interval { - writeln!(f, "HealthStartupInterval={interval}")?; - } - - if let Some(retries) = &self.health_startup_retries { - writeln!(f, "HealthStartupRetries={retries}")?; - } - - if let Some(retries) = &self.health_startup_success { - writeln!(f, "HealthStartupSuccess={retries}")?; - } - - if let Some(timeout) = &self.health_startup_timeout { - writeln!(f, "HealthStartupTimeout={timeout}")?; - } - - if let Some(timeout) = &self.health_timeout { - writeln!(f, "HealthTimeout={timeout}")?; - } - - if let Some(ip) = &self.ip { - writeln!(f, "IP={ip}")?; - } - - if let Some(ip6) = &self.ip6 { - writeln!(f, "IP6={ip6}")?; - } - - if !self.label.is_empty() { - writeln!(f, "Label={}", escape_spaces_join(&self.label))?; - } - - if let Some(log_driver) = &self.log_driver { - writeln!(f, "LogDriver={log_driver}")?; - } - - for mount in &self.mount { - writeln!(f, "Mount={mount}")?; - } - - for network in &self.network { - writeln!(f, "Network={network}")?; - } - - match self.sdnotify { - Notify::Conmon => Ok(()), - Notify::Container => writeln!(f, "Notify=true"), - }?; - - if let Some(rootfs) = &self.rootfs { - writeln!(f, "Rootfs={rootfs}")?; - } - - for port in &self.publish { - writeln!(f, "PublishPort={port}")?; - } - - if self.read_only { - writeln!(f, "ReadOnly=true")?; - } - - if self.init { - writeln!(f, "RunInit=true")?; - } - - for secret in &self.secret { - writeln!(f, "Secret={secret}")?; - } - - for tmpfs in &self.tmpfs { - if tmpfs == "/tmp" { - writeln!(f, "VolatileTmp=true")?; +impl From for crate::quadlet::Container { + fn from(value: QuadletOptions) -> Self { + let (user, group) = if let Some(user) = value.user { + if let Some((uid, gid)) = user.split_once(':') { + (Some(String::from(uid)), Some(String::from(gid))) } else { - writeln!(f, "Tmpfs={tmpfs}")?; + (Some(user), None) } - } + } else { + (None, None) + }; - if let Some(tz) = &self.tz { - writeln!(f, "Timezone={tz}")?; - } - - if let Some(user) = &self.user { - if let Some((uid, gid)) = user.split_once(':') { - writeln!(f, "User={uid}")?; - writeln!(f, "Group={gid}")?; + let mut tmpfs = value.tmpfs; + let mut volatile_tmp = false; + tmpfs.retain(|tmpfs| { + if tmpfs == "/tmp" { + volatile_tmp = true; + false } else { - writeln!(f, "User={user}")?; + true } + }); + + Self { + add_capability: value.cap_add, + add_device: value.device, + annotation: value.annotation, + container_name: value.name, + drop_capability: value.cap_drop, + environment: value.env, + environment_file: value.env_file, + environment_host: value.env_host, + expose_host_port: value.expose, + group, + health_cmd: value.health_cmd, + health_interval: value.health_interval, + health_on_failure: value.health_on_failure, + health_retries: value.health_retries, + health_start_period: value.health_start_period, + health_startup_cmd: value.health_startup_cmd, + health_startup_interval: value.health_startup_interval, + health_startup_retries: value.health_startup_retries, + health_startup_success: value.health_startup_success, + health_startup_timeout: value.health_startup_timeout, + health_timeout: value.health_timeout, + ip: value.ip, + ip6: value.ip6, + label: value.label, + log_driver: value.log_driver, + mount: value.mount, + network: value.network, + rootfs: value.rootfs, + notify: match value.sdnotify { + Notify::Conmon => false, + Notify::Container => true, + }, + publish_port: value.publish, + read_only: value.read_only, + run_init: value.init, + secret: value.secret, + tmpfs, + timezone: value.tz, + user, + user_ns: value.userns, + volatile_tmp, + volume: value.volume, + ..Self::default() } - - if let Some(userns) = &self.userns { - writeln!(f, "UserNS={userns}")?; - } - - for volume in &self.volume { - writeln!(f, "Volume={volume}")?; - } - - Ok(()) } } diff --git a/src/cli/container/security_opt.rs b/src/cli/container/security_opt.rs index 2225702..fa6638a 100644 --- a/src/cli/container/security_opt.rs +++ b/src/cli/container/security_opt.rs @@ -2,8 +2,6 @@ use std::str::FromStr; use thiserror::Error; -use super::Output; - #[derive(Debug, Clone, PartialEq)] pub enum SecurityOpt { Apparmor(String), @@ -58,30 +56,6 @@ pub enum ParseSecurityOptError { InvalidSecurityOpt(String), } -impl From for Output { - fn from(value: SecurityOpt) -> Self { - (&value).into() - } -} - -impl From<&SecurityOpt> for Output { - fn from(value: &SecurityOpt) -> Self { - match value { - SecurityOpt::Apparmor(policy) => Self::PodmanArg(format!("apparmor={policy}")), - SecurityOpt::Label(label_opt) => Self::from(label_opt), - SecurityOpt::Mask(mask) => Self::PodmanArg(format!("mask={mask}")), - SecurityOpt::NoNewPrivileges => { - Self::QuadletOptions(String::from("NoNewPrivileges=true")) - } - SecurityOpt::Seccomp(profile) => { - Self::QuadletOptions(format!("SeccompProfile={profile}")) - } - SecurityOpt::ProcOpts(proc_opts) => Self::PodmanArg(format!("proc-opts={proc_opts}")), - SecurityOpt::Unmask(unmask) => Self::PodmanArg(format!("unmask={unmask}")), - } - } -} - #[derive(Debug, Clone, PartialEq)] pub enum LabelOpt { User(String), @@ -129,26 +103,41 @@ impl FromStr for LabelOpt { #[error("`{0}` is not a valid label option")] pub struct InvalidLabelOpt(pub String); -impl From for Output { - fn from(value: LabelOpt) -> Self { - (&value).into() - } +#[derive(Debug, Default, Clone, PartialEq)] +pub struct QuadletOptions { + pub no_new_privileges: bool, + pub seccomp_profile: Option, + pub security_label_disable: bool, + pub security_label_file_type: Option, + pub security_label_level: Option, + pub security_label_type: Option, + pub podman_args: Vec, } -impl From<&LabelOpt> for Output { - fn from(value: &LabelOpt) -> Self { - match value { - LabelOpt::User(user) => Self::PodmanArg(format!("label=user:{user}")), - LabelOpt::Role(role) => Self::PodmanArg(format!("label=role:{role}")), - LabelOpt::Type(label_type) => { - Self::QuadletOptions(format!("SecurityLabelType={label_type}")) - } - LabelOpt::Level(level) => Self::QuadletOptions(format!("SecurityLabelLevel={level}")), - LabelOpt::Filetype(filetype) => { - Self::QuadletOptions(format!("SecurityLabelFileType={filetype}")) +impl QuadletOptions { + pub fn add_security_opt(&mut self, security_opt: SecurityOpt) { + match security_opt { + SecurityOpt::Apparmor(policy) => self.podman_args.push(format!("apparmor={policy}")), + SecurityOpt::Label(label_opt) => self.add_label_opt(label_opt), + SecurityOpt::Mask(mask) => self.podman_args.push(format!("mask={mask}")), + SecurityOpt::NoNewPrivileges => self.no_new_privileges = true, + SecurityOpt::Seccomp(profile) => self.seccomp_profile = Some(profile), + SecurityOpt::ProcOpts(proc_opts) => { + self.podman_args.push(format!("proc-opts={proc_opts}")); } - LabelOpt::Disable => Self::QuadletOptions(String::from("SecurityLabelDisable=true")), - LabelOpt::Nested => Self::PodmanArg(String::from("nested")), + SecurityOpt::Unmask(unmask) => self.podman_args.push(format!("unmask={unmask}")), + } + } + + pub fn add_label_opt(&mut self, label_opt: LabelOpt) { + match label_opt { + LabelOpt::User(user) => self.podman_args.push(format!("label=user:{user}")), + LabelOpt::Role(role) => self.podman_args.push(format!("label=role:{role}")), + LabelOpt::Type(label_type) => self.security_label_type = Some(label_type), + LabelOpt::Level(level) => self.security_label_level = Some(level), + LabelOpt::Filetype(file_type) => self.security_label_file_type = Some(file_type), + LabelOpt::Disable => self.security_label_disable = true, + LabelOpt::Nested => self.podman_args.push(String::from("nested")), } } } diff --git a/src/cli/install.rs b/src/cli/install.rs index af6f18c..4d97fd4 100644 --- a/src/cli/install.rs +++ b/src/cli/install.rs @@ -1,9 +1,5 @@ -use std::fmt::Display; - use clap::Args; -use crate::cli::escape_spaces_join; - #[derive(Args, Debug, Clone, PartialEq)] pub struct Install { /// Add an [Install] section to the unit @@ -34,22 +30,15 @@ pub struct Install { required_by: Vec, } -impl Display for Install { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "[Install]")?; - - if self.wanted_by.is_empty() && self.required_by.is_empty() { - writeln!(f, "WantedBy=default.target")?; - } - - if !self.wanted_by.is_empty() { - writeln!(f, "WantedBy={}", escape_spaces_join(&self.wanted_by))?; - } - - if !self.required_by.is_empty() { - writeln!(f, "RequiredBy={}", escape_spaces_join(&self.required_by))?; +impl From for crate::quadlet::Install { + fn from(value: Install) -> Self { + Self { + wanted_by: if value.wanted_by.is_empty() && value.required_by.is_empty() { + vec![String::from("default.target")] + } else { + value.wanted_by + }, + required_by: value.required_by, } - - Ok(()) } } diff --git a/src/cli/kube.rs b/src/cli/kube.rs index d744bf8..cfeb9ee 100644 --- a/src/cli/kube.rs +++ b/src/cli/kube.rs @@ -1,4 +1,10 @@ -use std::{convert::Infallible, ffi::OsStr, fmt::Display, path::PathBuf, str::FromStr}; +use std::{ + convert::Infallible, + ffi::OsStr, + fmt::{self, Display, Formatter}, + path::PathBuf, + str::FromStr, +}; use clap::{Args, Subcommand}; use url::Url; @@ -19,11 +25,16 @@ pub enum Kube { }, } -impl Display for Kube { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self::Play { play } = self; - writeln!(f, "[Kube]")?; - write!(f, "{play}") +impl From for crate::quadlet::Kube { + fn from(value: Kube) -> Self { + let Kube::Play { play } = value; + play.into() + } +} + +impl From for crate::quadlet::Resource { + fn from(value: Kube) -> Self { + crate::quadlet::Kube::from(value).into() } } @@ -43,7 +54,7 @@ pub struct Play { /// /// Can be specified multiple times #[arg(long, value_name = "PATH", value_delimiter = ',')] - configmap: Vec, + configmap: Vec, /// Set logging driver for the pod /// @@ -79,31 +90,16 @@ pub struct Play { file: File, } -impl Display for Play { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "Yaml={}", self.file)?; - - for configmap in &self.configmap { - writeln!(f, "ConfigMap={configmap}")?; +impl From for crate::quadlet::Kube { + fn from(value: Play) -> Self { + Self { + config_map: value.configmap, + log_driver: value.log_driver, + network: value.network, + publish_port: value.publish, + user_ns: value.userns, + yaml: value.file.to_string(), } - - if let Some(log_driver) = &self.log_driver { - writeln!(f, "LogDriver={log_driver}")?; - } - - for network in &self.network { - writeln!(f, "Network={network}")?; - } - - for port in &self.publish { - writeln!(f, "PublishPort={port}")?; - } - - if let Some(userns) = &self.userns { - writeln!(f, "UserNS={userns}")?; - } - - Ok(()) } } @@ -123,7 +119,7 @@ impl FromStr for File { } impl Display for File { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Self::Url(url) => write!(f, "{url}"), Self::Path(path) => write!(f, "{}", path.display()), diff --git a/src/cli/network.rs b/src/cli/network.rs index 8a0d6a1..4ca5b25 100644 --- a/src/cli/network.rs +++ b/src/cli/network.rs @@ -1,10 +1,8 @@ -use std::{fmt::Display, net::IpAddr}; +use std::net::IpAddr; use clap::{Args, Subcommand}; use ipnet::IpNet; -use crate::cli::escape_spaces_join; - #[derive(Subcommand, Debug, Clone, PartialEq)] pub enum Network { /// Generate a podman quadlet `.network` file @@ -21,11 +19,16 @@ pub enum Network { }, } -impl Display for Network { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self::Create { create } = self; - writeln!(f, "[Network]")?; - write!(f, "{create}") +impl From for crate::quadlet::Network { + fn from(value: Network) -> Self { + let Network::Create { create } = value; + create.into() + } +} + +impl From for crate::quadlet::Resource { + fn from(value: Network) -> Self { + crate::quadlet::Network::from(value).into() } } @@ -115,48 +118,19 @@ pub struct Create { name: String, } -impl Display for Create { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.disable_dns { - writeln!(f, "DisableDNS=true")?; - } - - if let Some(driver) = &self.driver { - writeln!(f, "Driver={driver}")?; - } - - for gateway in &self.gateway { - writeln!(f, "Gateway={gateway}")?; - } - - if self.internal { - writeln!(f, "Internal=true")?; - } - - if let Some(driver) = &self.ipam_driver { - writeln!(f, "IPAMDriver={driver}")?; - } - - for ip_range in &self.ip_range { - writeln!(f, "IPRange={ip_range}")?; - } - - if self.ipv6 { - writeln!(f, "IPv6=true")?; - } - - if !self.label.is_empty() { - writeln!(f, "Label={}", escape_spaces_join(&self.label))?; - } - - if !self.opt.is_empty() { - writeln!(f, "Options={}", self.opt.join(","))?; +impl From for crate::quadlet::Network { + fn from(value: Create) -> Self { + Self { + disable_dns: value.disable_dns, + driver: value.driver, + gateway: value.gateway, + internal: value.internal, + ipam_driver: value.ipam_driver, + ip_range: value.ip_range, + ipv6: value.ipv6, + label: value.label, + options: Some(value.opt.join(",")), + subnet: value.subnet, } - - for subnet in &self.subnet { - writeln!(f, "Subnet={subnet}")?; - } - - Ok(()) } } diff --git a/src/cli/service.rs b/src/cli/service.rs index ba615c3..a46b9ad 100644 --- a/src/cli/service.rs +++ b/src/cli/service.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use std::fmt::{self, Display, Formatter}; use clap::{Args, ValueEnum}; @@ -16,7 +16,7 @@ impl Service { } impl Display for Service { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { writeln!(f, "[Service]")?; if let Some(restart) = self.restart.and_then(|restart| restart.to_possible_value()) { writeln!(f, "Restart={}", restart.get_name())?; diff --git a/src/cli/unit.rs b/src/cli/unit.rs index 1b02cde..8d4209f 100644 --- a/src/cli/unit.rs +++ b/src/cli/unit.rs @@ -1,4 +1,4 @@ -use std::fmt::Display; +use std::fmt::{self, Display, Formatter}; use clap::Args; @@ -54,7 +54,7 @@ impl Unit { } impl Display for Unit { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { writeln!(f, "[Unit]")?; if let Some(description) = &self.description { diff --git a/src/cli/volume.rs b/src/cli/volume.rs index 55fa1af..e078b03 100644 --- a/src/cli/volume.rs +++ b/src/cli/volume.rs @@ -1,11 +1,8 @@ mod opt; -use std::fmt::Display; - use clap::{Args, Subcommand}; use self::opt::Opt; -use super::escape_spaces_join; #[derive(Subcommand, Debug, Clone, PartialEq)] pub enum Volume { @@ -23,11 +20,16 @@ pub enum Volume { }, } -impl Display for Volume { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self::Create { create } = self; - writeln!(f, "[Volume]")?; - write!(f, "{create}") +impl From for crate::quadlet::Volume { + fn from(value: Volume) -> Self { + let Volume::Create { create } = value; + create.into() + } +} + +impl From for crate::quadlet::Resource { + fn from(value: Volume) -> Self { + crate::quadlet::Volume::from(value).into() } } @@ -73,41 +75,35 @@ pub struct Create { name: String, } -impl Display for Create { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl From for crate::quadlet::Volume { + fn from(value: Create) -> Self { + let mut volume = Self { + label: value.label, + ..Self::default() + }; + let mut mount_options = Vec::new(); - for opt in &self.opt { + for opt in value.opt { match opt { - Opt::Type(opt_type) => writeln!(f, "Type={opt_type}")?, - Opt::Device(device) => writeln!(f, "Device={device}")?, - Opt::Copy => writeln!(f, "Copy=true")?, + Opt::Type(fs_type) => volume.fs_type = Some(fs_type), + Opt::Device(device) => volume.device = Some(device), + Opt::Copy => volume.copy = true, Opt::Mount(options) => { for option in options { match option { - opt::Mount::Uid(uid) => writeln!(f, "User={uid}")?, - opt::Mount::Gid(gid) => writeln!(f, "Group={gid}")?, + opt::Mount::Uid(uid) => volume.user = Some(uid), + opt::Mount::Gid(gid) => volume.group = Some(gid), opt::Mount::Other(option) => mount_options.push(option), } } } } } - if !mount_options.is_empty() { - writeln!( - f, - "Options={}", - mount_options - .into_iter() - .map(String::as_str) - .collect::>() - .join(",") - )?; - } - if !self.label.is_empty() { - writeln!(f, "Label={}", escape_spaces_join(&self.label))?; + if !mount_options.is_empty() { + volume.options = Some(mount_options.join(",")); } - Ok(()) + volume } } diff --git a/src/main.rs b/src/main.rs index 17f056a..3eefe10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ #![allow(clippy::multiple_crate_versions)] mod cli; +mod quadlet; use clap::Parser; use color_eyre::eyre; diff --git a/src/quadlet.rs b/src/quadlet.rs new file mode 100644 index 0000000..f32bf44 --- /dev/null +++ b/src/quadlet.rs @@ -0,0 +1,117 @@ +mod container; +mod install; +mod kube; +mod network; +mod volume; + +use std::{ + borrow::Cow, + fmt::{self, Display, Formatter}, +}; + +pub use self::{ + container::Container, install::Install, kube::Kube, network::Network, volume::Volume, +}; +use crate::cli::{service::Service, unit::Unit}; + +#[derive(Debug, Clone, PartialEq)] +pub struct File { + pub unit: Option, + pub resource: Resource, + pub service: Option, + pub install: Option, +} + +impl Display for File { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + if let Some(unit) = &self.unit { + writeln!(f, "{unit}")?; + } + + write!(f, "{}", self.resource)?; + + if let Some(service) = &self.service { + write!(f, "\n{service}")?; + } + + if let Some(install) = &self.install { + write!(f, "\n{install}")?; + } + + Ok(()) + } +} + +impl From for File { + fn from(value: Resource) -> Self { + Self { + unit: None, + resource: value, + service: None, + install: None, + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum Resource { + Container(Box), + Kube(Kube), + Network(Network), + Volume(Volume), +} + +impl Display for Resource { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self { + Self::Container(container) => write!(f, "{container}"), + Self::Kube(kube) => write!(f, "{kube}"), + Self::Network(network) => write!(f, "{network}"), + Self::Volume(volume) => write!(f, "{volume}"), + } + } +} + +impl From for Resource { + fn from(value: Container) -> Self { + Self::Container(Box::new(value)) + } +} + +impl From> for Resource { + fn from(value: Box) -> Self { + Self::Container(value) + } +} + +impl From for Resource { + fn from(value: Kube) -> Self { + Self::Kube(value) + } +} + +impl From for Resource { + fn from(value: Network) -> Self { + Self::Network(value) + } +} + +impl From for Resource { + fn from(value: Volume) -> Self { + Self::Volume(value) + } +} + +fn escape_spaces_join<'a>(words: impl IntoIterator) -> String { + words + .into_iter() + .map(|word| { + if word.contains(' ') { + format!("\"{word}\"").into() + } else { + word.into() + } + }) + .collect::>>() + .join(" ") +} diff --git a/src/quadlet/container.rs b/src/quadlet/container.rs new file mode 100644 index 0000000..93a5276 --- /dev/null +++ b/src/quadlet/container.rs @@ -0,0 +1,259 @@ +use std::{ + fmt::{self, Display, Formatter}, + net::{Ipv4Addr, Ipv6Addr}, + path::PathBuf, +}; + +use super::escape_spaces_join; + +#[derive(Debug, Default, Clone, PartialEq)] +#[allow(clippy::struct_excessive_bools)] +pub struct Container { + pub add_capability: Vec, + pub add_device: Vec, + pub annotation: Vec, + pub container_name: Option, + pub drop_capability: Vec, + pub environment: Vec, + pub environment_file: Vec, + pub environment_host: bool, + pub exec: Option, + pub expose_host_port: Vec, + pub group: Option, + pub health_cmd: Option, + pub health_interval: Option, + pub health_on_failure: Option, + pub health_retries: Option, + pub health_start_period: Option, + pub health_startup_cmd: Option, + pub health_startup_interval: Option, + pub health_startup_retries: Option, + pub health_startup_success: Option, + pub health_startup_timeout: Option, + pub health_timeout: Option, + pub image: String, + pub ip: Option, + pub ip6: Option, + pub label: Vec, + pub log_driver: Option, + pub mount: Vec, + pub network: Vec, + pub no_new_privileges: bool, + pub rootfs: Option, + pub notify: bool, + pub podman_args: Option, + pub publish_port: Vec, + pub read_only: bool, + pub run_init: bool, + pub seccomp_profile: Option, + pub security_label_disable: bool, + pub security_label_file_type: Option, + pub security_label_level: Option, + pub security_label_type: Option, + pub secret: Vec, + pub tmpfs: Vec, + pub timezone: Option, + pub user: Option, + pub user_ns: Option, + pub volatile_tmp: bool, + pub volume: Vec, +} + +impl Display for Container { + #[allow(clippy::too_many_lines)] + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + writeln!(f, "[Container]")?; + + writeln!(f, "Image={}", self.image)?; + + if !self.add_capability.is_empty() { + writeln!(f, "AddCapability={}", self.add_capability.join(" "))?; + } + + for device in &self.add_device { + writeln!(f, "AddDevice={device}")?; + } + + if !self.annotation.is_empty() { + writeln!(f, "Annotation={}", escape_spaces_join(&self.annotation))?; + } + + if let Some(name) = &self.container_name { + writeln!(f, "ContainerName={name}")?; + } + + if !self.drop_capability.is_empty() { + writeln!(f, "DropCapability={}", self.drop_capability.join(" "))?; + } + + if !self.environment.is_empty() { + writeln!(f, "Environment={}", escape_spaces_join(&self.environment))?; + } + + for file in &self.environment_file { + writeln!(f, "EnvironmentFile={}", file.display())?; + } + + if self.environment_host { + writeln!(f, "EnvironmentHost=true")?; + } + + for port in &self.expose_host_port { + writeln!(f, "ExposeHostPort={port}")?; + } + + if let Some(group) = &self.group { + writeln!(f, "Group={group}")?; + } + + if let Some(command) = &self.health_cmd { + writeln!(f, "HealthCmd={command}")?; + } + + if let Some(interval) = &self.health_interval { + writeln!(f, "HealthInterval={interval}")?; + } + + if let Some(action) = &self.health_on_failure { + writeln!(f, "HealthOnFailure={action}")?; + } + + if let Some(retries) = &self.health_retries { + writeln!(f, "HealthRetries={retries}")?; + } + + if let Some(period) = &self.health_start_period { + writeln!(f, "HealthStartPeriod={period}")?; + } + + if let Some(command) = &self.health_startup_cmd { + writeln!(f, "HealthStartupCmd={command}")?; + } + + if let Some(interval) = &self.health_startup_interval { + writeln!(f, "HealthStartupInterval={interval}")?; + } + + if let Some(retries) = &self.health_startup_retries { + writeln!(f, "HealthStartupRetries={retries}")?; + } + + if let Some(retries) = &self.health_startup_success { + writeln!(f, "HealthStartupSuccess={retries}")?; + } + + if let Some(timeout) = &self.health_startup_timeout { + writeln!(f, "HealthStartupTimeout={timeout}")?; + } + + if let Some(timeout) = &self.health_timeout { + writeln!(f, "HealthTimeout={timeout}")?; + } + + if let Some(ip) = &self.ip { + writeln!(f, "IP={ip}")?; + } + + if let Some(ip6) = &self.ip6 { + writeln!(f, "IP6={ip6}")?; + } + + if !self.label.is_empty() { + writeln!(f, "Label={}", escape_spaces_join(&self.label))?; + } + + if let Some(log_driver) = &self.log_driver { + writeln!(f, "LogDriver={log_driver}")?; + } + + for mount in &self.mount { + writeln!(f, "Mount={mount}")?; + } + + for network in &self.network { + writeln!(f, "Network={network}")?; + } + + if self.no_new_privileges { + writeln!(f, "NoNewPrivileges=true")?; + } + + if let Some(rootfs) = &self.rootfs { + writeln!(f, "Rootfs={rootfs}")?; + } + + if self.notify { + writeln!(f, "Notify=true")?; + } + + for port in &self.publish_port { + writeln!(f, "PublishPort={port}")?; + } + + if self.read_only { + writeln!(f, "ReadOnly=true")?; + } + + if self.run_init { + writeln!(f, "RunInit=true")?; + } + + if let Some(profile) = &self.seccomp_profile { + writeln!(f, "SeccompProfile={profile}")?; + } + + if self.security_label_disable { + writeln!(f, "SecurityLabelDisable=true")?; + } + + if let Some(file_type) = &self.security_label_file_type { + writeln!(f, "SecurityLabelFileType={file_type}")?; + } + + if let Some(level) = &self.security_label_level { + writeln!(f, "SecurityLabelLevel={level}")?; + } + + if let Some(label_type) = &self.security_label_type { + writeln!(f, "SecurityLabelType={label_type}")?; + } + + for secret in &self.secret { + writeln!(f, "Secret={secret}")?; + } + + for tmpfs in &self.tmpfs { + writeln!(f, "Tmpfs={tmpfs}")?; + } + + if let Some(timezone) = &self.timezone { + writeln!(f, "Timezone={timezone}")?; + } + + if let Some(user) = &self.user { + writeln!(f, "User={user}")?; + } + + if let Some(user_ns) = &self.user_ns { + writeln!(f, "UserNS={user_ns}")?; + } + + if self.volatile_tmp { + writeln!(f, "VolatileTmp=true")?; + } + + for volume in &self.volume { + writeln!(f, "Volume={volume}")?; + } + + if let Some(podman_args) = &self.podman_args { + writeln!(f, "PodmanArgs={podman_args}")?; + } + + if let Some(exec) = &self.exec { + writeln!(f, "Exec={exec}")?; + } + + Ok(()) + } +} diff --git a/src/quadlet/install.rs b/src/quadlet/install.rs new file mode 100644 index 0000000..c56babc --- /dev/null +++ b/src/quadlet/install.rs @@ -0,0 +1,25 @@ +use std::fmt::{self, Display, Formatter}; + +use super::escape_spaces_join; + +#[derive(Debug, Clone, PartialEq)] +pub struct Install { + pub wanted_by: Vec, + pub required_by: Vec, +} + +impl Display for Install { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + writeln!(f, "[Install]")?; + + if !self.wanted_by.is_empty() { + writeln!(f, "WantedBy={}", escape_spaces_join(&self.wanted_by))?; + } + + if !self.required_by.is_empty() { + writeln!(f, "RequiredBy={}", escape_spaces_join(&self.required_by))?; + } + + Ok(()) + } +} diff --git a/src/quadlet/kube.rs b/src/quadlet/kube.rs new file mode 100644 index 0000000..6ce7bf9 --- /dev/null +++ b/src/quadlet/kube.rs @@ -0,0 +1,44 @@ +use std::{ + fmt::{self, Display, Formatter}, + path::PathBuf, +}; + +#[derive(Debug, Clone, PartialEq)] +pub struct Kube { + pub config_map: Vec, + pub log_driver: Option, + pub network: Vec, + pub publish_port: Vec, + pub user_ns: Option, + pub yaml: String, +} + +impl Display for Kube { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + writeln!(f, "[Kube]")?; + + writeln!(f, "Yaml={}", self.yaml)?; + + for config_map in &self.config_map { + writeln!(f, "ConfigMap={}", config_map.display())?; + } + + if let Some(log_driver) = &self.log_driver { + writeln!(f, "LogDriver={log_driver}")?; + } + + for network in &self.network { + writeln!(f, "Network={network}")?; + } + + for port in &self.publish_port { + writeln!(f, "PublishPort={port}")?; + } + + if let Some(user_ns) = &self.user_ns { + writeln!(f, "UserNS={user_ns}")?; + } + + Ok(()) + } +} diff --git a/src/quadlet/network.rs b/src/quadlet/network.rs new file mode 100644 index 0000000..488096c --- /dev/null +++ b/src/quadlet/network.rs @@ -0,0 +1,70 @@ +use std::{ + fmt::{self, Display, Formatter}, + net::IpAddr, +}; + +use ipnet::IpNet; + +use super::escape_spaces_join; + +#[derive(Debug, Clone, PartialEq)] +pub struct Network { + pub disable_dns: bool, + pub driver: Option, + pub gateway: Vec, + pub internal: bool, + pub ipam_driver: Option, + pub ip_range: Vec, + pub ipv6: bool, + pub label: Vec, + pub options: Option, + pub subnet: Vec, +} + +impl Display for Network { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + writeln!(f, "[Network]")?; + + if self.disable_dns { + writeln!(f, "DisableDNS=true")?; + } + + if let Some(driver) = &self.driver { + writeln!(f, "Driver={driver}")?; + } + + for gateway in &self.gateway { + writeln!(f, "Gateway={gateway}")?; + } + + if self.internal { + writeln!(f, "Internal=true")?; + } + + if let Some(driver) = &self.ipam_driver { + writeln!(f, "IPAMDriver={driver}")?; + } + + for ip_range in &self.ip_range { + writeln!(f, "IPRange={ip_range}")?; + } + + if self.ipv6 { + writeln!(f, "IPv6=true")?; + } + + if !self.label.is_empty() { + writeln!(f, "Label={}", escape_spaces_join(&self.label))?; + } + + if let Some(options) = &self.options { + writeln!(f, "Options={options}")?; + } + + for subnet in &self.subnet { + writeln!(f, "Subnet={subnet}")?; + } + + Ok(()) + } +} diff --git a/src/quadlet/volume.rs b/src/quadlet/volume.rs new file mode 100644 index 0000000..fcf9c96 --- /dev/null +++ b/src/quadlet/volume.rs @@ -0,0 +1,50 @@ +use std::fmt::{self, Display, Formatter}; + +use super::escape_spaces_join; + +#[derive(Debug, Default, Clone, PartialEq)] +pub struct Volume { + pub copy: bool, + pub device: Option, + pub group: Option, + pub label: Vec, + pub options: Option, + pub fs_type: Option, + pub user: Option, +} + +impl Display for Volume { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + writeln!(f, "[Volume]")?; + + if self.copy { + writeln!(f, "Copy=true")?; + } + + if let Some(device) = &self.device { + writeln!(f, "Device={device}")?; + } + + if let Some(group) = &self.group { + writeln!(f, "Group={group}")?; + } + + if !self.label.is_empty() { + writeln!(f, "Label={}", escape_spaces_join(&self.label))?; + } + + if let Some(options) = &self.options { + writeln!(f, "Options={options}")?; + } + + if let Some(fs_type) = &self.fs_type { + writeln!(f, "Type={fs_type}")?; + } + + if let Some(user) = &self.user { + writeln!(f, "User={user}")?; + } + + Ok(()) + } +} From 4d32aebdbb12a36342750ef17f8a2bd628c6c4af Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Fri, 28 Apr 2023 01:52:50 -0500 Subject: [PATCH 02/14] Refactor to support creating multiple files --- Cargo.lock | 124 ++++++++++++++++++++++++++++ Cargo.toml | 2 + src/cli.rs | 215 ++++++++++++++++++++++++++++--------------------- src/main.rs | 2 +- src/quadlet.rs | 70 ++++++++++++++-- 5 files changed, 313 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b445a2..e0d29ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,6 +366,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "derivative" version = "2.2.0" @@ -377,6 +412,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.6" @@ -387,6 +453,18 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "docker-compose-types" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee50caf01e7a34feba906df016260b8850ccc7f5b3cf3a7e7841349af071e8b" +dependencies = [ + "derive_builder", + "indexmap", + "serde", + "serde_yaml", +] + [[package]] name = "enumflags2" version = "0.7.7" @@ -454,6 +532,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -569,6 +653,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -593,6 +683,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", + "serde", ] [[package]] @@ -633,6 +724,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "lazy_static" version = "1.4.0" @@ -758,8 +855,10 @@ version = "0.2.0-alpha.2" dependencies = [ "clap", "color-eyre", + "docker-compose-types", "ipnet", "nix", + "serde_yaml", "shlex", "thiserror", "url", @@ -892,6 +991,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + [[package]] name = "serde" version = "1.0.160" @@ -923,6 +1028,19 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "serde_yaml" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha1" version = "0.10.5" @@ -1168,6 +1286,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" + [[package]] name = "url" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index a2557eb..04aa578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,9 @@ categories = ["command-line-utilities"] [dependencies] clap = { version = "4.2", features = ["derive"] } color-eyre = "0.6" +docker-compose-types = "0.4.1" ipnet = "2.7" +serde_yaml = "0.9.21" shlex = "1.1" thiserror = "1.0.40" url = "2.3" diff --git a/src/cli.rs b/src/cli.rs index 53ca82f..a50f440 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -13,15 +13,13 @@ use std::{ borrow::Cow, env, ffi::OsStr, - fs::File, - io::{self, Write}, path::{Path, PathBuf}, }; use clap::{Parser, Subcommand}; use color_eyre::{ eyre::{self, Context}, - Help, Report, + Help, }; use crate::quadlet; @@ -33,7 +31,7 @@ use self::{ #[allow(clippy::option_option)] #[derive(Parser, Debug, Clone, PartialEq)] -#[command(author, version, about)] +#[command(author, version, about, subcommand_precedence_over_arg = true)] pub struct Cli { /// Generate a file instead of printing to stdout /// @@ -102,54 +100,74 @@ pub struct Cli { command: Commands, } -impl From for quadlet::File { - fn from(value: Cli) -> Self { - let Commands::Podman { command } = value.command; - let service = command.service().cloned(); - Self { - unit: (!value.unit.is_empty()).then_some(value.unit), - resource: command.into(), - service, - install: value.install.install.then(|| value.install.into()), - } - } -} - impl Cli { - pub fn print_or_write_file(self) -> eyre::Result<()> { + pub fn print_or_write_files(self) -> eyre::Result<()> { if self.unit_directory || self.file.is_some() { let path = self.file_path()?; - let path_display = path.display().to_string(); - let mut file = File::options() - .write(true) - .create_new(!self.overwrite) - .create(self.overwrite) - .open(&path) - .map_err(|error| match error.kind() { - io::ErrorKind::AlreadyExists => { - eyre::eyre!("File already exists, not overwriting it: {path_display}") - .suggestion("Use `--overwrite` if you wish overwrite existing files.") + if matches!(path, FilePath::Full(..)) + && matches!(self.command, Commands::Compose { .. }) + { + return Err(eyre::eyre!( + "A file path was provided to `--file` and the `compose` command was used" + ) + .suggestion( + "Provide a directory to `--file`. \ + `compose` can generate multiple files so a directory is needed.", + )); + } + + let overwrite = self.overwrite; + #[cfg(unix)] + let services_check = !self.skip_services_check; + + let quadlet_files = self.into_quadlet_files(); + + #[cfg(unix)] + if services_check { + for file in &quadlet_files { + match &path { + FilePath::Full(path) => { + if let Some(name) = path.file_stem().and_then(OsStr::to_str) { + let service = file.resource.name_to_service(name); + check_existing(name, &service, overwrite)?; + } + } + FilePath::Dir(_) => { + check_existing(&file.name, &file.service_name(), overwrite)?; + } } - _ => Report::new(error) - .wrap_err(format!("Failed to create/open file: {path_display}")) - .suggestion( - "Make sure the directory exists \ - and you have write permissions for the file", - ), - })?; - write!(file, "{}", quadlet::File::from(self)) - .wrap_err_with(|| format!("Failed to write to file: {path_display}"))?; - println!("Wrote to file: {path_display}"); + } + } + + for file in quadlet_files { + let path: Cow = match &path { + FilePath::Full(path) => path.into(), + FilePath::Dir(path) => { + let mut path = path.clone(); + path.push(&file.name); + path.set_extension(file.resource.extension()); + path.into() + } + }; + file.write(&path, overwrite)?; + } + Ok(()) } else { - print!("{}", quadlet::File::from(self)); + let quadlet_files = self + .into_quadlet_files() + .into_iter() + .map(|file| format!("# {}.{}\n{file}", file.name, file.resource.extension())) + .collect::>() + .join("\n---\n"); + print!("{quadlet_files}"); Ok(()) } } /// Returns the file path for the generated file - fn file_path(&self) -> eyre::Result> { - let mut path = if self.unit_directory { + fn file_path(&self) -> eyre::Result { + let path = if self.unit_directory { #[cfg(unix)] if nix::unistd::Uid::current().is_root() { let path = PathBuf::from("/etc/containers/systemd/"); @@ -175,50 +193,42 @@ impl Cli { if path.is_dir() { path.clone() } else { - if let Some(name) = path.file_stem().and_then(OsStr::to_str) { - self.check_existing(name)?; - } - return Ok(path.into()); + return Ok(FilePath::Full(path.clone())); } } else { env::current_dir() .wrap_err("File path not provided and can't access current directory")? }; - let Commands::Podman { command } = &self.command; - let name = self.name.as_deref().unwrap_or_else(|| command.name()); - self.check_existing(name)?; - - path.push(name); - path.set_extension(command.extension()); - - Ok(path.into()) + Ok(FilePath::Dir(path)) } - fn check_existing(&self, name: &str) -> eyre::Result<()> { - #[cfg(unix)] - if !self.skip_services_check { - if let Ok(unit_files) = systemd_dbus::unit_files() { - let Commands::Podman { command } = &self.command; - let service = command.name_to_service(name); - for systemd_dbus::UnitFile { file_name, status } in unit_files { - if !(self.overwrite && status == "generated") && file_name.contains(&service) { - return Err(eyre::eyre!( - "File name `{name}` conflicts with existing unit file: {file_name}" - ) - .suggestion( - "Change the generated file's name with `--file` or `--name`. \ - Alternatively, use `--skip-services-check` if this is ok.", - )); - } - } + fn into_quadlet_files(self) -> Vec { + let unit = (!self.unit.is_empty()).then_some(self.unit); + let install = self.install.install.then(|| self.install.into()); + match self.command { + Commands::Podman { command } => { + let service = command.service().cloned(); + let file = quadlet::File { + name: self.name.unwrap_or_else(|| String::from(command.name())), + unit, + resource: command.into(), + service, + install, + }; + vec![file] } + Commands::Compose { pod, compose_file } => todo!(), } - - Ok(()) } } +#[derive(Debug)] +enum FilePath { + Full(PathBuf), + Dir(PathBuf), +} + #[derive(Subcommand, Debug, Clone, PartialEq)] enum Commands { /// Generate a podman quadlet file from a podman command @@ -226,6 +236,32 @@ enum Commands { #[command(subcommand)] command: PodmanCommands, }, + + /// Generate podman quadlet files from a compose file + /// + /// Creates a `.container` file for each service, + /// a `.volume` file for each volume, + /// and a `.network` file for each network. + /// + /// The `--file` option must be a directory if used. + /// + /// Some compose options are not supported, such as `build`. + /// + /// When podlet encounters an unsupported option, a warning will be emitted on stderr. + Compose { + /// Create a Kubernetes YAML file for a pod instead of separate containers + /// + /// A `.kube` file using the generated Kubernetes YAML file will also be created. + #[arg(long)] + pod: Option, + + /// The compose file to convert + /// + /// If not provided, podlet will look for (in order) + /// `compose.yaml`, `compose.yml`, `docker-compose.yaml`, and `docker-compose.yml`, + /// in the current working directory. + compose_file: Option, + }, } #[derive(Subcommand, Debug, Clone, PartialEq)] @@ -303,28 +339,25 @@ impl PodmanCommands { Self::Volume { volume } => volume.name(), } } +} - /// Takes a file name (no extension) and returns the corresponding service file name - /// generated by quadlet - fn name_to_service(&self, name: &str) -> String { - let mut service = match self { - Self::Run { .. } | Self::Kube { .. } => String::from(name), - Self::Network { .. } => format!("{name}-network"), - Self::Volume { .. } => format!("{name}-volume"), - }; - service.push_str(".service"); - service - } - - /// Returns the extension that should be used for the generated file - fn extension(&self) -> &'static str { - match self { - Self::Run { .. } => "container", - Self::Kube { .. } => "kube", - Self::Network { .. } => "network", - Self::Volume { .. } => "volume", +#[cfg(unix)] +fn check_existing(name: &str, service: &str, overwrite: bool) -> eyre::Result<()> { + if let Ok(unit_files) = systemd_dbus::unit_files() { + for systemd_dbus::UnitFile { file_name, status } in unit_files { + if !(overwrite && status == "generated") && file_name.contains(service) { + return Err(eyre::eyre!( + "File name `{name}` conflicts with existing unit file: {file_name}" + ) + .suggestion( + "Change the generated file's name with `--file` or `--name`. \ + Alternatively, use `--skip-services-check` if this is ok.", + )); + } } } + + Ok(()) } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 3eefe10..b3b7a32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,5 +27,5 @@ use self::cli::Cli; fn main() -> eyre::Result<()> { color_eyre::install()?; - Cli::parse().print_or_write_file() + Cli::parse().print_or_write_files() } diff --git a/src/quadlet.rs b/src/quadlet.rs index f32bf44..0f350f3 100644 --- a/src/quadlet.rs +++ b/src/quadlet.rs @@ -7,6 +7,14 @@ mod volume; use std::{ borrow::Cow, fmt::{self, Display, Formatter}, + fs, + io::{self, Write}, + path::Path, +}; + +use color_eyre::{ + eyre::{self, WrapErr}, + Help, Report, }; pub use self::{ @@ -16,6 +24,7 @@ use crate::cli::{service::Service, unit::Unit}; #[derive(Debug, Clone, PartialEq)] pub struct File { + pub name: String, pub unit: Option, pub resource: Resource, pub service: Option, @@ -42,14 +51,35 @@ impl Display for File { } } -impl From for File { - fn from(value: Resource) -> Self { - Self { - unit: None, - resource: value, - service: None, - install: None, - } +impl File { + pub fn write(&self, path: impl AsRef, overwrite: bool) -> eyre::Result<()> { + let path_display = path.as_ref().display().to_string(); + let mut file = fs::File::options() + .write(true) + .create_new(!overwrite) + .create(overwrite) + .open(path) + .map_err(|error| match error.kind() { + io::ErrorKind::AlreadyExists => { + eyre::eyre!("File already exists, not overwriting it: {path_display}") + .suggestion("Use `--overwrite` if you wish overwrite existing files.") + } + _ => Report::new(error) + .wrap_err(format!("Failed to create/open file: {path_display}")) + .suggestion( + "Make sure the directory exists \ + and you have write permissions for the file", + ), + })?; + write!(file, "{self}") + .wrap_err_with(|| format!("Failed to write to file: {path_display}"))?; + println!("Wrote to file: {path_display}"); + Ok(()) + } + + /// Returns the corresponding service file name generated by quadlet + pub fn service_name(&self) -> String { + self.resource.name_to_service(&self.name) } } @@ -102,6 +132,30 @@ impl From for Resource { } } +impl Resource { + /// Returns the extension that should be used for the generated file + pub fn extension(&self) -> &'static str { + match self { + Self::Container { .. } => "container", + Self::Kube { .. } => "kube", + Self::Network { .. } => "network", + Self::Volume { .. } => "volume", + } + } + + /// Takes a file name (no extension) and returns the corresponding service file name + /// generated by quadlet + pub fn name_to_service(&self, name: &str) -> String { + let mut service = match self { + Self::Container { .. } | Self::Kube { .. } => String::from(name), + Self::Network { .. } => format!("{name}-network"), + Self::Volume { .. } => format!("{name}-volume"), + }; + service.push_str(".service"); + service + } +} + fn escape_spaces_join<'a>(words: impl IntoIterator) -> String { words .into_iter() From b5dade2b689a88cc908879ea5677c385f271af4a Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Wed, 3 May 2023 08:05:13 -0500 Subject: [PATCH 03/14] Compose services to `.container` files --- Cargo.lock | 54 ++++++++ Cargo.toml | 2 + src/cli.rs | 136 +++++++++++++++++-- src/cli/container.rs | 58 ++++++-- src/cli/container/podman.rs | 80 ++++++++++- src/cli/container/quadlet.rs | 254 ++++++++++++++++++++++++++++++++++- src/cli/service.rs | 15 +++ src/cli/unit.rs | 15 +++ src/quadlet/container.rs | 2 +- 9 files changed, 594 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0d29ab..6aff489 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "async-broadcast" version = "0.5.1" @@ -465,6 +471,17 @@ dependencies = [ "serde_yaml", ] +[[package]] +name = "duration-str" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f94be4825ff6a563f1bfbdb786ae10c687333c7524fade954e2271170e7f7e6d" +dependencies = [ + "nom", + "rust_decimal", + "thiserror", +] + [[package]] name = "enumflags2" version = "0.7.7" @@ -772,6 +789,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.6.2" @@ -794,6 +817,25 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.30.3" @@ -856,6 +898,8 @@ dependencies = [ "clap", "color-eyre", "docker-compose-types", + "duration-str", + "indexmap", "ipnet", "nix", "serde_yaml", @@ -971,6 +1015,16 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +[[package]] +name = "rust_decimal" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" +dependencies = [ + "arrayvec", + "num-traits", +] + [[package]] name = "rustc-demangle" version = "0.1.22" diff --git a/Cargo.toml b/Cargo.toml index 04aa578..87509b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,8 @@ categories = ["command-line-utilities"] clap = { version = "4.2", features = ["derive"] } color-eyre = "0.6" docker-compose-types = "0.4.1" +duration-str = { version = "0.5", default-features = false } +indexmap = { version = "1.9", features = ["std"] } ipnet = "2.7" serde_yaml = "0.9.21" shlex = "1.1" diff --git a/src/cli.rs b/src/cli.rs index a50f440..93e3dca 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -13,6 +13,7 @@ use std::{ borrow::Cow, env, ffi::OsStr, + fs::File, path::{Path, PathBuf}, }; @@ -21,6 +22,8 @@ use color_eyre::{ eyre::{self, Context}, Help, }; +use docker_compose_types::Compose; +use indexmap::IndexMap; use crate::quadlet; @@ -120,7 +123,7 @@ impl Cli { #[cfg(unix)] let services_check = !self.skip_services_check; - let quadlet_files = self.into_quadlet_files(); + let quadlet_files = self.into_quadlet_files()?; #[cfg(unix)] if services_check { @@ -143,8 +146,7 @@ impl Cli { let path: Cow = match &path { FilePath::Full(path) => path.into(), FilePath::Dir(path) => { - let mut path = path.clone(); - path.push(&file.name); + let mut path = path.join(&file.name); path.set_extension(file.resource.extension()); path.into() } @@ -155,11 +157,11 @@ impl Cli { Ok(()) } else { let quadlet_files = self - .into_quadlet_files() + .into_quadlet_files()? .into_iter() .map(|file| format!("# {}.{}\n{file}", file.name, file.resource.extension())) .collect::>() - .join("\n---\n"); + .join("\n---\n\n"); print!("{quadlet_files}"); Ok(()) } @@ -203,9 +205,10 @@ impl Cli { Ok(FilePath::Dir(path)) } - fn into_quadlet_files(self) -> Vec { + fn into_quadlet_files(self) -> color_eyre::Result> { let unit = (!self.unit.is_empty()).then_some(self.unit); let install = self.install.install.then(|| self.install.into()); + match self.command { Commands::Podman { command } => { let service = command.service().cloned(); @@ -216,9 +219,42 @@ impl Cli { service, install, }; - vec![file] + Ok(vec![file]) + } + Commands::Compose { pod, compose_file } => { + let mut compose = compose_from_file(&compose_file)?; + + let services = compose_services(&mut compose)?; + + if let Some(pod_name) = pod { + todo!(); + } else { + let mut files = Vec::with_capacity(services.len()); // TODO: add other file types + for (name, mut service) in services { + let mut unit = unit.clone(); + if let Some(depends_on) = service.depends_on.take() { + let unit = unit.get_or_insert(Unit::default()); + unit.add_dependencies(depends_on); + } + + let command: PodmanCommands = service.try_into().wrap_err_with(|| { + format!("Could not parse service `{name}` as a valid podman command") + })?; + + let service = command.service().cloned(); + + let file = quadlet::File { + name, + unit, + resource: command.into(), + service, + install: install.clone(), + }; + files.push(file); + } + Ok(files) + } } - Commands::Compose { pod, compose_file } => todo!(), } } } @@ -247,7 +283,8 @@ enum Commands { /// /// Some compose options are not supported, such as `build`. /// - /// When podlet encounters an unsupported option, a warning will be emitted on stderr. + /// When podlet encounters an unsupported option, an error will be returned. + /// Modify the compose file to resolve the error. Compose { /// Create a Kubernetes YAML file for a pod instead of separate containers /// @@ -311,6 +348,18 @@ enum PodmanCommands { }, } +impl TryFrom for PodmanCommands { + type Error = color_eyre::Report; + + fn try_from(value: docker_compose_types::Service) -> Result { + let service = (&value).try_into()?; + Ok(Self::Run { + container: Box::new(value.try_into()?), + service, + }) + } +} + impl From for quadlet::Resource { fn from(value: PodmanCommands) -> Self { match value { @@ -341,6 +390,75 @@ impl PodmanCommands { } } +fn compose_from_file(compose_file: &Option) -> color_eyre::Result { + let (compose_file, path) = if let Some(path) = compose_file { + let compose_file = File::open(path) + .wrap_err("Could not open provided compose file") + .suggestion("Make sure you have the proper permissions for the given file.")?; + (compose_file, path.display().to_string()) + } else { + let file_names = [ + "compose.yaml", + "compose.yml", + "docker-compose.yaml", + "docker-compose.yml", + ]; + let mut result = None; + for file_name in file_names { + if let Ok(compose_file) = File::open(file_name) { + result = Some((compose_file, String::from(file_name))); + break; + } + } + result.ok_or(eyre::eyre!("A compose file was not provided and none of \ + `compose.yaml`, `compose.yml`, `docker-compose.yaml`, or `docker-compose.yml` \ + exist in the current directory or could not be read"))? + }; + + serde_yaml::from_reader(compose_file) + .wrap_err_with(|| format!("File `{path}` is not a valid compose file")) +} + +fn compose_services( + compose: &mut Compose, +) -> color_eyre::Result> { + let mut services: IndexMap<_, _> = compose + .services + .take() + .map(|services| { + services + .0 + .into_iter() + .map(|(name, service)| { + service + .ok_or_else(|| { + eyre::eyre!( + "Service `{name}` does not have any corresponding options; \ + minimally, `image` is required" + ) + }) + .map(|service| (name, service)) + }) + .collect() + }) + .transpose()? + .unwrap_or_default(); + if let Some(service) = compose.service.take() { + services.insert(String::from(image_to_name(service.image())), service); + } + Ok(services) +} + +/// Takes an image and returns an appropriate default service name +fn image_to_name(image: &str) -> &str { + let image = image + .rsplit('/') + .next() + .expect("Split will have at least one element"); + // Remove image tag + image.split_once(':').map_or(image, |(name, _)| name) +} + #[cfg(unix)] fn check_existing(name: &str, service: &str, overwrite: bool) -> eyre::Result<()> { if let Ok(unit_files) = systemd_dbus::unit_files() { diff --git a/src/cli/container.rs b/src/cli/container.rs index 209053b..6f6ce3b 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -3,8 +3,10 @@ mod quadlet; mod security_opt; use clap::Args; +use color_eyre::eyre; use self::{podman::PodmanArgs, quadlet::QuadletOptions, security_opt::SecurityOpt}; +use super::image_to_name; #[derive(Args, Default, Debug, Clone, PartialEq)] pub struct Container { @@ -37,6 +39,49 @@ pub struct Container { command: Vec, } +impl TryFrom for Container { + type Error = color_eyre::Report; + + fn try_from(mut value: docker_compose_types::Service) -> Result { + let unsupported_options = [ + ("deploy", value.deploy.is_some()), + ("build", value.build_.is_some()), + ("profiles", value.profiles.is_some()), + ("links", value.links.is_some()), + ("net", value.net.is_some()), + ("volumes_from", !value.volumes_from.is_empty()), + ("extends", value.extends.is_some()), + ("scale", value.scale != 0), + ]; + for (option, exists) in unsupported_options { + if exists { + return Err(unsupported_option(option)); + } + } + if !value.extensions.is_empty() { + return Err(eyre::eyre!("compose extensions are not supported")); + } + + Ok(Self { + quadlet_options: (&mut value).try_into()?, + podman_args: (&mut value).try_into()?, + security_opt: Vec::new(), + image: value.image.ok_or(eyre::eyre!("image is required"))?, + command: value + .command + .map(|command| match command { + docker_compose_types::Command::Simple(s) => vec![s], + docker_compose_types::Command::Args(args) => args, + }) + .unwrap_or_default(), + }) + } +} + +fn unsupported_option(option: &str) -> color_eyre::Report { + eyre::eyre!("`{option}` is unsupported") +} + impl From for crate::quadlet::Container { fn from(value: Container) -> Self { let mut podman_args = value.podman_args.to_string(); @@ -73,15 +118,10 @@ impl From for crate::quadlet::Resource { impl Container { pub fn name(&self) -> &str { - self.quadlet_options.name.as_deref().unwrap_or_else(|| { - let image = self - .image - .rsplit('/') - .next() - .expect("Split will have at least one element"); - // Remove image tag - image.split_once(':').map_or(image, |(name, _)| name) - }) + self.quadlet_options + .name + .as_deref() + .unwrap_or_else(|| image_to_name(&self.image)) } } diff --git a/src/cli/container/podman.rs b/src/cli/container/podman.rs index 58ce867..9c3cc43 100644 --- a/src/cli/container/podman.rs +++ b/src/cli/container/podman.rs @@ -4,6 +4,7 @@ use std::{ }; use clap::{ArgAction, Args}; +use color_eyre::eyre::Context; #[allow(clippy::struct_excessive_bools, clippy::module_name_repetitions)] #[derive(Args, Default, Debug, Clone, PartialEq)] @@ -150,7 +151,7 @@ pub struct PodmanArgs { /// Set custom DNS servers #[arg(long, value_name = "IP_ADDRESS")] - dns: Option, + dns: Vec, /// Set custom DNS options #[arg(long, value_name = "OPTION")] @@ -468,7 +469,7 @@ impl PodmanArgs { + self.device_read_iops.len() + self.device_write_bps.len() + self.device_write_iops.len() - + self.dns.iter().len() + + self.dns.len() + self.dns_option.iter().len() + self.dns_search.iter().len() + self.entrypoint.iter().len() @@ -794,3 +795,78 @@ impl Display for PodmanArgs { write!(f, "{}", shlex::join(args)) } } + +impl TryFrom for PodmanArgs { + type Error = color_eyre::Report; + + fn try_from(mut value: docker_compose_types::Service) -> Result { + (&mut value).try_into() + } +} + +impl TryFrom<&mut docker_compose_types::Service> for PodmanArgs { + type Error = color_eyre::Report; + + fn try_from(value: &mut docker_compose_types::Service) -> Result { + let ulimit = value.ulimits.take().map(|ulimits| { + let docker_compose_types::Ulimits { + nofile: docker_compose_types::Nofile { soft, hard }, + } = ulimits; + if hard == 0 { + format!("nofile={soft}") + } else { + format!("nofile={soft}:{hard}") + } + }); + + let entrypoint = value.entrypoint.take().map(|entrypoint| match entrypoint { + docker_compose_types::Entrypoint::Simple(entrypoint) => entrypoint, + docker_compose_types::Entrypoint::List(list) => format!("{list:?}"), + }); + + let stop_timeout = value + .stop_grace_period + .take() + .map(|timeout| { + duration_str::parse(&timeout) + .map(|duration| duration.as_secs().try_into().unwrap_or(u16::MAX)) + .wrap_err_with(|| { + format!( + "could not parse `stop_grace_period` value `{timeout}` as a duration" + ) + }) + }) + .transpose()?; + + let log_opt = value + .logging + .as_mut() + .and_then(|logging| { + logging + .options + .take() + .map(|options| format!("max-size={}", options.max_size)) + }) + .into_iter() + .collect(); + + Ok(Self { + hostname: value.hostname.take(), + privileged: value.privileged, + pid: value.pid.take(), + ulimit, + entrypoint, + stop_signal: value.stop_signal.take(), + stop_timeout, + dns: value.dns.take().unwrap_or_default(), + ipc: value.ipc.take(), + workdir: value.working_dir.take().map(Into::into), + interactive: value.stdin_open, + shm_size: value.shm_size.take(), + log_opt, + add_host: value.extra_hosts.take().unwrap_or_default(), + tty: value.tty.take().unwrap_or_default(), + ..Self::default() + }) + } +} diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index e4f432a..8b8ea08 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -5,6 +5,8 @@ use std::{ use clap::{Args, ValueEnum}; +use super::unsupported_option; + #[allow(clippy::module_name_repetitions)] #[derive(Args, Default, Debug, Clone, PartialEq)] pub struct QuadletOptions { @@ -102,7 +104,7 @@ pub struct QuadletOptions { /// /// Converts to "HealthRetries=RETRIES" #[arg(long, value_name = "RETRIES")] - health_retries: Option, + health_retries: Option, /// The initialization time needed for the container to bootstrap /// @@ -353,3 +355,253 @@ impl From for crate::quadlet::Container { } } } + +impl TryFrom for QuadletOptions { + type Error = color_eyre::Report; + + fn try_from(mut value: docker_compose_types::Service) -> Result { + (&mut value).try_into() + } +} + +impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { + type Error = color_eyre::Report; + + fn try_from(value: &mut docker_compose_types::Service) -> Result { + let Healthcheck { + health_cmd, + health_interval, + health_timeout, + health_retries, + health_start_period, + } = value + .healthcheck + .take() + .map(Healthcheck::from) + .unwrap_or_default(); + + let env = value + .environment + .take() + .map(|env| match env { + docker_compose_types::Environment::List(list) => list, + docker_compose_types::Environment::KvPair(map) => map + .into_iter() + .map(|(key, value)| { + let value = value + .map(|value| match value { + docker_compose_types::EnvTypes::String(string) => string, + docker_compose_types::EnvTypes::Number(num) => num.to_string(), + docker_compose_types::EnvTypes::Bool(bool) => bool.to_string(), + docker_compose_types::EnvTypes::Null => String::new(), + }) + .unwrap_or_default(); + format!("{key}={value}") + }) + .collect(), + }) + .unwrap_or_default(); + + let network = value + .network_mode + .take() + .map(|mode| match mode.as_str() { + "bridge" | "host" | "none" => Ok(mode), + s if s.starts_with("container") => Ok(mode), + _ => Err(unsupported_option(&format!("network_mode: {mode}"))), + }) + .into_iter() + .chain( + value + .networks + .take() + .map(map_networks) + .unwrap_or_default() + .into_iter() + .map(Ok), + ) + .collect::>()?; + + let label = value + .labels + .take() + .map(|labels| { + labels + .0 + .into_iter() + .map(|(key, value)| format!("{key}={value}")) + .collect() + }) + .unwrap_or_default(); + + let mut tmpfs = Vec::new(); + + let volume = value + .volumes + .take() + .map(|volumes| volumes_to_short(volumes, &mut tmpfs)) + .unwrap_or_default(); + + let env_file = value + .env_file + .take() + .map(|env_file| match env_file { + docker_compose_types::EnvFile::Simple(s) => vec![s.into()], + docker_compose_types::EnvFile::List(list) => { + list.into_iter().map(Into::into).collect() + } + }) + .unwrap_or_default(); + + Ok(Self { + cap_add: value.cap_add.take().unwrap_or_default(), + name: value.container_name.take(), + publish: value.ports.take().unwrap_or_default(), + env, + env_file, + network, + device: value.devices.take().unwrap_or_default(), + label, + health_cmd, + health_interval, + health_retries, + health_start_period, + health_timeout, + tmpfs, + user: value.user.take(), + expose: value.expose.drain(..).collect(), + log_driver: value.logging.as_ref().map(|logging| logging.driver.clone()), + init: value.init, + volume, + ..Self::default() + }) + } +} + +#[derive(Debug, Default, Clone, PartialEq)] +struct Healthcheck { + health_cmd: Option, + health_interval: Option, + health_timeout: Option, + health_retries: Option, + health_start_period: Option, +} + +impl From for Healthcheck { + fn from(value: docker_compose_types::Healthcheck) -> Self { + let docker_compose_types::Healthcheck { + test, + interval, + timeout, + retries, + start_period, + mut disable, + } = value; + + let mut command = test.and_then(|test| match test { + docker_compose_types::HealthcheckTest::Single(s) => Some(s), + docker_compose_types::HealthcheckTest::Multiple(test) => { + match test.first().map(String::as_str) { + Some("NONE") => { + disable = true; + None + } + Some("CMD") => Some(format!("{:?}", &test[1..])), + Some("CMD-SHELL") => Some(shlex::join(test[1..].iter().map(String::as_str))), + _ => None, + } + } + }); + + if disable { + command = Some(String::from("none")); + } + + let retries = (retries > 0).then(|| u32::try_from(retries).unwrap_or_default()); + Self { + health_cmd: command, + health_interval: interval, + health_timeout: timeout, + health_retries: retries, + health_start_period: start_period, + } + } +} + +fn volumes_to_short( + volumes: docker_compose_types::Volumes, + tmpfs: &mut Vec, +) -> Vec { + match volumes { + docker_compose_types::Volumes::Simple(volumes) => volumes + .into_iter() + .map(|volume| match volume.split_once(':') { + Some((source, target)) if !source.starts_with(['.', '/', '~']) => { + format!("{source}.volume:{target}") + } + _ => volume, + }) + .collect(), + docker_compose_types::Volumes::Advanced(volumes) => volumes + .into_iter() + .filter_map(|volume| { + let docker_compose_types::AdvancedVolumes { + source, + target, + _type: kind, + read_only, + volume, + } = volume; + + if kind == "tmpfs" { + tmpfs.push(target); + None + } else { + let source = source + .map(|source| { + if kind == "bind" { + source + ":" + } else { + source + ".volume:" + } + }) + .unwrap_or_default(); + + let mut options = Vec::new(); + if read_only { + options.push("ro"); + } + if let Some(docker_compose_types::Volume { nocopy: true }) = volume { + options.push("nocopy"); + } + let options = if options.is_empty() { + String::new() + } else { + format!(":{}", options.join(",")) + }; + + Some(format!("{source}{target}{options}")) + } + }) + .collect(), + } +} + +fn map_networks(networks: docker_compose_types::Networks) -> Vec { + match networks { + docker_compose_types::Networks::Simple(networks) => networks + .into_iter() + .map(|network| network + ".network") + .collect(), + docker_compose_types::Networks::Advanced(networks) => networks + .0 + .into_iter() + .map(|(network, settings)| { + let options = settings + .map(|settings| format!(":ip={}", settings.ipv4_address)) + .unwrap_or_default(); + format!("{network}.network{options}") + }) + .collect(), + } +} diff --git a/src/cli/service.rs b/src/cli/service.rs index a46b9ad..503d95c 100644 --- a/src/cli/service.rs +++ b/src/cli/service.rs @@ -1,6 +1,7 @@ use std::fmt::{self, Display, Formatter}; use clap::{Args, ValueEnum}; +use color_eyre::eyre; #[derive(Args, Default, Debug, Clone, PartialEq, Eq)] pub struct Service { @@ -25,6 +26,20 @@ impl Display for Service { } } +impl TryFrom<&docker_compose_types::Service> for Service { + type Error = color_eyre::Report; + + fn try_from(value: &docker_compose_types::Service) -> Result { + let restart = value + .restart + .as_ref() + .map(|s| RestartConfig::from_str(s, true)) + .transpose() + .map_err(|error| eyre::eyre!("Service's restart value is invalid: {error}"))?; + Ok(Self { restart }) + } +} + /// Possible service restart configurations /// /// From [systemd.service](https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=) diff --git a/src/cli/unit.rs b/src/cli/unit.rs index 8d4209f..13b422a 100644 --- a/src/cli/unit.rs +++ b/src/cli/unit.rs @@ -51,6 +51,21 @@ impl Unit { pub fn is_empty(&self) -> bool { *self == Self::default() } + + pub fn add_dependencies(&mut self, depends_on: docker_compose_types::DependsOnOptions) { + let depends_on = match depends_on { + docker_compose_types::DependsOnOptions::Simple(depends_on) => depends_on, + docker_compose_types::DependsOnOptions::Conditional(depends_on) => { + depends_on.into_keys().collect() + } + }; + + self.requires.extend( + depends_on + .into_iter() + .map(|dependency| dependency + ".service"), + ); + } } impl Display for Unit { diff --git a/src/quadlet/container.rs b/src/quadlet/container.rs index 93a5276..8f437a4 100644 --- a/src/quadlet/container.rs +++ b/src/quadlet/container.rs @@ -23,7 +23,7 @@ pub struct Container { pub health_cmd: Option, pub health_interval: Option, pub health_on_failure: Option, - pub health_retries: Option, + pub health_retries: Option, pub health_start_period: Option, pub health_startup_cmd: Option, pub health_startup_interval: Option, From bbd1f69b86da45a1ae47ab5fcfb5ba8915e5cf54 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Wed, 3 May 2023 10:09:57 -0500 Subject: [PATCH 04/14] Get unit files for checking for conflicts only once --- src/cli.rs | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 93e3dca..eb54d82 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -127,19 +127,7 @@ impl Cli { #[cfg(unix)] if services_check { - for file in &quadlet_files { - match &path { - FilePath::Full(path) => { - if let Some(name) = path.file_stem().and_then(OsStr::to_str) { - let service = file.resource.name_to_service(name); - check_existing(name, &service, overwrite)?; - } - } - FilePath::Dir(_) => { - check_existing(&file.name, &file.service_name(), overwrite)?; - } - } - } + check_existing(&quadlet_files, &path, overwrite)?; } for file in quadlet_files { @@ -460,17 +448,33 @@ fn image_to_name(image: &str) -> &str { } #[cfg(unix)] -fn check_existing(name: &str, service: &str, overwrite: bool) -> eyre::Result<()> { - if let Ok(unit_files) = systemd_dbus::unit_files() { +fn check_existing( + quadlet_files: &[quadlet::File], + path: &FilePath, + overwrite: bool, +) -> eyre::Result<()> { + if let Ok(unit_files) = systemd_dbus::unit_files().map(Iterator::collect::>) { + let file_names: Vec<_> = quadlet_files + .iter() + .filter_map(|file| match &path { + FilePath::Full(path) => path.file_stem().and_then(OsStr::to_str).map(|name| { + let service = file.resource.name_to_service(name); + (name, service) + }), + FilePath::Dir(_) => Some((file.name.as_str(), file.service_name())), + }) + .collect(); for systemd_dbus::UnitFile { file_name, status } in unit_files { - if !(overwrite && status == "generated") && file_name.contains(service) { - return Err(eyre::eyre!( - "File name `{name}` conflicts with existing unit file: {file_name}" - ) - .suggestion( - "Change the generated file's name with `--file` or `--name`. \ + for (name, service) in &file_names { + if !(overwrite && status == "generated") && file_name.contains(service) { + return Err(eyre::eyre!( + "File name `{name}` conflicts with existing unit file: {file_name}" + ) + .suggestion( + "Change the generated file's name with `--file` or `--name`. \ Alternatively, use `--skip-services-check` if this is ok.", - )); + )); + } } } } From b789dfe1caeebd00aec958a86c51292a2dce94cf Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Sun, 21 May 2023 14:37:59 -0500 Subject: [PATCH 05/14] chore: update docker-compose-types dependency --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/cli.rs | 48 ++++--- src/cli/container.rs | 18 ++- src/cli/container/podman.rs | 66 ++++++---- src/cli/container/quadlet.rs | 249 +++++++++++++++++++++++------------ src/cli/unit.rs | 6 +- 7 files changed, 248 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6aff489..fdf472a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "docker-compose-types" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee50caf01e7a34feba906df016260b8850ccc7f5b3cf3a7e7841349af071e8b" +checksum = "48837264ee035ee6c652881fc5e1c9429d488db97e57bad4057bcc769454bf6f" dependencies = [ "derive_builder", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index 87509b7..ac27631 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ categories = ["command-line-utilities"] [dependencies] clap = { version = "4.2", features = ["derive"] } color-eyre = "0.6" -docker-compose-types = "0.4.1" +docker-compose-types = "0.5" duration-str = { version = "0.5", default-features = false } indexmap = { version = "1.9", features = ["std"] } ipnet = "2.7" diff --git a/src/cli.rs b/src/cli.rs index eb54d82..363ffd2 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -14,6 +14,7 @@ use std::{ env, ffi::OsStr, fs::File, + mem, path::{Path, PathBuf}, }; @@ -220,9 +221,9 @@ impl Cli { let mut files = Vec::with_capacity(services.len()); // TODO: add other file types for (name, mut service) in services { let mut unit = unit.clone(); - if let Some(depends_on) = service.depends_on.take() { - let unit = unit.get_or_insert(Unit::default()); - unit.add_dependencies(depends_on); + if !service.depends_on.is_empty() { + unit.get_or_insert(Unit::default()) + .add_dependencies(mem::take(&mut service.depends_on)); } let command: PodmanCommands = service.try_into().wrap_err_with(|| { @@ -398,9 +399,13 @@ fn compose_from_file(compose_file: &Option) -> color_eyre::Result) -> color_eyre::Result color_eyre::Result> { - let mut services: IndexMap<_, _> = compose - .services - .take() - .map(|services| { - services - .0 - .into_iter() - .map(|(name, service)| { - service - .ok_or_else(|| { - eyre::eyre!( - "Service `{name}` does not have any corresponding options; \ - minimally, `image` is required" - ) - }) - .map(|service| (name, service)) - }) - .collect() + let mut services: IndexMap<_, _> = mem::take(&mut compose.services.0) + .into_iter() + .map(|(name, service)| { + let service_name = name.clone(); + service.map(|service| (name, service)).ok_or_else(|| { + eyre::eyre!( + "Service `{service_name}` does not have any corresponding options; \ + minimally, `image` is required" + ) + }) }) - .transpose()? - .unwrap_or_default(); + .collect::>()?; if let Some(service) = compose.service.take() { services.insert(String::from(image_to_name(service.image())), service); } diff --git a/src/cli/container.rs b/src/cli/container.rs index 6f6ce3b..408c98b 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -2,8 +2,10 @@ mod podman; mod quadlet; mod security_opt; +use std::mem; + use clap::Args; -use color_eyre::eyre; +use color_eyre::eyre::{self, Context}; use self::{podman::PodmanArgs, quadlet::QuadletOptions, security_opt::SecurityOpt}; use super::image_to_name; @@ -46,11 +48,11 @@ impl TryFrom for Container { let unsupported_options = [ ("deploy", value.deploy.is_some()), ("build", value.build_.is_some()), - ("profiles", value.profiles.is_some()), - ("links", value.links.is_some()), + ("profiles", !value.profiles.is_empty()), + ("links", !value.links.is_empty()), ("net", value.net.is_some()), ("volumes_from", !value.volumes_from.is_empty()), - ("extends", value.extends.is_some()), + ("extends", !value.extends.is_empty()), ("scale", value.scale != 0), ]; for (option, exists) in unsupported_options { @@ -62,10 +64,16 @@ impl TryFrom for Container { return Err(eyre::eyre!("compose extensions are not supported")); } + let security_opt = mem::take(&mut value.security_opt) + .into_iter() + .map(|s| s.parse()) + .collect::>() + .wrap_err("invalid security option")?; + Ok(Self { quadlet_options: (&mut value).try_into()?, podman_args: (&mut value).try_into()?, - security_opt: Vec::new(), + security_opt, image: value.image.ok_or(eyre::eyre!("image is required"))?, command: value .command diff --git a/src/cli/container/podman.rs b/src/cli/container/podman.rs index 9c3cc43..d481fce 100644 --- a/src/cli/container/podman.rs +++ b/src/cli/container/podman.rs @@ -1,5 +1,6 @@ use std::{ fmt::{self, Display, Formatter}, + mem, path::{Path, PathBuf}, }; @@ -388,8 +389,10 @@ pub struct PodmanArgs { subuidname: Option, /// Configure namespaced kernel parameters at runtime + /// + /// Can be specified multiple times #[arg(long, value_name = "NAME=VALUE")] - sysctl: Option, + sysctl: Vec, /// Run container in systemd mode /// @@ -416,8 +419,10 @@ pub struct PodmanArgs { uidmap: Vec, /// Ulimit options + /// + /// Can be specified multiple times #[arg(long, value_name = "OPTION")] - ulimit: Option, + ulimit: Vec, /// Set the umask inside the container #[arg(long)] @@ -514,12 +519,12 @@ impl PodmanArgs { + self.stop_timeout.iter().len() + self.subgidname.iter().len() + self.subuidname.iter().len() - + self.sysctl.iter().len() + + self.sysctl.len() + self.systemd.iter().len() + self.timeout.iter().len() + self.tls_verify.iter().len() + self.uidmap.len() - + self.ulimit.iter().len() + + self.ulimit.len() + self.umask.iter().len() + self.variant.iter().len() + self.volumes_from.len() @@ -808,16 +813,20 @@ impl TryFrom<&mut docker_compose_types::Service> for PodmanArgs { type Error = color_eyre::Report; fn try_from(value: &mut docker_compose_types::Service) -> Result { - let ulimit = value.ulimits.take().map(|ulimits| { - let docker_compose_types::Ulimits { - nofile: docker_compose_types::Nofile { soft, hard }, - } = ulimits; - if hard == 0 { - format!("nofile={soft}") - } else { - format!("nofile={soft}:{hard}") - } - }); + let ulimit = mem::take(&mut value.ulimits) + .0 + .into_iter() + .map(|(kind, ulimit)| match ulimit { + docker_compose_types::Ulimit::Single(soft) => format!("{kind}={soft}"), + docker_compose_types::Ulimit::SoftHard { soft, hard } => { + if hard == 0 { + format!("{kind}={soft}") + } else { + format!("{kind}={soft}:{hard}") + } + } + }) + .collect(); let entrypoint = value.entrypoint.take().map(|entrypoint| match entrypoint { docker_compose_types::Entrypoint::Simple(entrypoint) => entrypoint, @@ -841,15 +850,25 @@ impl TryFrom<&mut docker_compose_types::Service> for PodmanArgs { let log_opt = value .logging .as_mut() - .and_then(|logging| { - logging - .options - .take() - .map(|options| format!("max-size={}", options.max_size)) - }) + .and_then(|logging| logging.options.take()) + .unwrap_or_default() .into_iter() + .map(|(key, value)| format!("{key}={value}")) .collect(); + let sysctl = match mem::take(&mut value.sysctls) { + docker_compose_types::SysCtls::List(vec) => vec, + docker_compose_types::SysCtls::Map(map) => map + .into_iter() + .map(|(key, value)| { + let value = value + .as_ref() + .map_or_else(|| String::from("null"), ToString::to_string); + format!("{key}={value}") + }) + .collect(), + }; + Ok(Self { hostname: value.hostname.take(), privileged: value.privileged, @@ -858,14 +877,15 @@ impl TryFrom<&mut docker_compose_types::Service> for PodmanArgs { entrypoint, stop_signal: value.stop_signal.take(), stop_timeout, - dns: value.dns.take().unwrap_or_default(), + dns: mem::take(&mut value.dns), ipc: value.ipc.take(), workdir: value.working_dir.take().map(Into::into), interactive: value.stdin_open, shm_size: value.shm_size.take(), log_opt, - add_host: value.extra_hosts.take().unwrap_or_default(), - tty: value.tty.take().unwrap_or_default(), + add_host: mem::take(&mut value.extra_hosts), + tty: value.tty, + sysctl, ..Self::default() }) } diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index 8b8ea08..761e3ad 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -1,9 +1,12 @@ use std::{ + mem, net::{Ipv4Addr, Ipv6Addr}, path::PathBuf, }; use clap::{Args, ValueEnum}; +use color_eyre::eyre::{self, Context}; +use docker_compose_types::MapOrEmpty; use super::unsupported_option; @@ -380,27 +383,19 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { .map(Healthcheck::from) .unwrap_or_default(); - let env = value - .environment - .take() - .map(|env| match env { - docker_compose_types::Environment::List(list) => list, - docker_compose_types::Environment::KvPair(map) => map - .into_iter() - .map(|(key, value)| { - let value = value - .map(|value| match value { - docker_compose_types::EnvTypes::String(string) => string, - docker_compose_types::EnvTypes::Number(num) => num.to_string(), - docker_compose_types::EnvTypes::Bool(bool) => bool.to_string(), - docker_compose_types::EnvTypes::Null => String::new(), - }) - .unwrap_or_default(); - format!("{key}={value}") - }) - .collect(), - }) - .unwrap_or_default(); + let publish = + ports_try_into_publish(mem::take(&mut value.ports)).wrap_err("invalid port")?; + + let env = match mem::take(&mut value.environment) { + docker_compose_types::Environment::List(list) => list, + docker_compose_types::Environment::KvPair(map) => map + .into_iter() + .map(|(key, value)| { + let value = value.as_ref().map(ToString::to_string).unwrap_or_default(); + format!("{key}={value}") + }) + .collect(), + }; let network = value .network_mode @@ -410,37 +405,32 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { s if s.starts_with("container") => Ok(mode), _ => Err(unsupported_option(&format!("network_mode: {mode}"))), }) + .transpose()? .into_iter() - .chain( - value - .networks - .take() - .map(map_networks) - .unwrap_or_default() - .into_iter() - .map(Ok), - ) - .collect::>()?; - - let label = value - .labels + .chain(map_networks(mem::take(&mut value.networks))) + .collect(); + + let label = match mem::take(&mut value.labels) { + docker_compose_types::Labels::List(vec) => vec, + docker_compose_types::Labels::Map(map) => map + .into_iter() + .map(|(key, value)| format!("{key}={value}")) + .collect(), + }; + + let mut tmpfs = value + .tmpfs .take() - .map(|labels| { - labels - .0 - .into_iter() - .map(|(key, value)| format!("{key}={value}")) - .collect() + .map(|tmpfs| match tmpfs { + docker_compose_types::Tmpfs::Simple(tmpfs) => vec![tmpfs], + docker_compose_types::Tmpfs::List(tmpfs) => tmpfs, }) .unwrap_or_default(); - let mut tmpfs = Vec::new(); + let mut mount = Vec::new(); - let volume = value - .volumes - .take() - .map(|volumes| volumes_to_short(volumes, &mut tmpfs)) - .unwrap_or_default(); + let volume = volumes_try_into_short(mem::take(&mut value.volumes), &mut tmpfs, &mut mount) + .wrap_err("invalid volume")?; let env_file = value .env_file @@ -454,13 +444,13 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { .unwrap_or_default(); Ok(Self { - cap_add: value.cap_add.take().unwrap_or_default(), + cap_add: mem::take(&mut value.cap_add), name: value.container_name.take(), - publish: value.ports.take().unwrap_or_default(), + publish, env, env_file, network, - device: value.devices.take().unwrap_or_default(), + device: mem::take(&mut value.devices), label, health_cmd, health_interval, @@ -468,9 +458,13 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { health_start_period, health_timeout, tmpfs, + mount, user: value.user.take(), - expose: value.expose.drain(..).collect(), - log_driver: value.logging.as_ref().map(|logging| logging.driver.clone()), + expose: mem::take(&mut value.expose), + log_driver: value + .logging + .as_mut() + .map(|logging| mem::take(&mut logging.driver)), init: value.init, volume, ..Self::default() @@ -528,12 +522,51 @@ impl From for Healthcheck { } } -fn volumes_to_short( +fn ports_try_into_publish(ports: docker_compose_types::Ports) -> color_eyre::Result> { + match ports { + docker_compose_types::Ports::Short(ports) => Ok(ports), + docker_compose_types::Ports::Long(ports) => ports + .into_iter() + .map(|port| { + let docker_compose_types::Port { + target, + host_ip, + published, + protocol, + mode, + } = port; + if let Some(mode) = mode { + if mode != "host" { + return Err(eyre::eyre!("unsupported port mode: {mode}")); + } + } + + let host_ip = host_ip.map(|host_ip| host_ip + ":").unwrap_or_default(); + + let host_port = published + .map(|port| match port { + docker_compose_types::PublishedPort::Single(port) => port.to_string(), + docker_compose_types::PublishedPort::Range(range) => range, + } + ":") + .unwrap_or_default(); + + let protocol = protocol + .map(|protocol| format!("/{protocol}")) + .unwrap_or_default(); + + Ok(format!("{host_ip}{host_port}{target}{protocol}")) + }) + .collect(), + } +} + +fn volumes_try_into_short( volumes: docker_compose_types::Volumes, tmpfs: &mut Vec, -) -> Vec { + mount: &mut Vec, +) -> color_eyre::Result> { match volumes { - docker_compose_types::Volumes::Simple(volumes) => volumes + docker_compose_types::Volumes::Simple(volumes) => Ok(volumes .into_iter() .map(|volume| match volume.split_once(':') { Some((source, target)) if !source.starts_with(['.', '/', '~']) => { @@ -541,7 +574,7 @@ fn volumes_to_short( } _ => volume, }) - .collect(), + .collect()), docker_compose_types::Volumes::Advanced(volumes) => volumes .into_iter() .filter_map(|volume| { @@ -550,37 +583,66 @@ fn volumes_to_short( target, _type: kind, read_only, + bind, volume, + tmpfs: tmpfs_settings, } = volume; - if kind == "tmpfs" { - tmpfs.push(target); - None - } else { - let source = source - .map(|source| { - if kind == "bind" { - source + ":" - } else { - source + ".volume:" - } - }) - .unwrap_or_default(); - - let mut options = Vec::new(); - if read_only { - options.push("ro"); + match kind.as_str() { + "bind" | "volume" if bind.is_none() => { + let Some(mut source) = source else { + return Some(Err(eyre::eyre!("{kind} mount without a source"))); + }; + if kind == "volume" { + source += ".volume"; + } + source += ":"; + + let mut options = Vec::new(); + if read_only { + options.push("ro"); + } + if let Some(docker_compose_types::Volume { nocopy: true }) = volume { + options.push("nocopy"); + } + let options = if options.is_empty() { + String::new() + } else { + format!(":{}", options.join(",")) + }; + + Some(Ok(format!("{source}{target}{options}"))) } - if let Some(docker_compose_types::Volume { nocopy: true }) = volume { - options.push("nocopy"); + "bind" => { + let Some(source) = source else { + return Some(Err(eyre::eyre!("bind mount without a source"))) + }; + let read_only = if read_only { ",ro" } else { "" }; + let propagation = bind + .map(|bind| format!(",bind-propagation={}", bind.propagation)) + .unwrap_or_default(); + mount.push(format!( + "type=bind,source={source},destination={target}{read_only}{propagation}" + )); + None } - let options = if options.is_empty() { - String::new() - } else { - format!(":{}", options.join(",")) - }; - - Some(format!("{source}{target}{options}")) + "tmpfs" => { + let mut options = Vec::new(); + if read_only { + options.push(String::from("ro")); + } + if let Some(docker_compose_types::TmpfsSettings { size }) = tmpfs_settings { + options.push(format!("size={size}")); + } + let options = if options.is_empty() { + String::new() + } else { + format!(":{}", options.join(",")) + }; + tmpfs.push(format!("{target}{options}")); + None + } + _ => Some(Err(eyre::eyre!("unsupported volume type: {kind}"))), } }) .collect(), @@ -597,9 +659,28 @@ fn map_networks(networks: docker_compose_types::Networks) -> Vec { .0 .into_iter() .map(|(network, settings)| { - let options = settings - .map(|settings| format!(":ip={}", settings.ipv4_address)) - .unwrap_or_default(); + let options = + if let MapOrEmpty::Map(docker_compose_types::AdvancedNetworkSettings { + ipv4_address, + ipv6_address, + aliases, + }) = settings + { + let mut options = Vec::new(); + for ip in ipv4_address.into_iter().chain(ipv6_address) { + options.push(format!("ip={ip}")); + } + for alias in aliases { + options.push(format!("alias={alias}")); + } + if options.is_empty() { + String::new() + } else { + format!(":{}", options.join(",")) + } + } else { + String::new() + }; format!("{network}.network{options}") }) .collect(), diff --git a/src/cli/unit.rs b/src/cli/unit.rs index 13b422a..2adb00f 100644 --- a/src/cli/unit.rs +++ b/src/cli/unit.rs @@ -54,10 +54,8 @@ impl Unit { pub fn add_dependencies(&mut self, depends_on: docker_compose_types::DependsOnOptions) { let depends_on = match depends_on { - docker_compose_types::DependsOnOptions::Simple(depends_on) => depends_on, - docker_compose_types::DependsOnOptions::Conditional(depends_on) => { - depends_on.into_keys().collect() - } + docker_compose_types::DependsOnOptions::Simple(vec) => vec, + docker_compose_types::DependsOnOptions::Conditional(map) => map.into_keys().collect(), }; self.requires.extend( From 60f117a87f3b7812edb63f8455487f693c9ef4f6 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Mon, 22 May 2023 08:03:45 -0500 Subject: [PATCH 06/14] feat(compose): networks into quadlet files --- src/cli.rs | 98 ++++++++++++++++++++++++++++-------------- src/quadlet/network.rs | 70 +++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 33 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 363ffd2..7283064 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -211,37 +211,16 @@ impl Cli { Ok(vec![file]) } Commands::Compose { pod, compose_file } => { - let mut compose = compose_from_file(&compose_file)?; + let compose = compose_from_file(&compose_file)?; - let services = compose_services(&mut compose)?; + if !compose.extensions.is_empty() { + eyre::bail!("extensions are not supported"); + } if let Some(pod_name) = pod { todo!(); } else { - let mut files = Vec::with_capacity(services.len()); // TODO: add other file types - for (name, mut service) in services { - let mut unit = unit.clone(); - if !service.depends_on.is_empty() { - unit.get_or_insert(Unit::default()) - .add_dependencies(mem::take(&mut service.depends_on)); - } - - let command: PodmanCommands = service.try_into().wrap_err_with(|| { - format!("Could not parse service `{name}` as a valid podman command") - })?; - - let service = command.service().cloned(); - - let file = quadlet::File { - name, - unit, - resource: command.into(), - service, - install: install.clone(), - }; - files.push(file); - } - Ok(files) + compose_try_into_files(compose, &unit, &install) } } } @@ -412,10 +391,63 @@ fn compose_from_file(compose_file: &Option) -> color_eyre::Result, + install: &Option, +) -> color_eyre::Result> { + let services = compose_services(&mut compose)?; + + let mut files = Vec::with_capacity(services.len() + compose.networks.0.len()); // TODO: add other file types + + for (name, mut service) in services { + let mut unit = unit.clone(); + if !service.depends_on.is_empty() { + unit.get_or_insert(Unit::default()) + .add_dependencies(mem::take(&mut service.depends_on)); + } + + let command: PodmanCommands = service.try_into().wrap_err_with(|| { + format!("Could not parse service `{name}` as a valid podman command") + })?; + + let service = command.service().cloned(); + + files.push(quadlet::File { + name, + unit, + resource: command.into(), + service, + install: install.clone(), + }); + } + + for (name, network) in compose.networks.0 { + let resource = Option::::from(network) + .map(quadlet::Network::try_from) + .transpose() + .wrap_err_with(|| { + format!("Could not parse network `{name}` as a valid podman network") + })? + .unwrap_or_default() + .into(); + + files.push(quadlet::File { + name, + unit: unit.clone(), + resource, + service: None, + install: install.clone(), + }); + } + + Ok(files) +} + fn compose_services( compose: &mut Compose, ) -> color_eyre::Result> { - let mut services: IndexMap<_, _> = mem::take(&mut compose.services.0) + mem::take(&mut compose.services.0) .into_iter() .map(|(name, service)| { let service_name = name.clone(); @@ -426,11 +458,13 @@ fn compose_services( ) }) }) - .collect::>()?; - if let Some(service) = compose.service.take() { - services.insert(String::from(image_to_name(service.image())), service); - } - Ok(services) + .chain( + compose + .service + .take() + .map(|service| Ok((String::from(image_to_name(service.image())), service))), + ) + .collect() } /// Takes an image and returns an appropriate default service name diff --git a/src/quadlet/network.rs b/src/quadlet/network.rs index 488096c..78b97d8 100644 --- a/src/quadlet/network.rs +++ b/src/quadlet/network.rs @@ -3,11 +3,12 @@ use std::{ net::IpAddr, }; +use color_eyre::eyre::{self, Context}; use ipnet::IpNet; use super::escape_spaces_join; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Default, Clone, PartialEq)] pub struct Network { pub disable_dns: bool, pub driver: Option, @@ -21,6 +22,73 @@ pub struct Network { pub subnet: Vec, } +impl TryFrom for Network { + type Error = color_eyre::Report; + + fn try_from(value: docker_compose_types::NetworkSettings) -> Result { + let unsupported_options = [ + ("attachable", value.attachable), + ("internal", value.internal), + ("external", value.external.is_some()), + ("name", value.name.is_some()), + ]; + for (option, exists) in unsupported_options { + if exists { + return Err(eyre::eyre!("`{option}` is not supported")); + } + } + + let options: Vec = value + .driver_opts + .into_iter() + .map(|(key, value)| { + let value = value.as_ref().map(ToString::to_string).unwrap_or_default(); + format!("{key}={value}") + }) + .collect(); + + let mut gateway = Vec::new(); + let mut subnet = Vec::new(); + let ipam_driver = value + .ipam + .map(|ipam| -> color_eyre::Result<_> { + for config in ipam.config { + if let Some(ip) = config.gateway { + gateway.push(ip.parse().wrap_err_with(|| { + format!("could not parse `{ip}` as a valid IP address") + })?); + } + subnet.push(config.subnet.parse().wrap_err_with(|| { + format!("could not parse `{}` as a valid IP subnet", config.subnet) + })?); + } + Ok(ipam.driver) + }) + .transpose() + .wrap_err("invalid ipam config")? + .flatten(); + + let label = match value.labels { + docker_compose_types::Labels::List(labels) => labels, + docker_compose_types::Labels::Map(labels) => labels + .into_iter() + .map(|(key, value)| format!("{key}={value}")) + .collect(), + }; + + Ok(Self { + driver: value.driver, + options: (!options.is_empty()).then(|| options.join(",")), + ipv6: value.enable_ipv6, + gateway, + subnet, + ipam_driver, + label, + ..Self::default() + }) + } +} + impl Display for Network { fn fmt(&self, f: &mut Formatter) -> fmt::Result { writeln!(f, "[Network]")?; From 98f836b9a39da2d94b6ccf542dc0ac4d2ac4753d Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 25 May 2023 16:23:49 -0500 Subject: [PATCH 07/14] feat(compose): volume quadlet files from compose --- Cargo.lock | 4 +-- Cargo.toml | 2 +- src/cli.rs | 36 +++++++++++++++++++--- src/cli/container.rs | 35 ++++++++++++--------- src/cli/container/quadlet.rs | 59 +++++++++++++++++++++--------------- src/cli/volume.rs | 30 ++---------------- src/cli/volume/opt.rs | 30 +++++++++++++++++- src/quadlet/volume.rs | 48 +++++++++++++++++++++++++++++ 8 files changed, 169 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdf472a..e17035a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,9 +461,9 @@ dependencies = [ [[package]] name = "docker-compose-types" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48837264ee035ee6c652881fc5e1c9429d488db97e57bad4057bcc769454bf6f" +checksum = "920abe4782ec03907a2f49f74a4fef2e12540a599436a9acd9303030da0a12f8" dependencies = [ "derive_builder", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index ac27631..8fd02b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ categories = ["command-line-utilities"] [dependencies] clap = { version = "4.2", features = ["derive"] } color-eyre = "0.6" -docker-compose-types = "0.5" +docker-compose-types = "0.5.1" duration-str = { version = "0.5", default-features = false } indexmap = { version = "1.9", features = ["std"] } ipnet = "2.7" diff --git a/src/cli.rs b/src/cli.rs index 7283064..35d45c1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -4,7 +4,7 @@ mod kube; mod network; pub mod service; pub mod unit; -mod volume; +pub mod volume; #[cfg(unix)] mod systemd_dbus; @@ -316,11 +316,11 @@ enum PodmanCommands { }, } -impl TryFrom for PodmanCommands { +impl<'a> TryFrom> for PodmanCommands { type Error = color_eyre::Report; - fn try_from(value: docker_compose_types::Service) -> Result { - let service = (&value).try_into()?; + fn try_from(value: ComposeService) -> Result { + let service = (&value.service).try_into()?; Ok(Self::Run { container: Box::new(value.try_into()?), service, @@ -358,6 +358,12 @@ impl PodmanCommands { } } +#[derive(Debug)] +struct ComposeService<'a> { + service: docker_compose_types::Service, + volumes: &'a docker_compose_types::TopLevelVolumes, +} + fn compose_from_file(compose_file: &Option) -> color_eyre::Result { let (compose_file, path) = if let Some(path) = compose_file { let compose_file = File::open(path) @@ -398,7 +404,8 @@ fn compose_try_into_files( ) -> color_eyre::Result> { let services = compose_services(&mut compose)?; - let mut files = Vec::with_capacity(services.len() + compose.networks.0.len()); // TODO: add other file types + let mut files = + Vec::with_capacity(services.len() + compose.networks.0.len() + compose.volumes.0.len()); for (name, mut service) in services { let mut unit = unit.clone(); @@ -407,6 +414,10 @@ fn compose_try_into_files( .add_dependencies(mem::take(&mut service.depends_on)); } + let service = ComposeService { + service, + volumes: &compose.volumes, + }; let command: PodmanCommands = service.try_into().wrap_err_with(|| { format!("Could not parse service `{name}` as a valid podman command") })?; @@ -441,6 +452,21 @@ fn compose_try_into_files( }); } + for (name, volume) in compose.volumes.0 { + if let docker_compose_types::MapOrEmpty::Map(volume) = volume { + let volume = quadlet::Volume::try_from(volume).wrap_err_with(|| { + format!("could not parse volume `{name}` as a valid podman volume") + })?; + files.push(quadlet::File { + name, + unit: unit.clone(), + resource: volume.into(), + service: None, + install: install.clone(), + }); + } + } + Ok(files) } diff --git a/src/cli/container.rs b/src/cli/container.rs index 408c98b..b09c917 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -8,7 +8,7 @@ use clap::Args; use color_eyre::eyre::{self, Context}; use self::{podman::PodmanArgs, quadlet::QuadletOptions, security_opt::SecurityOpt}; -use super::image_to_name; +use super::{image_to_name, ComposeService}; #[derive(Args, Default, Debug, Clone, PartialEq)] pub struct Container { @@ -41,30 +41,31 @@ pub struct Container { command: Vec, } -impl TryFrom for Container { +impl<'a> TryFrom> for Container { type Error = color_eyre::Report; - fn try_from(mut value: docker_compose_types::Service) -> Result { + fn try_from(mut value: ComposeService) -> Result { + let service = &value.service; let unsupported_options = [ - ("deploy", value.deploy.is_some()), - ("build", value.build_.is_some()), - ("profiles", !value.profiles.is_empty()), - ("links", !value.links.is_empty()), - ("net", value.net.is_some()), - ("volumes_from", !value.volumes_from.is_empty()), - ("extends", !value.extends.is_empty()), - ("scale", value.scale != 0), + ("deploy", service.deploy.is_some()), + ("build", service.build_.is_some()), + ("profiles", !service.profiles.is_empty()), + ("links", !service.links.is_empty()), + ("net", service.net.is_some()), + ("volumes_from", !service.volumes_from.is_empty()), + ("extends", !service.extends.is_empty()), + ("scale", service.scale != 0), ]; for (option, exists) in unsupported_options { if exists { return Err(unsupported_option(option)); } } - if !value.extensions.is_empty() { + if !service.extensions.is_empty() { return Err(eyre::eyre!("compose extensions are not supported")); } - let security_opt = mem::take(&mut value.security_opt) + let security_opt = mem::take(&mut value.service.security_opt) .into_iter() .map(|s| s.parse()) .collect::>() @@ -72,10 +73,14 @@ impl TryFrom for Container { Ok(Self { quadlet_options: (&mut value).try_into()?, - podman_args: (&mut value).try_into()?, + podman_args: (&mut value.service).try_into()?, security_opt, - image: value.image.ok_or(eyre::eyre!("image is required"))?, + image: value + .service + .image + .ok_or(eyre::eyre!("image is required"))?, command: value + .service .command .map(|command| match command { docker_compose_types::Command::Simple(s) => vec![s], diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index 761e3ad..e20dd79 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -9,6 +9,7 @@ use color_eyre::eyre::{self, Context}; use docker_compose_types::MapOrEmpty; use super::unsupported_option; +use crate::cli::ComposeService; #[allow(clippy::module_name_repetitions)] #[derive(Args, Default, Debug, Clone, PartialEq)] @@ -359,34 +360,36 @@ impl From for crate::quadlet::Container { } } -impl TryFrom for QuadletOptions { +impl<'a> TryFrom> for QuadletOptions { type Error = color_eyre::Report; - fn try_from(mut value: docker_compose_types::Service) -> Result { + fn try_from(mut value: ComposeService) -> Result { (&mut value).try_into() } } -impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { +impl<'a> TryFrom<&mut ComposeService<'a>> for QuadletOptions { type Error = color_eyre::Report; - fn try_from(value: &mut docker_compose_types::Service) -> Result { + fn try_from(value: &mut ComposeService) -> Result { + let service = &mut value.service; + let Healthcheck { health_cmd, health_interval, health_timeout, health_retries, health_start_period, - } = value + } = service .healthcheck .take() .map(Healthcheck::from) .unwrap_or_default(); let publish = - ports_try_into_publish(mem::take(&mut value.ports)).wrap_err("invalid port")?; + ports_try_into_publish(mem::take(&mut service.ports)).wrap_err("invalid port")?; - let env = match mem::take(&mut value.environment) { + let env = match mem::take(&mut service.environment) { docker_compose_types::Environment::List(list) => list, docker_compose_types::Environment::KvPair(map) => map .into_iter() @@ -397,7 +400,7 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { .collect(), }; - let network = value + let network = service .network_mode .take() .map(|mode| match mode.as_str() { @@ -407,10 +410,10 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { }) .transpose()? .into_iter() - .chain(map_networks(mem::take(&mut value.networks))) + .chain(map_networks(mem::take(&mut service.networks))) .collect(); - let label = match mem::take(&mut value.labels) { + let label = match mem::take(&mut service.labels) { docker_compose_types::Labels::List(vec) => vec, docker_compose_types::Labels::Map(map) => map .into_iter() @@ -418,7 +421,7 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { .collect(), }; - let mut tmpfs = value + let mut tmpfs = service .tmpfs .take() .map(|tmpfs| match tmpfs { @@ -429,10 +432,12 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { let mut mount = Vec::new(); - let volume = volumes_try_into_short(mem::take(&mut value.volumes), &mut tmpfs, &mut mount) - .wrap_err("invalid volume")?; + let volume = + volumes_try_into_short(value, &mut tmpfs, &mut mount).wrap_err("invalid volume")?; + + let service = &mut value.service; - let env_file = value + let env_file = service .env_file .take() .map(|env_file| match env_file { @@ -444,13 +449,13 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { .unwrap_or_default(); Ok(Self { - cap_add: mem::take(&mut value.cap_add), - name: value.container_name.take(), + cap_add: mem::take(&mut service.cap_add), + name: service.container_name.take(), publish, env, env_file, network, - device: mem::take(&mut value.devices), + device: mem::take(&mut service.devices), label, health_cmd, health_interval, @@ -459,13 +464,13 @@ impl TryFrom<&mut docker_compose_types::Service> for QuadletOptions { health_timeout, tmpfs, mount, - user: value.user.take(), - expose: mem::take(&mut value.expose), - log_driver: value + user: service.user.take(), + expose: mem::take(&mut service.expose), + log_driver: service .logging .as_mut() .map(|logging| mem::take(&mut logging.driver)), - init: value.init, + init: service.init, volume, ..Self::default() }) @@ -561,15 +566,19 @@ fn ports_try_into_publish(ports: docker_compose_types::Ports) -> color_eyre::Res } fn volumes_try_into_short( - volumes: docker_compose_types::Volumes, + service: &mut ComposeService, tmpfs: &mut Vec, mount: &mut Vec, ) -> color_eyre::Result> { + let volumes = mem::take(&mut service.service.volumes); match volumes { docker_compose_types::Volumes::Simple(volumes) => Ok(volumes .into_iter() .map(|volume| match volume.split_once(':') { - Some((source, target)) if !source.starts_with(['.', '/', '~']) => { + Some((source, target)) + if !source.starts_with(['.', '/', '~']) + && matches!(service.volumes.0.get(source), Some(MapOrEmpty::Map(_))) => + { format!("{source}.volume:{target}") } _ => volume, @@ -593,7 +602,9 @@ fn volumes_try_into_short( let Some(mut source) = source else { return Some(Err(eyre::eyre!("{kind} mount without a source"))); }; - if kind == "volume" { + if kind == "volume" + && matches!(service.volumes.0.get(&source), Some(MapOrEmpty::Map(_))) + { source += ".volume"; } source += ":"; diff --git a/src/cli/volume.rs b/src/cli/volume.rs index e078b03..6a03b1e 100644 --- a/src/cli/volume.rs +++ b/src/cli/volume.rs @@ -1,4 +1,4 @@ -mod opt; +pub mod opt; use clap::{Args, Subcommand}; @@ -77,33 +77,9 @@ pub struct Create { impl From for crate::quadlet::Volume { fn from(value: Create) -> Self { - let mut volume = Self { + Self { label: value.label, - ..Self::default() - }; - - let mut mount_options = Vec::new(); - for opt in value.opt { - match opt { - Opt::Type(fs_type) => volume.fs_type = Some(fs_type), - Opt::Device(device) => volume.device = Some(device), - Opt::Copy => volume.copy = true, - Opt::Mount(options) => { - for option in options { - match option { - opt::Mount::Uid(uid) => volume.user = Some(uid), - opt::Mount::Gid(gid) => volume.group = Some(gid), - opt::Mount::Other(option) => mount_options.push(option), - } - } - } - } - } - - if !mount_options.is_empty() { - volume.options = Some(mount_options.join(",")); + ..value.opt.into() } - - volume } } diff --git a/src/cli/volume/opt.rs b/src/cli/volume/opt.rs index 1bd5047..1a7c058 100644 --- a/src/cli/volume/opt.rs +++ b/src/cli/volume/opt.rs @@ -10,6 +10,34 @@ pub enum Opt { Mount(Vec), } +impl From> for crate::quadlet::Volume { + fn from(value: Vec) -> Self { + value.into_iter().fold(Self::default(), |mut volume, opt| { + match opt { + Opt::Type(fs_type) => volume.fs_type = Some(fs_type), + Opt::Device(device) => volume.device = Some(device), + Opt::Copy => volume.copy = true, + Opt::Mount(mount_opts) => { + for opt in mount_opts { + match opt { + Mount::Uid(uid) => volume.user = Some(uid), + Mount::Gid(gid) => volume.group = Some(gid), + Mount::Other(mount_opt) => { + if let Some(options) = volume.options.as_mut() { + *options = format!("{options},{mount_opt}"); + } else { + volume.options = Some(mount_opt); + } + } + } + } + } + } + volume + }) + } +} + impl FromStr for Opt { type Err = ParseOptError; @@ -29,7 +57,7 @@ impl FromStr for Opt { let options = options .split(',') .map(str::parse) - .collect::, _>>() + .collect::>() .expect("Mount::from_str cannot error"); Ok(Self::Mount(options)) } diff --git a/src/quadlet/volume.rs b/src/quadlet/volume.rs index fcf9c96..4be9ca5 100644 --- a/src/quadlet/volume.rs +++ b/src/quadlet/volume.rs @@ -1,5 +1,9 @@ use std::fmt::{self, Display, Formatter}; +use color_eyre::eyre::{self, Context}; + +use crate::cli::volume::opt::Opt; + use super::escape_spaces_join; #[derive(Debug, Default, Clone, PartialEq)] @@ -13,6 +17,50 @@ pub struct Volume { pub user: Option, } +impl TryFrom for Volume { + type Error = color_eyre::Report; + + fn try_from(value: docker_compose_types::ComposeVolume) -> Result { + let unsupported_options = [ + ("driver", value.driver.is_none()), + ("external", value.external.is_none()), + ("name", value.name.is_none()), + ]; + for (option, not_present) in unsupported_options { + eyre::ensure!(not_present, "`{option}` is not supported"); + } + + let options: Vec = value + .driver_opts + .into_iter() + .map(|(key, value)| { + let driver_opt = key.clone(); + match value { + Some(value) if key != "copy" => format!("{key}={value}"), + _ => key, + } + .parse() + .wrap_err_with(|| { + format!("driver_opt `{driver_opt}` is not a valid podman volume driver option") + }) + }) + .collect::>()?; + + let label = match value.labels { + docker_compose_types::Labels::List(labels) => labels, + docker_compose_types::Labels::Map(labels) => labels + .into_iter() + .map(|(key, value)| format!("{key}={value}")) + .collect(), + }; + + Ok(Self { + label, + ..options.into() + }) + } +} + impl Display for Volume { fn fmt(&self, f: &mut Formatter) -> fmt::Result { writeln!(f, "[Volume]")?; From 5b73b77e6daa499732b23d3f03b1713f0b999f48 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Sat, 27 May 2023 15:25:45 -0500 Subject: [PATCH 08/14] refactor: allow for multiple types of output files --- Cargo.lock | 78 ++++++++++ Cargo.toml | 1 + src/cli.rs | 274 +++++++++++++++++++++++------------ src/cli/container.rs | 2 +- src/cli/container/quadlet.rs | 10 +- src/quadlet.rs | 33 ----- 6 files changed, 269 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e17035a..a9aeb2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,6 +212,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bitflags" version = "1.3.2" @@ -248,6 +254,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + [[package]] name = "cc" version = "1.0.79" @@ -260,6 +272,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + [[package]] name = "clap" version = "4.2.2" @@ -747,6 +770,20 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "k8s-openapi" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd990069640f9db34b3b0f7a1afc62a05ffaa3be9b66aa3c313f58346df7f788" +dependencies = [ + "base64", + "bytes", + "chrono", + "serde", + "serde-value", + "serde_json", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -827,6 +864,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -851,6 +898,15 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -901,6 +957,7 @@ dependencies = [ "duration-str", "indexmap", "ipnet", + "k8s-openapi", "nix", "serde_yaml", "shlex", @@ -1060,6 +1117,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.160" @@ -1071,6 +1138,17 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.12" diff --git a/Cargo.toml b/Cargo.toml index 8fd02b6..665032f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ docker-compose-types = "0.5.1" duration-str = { version = "0.5", default-features = false } indexmap = { version = "1.9", features = ["std"] } ipnet = "2.7" +k8s-openapi = { version = "0.18.0", features = ["v1_26"], default-features = false } serde_yaml = "0.9.21" shlex = "1.1" thiserror = "1.0.40" diff --git a/src/cli.rs b/src/cli.rs index 35d45c1..a780bff 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -11,11 +11,15 @@ mod systemd_dbus; use std::{ borrow::Cow, + collections::HashMap, env, ffi::OsStr, - fs::File, - mem, + fmt::{self, Display}, + fs, + io::{self, Write}, + iter, mem, path::{Path, PathBuf}, + rc::Rc, }; use clap::{Parser, Subcommand}; @@ -23,8 +27,8 @@ use color_eyre::{ eyre::{self, Context}, Help, }; -use docker_compose_types::Compose; -use indexmap::IndexMap; +use docker_compose_types::{Compose, MapOrEmpty}; +use k8s_openapi::api::core::v1::Pod; use crate::quadlet; @@ -124,19 +128,23 @@ impl Cli { #[cfg(unix)] let services_check = !self.skip_services_check; - let quadlet_files = self.into_quadlet_files()?; + let files = self.try_into_files()?; #[cfg(unix)] if services_check { - check_existing(&quadlet_files, &path, overwrite)?; + check_existing( + files.iter().filter_map(File::quadlet_file), + &path, + overwrite, + )?; } - for file in quadlet_files { + for file in files { let path: Cow = match &path { FilePath::Full(path) => path.into(), FilePath::Dir(path) => { - let mut path = path.join(&file.name); - path.set_extension(file.resource.extension()); + let mut path = path.join(file.name()); + path.set_extension(file.extension()); path.into() } }; @@ -145,13 +153,13 @@ impl Cli { Ok(()) } else { - let quadlet_files = self - .into_quadlet_files()? + let files = self + .try_into_files()? .into_iter() - .map(|file| format!("# {}.{}\n{file}", file.name, file.resource.extension())) + .map(|file| format!("# {}.{}\n{file}", file.name(), file.extension())) .collect::>() .join("\n---\n\n"); - print!("{quadlet_files}"); + print!("{files}"); Ok(()) } } @@ -194,7 +202,7 @@ impl Cli { Ok(FilePath::Dir(path)) } - fn into_quadlet_files(self) -> color_eyre::Result> { + fn try_into_files(self) -> color_eyre::Result> { let unit = (!self.unit.is_empty()).then_some(self.unit); let install = self.install.install.then(|| self.install.into()); @@ -208,7 +216,7 @@ impl Cli { service, install, }; - Ok(vec![file]) + Ok(vec![file.into()]) } Commands::Compose { pod, compose_file } => { let compose = compose_from_file(&compose_file)?; @@ -220,7 +228,9 @@ impl Cli { if let Some(pod_name) = pod { todo!(); } else { - compose_try_into_files(compose, &unit, &install) + compose_try_into_quadlet_files(compose, &unit, &install) + .map(|result| result.map(Into::into)) + .collect() } } } @@ -316,7 +326,7 @@ enum PodmanCommands { }, } -impl<'a> TryFrom> for PodmanCommands { +impl TryFrom for PodmanCommands { type Error = color_eyre::Report; fn try_from(value: ComposeService) -> Result { @@ -359,14 +369,102 @@ impl PodmanCommands { } #[derive(Debug)] -struct ComposeService<'a> { +#[allow(clippy::large_enum_variant)] // false positive, [Pod] is not zero-sized +enum File { + Quadlet(quadlet::File), + KubePod { name: String, pod: Pod }, +} + +impl From for File { + fn from(value: quadlet::File) -> Self { + Self::Quadlet(value) + } +} + +impl Display for File { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Quadlet(file) => file.fmt(f), + Self::KubePod { name: _, pod } => { + f.write_str(&serde_yaml::to_string(pod).map_err(|_| fmt::Error)?) + } + } + } +} + +impl File { + fn name(&self) -> &str { + match self { + Self::Quadlet(file) => &file.name, + Self::KubePod { name, .. } => name, + } + } + + fn extension(&self) -> &str { + match self { + Self::Quadlet(file) => file.resource.extension(), + Self::KubePod { .. } => "yaml", + } + } + + fn quadlet_file(&self) -> Option<&quadlet::File> { + match self { + Self::Quadlet(file) => Some(file), + Self::KubePod { .. } => None, + } + } + + fn write(&self, path: impl AsRef, overwrite: bool) -> color_eyre::Result<()> { + let path_display = path.as_ref().display().to_string(); + let mut file = fs::File::options() + .write(true) + .create_new(!overwrite) + .create(overwrite) + .open(path) + .map_err(|error| match error.kind() { + io::ErrorKind::AlreadyExists => { + eyre::eyre!("File already exists, not overwriting it: {path_display}") + .suggestion("Use `--overwrite` if you wish overwrite existing files.") + } + _ => color_eyre::Report::new(error) + .wrap_err(format!("Failed to create/open file: {path_display}")) + .suggestion( + "Make sure the directory exists \ + and you have write permissions for the file", + ), + })?; + match self { + Self::Quadlet(quadlet_file) => { + write!(file, "{quadlet_file}").map_err(color_eyre::Report::from) + } + Self::KubePod { name: _, pod } => { + serde_yaml::to_writer(file, pod).map_err(color_eyre::Report::from) + } + } + .wrap_err_with(|| format!("Failed to write to file: {path_display}"))?; + println!("Wrote to file: {path_display}"); + Ok(()) + } +} + +#[derive(Debug)] +struct ComposeService { service: docker_compose_types::Service, - volumes: &'a docker_compose_types::TopLevelVolumes, + volume_has_options: Rc>, +} + +impl ComposeService { + fn volume_has_options(&self, volume: &str) -> bool { + self.volume_has_options + .get(volume) + .copied() + .unwrap_or_default() + } } fn compose_from_file(compose_file: &Option) -> color_eyre::Result { let (compose_file, path) = if let Some(path) = compose_file { - let compose_file = File::open(path) + let compose_file = fs::File::open(path) .wrap_err("Could not open provided compose file") .suggestion("Make sure you have the proper permissions for the given file.")?; (compose_file, path.display().to_string()) @@ -379,7 +477,7 @@ fn compose_from_file(compose_file: &Option) -> color_eyre::Result) -> color_eyre::Result( mut compose: Compose, - unit: &Option, - install: &Option, -) -> color_eyre::Result> { - let services = compose_services(&mut compose)?; - - let mut files = - Vec::with_capacity(services.len() + compose.networks.0.len() + compose.volumes.0.len()); - - for (name, mut service) in services { - let mut unit = unit.clone(); - if !service.depends_on.is_empty() { - unit.get_or_insert(Unit::default()) - .add_dependencies(mem::take(&mut service.depends_on)); - } - - let service = ComposeService { - service, - volumes: &compose.volumes, - }; - let command: PodmanCommands = service.try_into().wrap_err_with(|| { - format!("Could not parse service `{name}` as a valid podman command") - })?; - - let service = command.service().cloned(); + unit: &'a Option, + install: &'a Option, +) -> impl Iterator> + 'a { + let volume_has_options = compose + .volumes + .0 + .iter() + .map(|(name, volume)| (name.clone(), matches!(volume, MapOrEmpty::Map(_)))) + .collect(); + compose_services(&mut compose) + .zip(iter::repeat(Rc::new(volume_has_options))) + .map(|(result, volume_has_options)| { + result.and_then(|(name, mut service)| { + let mut unit = unit.clone(); + if !service.depends_on.is_empty() { + unit.get_or_insert(Unit::default()) + .add_dependencies(mem::take(&mut service.depends_on)); + } - files.push(quadlet::File { - name, - unit, - resource: command.into(), - service, - install: install.clone(), - }); - } + let service = ComposeService { + service, + volume_has_options, + }; + let command: PodmanCommands = service.try_into().wrap_err_with(|| { + format!("Could not parse service `{name}` as a valid podman command") + })?; - for (name, network) in compose.networks.0 { - let resource = Option::::from(network) - .map(quadlet::Network::try_from) - .transpose() - .wrap_err_with(|| { - format!("Could not parse network `{name}` as a valid podman network") - })? - .unwrap_or_default() - .into(); - - files.push(quadlet::File { - name, - unit: unit.clone(), - resource, - service: None, - install: install.clone(), - }); - } + let service = command.service().cloned(); - for (name, volume) in compose.volumes.0 { - if let docker_compose_types::MapOrEmpty::Map(volume) = volume { - let volume = quadlet::Volume::try_from(volume).wrap_err_with(|| { - format!("could not parse volume `{name}` as a valid podman volume") - })?; - files.push(quadlet::File { + Ok(quadlet::File { + name, + unit, + resource: command.into(), + service, + install: install.clone(), + }) + }) + }) + .chain(compose.networks.0.into_iter().map(|(name, network)| { + let network = Option::::from(network) + .map(quadlet::Network::try_from) + .transpose() + .wrap_err_with(|| { + format!("Could not parse network `{name}` as a valid podman network") + })? + .unwrap_or_default(); + Ok(quadlet::File { name, unit: unit.clone(), - resource: volume.into(), + resource: network.into(), service: None, install: install.clone(), - }); - } - } - - Ok(files) + }) + })) + .chain(compose.volumes.0.into_iter().filter_map(|(name, volume)| { + Option::::from(volume).map(|volume| { + let volume = quadlet::Volume::try_from(volume).wrap_err_with(|| { + format!("could not parse volume `{name}` as a valid podman volume") + })?; + Ok(quadlet::File { + name, + unit: unit.clone(), + resource: volume.into(), + service: None, + install: install.clone(), + }) + }) + })) } fn compose_services( compose: &mut Compose, -) -> color_eyre::Result> { +) -> impl Iterator> { mem::take(&mut compose.services.0) .into_iter() .map(|(name, service)| { @@ -490,7 +587,6 @@ fn compose_services( .take() .map(|service| Ok((String::from(image_to_name(service.image())), service))), ) - .collect() } /// Takes an image and returns an appropriate default service name @@ -504,14 +600,14 @@ fn image_to_name(image: &str) -> &str { } #[cfg(unix)] -fn check_existing( - quadlet_files: &[quadlet::File], +fn check_existing<'a>( + quadlet_files: impl IntoIterator, path: &FilePath, overwrite: bool, ) -> eyre::Result<()> { if let Ok(unit_files) = systemd_dbus::unit_files().map(Iterator::collect::>) { let file_names: Vec<_> = quadlet_files - .iter() + .into_iter() .filter_map(|file| match &path { FilePath::Full(path) => path.file_stem().and_then(OsStr::to_str).map(|name| { let service = file.resource.name_to_service(name); diff --git a/src/cli/container.rs b/src/cli/container.rs index b09c917..7d81dd5 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -41,7 +41,7 @@ pub struct Container { command: Vec, } -impl<'a> TryFrom> for Container { +impl TryFrom for Container { type Error = color_eyre::Report; fn try_from(mut value: ComposeService) -> Result { diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index e20dd79..94e9646 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -360,7 +360,7 @@ impl From for crate::quadlet::Container { } } -impl<'a> TryFrom> for QuadletOptions { +impl TryFrom for QuadletOptions { type Error = color_eyre::Report; fn try_from(mut value: ComposeService) -> Result { @@ -368,7 +368,7 @@ impl<'a> TryFrom> for QuadletOptions { } } -impl<'a> TryFrom<&mut ComposeService<'a>> for QuadletOptions { +impl TryFrom<&mut ComposeService> for QuadletOptions { type Error = color_eyre::Report; fn try_from(value: &mut ComposeService) -> Result { @@ -577,7 +577,7 @@ fn volumes_try_into_short( .map(|volume| match volume.split_once(':') { Some((source, target)) if !source.starts_with(['.', '/', '~']) - && matches!(service.volumes.0.get(source), Some(MapOrEmpty::Map(_))) => + && service.volume_has_options(source) => { format!("{source}.volume:{target}") } @@ -602,9 +602,7 @@ fn volumes_try_into_short( let Some(mut source) = source else { return Some(Err(eyre::eyre!("{kind} mount without a source"))); }; - if kind == "volume" - && matches!(service.volumes.0.get(&source), Some(MapOrEmpty::Map(_))) - { + if kind == "volume" && service.volume_has_options(&source) { source += ".volume"; } source += ":"; diff --git a/src/quadlet.rs b/src/quadlet.rs index 0f350f3..7ec36a5 100644 --- a/src/quadlet.rs +++ b/src/quadlet.rs @@ -7,14 +7,6 @@ mod volume; use std::{ borrow::Cow, fmt::{self, Display, Formatter}, - fs, - io::{self, Write}, - path::Path, -}; - -use color_eyre::{ - eyre::{self, WrapErr}, - Help, Report, }; pub use self::{ @@ -52,31 +44,6 @@ impl Display for File { } impl File { - pub fn write(&self, path: impl AsRef, overwrite: bool) -> eyre::Result<()> { - let path_display = path.as_ref().display().to_string(); - let mut file = fs::File::options() - .write(true) - .create_new(!overwrite) - .create(overwrite) - .open(path) - .map_err(|error| match error.kind() { - io::ErrorKind::AlreadyExists => { - eyre::eyre!("File already exists, not overwriting it: {path_display}") - .suggestion("Use `--overwrite` if you wish overwrite existing files.") - } - _ => Report::new(error) - .wrap_err(format!("Failed to create/open file: {path_display}")) - .suggestion( - "Make sure the directory exists \ - and you have write permissions for the file", - ), - })?; - write!(file, "{self}") - .wrap_err_with(|| format!("Failed to write to file: {path_display}"))?; - println!("Wrote to file: {path_display}"); - Ok(()) - } - /// Returns the corresponding service file name generated by quadlet pub fn service_name(&self) -> String { self.resource.name_to_service(&self.name) From c027859e18f028c5690f7cd5fb2f755e398b818a Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 8 Jun 2023 18:48:48 -0500 Subject: [PATCH 09/14] feat(compose): compose into pod --- src/cli.rs | 58 ++- src/cli/container.rs | 12 +- src/cli/container/quadlet.rs | 2 +- src/cli/k8s.rs | 966 +++++++++++++++++++++++++++++++++++ 4 files changed, 1030 insertions(+), 8 deletions(-) create mode 100644 src/cli/k8s.rs diff --git a/src/cli.rs b/src/cli.rs index a780bff..f4b6692 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,6 @@ mod container; mod install; +mod k8s; mod kube; mod network; pub mod service; @@ -28,7 +29,7 @@ use color_eyre::{ Help, }; use docker_compose_types::{Compose, MapOrEmpty}; -use k8s_openapi::api::core::v1::Pod; +use k8s_openapi::api::core::v1::{PersistentVolumeClaim, Pod}; use crate::quadlet; @@ -226,7 +227,34 @@ impl Cli { } if let Some(pod_name) = pod { - todo!(); + let (pod, persistent_volume_claims) = + k8s::compose_try_into_pod(compose, pod_name.clone())?; + + let kube = quadlet::Kube { + config_map: Vec::new(), + log_driver: None, + network: Vec::new(), + publish_port: Vec::new(), + user_ns: None, + yaml: String::from("kube.yaml"), + }; + + let quadlet_file = quadlet::File { + name: pod_name.clone(), + unit, + resource: kube.into(), + service: None, + install, + }; + + Ok(vec![ + quadlet_file.into(), + File::KubePod { + name: pod_name, + pod, + persistent_volume_claims, + }, + ]) } else { compose_try_into_quadlet_files(compose, &unit, &install) .map(|result| result.map(Into::into)) @@ -372,7 +400,11 @@ impl PodmanCommands { #[allow(clippy::large_enum_variant)] // false positive, [Pod] is not zero-sized enum File { Quadlet(quadlet::File), - KubePod { name: String, pod: Pod }, + KubePod { + name: String, + pod: Pod, + persistent_volume_claims: Vec, + }, } impl From for File { @@ -385,7 +417,15 @@ impl Display for File { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Quadlet(file) => file.fmt(f), - Self::KubePod { name: _, pod } => { + Self::KubePod { + name: _, + pod, + persistent_volume_claims, + } => { + for volume in persistent_volume_claims { + f.write_str(&serde_yaml::to_string(volume).map_err(|_| fmt::Error)?)?; + writeln!(f, "---")?; + } f.write_str(&serde_yaml::to_string(pod).map_err(|_| fmt::Error)?) } } @@ -437,7 +477,15 @@ impl File { Self::Quadlet(quadlet_file) => { write!(file, "{quadlet_file}").map_err(color_eyre::Report::from) } - Self::KubePod { name: _, pod } => { + Self::KubePod { + name: _, + pod, + persistent_volume_claims, + } => { + for volume in persistent_volume_claims { + serde_yaml::to_writer(&file, volume)?; + writeln!(file, "---")?; + } serde_yaml::to_writer(file, pod).map_err(color_eyre::Report::from) } } diff --git a/src/cli/container.rs b/src/cli/container.rs index 7d81dd5..caf5fa1 100644 --- a/src/cli/container.rs +++ b/src/cli/container.rs @@ -1,6 +1,6 @@ mod podman; mod quadlet; -mod security_opt; +pub mod security_opt; use std::mem; @@ -67,7 +67,15 @@ impl TryFrom for Container { let security_opt = mem::take(&mut value.service.security_opt) .into_iter() - .map(|s| s.parse()) + .filter_map(|s| { + if s == "no-new-privileges:true" { + Some(Ok(SecurityOpt::NoNewPrivileges)) + } else if s == "no-new-privileges:false" { + None + } else { + Some(s.replacen(':', "=", 1).parse()) + } + }) .collect::>() .wrap_err("invalid security option")?; diff --git a/src/cli/container/quadlet.rs b/src/cli/container/quadlet.rs index 94e9646..062272a 100644 --- a/src/cli/container/quadlet.rs +++ b/src/cli/container/quadlet.rs @@ -576,7 +576,7 @@ fn volumes_try_into_short( .into_iter() .map(|volume| match volume.split_once(':') { Some((source, target)) - if !source.starts_with(['.', '/', '~']) + if !source.starts_with(['.', '/', '~']) // not bind mount or anonymous volume && service.volume_has_options(source) => { format!("{source}.volume:{target}") diff --git a/src/cli/k8s.rs b/src/cli/k8s.rs new file mode 100644 index 0000000..961ead4 --- /dev/null +++ b/src/cli/k8s.rs @@ -0,0 +1,966 @@ +use std::collections::BTreeMap; + +use color_eyre::{ + eyre::{self, Context}, + Help, +}; +use docker_compose_types::{ + AdvancedVolumes, Command, Compose, ComposeVolume, Entrypoint, Environment, Healthcheck, + HealthcheckTest, Labels, Ports, PublishedPort, Service, SingleValue, Tmpfs, Ulimit, Ulimits, + Volumes as ComposeVolumes, +}; +use indexmap::IndexMap; +use k8s_openapi::{ + api::core::v1::{ + Capabilities, Container, ContainerPort, EmptyDirVolumeSource, EnvVar, ExecAction, + HostPathVolumeSource, PersistentVolumeClaim, PersistentVolumeClaimVolumeSource, Pod, + PodSpec, Probe, ResourceRequirements, SELinuxOptions, SecurityContext, Volume, VolumeMount, + }, + apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::ObjectMeta}, +}; + +use super::{ + compose_services, + container::security_opt::{LabelOpt, SecurityOpt}, +}; + +pub fn compose_try_into_pod( + mut compose: Compose, + name: String, +) -> color_eyre::Result<(Pod, Vec)> { + let mut volumes = Vec::new(); + + let containers = compose_services(&mut compose) + .map(|result| { + result.and_then(|(name, service)| { + let (container, container_volumes) = + service_try_into_container(name.clone(), service).wrap_err_with(|| { + format!("could not convert service `{name}` into k8s container spec") + })?; + volumes.extend(container_volumes); + Ok(container) + }) + }) + .collect::>()?; + + let spec = PodSpec { + containers, + volumes: volumes.filter_empty(), + ..PodSpec::default() + }; + + let pod = Pod { + metadata: ObjectMeta { + name: Some(name), + ..ObjectMeta::default() + }, + spec: Some(spec), + status: None, + }; + + let persistent_volume_claims = compose + .volumes + .0 + .into_iter() + .filter_map(|(name, volume)| { + Option::::from(volume).map(|volume| { + compose_volume_try_into_persistent_volume_claim(volume, name.clone()).wrap_err_with( + || { + format!( + "could not convert volume `{name}` into \ + k8s persistent volume claim spec" + ) + }, + ) + }) + }) + .collect::>()?; + + Ok((pod, persistent_volume_claims)) +} + +fn service_try_into_container( + name: String, + service: Service, +) -> color_eyre::Result<(Container, Vec)> { + service_check_unsupported(&service)?; + + let name = service.container_name.unwrap_or(name); + + let liveness_probe = service + .healthcheck + .filter(|healthcheck| !healthcheck_is_disable(healthcheck)) + .map(healthcheck_try_into_probe) + .transpose() + .wrap_err("could not convert healthcheck into k8s liveness probe")?; + + let capabilities = Capabilities { + add: service.cap_add.filter_empty(), + drop: None, + }; + let se_linux_options = security_opts_try_into_se_linux_options(service.security_opt) + .wrap_err("unsupported security option")?; + let security_context = SecurityContext { + privileged: service.privileged.then_some(true), + capabilities: capabilities.filter_default(), + se_linux_options: se_linux_options.filter_default(), + run_as_user: service + .user + .map(|user| user.parse()) + .transpose() + .wrap_err("user must be specified as a UID")?, + ..SecurityContext::default() + }; + + let ports = ports_try_into_container_ports(service.ports).wrap_err("could not parse ports")?; + + let env = environment_into_env_vars(service.environment); + + let (volume_mounts, volumes): (Vec<_>, _) = service + .tmpfs + .into_iter() + .flat_map(|tmpfs| match tmpfs { + Tmpfs::Simple(tmpfs) => vec![parse_tmpfs_volume_mount(&tmpfs, &name)], + Tmpfs::List(tmpfs) => tmpfs + .into_iter() + .map(|tmpfs| parse_tmpfs_volume_mount(&tmpfs, &name)) + .collect(), + }) + .chain( + compose_volumes_try_into_volume_mounts(service.volumes, &name) + .wrap_err("could not parse volumes")?, + ) + .unzip(); + + let args = service.command.map(|command| match command { + Command::Simple(command) => vec![command], + Command::Args(command) => command, + }); + + let command = service.entrypoint.map(|entrypoint| match entrypoint { + Entrypoint::Simple(entrypoint) => vec![entrypoint], + Entrypoint::List(entrypoint) => entrypoint, + }); + + let container = Container { + name, + image: service.image, + command, + args, + liveness_probe, + security_context: security_context.filter_default(), + ports: ports.filter_empty(), + env: env.filter_empty(), + resources: ulimits_into_resources(service.ulimits), + working_dir: service.working_dir, + stdin: service.stdin_open.then_some(true), + tty: service.tty.then_some(true), + volume_mounts: volume_mounts.filter_empty(), + ..Container::default() + }; + + Ok((container, volumes)) +} + +fn service_check_unsupported(service: &Service) -> color_eyre::Result<()> { + let unsupported_options = [ + ("hostname", service.hostname.is_none()), + ("deploy", service.deploy.is_none()), + ("build", service.build_.is_none()), + ("depends_on", service.depends_on.is_empty()), + ("env_file", service.env_file.is_none()), + ("profiles", service.profiles.is_empty()), + ("links", service.links.is_empty()), + ("net", service.net.is_none()), + ("stop_signal", service.stop_signal.is_none()), + ("expose", service.expose.is_empty()), + ("volumes_from", service.volumes_from.is_empty()), + ("extends", service.extends.is_empty()), + ("scale", service.scale == 0), + ("init", !service.init), + ("shm_size", service.shm_size.is_none()), + ("sysctls", service.sysctls.is_empty()), + ]; + for (option, not_present) in unsupported_options { + eyre::ensure!(not_present, "`{option}` is not supported for pods"); + } + + let unsupported_container_options = [ + ("pid", service.pid.is_none()), + ("network_mode", service.network_mode.is_none()), + ("restart", service.restart.is_none()), + ("labels", service.labels.is_empty()), + ("networks", service.networks.is_empty()), + ("stop_grace_period", service.stop_grace_period.is_none()), + ("dns", service.dns.is_empty()), + ("ipc", service.ipc.is_none()), + ("logging", service.logging.is_none()), + ("extra_hosts", service.extra_hosts.is_empty()), + ]; + for (option, not_present) in unsupported_container_options { + eyre::ensure!( + not_present, + "pods do not support per container `{option}` options, \ + try setting the pod option instead", + ); + } + + eyre::ensure!( + service.devices.is_empty(), + "pods do not directly support devices, try using a bind mount instead" + ); + + eyre::ensure!( + service.extensions.is_empty(), + "podman does not support docker extensions" + ); + + Ok(()) +} + +fn healthcheck_is_disable(healthcheck: &Healthcheck) -> bool { + healthcheck.disable + || healthcheck + .test + .as_ref() + .map(|test| match test { + HealthcheckTest::Single(_) => false, + HealthcheckTest::Multiple(test) => test == &["NONE"], + }) + .unwrap_or_default() +} + +fn healthcheck_try_into_probe(healthcheck: Healthcheck) -> color_eyre::Result { + let Healthcheck { + test, + interval, + timeout, + retries, + start_period, + disable: _, + } = healthcheck; + + let exec = test + .map(|test| { + match test { + HealthcheckTest::Single(_) => None, + HealthcheckTest::Multiple(mut test) => match test.first().map(String::as_str) { + Some("CMD") => { + test.remove(0); // can't panic, there is at least one element ("CMD") + Some(ExecAction { + command: Some(test), + }) + } + _ => None, + }, + } + .ok_or(eyre::eyre!( + "healthcheck implicitly using a shell is not supported for pods" + )) + .suggestion(r#"change healthcheck test to '["CMD", "/bin/sh", "-c", ...]'"#) + }) + .transpose()?; + + let period_seconds = interval + .map(|interval| parse_seconds(&interval)) + .transpose() + .wrap_err("could not parse `interval`")?; + + let timeout_seconds = timeout + .map(|timeout| parse_seconds(&timeout)) + .transpose() + .wrap_err("could not parse `timeout`")?; + + let failure_threshold = (retries != 0) + .then(|| retries.try_into()) + .transpose() + .wrap_err_with(|| format!("`{retries}` retries is too large"))?; + + let initial_delay_seconds = start_period + .map(|start_period| parse_seconds(&start_period)) + .transpose() + .wrap_err("could not parse `start_period`")?; + + Ok(Probe { + exec, + failure_threshold, + initial_delay_seconds, + period_seconds, + timeout_seconds, + ..Probe::default() + }) +} + +fn parse_seconds(duration: &str) -> color_eyre::Result { + duration_str::parse(duration) + .wrap_err_with(|| format!("could not parse `{duration}` as a valid duration")) + .and_then(|period| { + let seconds = period.as_secs(); + seconds + .try_into() + .wrap_err_with(|| format!("`{seconds}` seconds is too large")) + }) +} + +fn security_opts_try_into_se_linux_options( + security_opts: Vec, +) -> color_eyre::Result { + security_opts.into_iter().try_fold( + SELinuxOptions::default(), + |mut se_linux_options, security_opt| { + let security_opt = if security_opt == "no-new-privileges:true" { + SecurityOpt::NoNewPrivileges + } else if security_opt == "no-new-privileges:false" { + return Ok(se_linux_options); + } else { + security_opt.replacen(':', "=", 1).parse()? + }; + + match security_opt { + SecurityOpt::Apparmor(_) => Err(eyre::eyre!( + "`apparmor` security_opt is not supported for pods" + )), + SecurityOpt::Label(label_opt) => match label_opt { + LabelOpt::User(user) => { + se_linux_options.user = Some(user); + Ok(se_linux_options) + } + LabelOpt::Role(role) => { + se_linux_options.role = Some(role); + Ok(se_linux_options) + } + LabelOpt::Type(kind) => { + se_linux_options.type_ = Some(kind); + Ok(se_linux_options) + } + LabelOpt::Level(level) => { + se_linux_options.level = Some(level); + Ok(se_linux_options) + } + LabelOpt::Filetype(_) => Err(eyre::eyre!( + "`label:filetype` security_opt is not supported for pods" + )), + LabelOpt::Disable => Err(eyre::eyre!( + "`label:disable` security_opt is not supported for pods" + )), + LabelOpt::Nested => Err(eyre::eyre!( + "`label:nested` security_opt is not supported for pods" + )), + }, + SecurityOpt::Mask(_) => { + Err(eyre::eyre!("`mask` security_opt is not supported for pods")) + } + SecurityOpt::NoNewPrivileges => Err(eyre::eyre!( + "`no-new-privileges` security_opt is not supported for pods" + )), + SecurityOpt::Seccomp(_) => Err(eyre::eyre!( + "`seccomp` security_opt is not supported for pods" + )), + SecurityOpt::ProcOpts(_) => Err(eyre::eyre!( + "`proc-opts` security_opt is not supported for pods" + )), + SecurityOpt::Unmask(_) => Err(eyre::eyre!( + "`unmask` security_opt is not supported for pods" + )), + } + }, + ) +} + +fn ports_try_into_container_ports(ports: Ports) -> color_eyre::Result> { + match ports { + Ports::Short(ports) => ports + .into_iter() + .map(|port| parse_container_port_from_short(&port)) + .collect(), + Ports::Long(ports) => ports + .into_iter() + .map(|port| { + eyre::ensure!(port.mode.is_none(), "port mode is not supported for pods"); + Ok(ContainerPort { + container_port: port.target.into(), + host_ip: port.host_ip, + host_port: match port.published { + Some(PublishedPort::Single(host_port)) => Some(host_port.into()), + Some(PublishedPort::Range(_)) => { + eyre::bail!("pods do not support published port ranges") + } + None => None, + }, + name: None, + protocol: port.protocol, + }) + }) + .collect(), + } +} + +fn parse_container_port_from_short(port: &str) -> color_eyre::Result { + let (port, protocol) = port + .split_once('/') + .map_or((port, None), |(port, protocol)| { + (port, Some(String::from(protocol))) + }); + + let (host, container_port) = port + .rsplit_once(':') + .map_or((None, port), |(host, container_port)| { + (Some(host), container_port) + }); + let container_port = container_port + .parse() + .wrap_err_with(|| format!("could not parse `{container_port}` as container_port"))?; + + let (host_ip, host_port) = host + .map(|host| { + host.split_once(':') + .map_or((None, host), |(host_ip, host_port)| { + (Some(String::from(host_ip)), host_port) + }) + }) + .unzip(); + let host_port = host_port + .map(|host_port| { + host_port + .parse() + .wrap_err_with(|| format!("could not parse `{host_port}` as host_port")) + }) + .transpose()?; + + Ok(ContainerPort { + container_port, + host_ip: host_ip.flatten(), + host_port, + name: None, + protocol, + }) +} + +fn environment_into_env_vars(environment: Environment) -> Vec { + match environment { + Environment::List(environment) => environment + .into_iter() + .map(|env_var| { + let (name, value) = env_var + .split_once('=') + .map(|(name, value)| (String::from(name), String::from(value))) + .unzip(); + EnvVar { + name: name.unwrap_or(env_var), + value, + value_from: None, + } + }) + .collect(), + Environment::KvPair(environment) => environment + .into_iter() + .map(|(name, value)| EnvVar { + name, + value: value.as_ref().map(ToString::to_string), + value_from: None, + }) + .collect(), + } +} + +fn ulimits_into_resources(ulimits: Ulimits) -> Option { + (!ulimits.is_empty()).then(|| ResourceRequirements { + claims: None, + limits: Some( + ulimits + .0 + .into_iter() + .map(|(name, ulimit)| { + let limit = match ulimit { + Ulimit::Single(limit) => limit, + Ulimit::SoftHard { soft: _, hard } => hard, + }; + (name, Quantity(limit.to_string())) + }) + .collect(), + ), + requests: None, + }) +} + +fn parse_tmpfs_volume_mount(tmpfs: &str, container_name: &str) -> (VolumeMount, Volume) { + let name = volume_name(container_name, tmpfs); + let volume_mount = volume_mount(String::from(tmpfs), name.clone(), false); + (volume_mount, tmpfs_volume(name, None)) +} + +fn compose_volumes_try_into_volume_mounts( + volumes: ComposeVolumes, + container_name: &str, +) -> color_eyre::Result> { + match volumes { + ComposeVolumes::Simple(volumes) => volumes + .into_iter() + .map(|volume| parse_short_volume(volume, container_name)) + .collect(), + ComposeVolumes::Advanced(volumes) => volumes + .into_iter() + .map(|volume| advanced_volume_try_into_volume_mount(volume, container_name)) + .collect(), + } +} + +fn parse_short_volume( + volume: String, + container_name: &str, +) -> color_eyre::Result<(VolumeMount, Volume)> { + let mut split = volume.split(':'); + match split.clone().count() { + // anonymous volume, no options + 1 => { + let name = volume_name(container_name, &volume); + Ok(( + volume_mount(volume, name.clone(), false), + anonymous_volume(name), + )) + } + + // anonymous volume with options, named volume, or bind mount + 2 => { + let source_or_target = split.next().expect("split has 2 elements"); + let target_or_options = split.next().expect("split has 2 elements"); + + if target_or_options.contains('/') { + // named volume or bind mount + let source = source_or_target; + let target = target_or_options; + + if source.starts_with(['.', '/', '~']) { + // bind mount + let name = volume_name(container_name, target); + Ok(( + volume_mount(String::from(target), name.clone(), false), + bind_volume(name, String::from(source)), + )) + } else { + // named volume + let name = String::from(source); + Ok(( + volume_mount(String::from(target), name.clone(), false), + named_volume(name), + )) + } + } else { + // anonymous volume with options + let target = source_or_target; + let options = target_or_options; + + let (target, read_only) = parse_target_and_read_only(target, options); + + let name = volume_name(container_name, &target); + Ok(( + volume_mount(target, name.clone(), read_only), + anonymous_volume(name), + )) + } + } + + // named volume or bind mount with options + 3 => { + let source = split.next().expect("split has 3 elements"); + let target = split.next().expect("split has 3 elements"); + let options = split.next().expect("split has 3 elements"); + + let (target_with_options, read_only) = parse_target_and_read_only(target, options); + + if source.starts_with(['.', '/', '~']) { + // bind mount with options + let name = volume_name(container_name, target); + Ok(( + volume_mount(target_with_options, name.clone(), read_only), + bind_volume(name, String::from(source)), + )) + } else { + // named volume with options + let name = String::from(source); + Ok(( + volume_mount(target_with_options, name.clone(), read_only), + named_volume(name), + )) + } + } + + _ => eyre::bail!("too many `:` in volume definition"), + } +} + +fn parse_target_and_read_only(target: &str, options: &str) -> (String, bool) { + let mut read_only = false; + let target = options + .split(',') + .fold(String::from(target), |target, option| { + if option == "ro" { + read_only = true; + target + } else if option == "rw" { + target + } else if target.contains(':') { + target + "," + option + } else { + target + ":" + option + } + }); + (target, read_only) +} + +fn advanced_volume_try_into_volume_mount( + volume: AdvancedVolumes, + container_name: &str, +) -> color_eyre::Result<(VolumeMount, Volume)> { + let AdvancedVolumes { + source, + target, + _type: kind, + read_only, + bind, + volume, + tmpfs, + } = volume; + + let volume = match kind.as_str() { + "bind" => { + eyre::ensure!( + bind.is_none(), + "bind mount propagation is not supported by pods" + ); + let source = source.ok_or(eyre::eyre!("cannot have a bind mount without a source"))?; + let name = volume_name(container_name, &target); + bind_volume(name, source) + } + "volume" => { + eyre::ensure!( + volume.is_none(), + "volume nocopy option is not supported by pods" + ); + source.map_or_else( + || -> color_eyre::Result<_> { + let name = volume_name(container_name, &target); + Ok(anonymous_volume(name)) + }, + |source| Ok(named_volume(source)), + )? + } + "tmpfs" => { + let name = volume_name(container_name, &target); + tmpfs_volume(name, tmpfs.map(|settings| settings.size)) + } + _ => eyre::bail!("unsupported volume type: `{kind}`"), + }; + + Ok((volume_mount(target, volume.name.clone(), read_only), volume)) +} + +fn volume_name(container_name: &str, path: &str) -> String { + format!("{container_name}{}", path.replace(['/', '\\'], "-")) +} + +fn volume_mount(mount_path: String, name: String, read_only: bool) -> VolumeMount { + VolumeMount { + mount_path, + mount_propagation: None, + name, + read_only: read_only.then_some(true), + sub_path: None, + sub_path_expr: None, + } +} + +fn tmpfs_volume(name: String, size_limit: Option) -> Volume { + Volume { + name, + empty_dir: Some(EmptyDirVolumeSource { + medium: Some(String::from("Memory")), + size_limit: size_limit.map(|size_limit| Quantity(size_limit.to_string())), + }), + aws_elastic_block_store: None, + azure_disk: None, + azure_file: None, + cephfs: None, + cinder: None, + config_map: None, + csi: None, + downward_api: None, + ephemeral: None, + fc: None, + flex_volume: None, + flocker: None, + gce_persistent_disk: None, + git_repo: None, + glusterfs: None, + host_path: None, + iscsi: None, + nfs: None, + persistent_volume_claim: None, + photon_persistent_disk: None, + portworx_volume: None, + projected: None, + quobyte: None, + rbd: None, + scale_io: None, + secret: None, + storageos: None, + vsphere_volume: None, + } +} + +fn anonymous_volume(name: String) -> Volume { + Volume { + name, + empty_dir: Some(EmptyDirVolumeSource::default()), + aws_elastic_block_store: None, + azure_disk: None, + azure_file: None, + cephfs: None, + cinder: None, + config_map: None, + csi: None, + downward_api: None, + ephemeral: None, + fc: None, + flex_volume: None, + flocker: None, + gce_persistent_disk: None, + git_repo: None, + glusterfs: None, + host_path: None, + iscsi: None, + nfs: None, + persistent_volume_claim: None, + photon_persistent_disk: None, + portworx_volume: None, + projected: None, + quobyte: None, + rbd: None, + scale_io: None, + secret: None, + storageos: None, + vsphere_volume: None, + } +} + +fn bind_volume(name: String, path: String) -> Volume { + Volume { + name, + host_path: Some(HostPathVolumeSource { path, type_: None }), + aws_elastic_block_store: None, + azure_disk: None, + azure_file: None, + cephfs: None, + cinder: None, + config_map: None, + csi: None, + downward_api: None, + empty_dir: None, + ephemeral: None, + fc: None, + flex_volume: None, + flocker: None, + gce_persistent_disk: None, + git_repo: None, + glusterfs: None, + iscsi: None, + nfs: None, + persistent_volume_claim: None, + photon_persistent_disk: None, + portworx_volume: None, + projected: None, + quobyte: None, + rbd: None, + scale_io: None, + secret: None, + storageos: None, + vsphere_volume: None, + } +} + +fn named_volume(name: String) -> Volume { + Volume { + name: name.clone(), + persistent_volume_claim: Some(PersistentVolumeClaimVolumeSource { + claim_name: name, + read_only: None, + }), + aws_elastic_block_store: None, + azure_disk: None, + azure_file: None, + cephfs: None, + cinder: None, + config_map: None, + csi: None, + downward_api: None, + empty_dir: None, + ephemeral: None, + fc: None, + flex_volume: None, + flocker: None, + gce_persistent_disk: None, + git_repo: None, + glusterfs: None, + host_path: None, + iscsi: None, + nfs: None, + photon_persistent_disk: None, + portworx_volume: None, + projected: None, + quobyte: None, + rbd: None, + scale_io: None, + secret: None, + storageos: None, + vsphere_volume: None, + } +} + +fn compose_volume_try_into_persistent_volume_claim( + compose_volume: ComposeVolume, + name: String, +) -> color_eyre::Result { + eyre::ensure!( + compose_volume.external.is_none() && compose_volume.name.is_none(), + "external volumes are not supported" + ); + + let annotations: BTreeMap<_, _> = compose_volume + .driver + .map(|driver| Ok((String::from("volume.podman.io/driver"), driver))) + .into_iter() + .chain(driver_opts_try_into_annotations(compose_volume.driver_opts)) + .collect::>()?; + + let labels: BTreeMap<_, _> = match compose_volume.labels { + Labels::List(labels) => labels + .into_iter() + .map(|label| { + #[allow(clippy::map_unwrap_or)] // map_or_else forces clone of label + label + .split_once('=') + .map(|(label, value)| (String::from(label), String::from(value))) + .unwrap_or_else(|| (label, String::new())) + }) + .collect(), + Labels::Map(labels) => labels.into_iter().collect(), + }; + + Ok(PersistentVolumeClaim { + metadata: ObjectMeta { + name: Some(name), + annotations: annotations.filter_empty(), + labels: labels.filter_empty(), + ..ObjectMeta::default() + }, + spec: None, + status: None, + }) +} + +fn driver_opts_try_into_annotations( + driver_opts: IndexMap>, +) -> impl Iterator> { + driver_opts + .into_iter() + .flat_map(|(option, value)| match option.as_str() { + "type" => vec![Ok(( + String::from("volume.podman.io/type"), + value.as_ref().map(ToString::to_string).unwrap_or_default(), + ))], + "device" => vec![Ok(( + String::from("volume.podman.io/device"), + value.as_ref().map(ToString::to_string).unwrap_or_default(), + ))], + "o" => value + .map(|value| MountOptions::from(value.to_string())) + .unwrap_or_default() + .into_annotations() + .map(Ok) + .collect(), + _ => vec![Err(eyre::eyre!( + "unsupported volume driver_opt: `{option}`" + ))], + }) +} + +#[derive(Debug, Default)] +struct MountOptions { + uid: Option, + gid: Option, + options: Option, +} + +impl From for MountOptions { + fn from(value: String) -> Self { + value + .split(',') + .fold(Self::default(), |mut mount_options, option| { + if option.starts_with("uid=") { + let (_, uid) = option + .split_once('=') + .expect("delimiter is in if expression"); + mount_options.uid = Some(String::from(uid)); + mount_options + } else if option.starts_with("gid=") { + let (_, gid) = option + .split_once('=') + .expect("delimiter is in if expression"); + mount_options.gid = Some(String::from(gid)); + mount_options + } else if let Some(options) = mount_options.options { + mount_options.options = Some(options + "," + option); + mount_options + } else { + mount_options.options = Some(String::from(option)); + mount_options + } + }) + } +} + +impl MountOptions { + fn into_annotations(self) -> impl Iterator { + self.uid + .map(|uid| (String::from("volume.podman.io/uid"), uid)) + .into_iter() + .chain( + self.gid + .map(|gid| (String::from("volume.podman.io/gid"), gid)), + ) + .chain( + self.options + .map(|options| (String::from("volume.podman.io/mount-options"), options)), + ) + } +} + +trait FilterDefault { + fn filter_default(self) -> Option + where + Self: Sized; +} + +impl> FilterDefault for T { + fn filter_default(self) -> Option { + (self != Self::default()).then_some(self) + } +} + +trait FilterEmpty { + fn filter_empty(self) -> Option + where + Self: Sized; +} + +impl FilterEmpty for Vec { + fn filter_empty(self) -> Option { + (!self.is_empty()).then_some(self) + } +} + +impl FilterEmpty for BTreeMap { + fn filter_empty(self) -> Option { + (!self.is_empty()).then_some(self) + } +} From 15ec586903585f15d766fe43a40503a3a58adf25 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 8 Jun 2023 19:35:01 -0500 Subject: [PATCH 10/14] fix(compose): correct Default impl for PodmanArgs --- src/cli/container/podman.rs | 106 +++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/src/cli/container/podman.rs b/src/cli/container/podman.rs index d481fce..5f421ef 100644 --- a/src/cli/container/podman.rs +++ b/src/cli/container/podman.rs @@ -8,7 +8,7 @@ use clap::{ArgAction, Args}; use color_eyre::eyre::Context; #[allow(clippy::struct_excessive_bools, clippy::module_name_repetitions)] -#[derive(Args, Default, Debug, Clone, PartialEq)] +#[derive(Args, Debug, Clone, PartialEq)] pub struct PodmanArgs { /// Add a custom host-to-IP mapping /// @@ -443,6 +443,110 @@ pub struct PodmanArgs { workdir: Option, } +impl Default for PodmanArgs { + fn default() -> Self { + Self { + add_host: Vec::new(), + arch: None, + attach: Vec::new(), + authfile: None, + blkio_weight: None, + blkio_weight_device: None, + cgroup_conf: Vec::new(), + cgroup_parent: None, + cgroupns: None, + cgroups: None, + chrootdirs: None, + cidfile: None, + conmon_pidfile: None, + cpu_period: None, + cpu_quota: None, + cpu_rt_period: None, + cpu_rt_runtime: None, + cpu_shares: None, + cpus: None, + cpuset_cpus: None, + cpuset_mems: None, + decryption_key: None, + detach: false, + detach_keys: None, + device_cgroup_rule: Vec::new(), + device_read_bps: Vec::new(), + device_read_iops: Vec::new(), + device_write_bps: Vec::new(), + device_write_iops: Vec::new(), + disable_content_trust: false, + dns: Vec::new(), + dns_option: None, + dns_search: None, + entrypoint: None, + env_merge: Vec::new(), + gidmap: Vec::new(), + group_add: Vec::new(), + group_entry: None, + hostname: None, + hostuser: Vec::new(), + http_proxy: true, + image_volume: None, + init_path: None, + interactive: false, + ipc: None, + label_file: None, + link_local_ip: None, + log_opt: Vec::new(), + mac_address: None, + memory: None, + memory_reservation: None, + memory_swap: None, + memory_swappiness: None, + network_alias: None, + no_healthcheck: false, + no_hosts: false, + oom_kill_disable: false, + oom_score_adj: None, + os: None, + passwd: false, + passwd_entry: None, + personality: None, + pid: None, + pidfile: None, + pids_limit: None, + platform: None, + pod: None, + pod_id_file: None, + preserve_fds: None, + privileged: false, + publish_all: false, + pull: None, + quiet: false, + read_only_tmpfs: true, + replace: false, + requires: None, + rm: false, + rmi: false, + seccomp_policy: None, + shm_size: None, + shm_size_systemd: None, + sig_proxy: true, + stop_signal: None, + stop_timeout: None, + subgidname: None, + subuidname: None, + sysctl: Vec::new(), + systemd: None, + timeout: None, + tls_verify: None, + tty: false, + uidmap: Vec::new(), + ulimit: Vec::new(), + umask: None, + variant: None, + volumes_from: Vec::new(), + workdir: None, + } + } +} + impl PodmanArgs { /// The total resulting number of arguments fn args_len(&self) -> usize { From 25c6caa0a917fe8a12f5324b835b34e02c8f70da Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 8 Jun 2023 19:53:57 -0500 Subject: [PATCH 11/14] fix(compose): use name of pod in k8s yaml filename --- src/cli.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index f4b6692..73d1c01 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -236,7 +236,7 @@ impl Cli { network: Vec::new(), publish_port: Vec::new(), user_ns: None, - yaml: String::from("kube.yaml"), + yaml: format!("{pod_name}-kube.yaml"), }; let quadlet_file = quadlet::File { @@ -250,7 +250,7 @@ impl Cli { Ok(vec![ quadlet_file.into(), File::KubePod { - name: pod_name, + name: format!("{pod_name}-kube"), pod, persistent_volume_claims, }, From fb6284cbe0a33f50876c798b57656f607317cf65 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Sat, 10 Jun 2023 01:45:59 -0500 Subject: [PATCH 12/14] chore: update dependencies --- Cargo.lock | 343 ++++++++++++++++++++++++----------------------------- 1 file changed, 155 insertions(+), 188 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9aeb2d..878c713 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,18 +19,24 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "anstream" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", @@ -62,17 +68,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -157,6 +163,24 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-process" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +dependencies = [ + "async-io", + "async-lock", + "autocfg", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "signal-hook", + "windows-sys", +] + [[package]] name = "async-recursion" version = "1.0.4" @@ -165,7 +189,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -182,7 +206,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -274,20 +298,20 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ - "num-integer", + "android-tzdata", "num-traits", "serde", ] [[package]] name = "clap" -version = "4.2.2" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a" +checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" dependencies = [ "clap_builder", "clap_derive", @@ -296,9 +320,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.2" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6" +checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" dependencies = [ "anstream", "anstyle", @@ -309,21 +333,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "color-eyre" @@ -474,9 +498,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -496,9 +520,9 @@ dependencies = [ [[package]] name = "duration-str" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f94be4825ff6a563f1bfbdb786ae10c687333c7524fade954e2271170e7f7e6d" +checksum = "d9f037c488d179e21c87ef5fa9c331e8e62f5dddfa84618b41bb197da03edff1" dependencies = [ "nom", "rust_decimal", @@ -523,7 +547,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -534,7 +558,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -580,9 +604,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -654,9 +678,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -701,9 +725,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -737,13 +761,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -761,7 +785,7 @@ dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -792,24 +816,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" [[package]] name = "memchr" @@ -864,16 +885,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -885,18 +896,18 @@ dependencies = [ [[package]] name = "object" -version = "0.30.3" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "ordered-float" @@ -931,9 +942,9 @@ checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -979,7 +990,7 @@ dependencies = [ "libc", "log", "pin-project-lite", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1000,18 +1011,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1057,9 +1068,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1068,9 +1079,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "rust_decimal" @@ -1084,22 +1095,22 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1110,9 +1121,9 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "serde" -version = "1.0.160" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] @@ -1129,13 +1140,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -1157,7 +1168,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -1199,6 +1210,25 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + [[package]] name = "slab" version = "0.4.8" @@ -1243,9 +1273,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1254,15 +1284,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall", "rustix", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1282,7 +1313,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.18", ] [[package]] @@ -1312,9 +1343,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" [[package]] name = "toml_edit" @@ -1341,20 +1372,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.18", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -1372,9 +1403,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "sharded-slab", "thread_local", @@ -1405,9 +1436,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -1426,9 +1457,9 @@ checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", @@ -1487,37 +1518,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -1526,93 +1533,51 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -1640,15 +1605,16 @@ dependencies = [ [[package]] name = "zbus" -version = "3.12.0" +version = "3.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29242fa5ec5693629ae74d6eb1f69622a9511f600986d6d9779bccf36ac316e3" +checksum = "6c3d77c9966c28321f1907f0b6c5a5561189d1f7311eea6d94180c6be9daab29" dependencies = [ "async-broadcast", "async-executor", "async-fs", "async-io", "async-lock", + "async-process", "async-recursion", "async-task", "async-trait", @@ -1679,23 +1645,24 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "3.12.0" +version = "3.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537793e26e9af85f774801dc52c6f6292352b2b517c5cf0449ffd3735732a53a" +checksum = "f6e341d12edaff644e539ccbbf7f161601294c9a84ed3d7e015da33155b435af" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "regex", "syn 1.0.109", + "winnow", "zvariant_utils", ] [[package]] name = "zbus_names" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34f314916bd89bdb9934154627fab152f4f28acdda03e7c4c68181b214fe7e3" +checksum = "82441e6033be0a741157a72951a3e4957d519698f3a824439cc131c5ba77ac2a" dependencies = [ "serde", "static_assertions", @@ -1704,9 +1671,9 @@ dependencies = [ [[package]] name = "zvariant" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe4914a985446d6fd287019b5fceccce38303d71407d9e6e711d44954a05d8" +checksum = "622cc473f10cef1b0d73b7b34a266be30ebdcfaea40ec297dd8cbda088f9f93c" dependencies = [ "byteorder", "enumflags2", @@ -1718,9 +1685,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c20260af4b28b3275d6676c7e2a6be0d4332e8e0aba4616d34007fd84e462a" +checksum = "5d9c1b57352c25b778257c661f3c4744b7cefb7fc09dd46909a153cce7773da2" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1731,9 +1698,9 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b22993dbc4d128a17a3b6c92f1c63872dd67198537ee728d8b5d7c40640a8b" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" dependencies = [ "proc-macro2", "quote", From 278c4a1281bbdcda2bd1d327a8e51f35e408cecb Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 15 Jun 2023 01:10:51 -0500 Subject: [PATCH 13/14] chore: update readme and changelog --- .gitignore | 3 - CHANGELOG.md | 11 +- README.md | 25 +- compose-example.yaml | 11 + demo.cast | 550 +++++++++++++++++++++++++++++++++++++++++++ demo.gif | Bin 0 -> 563268 bytes demo.tape | 83 ------- 7 files changed, 590 insertions(+), 93 deletions(-) create mode 100644 compose-example.yaml create mode 100644 demo.cast create mode 100644 demo.gif delete mode 100644 demo.tape diff --git a/.gitignore b/.gitignore index c66cfab..9ef26b9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,3 @@ # VS Code user settings /.vscode - -# VHS Demo -demo.gif diff --git a/CHANGELOG.md b/CHANGELOG.md index fb37162..8a1c0bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,18 @@ # Changelog -## [Unreleased] +## [0.2.0] - 2023-06-15 ### Added -- Check for existing unit files with the same name as the service generated by quadlet from the podlet generated quadlet file and throw an error if there is a conflict (#14). - - Use `--skip-services-check` to opt out. +- Check for existing systemd unit files with the same name as the service generated by quadlet from the podlet generated quadlet file and throw an error if there is a conflict ([#14](https://github.com/k9withabone/podlet/issues/14)). + - Use `--skip-services-check` to opt-out. +- Convert a (docker) compose file ([#9](https://github.com/k9withabone/podlet/issues/9)) to: + - Multiple quadlet files + - A pod with a quadlet kube file and Kubernetes YAML ### Changed -- Breaking: files are no longer overwritten by default, added `--overwrite` flag if overwriting is desired. +- **Breaking**: files are no longer overwritten by default, added `--overwrite` flag if overwriting is desired. ## [0.1.1] - 2023-04-19 diff --git a/README.md b/README.md index 168c674..1a7376d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ Podlet generates [podman](https://podman.io/) [quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) (systemd-like) files from a podman command. -![Made with VHS](https://vhs.charm.sh/vhs-7GpylCk1SkTulSrL7jp6UV.gif) +[![demo.gif](./demo.gif)](https://asciinema.org/a/591369) +You can also view the demo on [asciinema](https://asciinema.org/a/591369). ## Features @@ -16,8 +17,13 @@ Podlet generates [podman](https://podman.io/) [quadlet](https://docs.podman.io/e - `podman kube play` - `podman network create` - `podman volume create` +- Convert a (docker) compose file to: + - Multiple quadlet files + - A pod with a quadlet kube file and Kubernetes YAML - Write to stdout or to a file - Options for including common systemd unit options +- Checks for existing systemd services to avoid conflict + - Opt-out with `--skip-services-check` ## Install @@ -39,13 +45,16 @@ Podlet generates podman quadlet (systemd-like) files from a podman command. Usage: podlet [OPTIONS] Commands: - podman Generate a podman quadlet file from a podman command - help Print this message or the help of the given subcommand(s) + podman Generate a podman quadlet file from a podman command + compose Generate podman quadlet files from a compose file + help Print this message or the help of the given subcommand(s) Options: -f, --file [] Generate a file instead of printing to stdout -u, --unit-directory Generate a file in the podman unit directory instead of printing to stdout [aliases: unit-dir] -n, --name Override the name of the generated file (without the extension) + --overwrite Overwrite existing files when generating a file + --skip-services-check Skip the check for existing services of the same name -d, --description Add a description to the unit --wants Add (weak) requirement dependencies to the unit --requires Similar to --wants, but adds stronger requirement dependencies @@ -63,6 +72,7 @@ To generate a quadlet file, just put `podlet` in front of your podman command! ``` $ podlet podman run quay.io/podman/hello +# hello.container [Container] Image=quay.io/podman/hello ``` @@ -113,10 +123,19 @@ Network=pasta UserNS=auto ``` +Use the following commands for more usage information: +- `podlet --help` +- `podlet podman --help` +- `podlet compose --help` + +## Cautions + Podlet is not (yet) a validator for podman commands. Some podman options are incompatible with each other and most options require specific formatting and/or only accept certain values. However, a few options are fully parsed and validated in order to facilitate creating the quadlet file. For the `kube play`, `network create`, and `volume create` commands, not all of podman's options are available as not all options are supported by quadlet. +When converting compose files, not all options are supported by podman/quadlet. This is especially true when converting to a pod as some options must be applied to the pod as a whole. If podlet encounters an unsupported option an error will be returned. You will have to remove or comment out unsupported options to proceed. + Podlet is meant to be used with podman v4.5.0 or newer. Some quadlet options are unavailable or behave differently with earlier versions of podman/quadlet. ## Contribution diff --git a/compose-example.yaml b/compose-example.yaml new file mode 100644 index 0000000..256518f --- /dev/null +++ b/compose-example.yaml @@ -0,0 +1,11 @@ +services: + caddy: + image: docker.io/library/caddy:latest + ports: + - 8000:80 + - 8443:443 + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy-data:/data +volumes: + caddy-data: diff --git a/demo.cast b/demo.cast new file mode 100644 index 0000000..e5264d4 --- /dev/null +++ b/demo.cast @@ -0,0 +1,550 @@ +{"version": 2, "width": 129, "height": 34, "timestamp": 1686723165, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}, "title": "podlet v0.2.0 demo"} +[0.035786, "o", "\u001b[?2004h$ "] +[0.037764, "o", "p"] +[0.137935, "o", "o"] +[0.238236, "o", "d"] +[0.338354, "o", "l"] +[0.438665, "o", "e"] +[0.538852, "o", "t"] +[0.639016, "o", " "] +[0.739366, "o", "-"] +[0.839662, "o", "h"] +[0.939667, "o", "\r\n\u001b[?2004l\r"] +[0.943095, "o", "Podlet generates podman quadlet (systemd-like) files from a podman command.\r\n\r\n\u001b[1m\u001b[4mUsage:\u001b[0m \u001b[1mpodlet\u001b[0m [OPTIONS] \r\n\r\n\u001b[1m\u001b[4mCommands:\u001b[0m\r\n \u001b[1mpodman\u001b[0m Generate a podman quadlet file from a podman command\r\n \u001b[1mcompose\u001b[0m Generate podman quadlet files from a compose file\r\n \u001b[1mhelp\u001b[0m Print this message or the help of the given subcommand(s)\r\n\r\n\u001b[1m\u001b[4mOptions:\u001b[0m\r\n \u001b[1m-f\u001b[0m, \u001b[1m--file\u001b[0m [] Generate a file instead of printing to stdout\r\n \u001b[1m-u\u001b[0m, \u001b[1m--unit-directory\u001b[0m Generate a file in the podman unit directory instead of printing to stdout [aliases: unit-dir]\r\n \u001b[1m-n\u001b[0m, \u001b[1m--name\u001b[0m Override the name of the generated file (without the extension)\r\n \u001b[1m--overwrite\u001b[0m Overwrite existing files when generating a file\r\n \u001b[1m--skip-services-check\u001b[0m Skip the check for existing services of the same name\r\n \u001b[1m-d\u001b[0m, \u001b[1m--description\u001b[0m Add a description "] +[0.943269, "o", "to the unit\r\n \u001b[1m--wants\u001b[0m Add (weak) requirement dependencies to the unit\r\n \u001b[1m--requires\u001b[0m Similar to --wants, but adds stronger requirement dependencies\r\n \u001b[1m--before\u001b[0m Configure ordering dependency between units\r\n \u001b[1m--after\u001b[0m Configure ordering dependency between units\r\n \u001b[1m-i\u001b[0m, \u001b[1m--install\u001b[0m Add an [Install] section to the unit\r\n \u001b[1m--wanted-by\u001b[0m Add (weak) parent dependencies to the unit\r\n \u001b[1m--required-by\u001b[0m Similar to --wanted-by, but adds stronger parent dependencies\r\n \u001b[1m-h\u001b[0m, \u001b[1m--help\u001b[0m Print help (see more with '--help')\r\n \u001b[1m-V\u001b[0m, \u001b[1m--version\u001b[0m Print version\r\n"] +[0.943869, "o", "\u001b[?2004h$ "] +[8.049493, "o", "\u001b[H\u001b[2J\u001b[3J"] +[8.049967, "o", "\u001b[?2004h$ "] +[8.150679, "o", "p"] +[8.251048, "o", "o"] +[8.351274, "o", "d"] +[8.451459, "o", "l"] +[8.551528, "o", "e"] +[8.651722, "o", "t"] +[8.751704, "o", " "] +[8.852111, "o", "p"] +[8.952416, "o", "o"] +[9.052625, "o", "d"] +[9.152747, "o", "m"] +[9.252927, "o", "a"] +[9.353179, "o", "n"] +[9.453471, "o", " "] +[9.553660, "o", "-"] +[9.653722, "o", "h"] +[9.754043, "o", "\r\n\u001b[?2004l\r"] +[9.757319, "o", "Generate a podman quadlet file from a podman command\r\n\r\n\u001b[1m\u001b[4mUsage:\u001b[0m \u001b[1mpodlet podman\u001b[0m \r\n\r\n\u001b[1m\u001b[4mCommands:\u001b[0m\r\n \u001b[1mrun\u001b[0m Generate a podman quadlet `.container` file\r\n \u001b[1mkube\u001b[0m Generate a podman quadlet `.kube` file\r\n \u001b[1mnetwork\u001b[0m Generate a podman quadlet `.network` file\r\n \u001b[1mvolume\u001b[0m Generate a podman quadlet `.volume` file\r\n \u001b[1mhelp\u001b[0m Print this message or the help of the given subcommand(s)\r\n\r\n\u001b[1m\u001b[4mOptions:\u001b[0m\r\n \u001b[1m-h\u001b[0m, \u001b[1m--help\u001b[0m Print help\r\n"] +[9.758050, "o", "\u001b[?2004h$ "] +[16.863609, "o", "\u001b[H\u001b[2J\u001b[3J"] +[16.863998, "o", "\u001b[?2004h$ "] +[16.964905, "o", "p"] +[17.065108, "o", "o"] +[17.165422, "o", "d"] +[17.265573, "o", "l"] +[17.365654, "o", "e"] +[17.465846, "o", "t"] +[17.566128, "o", " "] +[17.666339, "o", "\\"] +[17.766558, "o", "\r\n\u001b[?2004l\r"] +[17.766789, "o", "\u001b[?2004h> "] +[17.866808, "o", " "] +[17.966970, "o", " "] +[18.067143, "o", "p"] +[18.167347, "o", "o"] +[18.267616, "o", "d"] +[18.367771, "o", "m"] +[18.467929, "o", "a"] +[18.568077, "o", "n"] +[18.668398, "o", " "] +[18.768589, "o", "r"] +[18.868818, "o", "u"] +[18.968970, "o", "n"] +[19.069145, "o", " "] +[19.169374, "o", "\\"] +[19.269590, "o", "\r\n\u001b[?2004l\r"] +[19.269656, "o", "\u001b[?2004h> "] +[19.369841, "o", " "] +[19.469889, "o", " "] +[19.570152, "o", "-"] +[19.670380, "o", "p"] +[19.770679, "o", " "] +[19.870856, "o", "8"] +[19.971039, "o", "0"] +[20.071278, "o", "0"] +[20.171357, "o", "0"] +[20.271705, "o", ":"] +[20.371894, "o", "8"] +[20.472115, "o", "0"] +[20.572337, "o", " "] +[20.672598, "o", "\\"] +[20.772712, "o", "\r\n\u001b[?2004l\r"] +[20.772980, "o", "\u001b[?2004h> "] +[20.872950, "o", " "] +[20.972953, "o", " "] +[21.073212, "o", "-"] +[21.173367, "o", "p"] +[21.273581, "o", " "] +[21.373813, "o", "8"] +[21.473962, "o", "4"] +[21.574200, "o", "4"] +[21.674445, "o", "3"] +[21.774435, "o", ":"] +[21.874821, "o", "4"] +[21.975080, "o", "4"] +[22.075265, "o", "3"] +[22.175371, "o", " "] +[22.275659, "o", "\\"] +[22.375848, "o", "\r\n\u001b[?2004l\r"] +[22.375910, "o", "\u001b[?2004h> "] +[22.476061, "o", " "] +[22.576283, "o", " "] +[22.676457, "o", "-"] +[22.776719, "o", "v"] +[22.876798, "o", " "] +[22.977094, "o", "."] +[23.077336, "o", "/"] +[23.177545, "o", "C"] +[23.277632, "o", "a"] +[23.377961, "o", "d"] +[23.478173, "o", "d"] +[23.578383, "o", "y"] +[23.678626, "o", "f"] +[23.778876, "o", "i"] +[23.879031, "o", "l"] +[23.979246, "o", "e"] +[24.079461, "o", ":"] +[24.179677, "o", "/"] +[24.279964, "o", "e"] +[24.380169, "o", "t"] +[24.480352, "o", "c"] +[24.580613, "o", "/"] +[24.680845, "o", "c"] +[24.781065, "o", "a"] +[24.881162, "o", "d"] +[24.981355, "o", "d"] +[25.081581, "o", "y"] +[25.181875, "o", "/"] +[25.282079, "o", "C"] +[25.382330, "o", "a"] +[25.482510, "o", "d"] +[25.582785, "o", "d"] +[25.682936, "o", "y"] +[25.783171, "o", "f"] +[25.883395, "o", "i"] +[25.983584, "o", "l"] +[26.083826, "o", "e"] +[26.183990, "o", " "] +[26.284167, "o", "\\"] +[26.384365, "o", "\r\n\u001b[?2004l\r"] +[26.384422, "o", "\u001b[?2004h> "] +[26.484807, "o", " "] +[26.584933, "o", " "] +[26.685094, "o", "-"] +[26.785375, "o", "v"] +[26.885511, "o", " "] +[26.985819, "o", "c"] +[27.086027, "o", "a"] +[27.186223, "o", "d"] +[27.286315, "o", "d"] +[27.386485, "o", "y"] +[27.486745, "o", "-"] +[27.586996, "o", "d"] +[27.687154, "o", "a"] +[27.787327, "o", "t"] +[27.887554, "o", "a"] +[27.987756, "o", ":"] +[28.087932, "o", "/"] +[28.188129, "o", "d"] +[28.288386, "o", "a"] +[28.388663, "o", "t"] +[28.488900, "o", "a"] +[28.589032, "o", " "] +[28.689163, "o", "\\"] +[28.789485, "o", "\r\n\u001b[?2004l\r"] +[28.789589, "o", "\u001b[?2004h> "] +[28.889785, "o", " "] +[28.989966, "o", " "] +[29.090075, "o", "d"] +[29.190286, "o", "o"] +[29.290489, "o", "c"] +[29.390770, "o", "k"] +[29.490981, "o", "e"] +[29.591212, "o", "r"] +[29.691269, "o", "."] +[29.791543, "o", "i"] +[29.891739, "o", "o"] +[29.991961, "o", "/"] +[30.091961, "o", "l"] +[30.192264, "o", "i"] +[30.292424, "o", "b"] +[30.392664, "o", "r"] +[30.492891, "o", "a"] +[30.593147, "o", "r"] +[30.693231, "o", "y"] +[30.793435, "o", "/"] +[30.893609, "o", "c"] +[30.993847, "o", "a"] +[31.093972, "o", "d"] +[31.194266, "o", "d"] +[31.294438, "o", "y"] +[31.394787, "o", ":"] +[31.495043, "o", "l"] +[31.595204, "o", "a"] +[31.695433, "o", "t"] +[31.795651, "o", "e"] +[31.895965, "o", "s"] +[31.996115, "o", "t"] +[32.096297, "o", "\r\n\u001b[?2004l\r"] +[32.099684, "o", "# caddy.container\r\n[Container]\r\nImage=docker.io/library/caddy:latest\r\nPublishPort=8000:80\r\nPublishPort=8443:443\r\nVolume=./Caddyfile:/etc/caddy/Caddyfile\r\nVolume=caddy-data:/data\r\n"] +[32.100421, "o", "\u001b[?2004h$ "] +[40.206173, "o", "\u001b[H\u001b[2J\u001b[3J"] +[40.206655, "o", "\u001b[?2004h$ "] +[40.307470, "o", "p"] +[40.407703, "o", "o"] +[40.507934, "o", "d"] +[40.608150, "o", "l"] +[40.708295, "o", "e"] +[40.808424, "o", "t"] +[40.908631, "o", " "] +[41.008791, "o", "-"] +[41.109049, "o", "-"] +[41.209284, "o", "f"] +[41.309350, "o", "i"] +[41.409625, "o", "l"] +[41.509849, "o", "e"] +[41.609981, "o", " "] +[41.709859, "o", "."] +[41.810158, "o", " "] +[41.910382, "o", "-"] +[42.010575, "o", "-"] +[42.110769, "o", "i"] +[42.210978, "o", "n"] +[42.310978, "o", "s"] +[42.411338, "o", "t"] +[42.511515, "o", "a"] +[42.611760, "o", "l"] +[42.711918, "o", "l"] +[42.811936, "o", " "] +[42.912290, "o", "\\"] +[43.012438, "o", "\r\n\u001b[?2004l\r"] +[43.012497, "o", "\u001b[?2004h"] +[43.012516, "o", "> "] +[43.112729, "o", " "] +[43.212897, "o", " "] +[43.313018, "o", "p"] +[43.413217, "o", "o"] +[43.513462, "o", "d"] +[43.613598, "o", "m"] +[43.713695, "o", "a"] +[43.813822, "o", "n"] +[43.914067, "o", " "] +[44.014334, "o", "r"] +[44.114541, "o", "u"] +[44.214705, "o", "n"] +[44.314784, "o", " "] +[44.415074, "o", "\\"] +[44.515291, "o", "\r\n\u001b[?2004l\r"] +[44.515343, "o", "\u001b[?2004h> "] +[44.615456, "o", " "] +[44.715645, "o", " "] +[44.815933, "o", "-"] +[44.916004, "o", "-"] +[45.016088, "o", "r"] +[45.116353, "o", "e"] +[45.216460, "o", "s"] +[45.316581, "o", "t"] +[45.416800, "o", "a"] +[45.517128, "o", "r"] +[45.617235, "o", "t"] +[45.717296, "o", " "] +[45.817467, "o", "a"] +[45.917798, "o", "l"] +[46.017841, "o", "w"] +[46.118023, "o", "a"] +[46.218161, "o", "y"] +[46.318388, "o", "s"] +[46.418643, "o", " "] +[46.518846, "o", "\\"] +[46.618943, "o", "\r\n\u001b[?2004l\r"] +[46.618999, "o", "\u001b[?2004h> "] +[46.719025, "o", " "] +[46.819169, "o", " "] +[46.919380, "o", "-"] +[47.019596, "o", "p"] +[47.119765, "o", " "] +[47.219992, "o", "8"] +[47.320176, "o", "0"] +[47.420425, "o", "0"] +[47.520638, "o", "0"] +[47.620826, "o", ":"] +[47.720873, "o", "8"] +[47.821138, "o", "0"] +[47.921279, "o", " "] +[48.021531, "o", "\\"] +[48.121761, "o", "\r\n\u001b[?2004l\r"] +[48.121814, "o", "\u001b[?2004h> "] +[48.221947, "o", " "] +[48.322177, "o", " "] +[48.422409, "o", "-"] +[48.522582, "o", "p"] +[48.622761, "o", " "] +[48.722917, "o", "8"] +[48.823148, "o", "4"] +[48.923413, "o", "4"] +[49.023648, "o", "3"] +[49.123893, "o", ":"] +[49.224058, "o", "4"] +[49.324326, "o", "4"] +[49.424513, "o", "3"] +[49.524702, "o", " "] +[49.624930, "o", "\\"] +[49.725126, "o", "\r\n\u001b[?2004l\r"] +[49.725374, "o", "\u001b[?2004h> "] +[49.825327, "o", " "] +[49.925508, "o", " "] +[50.025749, "o", "-"] +[50.125957, "o", "v"] +[50.226146, "o", " "] +[50.326295, "o", "."] +[50.426543, "o", "/"] +[50.526667, "o", "C"] +[50.626935, "o", "a"] +[50.727165, "o", "d"] +[50.827324, "o", "d"] +[50.927495, "o", "y"] +[51.027591, "o", "f"] +[51.127928, "o", "i"] +[51.228208, "o", "l"] +[51.328372, "o", "e"] +[51.428631, "o", ":"] +[51.528913, "o", "/"] +[51.629026, "o", "e"] +[51.729221, "o", "t"] +[51.829489, "o", "c"] +[51.929655, "o", "/"] +[52.029816, "o", "c"] +[52.130069, "o", "a"] +[52.230331, "o", "d"] +[52.330536, "o", "d"] +[52.430709, "o", "y"] +[52.530926, "o", "/"] +[52.631127, "o", "C"] +[52.731398, "o", "a"] +[52.831607, "o", "d"] +[52.931860, "o", "d"] +[53.031821, "o", "y"] +[53.132146, "o", "f"] +[53.232136, "o", "i"] +[53.332456, "o", "l"] +[53.432656, "o", "e"] +[53.532882, "o", " "] +[53.633189, "o", "\\"] +[53.733349, "o", "\r\n\u001b[?2004l\r"] +[53.733412, "o", "\u001b[?2004h> "] +[53.833525, "o", " "] +[53.933782, "o", " "] +[54.033915, "o", "-"] +[54.134170, "o", "v"] +[54.234328, "o", " "] +[54.334535, "o", "c"] +[54.434758, "o", "a"] +[54.535025, "o", "d"] +[54.635185, "o", "d"] +[54.735422, "o", "y"] +[54.835618, "o", "-"] +[54.935842, "o", "d"] +[55.036065, "o", "a"] +[55.136324, "o", "t"] +[55.236466, "o", "a"] +[55.336641, "o", ":"] +[55.436862, "o", "/"] +[55.537133, "o", "d"] +[55.637314, "o", "a"] +[55.737429, "o", "t"] +[55.837729, "o", "a"] +[55.937827, "o", " "] +[56.037985, "o", "\\"] +[56.138343, "o", "\r\n\u001b[?2004l\r"] +[56.138432, "o", "\u001b[?2004h> "] +[56.238490, "o", " "] +[56.338652, "o", " "] +[56.439109, "o", "d"] +[56.539226, "o", "o"] +[56.639364, "o", "c"] +[56.739669, "o", "k"] +[56.839890, "o", "e"] +[56.940137, "o", "r"] +[57.040347, "o", "."] +[57.140526, "o", "i"] +[57.240789, "o", "o"] +[57.340985, "o", "/"] +[57.441170, "o", "l"] +[57.541516, "o", "i"] +[57.641659, "o", "b"] +[57.741638, "o", "r"] +[57.841957, "o", "a"] +[57.942148, "o", "r"] +[58.042325, "o", "y"] +[58.142514, "o", "/"] +[58.242758, "o", "c"] +[58.342983, "o", "a"] +[58.443236, "o", "d"] +[58.543477, "o", "d"] +[58.643653, "o", "y"] +[58.743813, "o", ":"] +[58.843859, "o", "l"] +[58.944079, "o", "a"] +[59.044350, "o", "t"] +[59.144521, "o", "e"] +[59.244731, "o", "s"] +[59.344973, "o", "t"] +[59.445182, "o", "\r\n\u001b[?2004l\r"] +[60.082085, "o", "Wrote to file: ./caddy.container\r\n"] +[60.082562, "o", "\u001b[?2004h$ "] +[63.287302, "o", "c"] +[63.387434, "o", "a"] +[63.487626, "o", "t"] +[63.587829, "o", " "] +[63.688098, "o", "c"] +[63.788246, "o", "a"] +[63.888440, "o", "d"] +[63.988678, "o", "d"] +[64.088881, "o", "y"] +[64.189115, "o", "."] +[64.289392, "o", "c"] +[64.389516, "o", "o"] +[64.489744, "o", "n"] +[64.589995, "o", "t"] +[64.690067, "o", "a"] +[64.790447, "o", "i"] +[64.890630, "o", "n"] +[64.990732, "o", "e"] +[65.090891, "o", "r"] +[65.191138, "o", "\r\n\u001b[?2004l\r"] +[65.192927, "o", "[Container]\r\nImage=docker.io/library/caddy:latest\r\nPublishPort=8000:80\r\nPublishPort=8443:443\r\nVolume=./Caddyfile:/etc/caddy/Caddyfile\r\nVolume=caddy-data:/data\r\n\r\n[Service]\r\nRestart=always\r\n\r\n[Install]\r\nWantedBy=default.target\r\n"] +[65.193321, "o", "\u001b[?2004h$ "] +[75.298845, "o", "\u001b[H\u001b[2J\u001b[3J"] +[75.299309, "o", "\u001b[?2004h$ "] +[75.400226, "o", "c"] +[75.500401, "o", "a"] +[75.600606, "o", "t"] +[75.700787, "o", " "] +[75.801001, "o", "c"] +[75.901179, "o", "o"] +[76.001345, "o", "m"] +[76.101504, "o", "p"] +[76.201678, "o", "o"] +[76.301892, "o", "s"] +[76.402184, "o", "e"] +[76.502376, "o", "-"] +[76.602637, "o", "e"] +[76.702706, "o", "x"] +[76.802981, "o", "a"] +[76.903152, "o", "m"] +[77.003334, "o", "p"] +[77.103578, "o", "l"] +[77.203681, "o", "e"] +[77.303831, "o", "."] +[77.404180, "o", "y"] +[77.504249, "o", "a"] +[77.604436, "o", "m"] +[77.704593, "o", "l"] +[77.804766, "o", "\r\n\u001b[?2004l\r"] +[77.806584, "o", "services:\r\n caddy:\r\n image: docker.io/library/caddy:latest\r\n ports:\r\n - 8000:80\r\n - 8443:443\r\n volumes:\r\n - ./Caddyfile:/etc/caddy/Caddyfile\r\n - caddy-data:/data\r\nvolumes:\r\n caddy-data:\r\n"] +[77.807013, "o", "\u001b[?2004h$ "] +[81.011869, "o", "p"] +[81.112208, "o", "o"] +[81.212335, "o", "d"] +[81.312467, "o", "l"] +[81.412621, "o", "e"] +[81.512951, "o", "t"] +[81.612855, "o", " "] +[81.713001, "o", "c"] +[81.813175, "o", "o"] +[81.913280, "o", "m"] +[82.013520, "o", "p"] +[82.113738, "o", "o"] +[82.214016, "o", "s"] +[82.314164, "o", "e"] +[82.414400, "o", " "] +[82.514523, "o", "c"] +[82.614742, "o", "o"] +[82.714945, "o", "m"] +[82.815178, "o", "p"] +[82.915399, "o", "o"] +[83.015624, "o", "s"] +[83.115671, "o", "e"] +[83.215971, "o", "-"] +[83.316094, "o", "e"] +[83.416344, "o", "x"] +[83.516483, "o", "a"] +[83.616661, "o", "m"] +[83.716846, "o", "p"] +[83.817123, "o", "l"] +[83.917174, "o", "e"] +[84.017389, "o", "."] +[84.117510, "o", "y"] +[84.217590, "o", "a"] +[84.317858, "o", "m"] +[84.418106, "o", "l"] +[84.518265, "o", "\r\n\u001b[?2004l\r"] +[84.521946, "o", "# caddy.container\r\n[Container]\r\nImage=docker.io/library/caddy:latest\r\nPublishPort=8000:80\r\nPublishPort=8443:443\r\nVolume=./Caddyfile:/etc/caddy/Caddyfile\r\nVolume=caddy-data:/data\r\n"] +[84.522630, "o", "\u001b[?2004h$ "] +[91.727125, "o", "p"] +[91.827523, "o", "o"] +[91.927696, "o", "d"] +[92.027901, "o", "l"] +[92.127877, "o", "e"] +[92.228252, "o", "t"] +[92.328473, "o", " "] +[92.428732, "o", "c"] +[92.528948, "o", "o"] +[92.629149, "o", "m"] +[92.729385, "o", "p"] +[92.829439, "o", "o"] +[92.929704, "o", "s"] +[93.029925, "o", "e"] +[93.130143, "o", " "] +[93.230416, "o", "-"] +[93.330633, "o", "-"] +[93.430848, "o", "p"] +[93.531091, "o", "o"] +[93.631299, "o", "d"] +[93.731401, "o", " "] +[93.831609, "o", "c"] +[93.931782, "o", "a"] +[94.031944, "o", "d"] +[94.132015, "o", "d"] +[94.232208, "o", "y"] +[94.332439, "o", "-"] +[94.432639, "o", "e"] +[94.532862, "o", "x"] +[94.632820, "o", "a"] +[94.733007, "o", "m"] +[94.833147, "o", "p"] +[94.933381, "o", "l"] +[95.033554, "o", "e"] +[95.133782, "o", " "] +[95.233905, "o", "c"] +[95.334140, "o", "o"] +[95.434368, "o", "m"] +[95.534609, "o", "p"] +[95.634697, "o", "o"] +[95.735014, "o", "s"] +[95.835231, "o", "e"] +[95.935397, "o", "-"] +[96.035615, "o", "e"] +[96.135771, "o", "x"] +[96.235982, "o", "a"] +[96.336212, "o", "m"] +[96.436369, "o", "p"] +[96.536630, "o", "l"] +[96.636742, "o", "e"] +[96.737008, "o", "."] +[96.837122, "o", "y"] +[96.937309, "o", "a"] +[97.037480, "o", "m"] +[97.137714, "o", "l"] +[97.237754, "o", "\r\n\u001b[?2004l\r"] +[97.241351, "o", "# caddy-example.kube\r\n[Kube]\r\nYaml=caddy-example-kube.yaml\r\n\r\n---\r\n\r\n# caddy-example-kube.yaml\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n name: caddy-example\r\nspec:\r\n containers:\r\n - image: docker.io/library/caddy:latest\r\n name: caddy\r\n ports:\r\n - containerPort: 80\r\n hostPort: 8000\r\n - containerPort: 443\r\n hostPort: 8443\r\n volumeMounts:\r\n - mountPath: /etc/caddy/Caddyfile\r\n name: caddy-etc-caddy-Caddyfile\r\n - mountPath: /data\r\n name: caddy-data\r\n volumes:\r\n - hostPath:\r\n path: ./Caddyfile\r\n name: caddy-etc-caddy-Caddyfile\r\n - name: caddy-data\r\n persistentVolumeClaim:\r\n claimName: caddy-data\r\n"] +[97.242122, "o", "\u001b[?2004h$ "] +[107.856640, "o", "\u001b[?2004l\r\n"] diff --git a/demo.gif b/demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..28005eee779c89896983b8985a5aad13668e7933 GIT binary patch literal 563268 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 z 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%0D7317_^@jI}bVjLoZgvvbZ>v z-p#7+++!PXkL106BxN49wc?kwP9Vh`q}1r##-{@;fC8A{0|Ey`5Nad^1-Qf`xDX5Y z_(Cr?g$CT}gtl!Y+2~Kj8WVB<=<*d|=v4)47)b{=Bgi6Nz$U>6DhW~`34##CfFx)I zM?@t898dzApb2;qO+p|O<4LAU!b*S?d=aMtWf~FcKk}Cdi`3item8S~CiNT}+G)Kd zJzPh@amG${9!9H3mp|b0wH7J9eQK?8vL#HFILLY|(re^S*|WphO)g4bSzx$F4?cU| zT(Z1DmyuRU-H*#+_Kc_XL<7g0IIVZ{>d}4Agpc|AU(OWAMHcNX@`EqXqeMOP9gmnH ze(tq5*O-;9a^!F_6u-H&wu*&Ct@b4p7H5c~VHYrtJ8VtH!ONvf=g|}m?m#qn2UfVj zfnqR=FogA)@c$y5;l_t+BMv+GcJbmHvt~W|qPJ~J-<_RZS$XAj=_%@he){wQIx-*{ zq8JenjFW&sG&BUv1sM_G6jcdxK~mrysuGZ=M>VRv5c1U8jZ>Jw7X(M=I3Cgj1wem@ z(If(>5IPWq2sPk>NmC)A1`;LY__u0;-4GQD9R2>Yw>iB>|Mtmfzs9wjKEnLm7WS*j zxW80io7=ou8ts{+DyZ=l*r`&v)|Rc?WP4RBxK5meYyLpmwj%YD#1ZX*r#4%df6N`a ztlptG>bkDIjc)ZB^^-)%b!!vF=9^UGC0zSG^xZx$T+yul#aXC8FDSuY=n$*t0%ESh(kc3q-dzs0dI)xz9oi!8ji*|TBg zr-m5}bCe!Hjbm?%3z;sN8~KH~W5Rrn9_HWO#?79!V8-C#($rE~rhXQ&4 zbWRg=8bJvV0XL#IVkS5S^dJ>M6>y_00%CBU0~as>8fdsKoW6^f1fXCM8n#jxtBc@? znYt)Rl#~>MZ}=c6j015Dw-osJ9$0|Eo$Brp;NWF~+PkpOgo za-2JmA1H^eAQfaQkP00!&?In&CXtUoHc%#|BsjBxJE;^(2K3M>R^vjVpaY@>{m?Bm zM%1gzuua`eCEo&H3t=pM{|>CP{IGl z-j|2fxbN*hYiPAvO{)Q^WR*&2+ZlJJtWs2pka?d#!N=O-^ zkhu~vXS0nPzx#QESU|P`an$GV0K(}sG*SsPs3rae zS(hLQI0J5wXA>}uSqNfi0CWO+AQdo$5)*F(+F;0m2swx`)+YdN8LAAJf=hrYXvQ)M ziyy!%U&@R2~d#|qChl{G%!Eu3xXUoW*} z>D+qDa*L8a%yjVqzmbEO>EfNL z)5UI(aDGDx2dwcIkM|P3_yn)OH}DF?1LeRjKu;hGyaN4zETB)&3=jkKfGjx&4(LPp zfmE=96aj!#(1V335mZ&ALgq;zG4KlI28#$}S-e7A2~vq20!%><7NejUi%#$j*9y^t z`8zTC#|ZvMKU+W9_7^uq_GiW9#m9f2!f_m{*$q-S_FRnOT}r6@I@$JeV>PEHmVe|| zcCzht?~7w{gOz7LPewiytu~e_+c~>GXY+;=vO(bE%BZ`)-i4pN~Hp&l^yb zJlT=Xj5)a5ZXw6|2AOR8>Cq!K<^>t>Ql~dF+19zynowp#M8~RmA(O)KsN)kZ&VD{B z+pW5GJszm8Z5X)?sRdlo69K%DgN|H(Xf6$z7*?`H3{>k;bb?_pOE zI_`6S?Ty+Qb!1DV&9CR)d>}=+;a_s!cO|dSM-r)&gN$MQ5!;p%9goXxwbzbW$8NXO zbVs|?;x(9=UwmfP&2#iVtL2cKnhUfu4=r}B)1W%@1oXXMK807;IJ`rxUVmOs{v zIR@mqw>p(i*?O1+R)+TK(U^q8oHZACbgyvrD>&oYk|`ml=WsNo{ddVD z*;p735J)Q&zG0DE9(QU7`cg&au(GMUQhm0R&l`Rc@5s(mvi5u_rlXan73By~qE�BxWjsYXBUG#yb&MCS)Rr2FBUi2WowU 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 Lv1>=5fX4p;0BOt# literal 0 HcmV?d00001 diff --git a/demo.tape b/demo.tape deleted file mode 100644 index 4978631..0000000 --- a/demo.tape +++ /dev/null @@ -1,83 +0,0 @@ -# Podlet demo using VHS (https://github.com/charmbracelet/vhs) - -Output demo.gif - -Set Width 1650 -Set Height 1100 -Set LineHeight 1.5 - -# Setup -Hide -Type "cargo build --release && alias podlet=target/release/podlet && clear" -Enter -Sleep 500ms -Show - -Sleep 500ms -Type "podlet -h" -Enter -Sleep 7s - -Hide -Type "clear" -Enter -Show -Sleep 500ms - -Type "podlet podman -h" -Enter -Sleep 7s - -Hide -Type "clear" -Enter -Show -Sleep 500ms - -Type "podlet \" -Enter -Type " podman run \" -Enter -Type " -p 8000:80 \" -Enter -Type " -p 8443:443 \" -Enter -Type " -v ./Caddyfile:/etc/caddy/Caddyfile \" -Enter -Type " -v caddy_data:/data \" -Enter -Type " docker.io/library/caddy:latest" -Enter -Sleep 8s - -Hide -Type "clear" -Enter -Show -Sleep 500ms - -Type "podlet --file . --install \" -Enter -Type " podman run \" -Enter -Type " --restart always \" -Enter -Type " -p 8000:80 \" -Enter -Type " -p 8443:443 \" -Enter -Type " -v ./Caddyfile:/etc/caddy/Caddyfile \" -Enter -Type " -v caddy_data:/data \" -Enter -Type " docker.io/library/caddy:latest" -Enter -Sleep 3s -Type "cat caddy.container" -Enter -Sleep 10s - -# Cleanup -Hide -Type "unalias podlet; rm caddy.container" -Enter From 18140a32a8cc190e9446bb177a3d35288a729592 Mon Sep 17 00:00:00 2001 From: Paul Nettleton Date: Thu, 15 Jun 2023 01:28:10 -0500 Subject: [PATCH 14/14] chore: update cargo-dist --- .github/workflows/release.yml | 30 +++++++++++++++--------------- Cargo.lock | 2 +- Cargo.toml | 17 +++++++---------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18b71f6..dc129e4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,19 +52,19 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install Rust - run: rustup update 1.68.2 --no-self-update && rustup default 1.68.2 + run: rustup update 1.70.0 --no-self-update && rustup default 1.70.0 - name: Install cargo-dist - run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.5/cargo-dist-v0.0.5-installer.sh | sh + run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.7/cargo-dist-installer.sh | sh - id: create-release run: | - cargo dist manifest --tag=${{ github.ref_name }} --artifacts=all --no-local-paths --output-format=json > dist-manifest.json - echo "dist manifest ran successfully" + cargo dist plan --tag=${{ github.ref_name }} --output-format=json > dist-manifest.json + echo "dist plan ran successfully" cat dist-manifest.json - + # Create the Github Releaseā„¢ based on what cargo-dist thinks it should be - ANNOUNCEMENT_TITLE=$(cat dist-manifest.json | jq --raw-output ".announcement_title") - IS_PRERELEASE=$(cat dist-manifest.json | jq --raw-output ".announcement_is_prerelease") - cat dist-manifest.json | jq --raw-output ".announcement_github_body" > new_dist_announcement.md + ANNOUNCEMENT_TITLE=$(jq --raw-output ".announcement_title" dist-manifest.json) + IS_PRERELEASE=$(jq --raw-output ".announcement_is_prerelease" dist-manifest.json) + jq --raw-output ".announcement_github_body" dist-manifest.json > new_dist_announcement.md gh release create ${{ github.ref_name }} --draft --prerelease="$IS_PRERELEASE" --title="$ANNOUNCEMENT_TITLE" --notes-file=new_dist_announcement.md echo "created announcement!" @@ -73,7 +73,7 @@ jobs: echo "uploaded manifest!" # Disable all the upload-artifacts tasks if we have no actual releases - HAS_RELEASES=$(cat dist-manifest.json | jq --raw-output ".releases != null") + HAS_RELEASES=$(jq --raw-output ".releases != null" dist-manifest.json) echo "has-releases=$HAS_RELEASES" >> "$GITHUB_OUTPUT" # Build and packages all the things @@ -87,13 +87,13 @@ jobs: include: - os: macos-11 dist-args: --artifacts=local --target=aarch64-apple-darwin --target=x86_64-apple-darwin - install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.5/cargo-dist-v0.0.5-installer.sh | sh + install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.7/cargo-dist-installer.sh | sh - os: ubuntu-20.04 dist-args: --artifacts=local --target=x86_64-unknown-linux-gnu - install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.5/cargo-dist-v0.0.5-installer.sh | sh + install-dist: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.0.7/cargo-dist-installer.sh | sh - os: windows-2019 dist-args: --artifacts=local --target=x86_64-pc-windows-msvc - install-dist: irm https://github.com/axodotdev/cargo-dist/releases/download/v0.0.5/cargo-dist-v0.0.5-installer.ps1 | iex + install-dist: irm https://github.com/axodotdev/cargo-dist/releases/download/v0.0.7/cargo-dist-installer.ps1 | iex runs-on: ${{ matrix.os }} env: @@ -101,7 +101,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install Rust - run: rustup update 1.68.2 --no-self-update && rustup default 1.68.2 + run: rustup update 1.70.0 --no-self-update && rustup default 1.70.0 - name: Install cargo-dist run: ${{ matrix.install-dist }} - name: Run cargo-dist @@ -116,7 +116,7 @@ jobs: cat dist-manifest.json # Parse out what we just built and upload it to the Github Releaseā„¢ - cat dist-manifest.json | jq --raw-output ".artifacts[]?.path | select( . != null )" > uploads.txt + jq --raw-output ".artifacts[]?.path | select( . != null )" dist-manifest.json > uploads.txt echo "uploading..." cat uploads.txt gh release upload ${{ github.ref_name }} $(cat uploads.txt) @@ -134,4 +134,4 @@ jobs: - uses: actions/checkout@v3 - name: mark release as non-draft run: | - gh release edit ${{ github.ref_name }} --draft=false \ No newline at end of file + gh release edit ${{ github.ref_name }} --draft=false diff --git a/Cargo.lock b/Cargo.lock index 878c713..fd38aba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -960,7 +960,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "podlet" -version = "0.2.0-alpha.2" +version = "0.2.0" dependencies = [ "clap", "color-eyre", diff --git a/Cargo.toml b/Cargo.toml index 665032f..a41a69e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "podlet" -version = "0.2.0-alpha.2" +version = "0.2.0" authors = ["Paul Nettleton "] edition = "2021" description = "Podlet generates podman quadlet (systemd-like) files from a podman command." @@ -17,7 +17,7 @@ docker-compose-types = "0.5.1" duration-str = { version = "0.5", default-features = false } indexmap = { version = "1.9", features = ["std"] } ipnet = "2.7" -k8s-openapi = { version = "0.18.0", features = ["v1_26"], default-features = false } +k8s-openapi = { version = "0.18", features = ["v1_26"], default-features = false } serde_yaml = "0.9.21" shlex = "1.1" thiserror = "1.0.40" @@ -35,15 +35,12 @@ lto = "thin" # Config for 'cargo dist' [workspace.metadata.dist] # The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax) -cargo-dist-version = "0.0.5" +cargo-dist-version = "0.0.7" # The preferred Rust toolchain to use in CI (rustup toolchain syntax) -rust-toolchain-version = "1.68.2" +rust-toolchain-version = "1.70.0" # CI backends to support (see 'cargo dist generate-ci') ci = ["github"] # Target platforms to build apps for (Rust target-triple syntax) -targets = [ - "x86_64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-pc-windows-msvc", - "aarch64-apple-darwin", -] +targets = ["x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-msvc", "aarch64-apple-darwin"] +# The installers to generate for each app +installers = []