Skip to content

Commit f93a4db

Browse files
authored
Merge pull request #122 from containers/compose_spec-v0.3.0
Update `compose_spec` to v0.3.0
2 parents 3f2bd47 + 7841b4f commit f93a4db

File tree

6 files changed

+62
-34
lines changed

6 files changed

+62
-34
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ verbose_file_reads = "warn"
6060
[dependencies]
6161
clap = { version = "4.2", features = ["derive", "wrap_help"] }
6262
color-eyre = "0.6"
63-
compose_spec = "0.2"
63+
compose_spec = "0.3.0"
6464
indexmap = { version = "2", features = ["serde"] }
6565
ipnet = { version = "2.7", features = ["serde"] }
6666
k8s-openapi = { version = "0.22.0", features = ["latest"] }

src/cli/compose.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use color_eyre::{
1111
eyre::{bail, ensure, eyre, OptionExt, WrapErr},
1212
Help,
1313
};
14-
use compose_spec::{service::Command, Identifier, Network, Networks, Resource, Service, Volumes};
14+
use compose_spec::{
15+
service::Command, Identifier, Network, Networks, Options, Resource, Service, Volumes,
16+
};
1517
use indexmap::IndexMap;
1618

1719
use crate::quadlet::{self, container::volume::Source, Globals};
@@ -93,8 +95,13 @@ impl Compose {
9395
compose_file,
9496
} = self;
9597

96-
let compose = read_from_file_or_stdin(compose_file.as_deref())
98+
let mut options = compose_spec::Compose::options();
99+
options.apply_merge(true);
100+
let compose = read_from_file_or_stdin(compose_file.as_deref(), &options)
97101
.wrap_err("error reading compose file")?;
102+
compose
103+
.validate_all()
104+
.wrap_err("error validating compose file")?;
98105

99106
if kube {
100107
let mut k8s_file = k8s::File::try_from(compose)
@@ -163,10 +170,13 @@ impl Compose {
163170
/// - Stdin was selected and stdin is a terminal.
164171
/// - No path was given and none of the default files could be opened.
165172
/// - There was an error deserializing [`compose_spec::Compose`].
166-
fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_spec::Compose> {
173+
fn read_from_file_or_stdin(
174+
path: Option<&Path>,
175+
options: &Options,
176+
) -> color_eyre::Result<compose_spec::Compose> {
167177
let (compose_file, path) = if let Some(path) = path {
168178
if path.as_os_str() == "-" {
169-
return read_from_stdin();
179+
return read_from_stdin(options);
170180
}
171181
let compose_file = fs::File::open(path)
172182
.wrap_err("could not open provided compose file")
@@ -181,7 +191,7 @@ fn read_from_file_or_stdin(path: Option<&Path>) -> color_eyre::Result<compose_sp
181191
];
182192

183193
if !io::stdin().is_terminal() {
184-
return read_from_stdin();
194+
return read_from_stdin(options);
185195
}
186196

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

202-
serde_yaml::from_reader(compose_file)
212+
options
213+
.from_yaml_reader(compose_file)
203214
.wrap_err_with(|| format!("File `{}` is not a valid compose file", path.display()))
204215
}
205216

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

217-
serde_yaml::from_reader(stdin).wrap_err("data from stdin is not a valid compose file")
228+
options
229+
.from_yaml_reader(stdin)
230+
.wrap_err("data from stdin is not a valid compose file")
218231
}
219232

220233
/// Attempt to convert [`Service`]s, [`Networks`], and [`Volumes`] into [`File`]s.

src/cli/container/compose.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use compose_spec::{
88
service::{
99
build::Context, device::CgroupRule, AbsolutePath, BlkioConfig, Build, ByteValue, Cgroup,
1010
Command, ConfigOrSecret, CpuSet, Cpus, CredentialSpec, Deploy, Develop, Device, EnvFile,
11-
Expose, Extends, Healthcheck, Hostname, Image, Ipc, Limit, Link, Logging, MacAddress,
12-
NetworkConfig, OomScoreAdj, Percent, Platform, Ports, PullPolicy, Ulimits, UserOrGroup,
13-
Uts, Volumes, VolumesFrom,
11+
Expose, Extends, Healthcheck, Hostname, IdOrName, Image, Ipc, Limit, Link, Logging,
12+
MacAddress, NetworkConfig, OomScoreAdj, Percent, Platform, Ports, PullPolicy, Ulimits,
13+
User, Uts, Volumes, VolumesFrom,
1414
},
1515
Extensions, Identifier, ItemOrList, ListOrMap, MapKey, ShortOrLong, StringOrNumber,
1616
};
@@ -319,7 +319,7 @@ pub struct Quadlet {
319319
pub environment: ListOrMap,
320320
pub expose: IndexSet<Expose>,
321321
pub annotations: ListOrMap,
322-
pub group_add: IndexSet<UserOrGroup>,
322+
pub group_add: IndexSet<IdOrName>,
323323
pub healthcheck: Option<Healthcheck>,
324324
pub hostname: Option<Hostname>,
325325
pub init: bool,
@@ -336,7 +336,7 @@ pub struct Quadlet {
336336
pub sysctls: ListOrMap,
337337
pub tmpfs: Option<ItemOrList<AbsolutePath>>,
338338
pub ulimits: Ulimits,
339-
pub user: Option<UserOrGroup>,
339+
pub user: Option<User>,
340340
pub userns_mode: Option<String>,
341341
pub volumes: Volumes,
342342
pub working_dir: Option<AbsolutePath>,

src/cli/container/quadlet.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,12 +933,13 @@ fn network_config_try_into_network_options(
933933
/// Returns an error if the given `network_mode` is not supported by `podman run --network`.
934934
fn validate_network_mode(network_mode: NetworkMode) -> color_eyre::Result<String> {
935935
match network_mode {
936-
NetworkMode::None | NetworkMode::Host => Ok(network_mode.to_string()),
936+
NetworkMode::None | NetworkMode::Host | NetworkMode::Container(_) => {
937+
Ok(network_mode.to_string())
938+
}
937939
NetworkMode::Service(_) => Err(eyre!("network_mode `service:` is not supported")
938940
.suggestion("try using the `container:` network_mode instead")),
939941
NetworkMode::Other(s) => {
940942
if s.starts_with("bridge")
941-
|| s.starts_with("container")
942943
|| s.starts_with("ns:")
943944
|| s == "private"
944945
|| s.starts_with("slirp4netns")
@@ -971,6 +972,7 @@ fn network_options(
971972
ipv6_address,
972973
link_local_ips,
973974
mac_address,
975+
driver_opts,
974976
priority,
975977
extensions,
976978
}: Network,
@@ -979,6 +981,10 @@ fn network_options(
979981
link_local_ips.is_empty(),
980982
"network `link_local_ips` option is not supported"
981983
);
984+
ensure!(
985+
driver_opts.is_empty(),
986+
"container specific network `driver_opts` are not supported"
987+
);
982988
ensure!(
983989
priority.is_none(),
984990
"network `priority` option is not supported"
@@ -1046,7 +1052,7 @@ fn secret_try_into_short(
10461052
///
10471053
/// Returns an error if the [`Ulimit`] has extensions.
10481054
fn ulimit_try_into_short(
1049-
(resource, ulimit): (service::Resource, ShortOrLong<u64, Ulimit>),
1055+
(resource, ulimit): (service::Resource, ShortOrLong<Limit<u64>, Ulimit>),
10501056
) -> color_eyre::Result<String> {
10511057
match ulimit {
10521058
ShortOrLong::Short(ulimit) => Ok(format!("{resource}={ulimit}")),

src/cli/k8s/service.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod mount;
55
use std::{collections::BTreeMap, net::IpAddr, time::Duration};
66

77
use color_eyre::{
8-
eyre::{bail, ensure, eyre, OptionExt, WrapErr},
8+
eyre::{ensure, eyre, OptionExt, WrapErr},
99
Section,
1010
};
1111
use compose_spec::{
@@ -16,8 +16,8 @@ use compose_spec::{
1616
ports::{self, Port, Protocol},
1717
AbsolutePath, BlkioConfig, Build, ByteValue, Cgroup, Command, ConfigOrSecret, CpuSet, Cpus,
1818
CredentialSpec, DependsOn, Deploy, Develop, Device, EnvFile, Expose, Extends, Healthcheck,
19-
Hostname, Image, Ipc, Limit, Link, Logging, MacAddress, NetworkConfig, OomScoreAdj,
20-
Percent, Platform, Ports, PullPolicy, Restart, Ulimits, UserOrGroup, Uts, Volumes,
19+
Hostname, IdOrName, Image, Ipc, Limit, Link, Logging, MacAddress, NetworkConfig,
20+
OomScoreAdj, Percent, Platform, Ports, PullPolicy, Restart, Ulimits, User, Uts, Volumes,
2121
VolumesFrom,
2222
},
2323
Extensions, Identifier, ItemOrList, ListOrMap, Map, ShortOrLong,
@@ -535,7 +535,7 @@ struct ContainerSecurityContext {
535535
privileged: bool,
536536
read_only: bool,
537537
security_opt: IndexSet<String>,
538-
user: Option<UserOrGroup>,
538+
user: Option<User>,
539539
}
540540

541541
impl ContainerSecurityContext {
@@ -594,14 +594,23 @@ impl ContainerSecurityContext {
594594
.se_linux_options = Some(se_linux_options);
595595
}
596596

597-
if let Some(user) = user {
598-
let user = match user {
599-
UserOrGroup::Id(user) => user,
600-
UserOrGroup::Name(_) => bail!("only numeric UIDs are supported for `user`"),
601-
};
602-
security_context
603-
.get_or_insert_with(SecurityContext::default)
604-
.run_as_user = Some(user.into());
597+
if let Some(User { user, group }) = user {
598+
let user = user
599+
.as_id()
600+
.ok_or_eyre("only numeric UIDs are supported for `user`")?
601+
.into();
602+
let group = group
603+
.map(|group| {
604+
group
605+
.as_id()
606+
.ok_or_eyre("only numeric GIDs are supported for `user`")
607+
})
608+
.transpose()?
609+
.map(Into::into);
610+
611+
let security_context = security_context.get_or_insert_with(SecurityContext::default);
612+
security_context.run_as_user = Some(user);
613+
security_context.run_as_group = group;
605614
}
606615

607616
Ok(security_context)
@@ -699,7 +708,7 @@ struct Unsupported {
699708
annotations: ListOrMap,
700709
external_links: IndexSet<Link>,
701710
extra_hosts: IndexMap<Hostname, IpAddr>,
702-
group_add: IndexSet<UserOrGroup>,
711+
group_add: IndexSet<IdOrName>,
703712
hostname: Option<Hostname>,
704713
init: bool,
705714
ipc: Option<Ipc>,

0 commit comments

Comments
 (0)