Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update compose_spec to v0.3.0 #122

Merged
merged 3 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ verbose_file_reads = "warn"
[dependencies]
clap = { version = "4.2", features = ["derive", "wrap_help"] }
color-eyre = "0.6"
compose_spec = "0.2"
compose_spec = "0.3.0"
indexmap = { version = "2", features = ["serde"] }
ipnet = { version = "2.7", features = ["serde"] }
k8s-openapi = { version = "0.22.0", features = ["latest"] }
Expand Down
29 changes: 21 additions & 8 deletions src/cli/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use color_eyre::{
eyre::{bail, ensure, eyre, OptionExt, WrapErr},
Help,
};
use compose_spec::{service::Command, Identifier, Network, Networks, Resource, Service, Volumes};
use compose_spec::{
service::Command, Identifier, Network, Networks, Options, Resource, Service, Volumes,
};
use indexmap::IndexMap;

use crate::quadlet::{self, container::volume::Source, Globals};
Expand Down Expand Up @@ -93,8 +95,13 @@ impl Compose {
compose_file,
} = self;

let compose = read_from_file_or_stdin(compose_file.as_deref())
let mut options = compose_spec::Compose::options();
options.apply_merge(true);
let compose = read_from_file_or_stdin(compose_file.as_deref(), &options)
.wrap_err("error reading compose file")?;
compose
.validate_all()
.wrap_err("error validating compose file")?;

if kube {
let mut k8s_file = k8s::File::try_from(compose)
Expand Down Expand Up @@ -163,10 +170,13 @@ impl Compose {
/// - Stdin was selected and stdin is a terminal.
/// - No path was given and none of the default files could be opened.
/// - There was an error deserializing [`compose_spec::Compose`].
fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_spec::Compose> {
fn read_from_file_or_stdin(
path: Option<&Path>,
options: &Options,
) -> color_eyre::Result<compose_spec::Compose> {
let (compose_file, path) = if let Some(path) = path {
if path.as_os_str() == "-" {
return read_from_stdin();
return read_from_stdin(options);
}
let compose_file = fs::File::open(path)
.wrap_err("could not open provided compose file")
Expand All @@ -181,7 +191,7 @@ fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_sp
];

if !io::stdin().is_terminal() {
return read_from_stdin();
return read_from_stdin(options);
}

let mut result = None;
Expand All @@ -199,7 +209,8 @@ fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_sp
)?
};

serde_yaml::from_reader(compose_file)
options
.from_yaml_reader(compose_file)
.wrap_err_with(|| format!("File `{}` is not a valid compose file", path.display()))
}

Expand All @@ -208,13 +219,15 @@ fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_sp
/// # Errors
///
/// Returns an error if stdin is a terminal or there was an error deserializing.
fn read_from_stdin() -> color_eyre::Result<compose_spec::Compose> {
fn read_from_stdin(options: &Options) -> color_eyre::Result<compose_spec::Compose> {
let stdin = io::stdin();
if stdin.is_terminal() {
bail!("cannot read compose from stdin, stdin is a terminal");
}

serde_yaml::from_reader(stdin).wrap_err("data from stdin is not a valid compose file")
options
.from_yaml_reader(stdin)
.wrap_err("data from stdin is not a valid compose file")
}

/// Attempt to convert [`Service`]s, [`Networks`], and [`Volumes`] into [`File`]s.
Expand Down
10 changes: 5 additions & 5 deletions src/cli/container/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use compose_spec::{
service::{
build::Context, device::CgroupRule, AbsolutePath, BlkioConfig, Build, ByteValue, Cgroup,
Command, ConfigOrSecret, CpuSet, Cpus, CredentialSpec, Deploy, Develop, Device, EnvFile,
Expose, Extends, Healthcheck, Hostname, Image, Ipc, Limit, Link, Logging, MacAddress,
NetworkConfig, OomScoreAdj, Percent, Platform, Ports, PullPolicy, Ulimits, UserOrGroup,
Uts, Volumes, VolumesFrom,
Expose, Extends, Healthcheck, Hostname, IdOrName, Image, Ipc, Limit, Link, Logging,
MacAddress, NetworkConfig, OomScoreAdj, Percent, Platform, Ports, PullPolicy, Ulimits,
User, Uts, Volumes, VolumesFrom,
},
Extensions, Identifier, ItemOrList, ListOrMap, MapKey, ShortOrLong, StringOrNumber,
};
Expand Down Expand Up @@ -319,7 +319,7 @@ pub struct Quadlet {
pub environment: ListOrMap,
pub expose: IndexSet<Expose>,
pub annotations: ListOrMap,
pub group_add: IndexSet<UserOrGroup>,
pub group_add: IndexSet<IdOrName>,
pub healthcheck: Option<Healthcheck>,
pub hostname: Option<Hostname>,
pub init: bool,
Expand All @@ -336,7 +336,7 @@ pub struct Quadlet {
pub sysctls: ListOrMap,
pub tmpfs: Option<ItemOrList<AbsolutePath>>,
pub ulimits: Ulimits,
pub user: Option<UserOrGroup>,
pub user: Option<User>,
pub userns_mode: Option<String>,
pub volumes: Volumes,
pub working_dir: Option<AbsolutePath>,
Expand Down
12 changes: 9 additions & 3 deletions src/cli/container/quadlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,12 +933,13 @@ fn network_config_try_into_network_options(
/// Returns an error if the given `network_mode` is not supported by `podman run --network`.
fn validate_network_mode(network_mode: NetworkMode) -> color_eyre::Result<String> {
match network_mode {
NetworkMode::None | NetworkMode::Host => Ok(network_mode.to_string()),
NetworkMode::None | NetworkMode::Host | NetworkMode::Container(_) => {
Ok(network_mode.to_string())
}
NetworkMode::Service(_) => Err(eyre!("network_mode `service:` is not supported")
.suggestion("try using the `container:` network_mode instead")),
NetworkMode::Other(s) => {
if s.starts_with("bridge")
|| s.starts_with("container")
|| s.starts_with("ns:")
|| s == "private"
|| s.starts_with("slirp4netns")
Expand Down Expand Up @@ -971,6 +972,7 @@ fn network_options(
ipv6_address,
link_local_ips,
mac_address,
driver_opts,
priority,
extensions,
}: Network,
Expand All @@ -979,6 +981,10 @@ fn network_options(
link_local_ips.is_empty(),
"network `link_local_ips` option is not supported"
);
ensure!(
driver_opts.is_empty(),
"container specific network `driver_opts` are not supported"
);
ensure!(
priority.is_none(),
"network `priority` option is not supported"
Expand Down Expand Up @@ -1046,7 +1052,7 @@ fn secret_try_into_short(
///
/// Returns an error if the [`Ulimit`] has extensions.
fn ulimit_try_into_short(
(resource, ulimit): (service::Resource, ShortOrLong<u64, Ulimit>),
(resource, ulimit): (service::Resource, ShortOrLong<Limit<u64>, Ulimit>),
) -> color_eyre::Result<String> {
match ulimit {
ShortOrLong::Short(ulimit) => Ok(format!("{resource}={ulimit}")),
Expand Down
35 changes: 22 additions & 13 deletions src/cli/k8s/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod mount;
use std::{collections::BTreeMap, net::IpAddr, time::Duration};

use color_eyre::{
eyre::{bail, ensure, eyre, OptionExt, WrapErr},
eyre::{ensure, eyre, OptionExt, WrapErr},
Section,
};
use compose_spec::{
Expand All @@ -16,8 +16,8 @@ use compose_spec::{
ports::{self, Port, Protocol},
AbsolutePath, BlkioConfig, Build, ByteValue, Cgroup, Command, ConfigOrSecret, CpuSet, Cpus,
CredentialSpec, DependsOn, Deploy, Develop, Device, EnvFile, Expose, Extends, Healthcheck,
Hostname, Image, Ipc, Limit, Link, Logging, MacAddress, NetworkConfig, OomScoreAdj,
Percent, Platform, Ports, PullPolicy, Restart, Ulimits, UserOrGroup, Uts, Volumes,
Hostname, IdOrName, Image, Ipc, Limit, Link, Logging, MacAddress, NetworkConfig,
OomScoreAdj, Percent, Platform, Ports, PullPolicy, Restart, Ulimits, User, Uts, Volumes,
VolumesFrom,
},
Extensions, Identifier, ItemOrList, ListOrMap, Map, ShortOrLong,
Expand Down Expand Up @@ -535,7 +535,7 @@ struct ContainerSecurityContext {
privileged: bool,
read_only: bool,
security_opt: IndexSet<String>,
user: Option<UserOrGroup>,
user: Option<User>,
}

impl ContainerSecurityContext {
Expand Down Expand Up @@ -594,14 +594,23 @@ impl ContainerSecurityContext {
.se_linux_options = Some(se_linux_options);
}

if let Some(user) = user {
let user = match user {
UserOrGroup::Id(user) => user,
UserOrGroup::Name(_) => bail!("only numeric UIDs are supported for `user`"),
};
security_context
.get_or_insert_with(SecurityContext::default)
.run_as_user = Some(user.into());
if let Some(User { user, group }) = user {
let user = user
.as_id()
.ok_or_eyre("only numeric UIDs are supported for `user`")?
.into();
let group = group
.map(|group| {
group
.as_id()
.ok_or_eyre("only numeric GIDs are supported for `user`")
})
.transpose()?
.map(Into::into);

let security_context = security_context.get_or_insert_with(SecurityContext::default);
security_context.run_as_user = Some(user);
security_context.run_as_group = group;
}

Ok(security_context)
Expand Down Expand Up @@ -699,7 +708,7 @@ struct Unsupported {
annotations: ListOrMap,
external_links: IndexSet<Link>,
extra_hosts: IndexMap<Hostname, IpAddr>,
group_add: IndexSet<UserOrGroup>,
group_add: IndexSet<IdOrName>,
hostname: Option<Hostname>,
init: bool,
ipc: Option<Ipc>,
Expand Down