Skip to content

Commit

Permalink
refactor(compose): container quadlet options from `compose_spec::Serv…
Browse files Browse the repository at this point in the history
…ice`

Split up `compose_spec::Service` into separate parts in
`cli::container::compose`. Allows for destructuring, ensuring all fields
of `compose_spec::Service` are considered for conversion. Also, no more
`TryFrom<&mut ComposeService>`, yay!

Signed-off-by: Paul Nettleton <k9@k9withabone.dev>
  • Loading branch information
k9withabone committed Apr 26, 2024
1 parent 916ea15 commit d3da789
Show file tree
Hide file tree
Showing 11 changed files with 1,072 additions and 396 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ ipnet = { version = "2.7", features = ["serde"] }
k8s-openapi = { version = "0.21", features = ["latest"] }
path-clean = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9.21"
shlex = "1.3"
smart-default = "0.7"
Expand Down
17 changes: 9 additions & 8 deletions src/cli/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use color_eyre::{
eyre::{bail, eyre, OptionExt, WrapErr},
Help,
};
use compose_spec::{Compose, Identifier, Network, Networks, Resource, Service, Volumes};
use compose_spec::{
service::Command, Compose, Identifier, Network, Networks, Resource, Service, Volumes,
};

use crate::quadlet::{self, container::volume::Source, Globals};

Expand Down Expand Up @@ -84,25 +86,24 @@ fn from_stdin() -> color_eyre::Result<Compose> {
serde_yaml::from_reader(stdin).wrap_err("data from stdin is not a valid compose file")
}

/*
/// Converts a [`Command`] into a `Vec<String>`, splitting the `String` variant as a shell would.
/// Converts a [`Command`] into a [`Vec<String>`], splitting the [`String`](Command::String) variant
/// as a shell would.
///
/// # Errors
///
/// Returns an error if, while splitting the string variant, the command ends while in a quote or
/// has a trailing unescaped '\\'.
pub fn command_try_into_vec(command: Command) -> color_eyre::Result<Vec<String>> {
match command {
Command::Simple(s) => shlex::split(&s)
.ok_or_else(|| eyre::eyre!("invalid command: `{s}`"))
Command::String(command) => shlex::split(&command)
.ok_or_else(|| eyre!("invalid command: `{command}`"))
.suggestion(
"In the command, make sure quotes are closed properly and there are no \
trailing \\. Alternatively, use an array instead of a string.",
trailing \\. Alternatively, use an array instead of a string.",
),
Command::Args(args) => Ok(args),
Command::List(command) => Ok(command),
}
}
*/

/// Attempt to convert a [`Compose`] file into an [`Iterator`] of [`quadlet::File`]s.
///
Expand Down
57 changes: 23 additions & 34 deletions src/cli/container.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
mod compose;
mod podman;
mod quadlet;
pub mod security_opt;

use std::mem;

use clap::Args;
use color_eyre::eyre::{self, Context, OptionExt};
use color_eyre::eyre::{Context, OptionExt};

use crate::{cli::compose, escape::command_join};
use crate::escape::command_join;

use self::{podman::PodmanArgs, quadlet::QuadletOptions, security_opt::SecurityOpt};

Expand Down Expand Up @@ -59,29 +58,22 @@ impl Container {
impl TryFrom<compose_spec::Service> for Container {
type Error = color_eyre::Report;

fn try_from(mut value: compose_spec::Service) -> Result<Self, Self::Error> {
todo!()
/*
let service = &value.service;
let unsupported_options = [
("deploy", service.deploy.is_none()),
("build", service.build_.is_none()),
("profiles", service.profiles.is_empty()),
("links", service.links.is_empty()),
("net", service.net.is_none()),
("volumes_from", service.volumes_from.is_empty()),
("extends", service.extends.is_empty()),
("scale", service.scale == 0),
];
for (option, not_present) in unsupported_options {
eyre::ensure!(not_present, "`{option}` is unsupported");
}
eyre::ensure!(
service.extensions.is_empty(),
"compose extensions are not supported"
);
fn try_from(value: compose_spec::Service) -> Result<Self, Self::Error> {
let compose::Service {
unsupported,
quadlet,
podman_args,
container:
compose::Container {
command,
image,
security_opt,
},
} = compose::Service::from(value);

unsupported.ensure_empty()?;

let security_opt = mem::take(&mut value.service.security_opt)
let security_opt = security_opt
.into_iter()
.filter_map(|s| {
if s == "no-new-privileges:true" {
Expand All @@ -96,18 +88,15 @@ impl TryFrom<compose_spec::Service> for Container {
.wrap_err("invalid security option")?;

Ok(Self {
quadlet_options: (&mut value).try_into()?,
podman_args: (&mut value.service).try_into()?,
quadlet_options: quadlet.try_into()?,
podman_args: podman_args.try_into()?,
security_opt,
image: value.service.image.ok_or_eyre("image is required")?,
command: value
.service
.command
.map(compose::command_try_into_vec)
image: image.ok_or_eyre("`image` is required")?.into(),
command: command
.map(super::compose::command_try_into_vec)
.transpose()?
.unwrap_or_default(),
})
*/
}
}

Expand Down
Loading

0 comments on commit d3da789

Please # to comment.