treefile: allow ${releasever} in more keys
Besides allowing ${releasever}, only do the substitution as the final pass after merging the treefiles for all the keys (currently ${basearch} and ${releasever}) instead of doing it per parse. This way we have the expected semantics where one could do: ``` include: "fedora-coreos.yaml" releasever: "42" ``` and have that releasever used. Fixes #1809 Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> Closes: #1848 Approved by: cgwalters
This commit is contained in:
parent
d0f90ca4dd
commit
c94bd08b02
10
rust/Cargo.lock
generated
10
rust/Cargo.lock
generated
@ -216,6 +216,14 @@ name = "encode_unicode"
|
|||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "envsubst"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -631,6 +639,7 @@ dependencies = [
|
|||||||
"c_utf8 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"c_utf8 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"curl 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"curl 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"envsubst 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gio-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -937,6 +946,7 @@ dependencies = [
|
|||||||
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
|
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
|
||||||
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
||||||
"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
|
"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
|
||||||
|
"checksum envsubst 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13cf19a8d534c83456ea13365a1935810a39f0e43bf1ec9371077e1966da396a"
|
||||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
@ -23,6 +23,7 @@ c_utf8 = "0.1.0"
|
|||||||
systemd = "0.4.0"
|
systemd = "0.4.0"
|
||||||
indicatif = "0.11.0"
|
indicatif = "0.11.0"
|
||||||
lazy_static = "1.1.0"
|
lazy_static = "1.1.0"
|
||||||
|
envsubst = "0.1.0"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "rpmostree_rust"
|
name = "rpmostree_rust"
|
||||||
|
@ -130,19 +130,6 @@ fn treefile_parse_stream<R: io::Read>(
|
|||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Substitute ${basearch}
|
|
||||||
treefile.treeref = match (basearch, treefile.treeref.take()) {
|
|
||||||
(Some(basearch), Some(treeref)) => {
|
|
||||||
let mut varsubsts = HashMap::new();
|
|
||||||
varsubsts.insert("basearch".to_string(), basearch.to_string());
|
|
||||||
Some(
|
|
||||||
utils::varsubst(&treeref, &varsubsts)
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e.to_string()))?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
(_, v) => v,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Special handling for packages, since we allow whitespace within items.
|
// Special handling for packages, since we allow whitespace within items.
|
||||||
// We also canonicalize bootstrap_packages to packages here so it's
|
// We also canonicalize bootstrap_packages to packages here so it's
|
||||||
// easier to append the basearch packages after.
|
// easier to append the basearch packages after.
|
||||||
@ -410,7 +397,8 @@ impl Treefile {
|
|||||||
basearch: Option<&str>,
|
basearch: Option<&str>,
|
||||||
workdir: openat::Dir,
|
workdir: openat::Dir,
|
||||||
) -> Fallible<Box<Treefile>> {
|
) -> Fallible<Box<Treefile>> {
|
||||||
let parsed = treefile_parse_recurse(filename, basearch, 0)?;
|
let mut parsed = treefile_parse_recurse(filename, basearch, 0)?;
|
||||||
|
parsed.config = parsed.config.substitute_vars()?;
|
||||||
Treefile::validate_config(&parsed.config)?;
|
Treefile::validate_config(&parsed.config)?;
|
||||||
let dfd = openat::Dir::open(filename.parent().unwrap())?;
|
let dfd = openat::Dir::open(filename.parent().unwrap())?;
|
||||||
let (rojig_name, rojig_spec) = if let Some(rojig) = parsed.config.rojig.as_ref() {
|
let (rojig_name, rojig_spec) = if let Some(rojig) = parsed.config.rojig.as_ref() {
|
||||||
@ -718,6 +706,39 @@ impl TreeComposeConfig {
|
|||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Look for use of ${variable} and replace it by its proper value
|
||||||
|
fn substitute_vars(mut self) -> Fallible<Self> {
|
||||||
|
let mut substvars: collections::HashMap<String, String> = collections::HashMap::new();
|
||||||
|
// Substitute ${basearch} and ${releasever}
|
||||||
|
if let Some(arch) = &self.basearch {
|
||||||
|
substvars.insert("basearch".to_string(), arch.clone());
|
||||||
|
}
|
||||||
|
if let Some(releasever) = &self.releasever {
|
||||||
|
substvars.insert("releasever".to_string(), releasever.clone());
|
||||||
|
}
|
||||||
|
envsubst::validate_vars(&substvars)?;
|
||||||
|
|
||||||
|
macro_rules! substitute_field {
|
||||||
|
( $field:ident ) => {{
|
||||||
|
if let Some(value) = self.$field.take() {
|
||||||
|
self.$field = if envsubst::is_templated(&value) {
|
||||||
|
match envsubst::substitute(value, &substvars) {
|
||||||
|
Ok(s) => Some(s),
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
};
|
||||||
|
substitute_field!(treeref);
|
||||||
|
substitute_field!(automatic_version_prefix);
|
||||||
|
substitute_field!(mutate_os_release);
|
||||||
|
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -753,8 +774,9 @@ packages-s390x:
|
|||||||
#[test]
|
#[test]
|
||||||
fn basic_valid() {
|
fn basic_valid() {
|
||||||
let mut input = io::BufReader::new(VALID_PRELUDE.as_bytes());
|
let mut input = io::BufReader::new(VALID_PRELUDE.as_bytes());
|
||||||
let treefile =
|
let mut treefile =
|
||||||
treefile_parse_stream(InputFormat::YAML, &mut input, Some(ARCH_X86_64)).unwrap();
|
treefile_parse_stream(InputFormat::YAML, &mut input, Some(ARCH_X86_64)).unwrap();
|
||||||
|
treefile = treefile.substitute_vars().unwrap();
|
||||||
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
||||||
assert!(treefile.packages.unwrap().len() == 5);
|
assert!(treefile.packages.unwrap().len() == 5);
|
||||||
}
|
}
|
||||||
@ -785,8 +807,9 @@ remove-files:
|
|||||||
#[test]
|
#[test]
|
||||||
fn basic_js_valid() {
|
fn basic_js_valid() {
|
||||||
let mut input = io::BufReader::new(VALID_PRELUDE_JS.as_bytes());
|
let mut input = io::BufReader::new(VALID_PRELUDE_JS.as_bytes());
|
||||||
let treefile =
|
let mut treefile =
|
||||||
treefile_parse_stream(InputFormat::JSON, &mut input, Some(ARCH_X86_64)).unwrap();
|
treefile_parse_stream(InputFormat::JSON, &mut input, Some(ARCH_X86_64)).unwrap();
|
||||||
|
treefile = treefile.substitute_vars().unwrap();
|
||||||
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
||||||
assert!(treefile.packages.unwrap().len() == 5);
|
assert!(treefile.packages.unwrap().len() == 5);
|
||||||
}
|
}
|
||||||
@ -794,7 +817,8 @@ remove-files:
|
|||||||
#[test]
|
#[test]
|
||||||
fn basic_valid_noarch() {
|
fn basic_valid_noarch() {
|
||||||
let mut input = io::BufReader::new(VALID_PRELUDE.as_bytes());
|
let mut input = io::BufReader::new(VALID_PRELUDE.as_bytes());
|
||||||
let treefile = treefile_parse_stream(InputFormat::YAML, &mut input, None).unwrap();
|
let mut treefile = treefile_parse_stream(InputFormat::YAML, &mut input, None).unwrap();
|
||||||
|
treefile = treefile.substitute_vars().unwrap();
|
||||||
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/blah");
|
||||||
assert!(treefile.packages.unwrap().len() == 3);
|
assert!(treefile.packages.unwrap().len() == 3);
|
||||||
}
|
}
|
||||||
@ -802,7 +826,9 @@ remove-files:
|
|||||||
fn append_and_parse(append: &'static str) -> TreeComposeConfig {
|
fn append_and_parse(append: &'static str) -> TreeComposeConfig {
|
||||||
let buf = VALID_PRELUDE.to_string() + append;
|
let buf = VALID_PRELUDE.to_string() + append;
|
||||||
let mut input = io::BufReader::new(buf.as_bytes());
|
let mut input = io::BufReader::new(buf.as_bytes());
|
||||||
treefile_parse_stream(InputFormat::YAML, &mut input, Some(ARCH_X86_64)).unwrap()
|
let treefile =
|
||||||
|
treefile_parse_stream(InputFormat::YAML, &mut input, Some(ARCH_X86_64)).unwrap();
|
||||||
|
treefile.substitute_vars().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_invalid(data: &'static str) {
|
fn test_invalid(data: &'static str) {
|
||||||
@ -817,6 +843,31 @@ remove-files:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_valid_releasever() {
|
||||||
|
let buf = r###"
|
||||||
|
ref: "exampleos/${basearch}/${releasever}"
|
||||||
|
releasever: 30
|
||||||
|
automatic-version-prefix: ${releasever}
|
||||||
|
mutate-os-release: ${releasever}
|
||||||
|
"###;
|
||||||
|
let mut input = io::BufReader::new(buf.as_bytes());
|
||||||
|
let mut treefile =
|
||||||
|
treefile_parse_stream(InputFormat::YAML, &mut input, Some(ARCH_X86_64)).unwrap();
|
||||||
|
treefile = treefile.substitute_vars().unwrap();
|
||||||
|
assert!(treefile.treeref.unwrap() == "exampleos/x86_64/30");
|
||||||
|
assert!(treefile.releasever.unwrap() == "30");
|
||||||
|
assert!(treefile.automatic_version_prefix.unwrap() == "30");
|
||||||
|
assert!(treefile.mutate_os_release.unwrap() == "30");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_valid_no_releasever() {
|
||||||
|
let treefile = append_and_parse("automatic_version_prefix: ${releasever}");
|
||||||
|
assert!(treefile.releasever == None);
|
||||||
|
assert!(treefile.automatic_version_prefix.unwrap() == "${releasever}");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_valid_legacy() {
|
fn basic_valid_legacy() {
|
||||||
let treefile = append_and_parse(
|
let treefile = append_and_parse(
|
||||||
|
Loading…
Reference in New Issue
Block a user