|
2 | 2 |
|
3 | 3 | // SPDX-License-Identifier: Apache-2.0 OR MIT
|
4 | 4 |
|
| 5 | +use std::borrow::Cow; |
5 | 6 | use std::ffi::OsStr;
|
6 | 7 | use std::fs::File;
|
7 | 8 | use std::io::{BufRead, BufReader, BufWriter, Write};
|
@@ -346,26 +347,50 @@ fn mutate_one_dnf_repo(
|
346 | 347 | writeln!(w, "{line}")?;
|
347 | 348 | continue;
|
348 | 349 | };
|
349 |
| - // If the gpg key isn't a local file, pass through the line. |
350 |
| - let Some(relpath) = value |
351 |
| - .strip_prefix("file://") |
352 |
| - .and_then(|path| path.strip_prefix('/')) |
353 |
| - else { |
354 |
| - writeln!(w, "{line}")?; |
355 |
| - continue; |
356 |
| - }; |
357 |
| - // If it doesn't exist in the source root, then assume the absolute |
358 |
| - // reference is intentional. |
359 |
| - let target_repo_file = source_root.join(relpath); |
360 |
| - if !exec_root.try_exists(&target_repo_file)? { |
| 350 | + let mut gpg_modified = false; |
| 351 | + let mut updated_gpgkeys: Vec<Cow<str>> = Vec::new(); |
| 352 | + for key in value.split_ascii_whitespace() { |
| 353 | + // If the gpg key isn't a local file, pass through the line. |
| 354 | + let Some(relpath) = key |
| 355 | + .strip_prefix("file://") |
| 356 | + .and_then(|path| path.strip_prefix('/')) |
| 357 | + else { |
| 358 | + updated_gpgkeys.push(key.into()); |
| 359 | + continue; |
| 360 | + }; |
| 361 | + // Handling variable substitutions here is painful, so we punt |
| 362 | + // if we find them and assume they should always be under the source root. |
| 363 | + let contains_varsubst = relpath.contains('$'); |
| 364 | + // If it doesn't exist in the source root, then assume the absolute |
| 365 | + // reference is intentional. |
| 366 | + let target_repo_file = source_root.join(relpath); |
| 367 | + if !contains_varsubst && !exec_root.try_exists(&target_repo_file)? { |
| 368 | + tracing::debug!("Not present under source root: {target_repo_file}"); |
| 369 | + updated_gpgkeys.push(key.into()); |
| 370 | + continue; |
| 371 | + } |
| 372 | + gpg_modified = true; |
| 373 | + updated_gpgkeys.push(Cow::Owned(format!("file:///{target_repo_file}"))); |
| 374 | + } |
| 375 | + if gpg_modified { |
| 376 | + modified = true; |
| 377 | + write!(w, "gpgkey=")?; |
| 378 | + for (i, key) in updated_gpgkeys.iter().enumerate() { |
| 379 | + if i != 0 { |
| 380 | + write!(w, " ")?; |
| 381 | + } |
| 382 | + write!(w, "{key}")?; |
| 383 | + } |
| 384 | + writeln!(w)?; |
| 385 | + } else { |
361 | 386 | writeln!(w, "{line}")?;
|
362 |
| - continue; |
363 | 387 | }
|
364 |
| - modified = true; |
365 |
| - writeln!(w, "gpgkey=file:///{target_repo_file}")?; |
366 | 388 | }
|
367 | 389 | if modified {
|
| 390 | + tracing::debug!("Updated {name}"); |
368 | 391 | reposdir.write(name, w)?;
|
| 392 | + } else { |
| 393 | + tracing::debug!("Unchanged repo file: {name}"); |
369 | 394 | }
|
370 | 395 | Ok(())
|
371 | 396 | }
|
@@ -1170,17 +1195,36 @@ mod tests {
|
1170 | 1195 | baseurl=other
|
1171 | 1196 | gpgkey=file:///etc/pki/rpm-gpg/repo2.key
|
1172 | 1197 |
|
| 1198 | + [repo4] |
| 1199 | + baseurl=other |
| 1200 | + # These keys don't exist in the source root, but we rewrite anyways |
| 1201 | + gpgkey=file:///etc/pki/rpm-gpg/some-key-with-$releasever-and-$basearch file:///etc/pki/rpm-gpg/another-key-with-$releasever-and-$basearch |
| 1202 | +
|
1173 | 1203 | [repo3]
|
1174 | 1204 | baseurl=blah
|
1175 | 1205 | gpgkey=file:///absolute/path/not-in-source-root
|
1176 | 1206 | "#};
|
1177 | 1207 | rootfs.write("repos/etc/yum.repos.d/test.repo", orig_repo_content)?;
|
1178 | 1208 | mutate_source_root(rootfs, "repos".into()).unwrap();
|
1179 | 1209 | let found_repos = rootfs.read_to_string("repos/etc/yum.repos.d/test.repo")?;
|
1180 |
| - let expected = orig_repo_content.replace( |
1181 |
| - "gpgkey=file:///etc/pki/rpm-gpg/repo2.key", |
1182 |
| - "gpgkey=file:///repos/etc/pki/rpm-gpg/repo2.key", |
1183 |
| - ); |
| 1210 | + let expected = indoc::indoc! { r#" |
| 1211 | + [repo] |
| 1212 | + baseurl=blah |
| 1213 | + gpgkey=https://example.com |
| 1214 | +
|
| 1215 | + [repo2] |
| 1216 | + baseurl=other |
| 1217 | + gpgkey=file:///repos/etc/pki/rpm-gpg/repo2.key |
| 1218 | +
|
| 1219 | + [repo4] |
| 1220 | + baseurl=other |
| 1221 | + # These keys don't exist in the source root, but we rewrite anyways |
| 1222 | + gpgkey=file:///repos/etc/pki/rpm-gpg/some-key-with-$releasever-and-$basearch file:///repos/etc/pki/rpm-gpg/another-key-with-$releasever-and-$basearch |
| 1223 | +
|
| 1224 | + [repo3] |
| 1225 | + baseurl=blah |
| 1226 | + gpgkey=file:///absolute/path/not-in-source-root |
| 1227 | + "#}; |
1184 | 1228 | similar_asserts::assert_eq!(expected, found_repos);
|
1185 | 1229 |
|
1186 | 1230 | Ok(())
|
|
0 commit comments