From 953bdddbecd26c84aad0ac4b22509922fc5acbbd Mon Sep 17 00:00:00 2001 From: Luke Yang Date: Wed, 7 Jun 2023 15:10:32 -0400 Subject: [PATCH 01/28] Sorted builtin commands alphabetically --- src/app/libmain.cxx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/app/libmain.cxx b/src/app/libmain.cxx index 60059238eb..cca6f78a3e 100644 --- a/src/app/libmain.cxx +++ b/src/app/libmain.cxx @@ -154,6 +154,14 @@ static GOptionEntry pkg_entries[] "Remove overlayed additional package", "PKG" }, { NULL } }; +static int +cmp_by_name (const void *a, const void *b) +{ + struct RpmOstreeCommand *command_a = (RpmOstreeCommand *)a; + struct RpmOstreeCommand *command_b = (RpmOstreeCommand *)b; + return strcmp (command_a->name, command_b->name); +} + static GOptionContext * option_context_new_with_commands (RpmOstreeCommandInvocation *invocation, RpmOstreeCommand *commands) @@ -171,6 +179,13 @@ option_context_new_with_commands (RpmOstreeCommandInvocation *invocation, else /* top level */ g_string_append (summary, "Builtin Commands:"); + int command_count = 0; + for (RpmOstreeCommand *command = commands; command->name != NULL; command++) + { + command_count++; + } + + qsort (commands, command_count, sizeof (RpmOstreeCommand), cmp_by_name); for (RpmOstreeCommand *command = commands; command->name != NULL; command++) { gboolean hidden = (command->flags & RPM_OSTREE_BUILTIN_FLAG_HIDDEN) > 0; From 375c3d5efd49ffbc3785f567843dd9bbb73b3279 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 9 Jun 2023 17:35:48 -0400 Subject: [PATCH 02/28] core: Error out instead of aborting on reinstalls I think originally something higher level was intending to catch this "reinstall exact base package version" case, but it's way simpler to just return a clear error here instead of crashing. Assertions should only be used for things we're *pretty sure* can't be reached and particularly when it may be a hard to recover from internal consistency error. That's not the case here. Closes: https://github.com/coreos/rpm-ostree/issues/4141 --- src/libpriv/rpmostree-core.cxx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libpriv/rpmostree-core.cxx b/src/libpriv/rpmostree-core.cxx index 9ac15b3154..5c3b0144b0 100644 --- a/src/libpriv/rpmostree-core.cxx +++ b/src/libpriv/rpmostree-core.cxx @@ -1466,7 +1466,18 @@ check_goal_solution (RpmOstreeContext *self, GPtrArray *removed_pkgnames, * for it anyway so that we get a bug report in case it somehow happens. */ { g_autoptr (GPtrArray) packages = dnf_goal_get_packages (goal, DNF_PACKAGE_INFO_REINSTALL, -1); - g_assert_cmpint (packages->len, ==, 0); + if (packages->len > 0) + { + g_autoptr (GString) buf = g_string_new (""); + for (guint i = 0; i < packages->len; i++) + { + if (i > 0) + g_string_append_c (buf, ' '); + auto pkg = static_cast (packages->pdata[i]); + g_string_append (buf, dnf_package_get_name (pkg)); + } + return glnx_throw (error, "Request to reinstall exact base package versions: %s", buf->str); + } } /* Look at UPDATE and DOWNGRADE, and see whether they're doing what we expect */ From f3b0a3823212a1aee886a4f8af813ed211a47241 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 21:59:20 +0000 Subject: [PATCH 03/28] build(deps): bump openssl from 0.10.52 to 0.10.54 Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.52 to 0.10.54. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.52...openssl-v0.10.54) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f7759507c..bb48de12f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1693,9 +1693,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -1725,9 +1725,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index c414e92e7a..96c4699ee6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ libdnf-sys = { path = "rust/libdnf-sys", version = "0.1.0" } maplit = "1.0" memfd = "0.6.0" nix = "0.26.1" -openssl = "0.10.49" +openssl = "0.10.54" once_cell = "1.18.0" os-release = "0.1.0" ostree-ext = "0.11.0" From cc7292d2e717fd21c3fcf3db4e30ee723fbe7924 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 9 Jun 2023 17:03:28 -0400 Subject: [PATCH 04/28] importer: Drop non-root files in CPIO check rpm upstream did https://github.com/rpm-software-management/rpm/commit/0f957330f24cdb2510e0bbdface54ffa8064b8ce The file metadata is still duplicated in the header, and *that* seems unlikely to change soon. So we can just safely drop this "sanity check". Closes: https://github.com/coreos/rpm-ostree/issues/4437 --- rust/src/importer.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/rust/src/importer.rs b/rust/src/importer.rs index eb91ff23a1..f552bc64ca 100644 --- a/rust/src/importer.rs +++ b/rust/src/importer.rs @@ -346,16 +346,9 @@ fn tweak_imported_file_info(file_info: &FileInfo, ro_executables: bool) { #[context("Analyzing {}", path)] fn import_filter( path: &str, - file_info: &FileInfo, + _file_info: &FileInfo, skip_extraneous: bool, ) -> Result { - // Sanity check that RPM isn't using CPIO id fields. - let uid = file_info.attribute_uint32("unix::uid"); - let gid = file_info.attribute_uint32("unix::gid"); - if uid != 0 || gid != 0 { - bail!("Unexpected non-root owned path (marked as {}:{})", uid, gid); - } - // Skip some empty lock files, they are known to cause problems: // https://github.com/projectatomic/rpm-ostree/pull/1002 if path.starts_with("/usr/etc/selinux") && path.ends_with(".LOCK") { From 2e63e3cb276c72b6071a535229155661aad4bfef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:56:38 +0000 Subject: [PATCH 05/28] build(deps): bump libdnf from `2362930` to `3fca06e` Bumps [libdnf](https://github.com/rpm-software-management/libdnf) from `2362930` to `3fca06e`. - [Release notes](https://github.com/rpm-software-management/libdnf/releases) - [Commits](https://github.com/rpm-software-management/libdnf/compare/2362930d10375a348bf2659db14b0ca4b911d4b7...3fca06e8b1037f117ba57b5e824ea59a343b44ed) --- updated-dependencies: - dependency-name: libdnf dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- libdnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdnf b/libdnf index 2362930d10..3fca06e8b1 160000 --- a/libdnf +++ b/libdnf @@ -1 +1 @@ -Subproject commit 2362930d10375a348bf2659db14b0ca4b911d4b7 +Subproject commit 3fca06e8b1037f117ba57b5e824ea59a343b44ed From 4f48969487f23b095e77f1216ddc49d6f07853ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:57:03 +0000 Subject: [PATCH 06/28] build(deps): bump rustix from 0.37.19 to 0.37.20 Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.37.19 to 0.37.20. - [Release notes](https://github.com/bytecodealliance/rustix/releases) - [Commits](https://github.com/bytecodealliance/rustix/compare/v0.37.19...v0.37.20) --- updated-dependencies: - dependency-name: rustix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb48de12f0..cfbada4e0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,7 +222,7 @@ dependencies = [ "io-lifetimes", "ipnet", "maybe-owned", - "rustix 0.37.19", + "rustix 0.37.20", "windows-sys 0.48.0", "winx", ] @@ -237,7 +237,7 @@ dependencies = [ "cap-primitives", "io-extras", "io-lifetimes", - "rustix 0.37.19", + "rustix 0.37.20", ] [[package]] @@ -257,7 +257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6012b1e726e3e3ccf8151e2dc9cb454e593e0e7623b0e35464f5e62a15158c27" dependencies = [ "cap-tempfile", - "rustix 0.37.19", + "rustix 0.36.13", ] [[package]] @@ -268,7 +268,7 @@ checksum = "6fd9864347f55a9c31de436ec9d7d3577476f3e6eeb3cc44ae2204de9164f78d" dependencies = [ "cap-std", "rand", - "rustix 0.37.19", + "rustix 0.37.20", "uuid 1.3.2", ] @@ -861,7 +861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7833d0f115a013d51c55950a3b09d30e4b057be9961b709acb9b5b17a1108861" dependencies = [ "io-lifetimes", - "rustix 0.37.19", + "rustix 0.37.20", "windows-sys 0.48.0", ] @@ -1354,7 +1354,7 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix 0.37.19", + "rustix 0.37.20", "windows-sys 0.48.0", ] @@ -1508,7 +1508,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix 0.37.19", + "rustix 0.37.20", ] [[package]] @@ -1803,7 +1803,7 @@ dependencies = [ "ostree", "pin-project", "regex", - "rustix 0.37.19", + "rustix 0.37.20", "serde", "serde_json", "tar", @@ -2209,7 +2209,7 @@ dependencies = [ "reqwest", "rpmostree-client", "rust-ini", - "rustix 0.37.19", + "rustix 0.37.20", "serde", "serde_derive", "serde_json", @@ -2252,9 +2252,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags 1.3.2", "errno", @@ -2547,7 +2547,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.19", + "rustix 0.37.20", "windows-sys 0.45.0", ] From 5745d2d3040b6ed58abde42e192a3576f216eac9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:57:15 +0000 Subject: [PATCH 07/28] build(deps): bump indicatif from 0.17.3 to 0.17.5 Bumps [indicatif](https://github.com/console-rs/indicatif) from 0.17.3 to 0.17.5. - [Release notes](https://github.com/console-rs/indicatif/releases) - [Commits](https://github.com/console-rs/indicatif/compare/0.17.3...0.17.5) --- updated-dependencies: - dependency-name: indicatif dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 9 +++++---- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb48de12f0..2da95b32a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1294,11 +1294,12 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.3" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" dependencies = [ "console", + "instant", "number_prefix", "portable-atomic", "unicode-width", @@ -1928,9 +1929,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "portable-atomic" -version = "0.3.19" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" +checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "ppv-lite86" diff --git a/Cargo.toml b/Cargo.toml index 96c4699ee6..a881c6368c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ fail = { version = "0.5", features = ["failpoints"] } fn-error-context = "0.2.0" futures = "0.3.28" indoc = "2.0.1" -indicatif = "0.17.3" +indicatif = "0.17.5" is-terminal = "0.4" libc = "0.2.146" libdnf-sys = { path = "rust/libdnf-sys", version = "0.1.0" } From f2d07e90b0826c7a3943294b7a2d38348f584625 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:57:32 +0000 Subject: [PATCH 08/28] build(deps): bump serde from 1.0.163 to 1.0.164 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.163 to 1.0.164. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.163...v1.0.164) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- rust/rpmostree-client/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb48de12f0..58a7b0d236 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2330,18 +2330,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 96c4699ee6..56e530b897 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,7 +82,7 @@ regex = "1.7" reqwest = { version = "0.11", features = ["native-tls", "blocking", "gzip"] } rpmostree-client = { path = "rust/rpmostree-client", version = "0.1.0" } rust-ini = "0.19.0" -serde = { version = "1.0.163", features = ["derive"] } +serde = { version = "1.0.164", features = ["derive"] } serde_derive = "1.0.118" serde_json = "1.0.96" serde_yaml = "0.9.16" diff --git a/rust/rpmostree-client/Cargo.toml b/rust/rpmostree-client/Cargo.toml index a41e1b92d3..2886312870 100644 --- a/rust/rpmostree-client/Cargo.toml +++ b/rust/rpmostree-client/Cargo.toml @@ -12,6 +12,6 @@ publish = false [dependencies] anyhow = "1.0.69" -serde = { version = "1.0.163", features = ["derive"] } +serde = { version = "1.0.164", features = ["derive"] } serde_derive = "1.0.118" serde_json = "1.0.96" From d7d71e864dc55f6f2ad06651d8b3cfeb87a81f68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:57:42 +0000 Subject: [PATCH 09/28] build(deps): bump clap from 4.3.2 to 4.3.3 Bumps [clap](https://github.com/clap-rs/clap) from 4.3.2 to 4.3.3. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.3.2...v4.3.3) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb48de12f0..ec507f1ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.2" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2" +checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" dependencies = [ "clap_builder", "clap_derive", @@ -334,9 +334,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.1" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" +checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" dependencies = [ "anstream", "anstyle", From e2b646fa19ccf31744cfc73217f481580eea8a84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 11:55:14 +0000 Subject: [PATCH 10/28] build(deps): bump regex from 1.8.1 to 1.8.4 Bumps [regex](https://github.com/rust-lang/regex) from 1.8.1 to 1.8.4. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.8.1...1.8.4) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6eb904a119..0da8a3be82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,7 +257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6012b1e726e3e3ccf8151e2dc9cb454e593e0e7623b0e35464f5e62a15158c27" dependencies = [ "cap-tempfile", - "rustix 0.36.13", + "rustix 0.37.20", ] [[package]] @@ -2089,13 +2089,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.1", + "regex-syntax 0.7.2", ] [[package]] @@ -2115,9 +2115,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reqwest" diff --git a/Cargo.toml b/Cargo.toml index d4e248f7e5..e28bb83189 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ paste = "1.0" phf = { version = "0.11", features = ["macros"] } rand = "0.8.5" rayon = "1.6.0" -regex = "1.7" +regex = "1.8" reqwest = { version = "0.11", features = ["native-tls", "blocking", "gzip"] } rpmostree-client = { path = "rust/rpmostree-client", version = "0.1.0" } rust-ini = "0.19.0" From 6cc0c424a040994e8a23beeff3fb3581a88c0ce6 Mon Sep 17 00:00:00 2001 From: Joseph Marrero Date: Tue, 13 Jun 2023 16:33:40 -0400 Subject: [PATCH 11/28] packaging/rpm-ostree.spec.in: use SPDX license identifier --- packaging/rpm-ostree.spec.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm-ostree.spec.in b/packaging/rpm-ostree.spec.in index 127e807281..da7d166a6f 100644 --- a/packaging/rpm-ostree.spec.in +++ b/packaging/rpm-ostree.spec.in @@ -5,7 +5,7 @@ Summary: Hybrid image/package system Name: rpm-ostree Version: 2023.4 Release: 1%{?dist} -License: LGPLv2+ +License: LGPL-2.0-or-later URL: https://github.com/coreos/rpm-ostree # This tarball is generated via "cd packaging && make -f Makefile.dist-packaging dist-snapshot" # in the upstream git. It also contains vendored Rust sources. From daac606dbf1192b78ec5b48ce17e428454b888be Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Jun 2023 16:44:25 -0400 Subject: [PATCH 12/28] tests: Use `-p qemu` for cosa Our tests were broken by https://github.com/coreos/coreos-assembler/pull/3285 --- tests/common/libvm.sh | 2 +- tests/vm.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/common/libvm.sh b/tests/common/libvm.sh index 25f349e8bf..c5bf52008e 100644 --- a/tests/common/libvm.sh +++ b/tests/common/libvm.sh @@ -66,7 +66,7 @@ vm_kola_spawn() { exit 1 fi setpriv --pdeathsig SIGKILL -- \ - env MANTLE_SSH_DIR="$PWD/kola-ssh" kola spawn -p qemu-unpriv \ + env MANTLE_SSH_DIR="$PWD/kola-ssh" kola spawn -p qemu \ --qemu-image "$test_image" -v --idle \ --json-info-fd 4 --output-dir "$outputdir" & # hack; need cleaner API for async kola spawn diff --git a/tests/vm.sh b/tests/vm.sh index a54f85d8a4..996f67304f 100755 --- a/tests/vm.sh +++ b/tests/vm.sh @@ -39,7 +39,7 @@ spawn_vm() { exec 4> .kolavm/info.json env MANTLE_SSH_DIR="$PWD/.kolavm/ssh" \ - kola spawn -k -p qemu-unpriv \ + kola spawn -k -p qemu \ --qemu-image "$image" -v --idle \ --json-info-fd 4 --output-dir "$PWD/.kolavm/output" & From bf9f12338281bbdf2a18b4e6589fcac382353ed9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Jun 2023 08:03:13 -0400 Subject: [PATCH 13/28] Bump to ostree-ext 0.11.1 Mainly for the pulling from containers-storage fixes. --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e91b1f048..79d1334778 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1776,9 +1776,9 @@ dependencies = [ [[package]] name = "ostree-ext" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8903d59c4a56794b6ef8a2b11a5674fe85b370f1da33ae34450a6de1e39a20d6" +checksum = "a690495144c18cb333a67a2ec61dd008831710bbd37804cfa79ab93b51146a6f" dependencies = [ "anyhow", "async-compression 0.3.15", From 8c7d49f10760da52167dbb6e3732e9f40275e573 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Jun 2023 08:13:48 -0400 Subject: [PATCH 14/28] Drop isolation when fetching from containers-storage: This enables `rpm-ostree rebase ostree-unverified-image:containers-storage:localhost/mytestimage` The history here is pretty fun: - I changed rpm-ostreed to block access to `/var/lib/containers` in https://github.com/cgwalters/rpm-ostree/commit/94666faad0d403f5830184d10b1729236d783a41 - We added basic support for fetching from containers-storage in https://github.com/ostreedev/ostree-rs-ext/pull/396 which worked for ostree, but not rpm-ostree because of the above - Then we changed to isolate skopeo fetches by default https://github.com/ostreedev/ostree-rs-ext/pull/413/commits/48dfc0b74dc12bd11b0d697ba5302a6188ad795e which broke it in ostree too, but only when running under systemd so this wasn't quite caught by our tests - We fixed the isolation in ostree in https://github.com/ostreedev/ostree-rs-ext/pull/492 But finally, we also need to adapt our own distinct isolation setup to do the same thing *and* we also need to drop the systemd unit isolation which we don't need anymore because we drop privileges by default (except when fetching from container-storage) Closes: https://github.com/coreos/rpm-ostree/issues/4283 --- rust/src/sysroot_upgrade.rs | 20 ++++++++++++++------ src/daemon/rpm-ostreed.service | 4 ---- tests/kolainst/destructive/container-image | 12 ++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/rust/src/sysroot_upgrade.rs b/rust/src/sysroot_upgrade.rs index 8699156ea9..a4db0e729b 100644 --- a/rust/src/sysroot_upgrade.rs +++ b/rust/src/sysroot_upgrade.rs @@ -56,12 +56,20 @@ async fn layer_progress_print(mut r: Receiver) { } } -fn default_container_pull_config() -> Result { +fn default_container_pull_config(imgref: &OstreeImageReference) -> Result { let mut cfg = ImageProxyConfig::default(); - let isolation_systemd = crate::utils::running_in_systemd().then(|| "rpm-ostree"); - let isolation_default = rustix::process::getuid().is_root().then(|| "nobody"); - let isolation_user = isolation_systemd.or(isolation_default); - ostree_container::merge_default_container_proxy_opts_with_isolation(&mut cfg, isolation_user)?; + if imgref.imgref.transport == ostree_container::Transport::ContainerStorage { + // Fetching from containers-storage, may require privileges to read files + ostree_container::merge_default_container_proxy_opts_with_isolation(&mut cfg, None)?; + } else { + let isolation_systemd = crate::utils::running_in_systemd().then(|| "rpm-ostree"); + let isolation_default = rustix::process::getuid().is_root().then(|| "nobody"); + let isolation_user = isolation_systemd.or(isolation_default); + ostree_container::merge_default_container_proxy_opts_with_isolation( + &mut cfg, + isolation_user, + )?; + } Ok(cfg) } @@ -70,7 +78,7 @@ async fn pull_container_async( imgref: &OstreeImageReference, ) -> Result { output_message(&format!("Pulling manifest: {}", &imgref)); - let config = default_container_pull_config()?; + let config = default_container_pull_config(imgref)?; let mut imp = ImageImporter::new(repo, imgref, config).await?; let layer_progress = imp.request_progress(); let prep = match imp.prepare().await? { diff --git a/src/daemon/rpm-ostreed.service b/src/daemon/rpm-ostreed.service index 8d1ef69cba..406ead652f 100644 --- a/src/daemon/rpm-ostreed.service +++ b/src/daemon/rpm-ostreed.service @@ -20,10 +20,6 @@ MountFlags=slave # and have a system rpm-ostreed-transaction.service that runs privileged # but as a subprocess. ProtectHome=true -# Explicitly list paths here which we should never access. The initial -# entry here ensures that the skopeo process we fork won't interact with -# application containers. -BindReadOnlyPaths=-/var/lib/containers NotifyAccess=main # Significantly bump this timeout from the default because # we do a lot of stuff on daemon startup. diff --git a/tests/kolainst/destructive/container-image b/tests/kolainst/destructive/container-image index 4cb34d5f8a..fc812d975f 100755 --- a/tests/kolainst/destructive/container-image +++ b/tests/kolainst/destructive/container-image @@ -162,9 +162,7 @@ EOF if test "${touched_resolv_conf}" -eq 1; then rm -vf /etc/resolv.conf fi - derived=oci:$image_dir:derived - skopeo copy containers-storage:localhost/fcos-derived $derived - rpm-ostree rebase ostree-unverified-image:$derived + rpm-ostree rebase ostree-unverified-image:containers-storage:localhost/fcos-derived ostree container image list --repo=/ostree/repo | tee imglist.txt assert_streq "$(wc -l < imglist.txt)" 1 rm $image_dir -rf @@ -181,7 +179,7 @@ EOF assert_streq $(rpm -q baz) baz-2.0-1.${arch} test -f /usr/bin/baz ! rpm -q nano - rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:derived\"" + rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:containers-storage:localhost/fcos-derived\"" # We'll test the "apply" automatic updates policy here systemctl stop rpm-ostreed @@ -190,9 +188,7 @@ EOF rpm-ostree reload # Now revert back to the base image, but keep our layered package foo - rm "${image_dir}" -rf - skopeo copy containers-storage:localhost/fcos ${image}:latest - rpm-ostree rebase ostree-unverified-image:${image}:latest + rpm-ostree rebase ostree-unverified-image:containers-storage:localhost/fcos /tmp/autopkgtest-reboot 4 ;; 4) @@ -204,7 +200,7 @@ EOF fatal "found $p" fi done - rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:oci:$image_dir:latest\"" + rpmostree_assert_status ".deployments[0][\"container-image-reference\"] == \"ostree-unverified-image:containers-storage:localhost/fcos\"" ;; *) echo "unexpected mark: ${AUTOPKGTEST_REBOOT_MARK}"; exit 1;; esac From 8052574ff0979b6925015e766ef11eb6d59845d6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Jun 2023 11:13:31 -0400 Subject: [PATCH 15/28] deploy-from-self: Add some error prefixing We got a bare ``` error: Invalid checksum of length 0 expected 32 ``` in a bug report; this will help narrow it down very slightly, whether the problem is the commit object filename or something in the pull. --- rust/src/container.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/rust/src/container.rs b/rust/src/container.rs index 6ca9605dbf..e6a3729416 100644 --- a/rust/src/container.rs +++ b/rust/src/container.rs @@ -7,13 +7,14 @@ use std::num::NonZeroU32; use std::process::Command; use std::rc::Rc; -use anyhow::Result; +use anyhow::{Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; use cap_std::fs::Dir; use cap_std_ext::cap_std; use cap_std_ext::prelude::*; use chrono::prelude::*; use clap::Parser; +use fn_error_context::context; use ostree::glib; use ostree_ext::chunking::ObjectMetaSized; use ostree_ext::container::{Config, ExportOpts, ImageReference}; @@ -483,6 +484,7 @@ struct UpdateFromRunningOpts { } // This reimplements https://github.com/ostreedev/ostree/pull/2691 basically +#[context("Finding encapsulated commits")] fn find_encapsulated_commits(repo: &Utf8Path) -> Result> { let objects = Dir::open_ambient_dir(&repo.join("objects"), cap_std::ambient_authority())?; let mut r = Vec::new(); @@ -550,7 +552,10 @@ pub(crate) fn deploy_from_self_entrypoint(args: Vec) -> CxxResult<()> { let encapsulated_commits = find_encapsulated_commits(src_repo_path)?; let commit = match encapsulated_commits.as_slice() { [] => return Err(format!("No encapsulated commit found in container").into()), - [c] => c.as_str(), + [c] => { + ostree::validate_checksum_string(&c)?; + c.as_str() + } o => return Err(format!("Found {} commit objects, expected just one", o.len()).into()), }; @@ -564,12 +569,14 @@ pub(crate) fn deploy_from_self_entrypoint(args: Vec) -> CxxResult<()> { opts.insert("refs", &&refs[..]); opts.insert("flags", &(flags.bits() as i32)); let options = opts.to_variant(); - target_repo.pull_with_options( - &format!("file://{src_repo_path}"), - &options, - None, - cancellable, - )?; + target_repo + .pull_with_options( + &format!("file://{src_repo_path}"), + &options, + None, + cancellable, + ) + .context("Pulling from embedded repo")?; } println!("Imported: {commit}"); From c67c4896e1365e44990043f5b69de114dc49e3ee Mon Sep 17 00:00:00 2001 From: Joseph Marrero Date: Tue, 20 Jun 2023 21:01:46 -0400 Subject: [PATCH 16/28] Release 2023.5 --- configure.ac | 2 +- packaging/rpm-ostree.spec.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f9aface629..b51a529bd2 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl dnl SEE RELEASE.md FOR INSTRUCTIONS ON HOW TO DO A RELEASE. dnl m4_define([year_version], [2023]) -m4_define([release_version], [4]) +m4_define([release_version], [5]) m4_define([package_version], [year_version.release_version]) AC_INIT([rpm-ostree], [package_version], [coreos@lists.fedoraproject.org]) AC_CONFIG_HEADER([config.h]) diff --git a/packaging/rpm-ostree.spec.in b/packaging/rpm-ostree.spec.in index da7d166a6f..67d2793762 100644 --- a/packaging/rpm-ostree.spec.in +++ b/packaging/rpm-ostree.spec.in @@ -3,7 +3,7 @@ Summary: Hybrid image/package system Name: rpm-ostree -Version: 2023.4 +Version: 2023.5 Release: 1%{?dist} License: LGPL-2.0-or-later URL: https://github.com/coreos/rpm-ostree From 4de52c41c5ec8f348cec9f30613d4e30ff0fbc71 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Jun 2023 16:42:15 -0400 Subject: [PATCH 17/28] postprocess: Use --refresh now This drops a deprecation warning. At this point, I think we can hard require the new policycoreutils. --- src/libpriv/rpmostree-postprocess.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libpriv/rpmostree-postprocess.cxx b/src/libpriv/rpmostree-postprocess.cxx index bfadaa73dd..9b38da931a 100644 --- a/src/libpriv/rpmostree-postprocess.cxx +++ b/src/libpriv/rpmostree-postprocess.cxx @@ -397,8 +397,8 @@ postprocess_final (int rootfs_dfd, rpmostreecxx::Treefile &treefile, gboolean un /* Temporary workaround for https://github.com/openshift/os/issues/1036. */ { - rust::Vec child_argv = { rust::String ("semodule"), rust::String ("-n"), - rust::String ("--rebuild-if-modules-changed") }; + rust::Vec child_argv + = { rust::String ("semodule"), rust::String ("-n"), rust::String ("--refresh") }; ROSCXX_TRY (bubblewrap_run_sync (rootfs_dfd, child_argv, false, (bool)unified_core_mode), error); } From 93ac42ccd538adef31490a529cf59a31a5384034 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Wed, 21 Jun 2023 07:51:58 +0000 Subject: [PATCH 18/28] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@09358545a5b1f1a646aa224e4e7e2991dcb80702. --- docs/_config.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 006ac4bd2d..26bd9ccfdd 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,12 @@ -title: coreos/rpm-ostree +# Template generated by https://github.com/coreos/repo-templates; do not edit downstream + +# To test documentation changes locally or using GitHub Pages, see: +# https://github.com/coreos/fedora-coreos-tracker/blob/main/docs/testing-project-documentation-changes.md + +title: rpm-ostree description: rpm-ostree documentation baseurl: "/rpm-ostree" url: "https://coreos.github.io" -# Comment above and use below for local development -# url: "http://localhost:4000" permalink: /:title/ markdown: kramdown kramdown: From 045767a9a769d1a8c5910071d5f2aa3f3f721536 Mon Sep 17 00:00:00 2001 From: Luke Yang Date: Fri, 9 Jun 2023 14:57:51 -0400 Subject: [PATCH 19/28] Add a `search` CLI verb and DBus API This closes a longstanding feature request and improves compatibility with the `dnf`/`yum` CLI. The feature set and output text intentionally matches that tool, e.g. globs like `rpm-ostree search kernel*` or multi term searches like `rpm-ostree search kernel python` are supported. Search results per section are limited to 50 due to DBus message size limits. Closes: https://github.com/coreos/rpm-ostree/issues/1877 --- man/rpm-ostree.xml | 14 +++ src/app/libmain.cxx | 2 + src/app/rpmostree-builtins.h | 1 + src/app/rpmostree-pkg-builtins.cxx | 101 ++++++++++++++++++ src/daemon/org.projectatomic.rpmostree1.xml | 6 ++ src/daemon/rpmostreed-os.cxx | 112 +++++++++++++++++++- 6 files changed, 235 insertions(+), 1 deletion(-) diff --git a/man/rpm-ostree.xml b/man/rpm-ostree.xml index 1b530856f6..dcf7e1974c 100644 --- a/man/rpm-ostree.xml +++ b/man/rpm-ostree.xml @@ -328,6 +328,20 @@ Boston, MA 02111-1307, USA. + + search + + + + Takes one or more query terms as arguments. The packages are + searched within the enabled repositories in + /etc/yum.repos.d/. Packages can be + overlayed and removed using the install + and uninstall commands. + + + + rebase diff --git a/src/app/libmain.cxx b/src/app/libmain.cxx index 60059238eb..ea56bc2c5b 100644 --- a/src/app/libmain.cxx +++ b/src/app/libmain.cxx @@ -73,6 +73,8 @@ static RpmOstreeCommand commands[] = { "Overlay additional packages", rpmostree_builtin_install }, { "uninstall", static_cast (RPM_OSTREE_BUILTIN_FLAG_CONTAINER_CAPABLE), "Remove overlayed additional packages", rpmostree_builtin_uninstall }, + { "search", static_cast (RPM_OSTREE_BUILTIN_FLAG_CONTAINER_CAPABLE), + "Search for packages", rpmostree_builtin_search }, { "override", static_cast (RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD), "Manage base package overrides", rpmostree_builtin_override }, { "reset", static_cast (RPM_OSTREE_BUILTIN_FLAG_SUPPORTS_PKG_INSTALLS), diff --git a/src/app/rpmostree-builtins.h b/src/app/rpmostree-builtins.h index 43ef9ca6a8..877bdd34e0 100644 --- a/src/app/rpmostree-builtins.h +++ b/src/app/rpmostree-builtins.h @@ -50,6 +50,7 @@ BUILTINPROTO (internals); BUILTINPROTO (container); BUILTINPROTO (install); BUILTINPROTO (uninstall); +BUILTINPROTO (search); BUILTINPROTO (override); BUILTINPROTO (kargs); BUILTINPROTO (reset); diff --git a/src/app/rpmostree-pkg-builtins.cxx b/src/app/rpmostree-pkg-builtins.cxx index f2c26730d0..ec8790360f 100644 --- a/src/app/rpmostree-pkg-builtins.cxx +++ b/src/app/rpmostree-pkg-builtins.cxx @@ -31,6 +31,8 @@ #include +#include + static char *opt_osname; static gboolean opt_reboot; static gboolean opt_dry_run; @@ -310,3 +312,102 @@ rpmostree_builtin_uninstall (int argc, char **argv, RpmOstreeCommandInvocation * return pkg_change (invocation, sysroot_proxy, FALSE, (const char *const *)opt_install, (const char *const *)argv, cancellable, error); } + +struct cstrless +{ + bool + operator() (const gchar *a, const gchar *b) const + { + return strcmp (a, b) < 0; + } +}; + +gboolean +rpmostree_builtin_search (int argc, char **argv, RpmOstreeCommandInvocation *invocation, + GCancellable *cancellable, GError **error) +{ + GOptionContext *context; + glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL; + + context = g_option_context_new ("PACKAGE [PACKAGE...]"); + g_option_context_add_main_entries (context, install_option_entry, NULL); + g_option_context_add_main_entries (context, uninstall_option_entry, NULL); + + if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, invocation, + cancellable, NULL, NULL, &sysroot_proxy, error)) + return FALSE; + + if (argc < 2) + { + rpmostree_usage_error (context, "At least one PACKAGE must be specified", error); + return FALSE; + } + + glnx_unref_object RPMOSTreeOS *os_proxy = NULL; + + if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname, cancellable, &os_proxy, error)) + return FALSE; + + g_autoptr (GPtrArray) arg_names = g_ptr_array_new (); + for (guint i = 1; i < argc; i++) + { + g_ptr_array_add (arg_names, (char *)argv[i]); + } + g_ptr_array_add (arg_names, NULL); + + g_autoptr (GVariant) out_packages = NULL; + + if (!rpmostree_os_call_search_sync (os_proxy, (const char *const *)arg_names->pdata, + &out_packages, cancellable, error)) + return FALSE; + + g_autoptr (GVariantIter) iter1 = NULL; + g_variant_get (out_packages, "aa{sv}", &iter1); + + g_autoptr (GVariantIter) iter2 = NULL; + std::set query_set; + + while (g_variant_iter_loop (iter1, "a{sv}", &iter2)) + { + const gchar *key; + const gchar *name; + const gchar *summary; + const gchar *query; + const gchar *match_group = ""; + + g_autoptr (GVariant) value = NULL; + + while (g_variant_iter_loop (iter2, "{sv}", &key, &value)) + { + if (strcmp (key, "key") == 0) + g_variant_get (value, "s", &query); + else if (strcmp (key, "name") == 0) + g_variant_get (value, "s", &name); + else if (strcmp (key, "summary") == 0) + g_variant_get (value, "s", &summary); + } + + if (!query_set.count (query)) + { + query_set.insert (query); + + if (strcmp (query, "match_group_a") == 0) + match_group = "Summary & Name"; + else if (strcmp (query, "match_group_b") == 0) + match_group = "Name"; + else if (strcmp (query, "match_group_c") == 0) + match_group = "Summary"; + + g_print ("\n===== %s Matched =====\n", match_group); + } + + g_print ("%s : %s\n", name, summary); + } + + if (query_set.size () == 0) + { + g_print ("No matches found."); + } + + return TRUE; +} \ No newline at end of file diff --git a/src/daemon/org.projectatomic.rpmostree1.xml b/src/daemon/org.projectatomic.rpmostree1.xml index b11ff5dfd2..7765b3fe54 100644 --- a/src/daemon/org.projectatomic.rpmostree1.xml +++ b/src/daemon/org.projectatomic.rpmostree1.xml @@ -477,6 +477,12 @@ + + + + + + diff --git a/src/daemon/rpmostreed-os.cxx b/src/daemon/rpmostreed-os.cxx index 090c2dfd13..2275c8f2db 100644 --- a/src/daemon/rpmostreed-os.cxx +++ b/src/daemon/rpmostreed-os.cxx @@ -36,6 +36,11 @@ #include "rpmostreed-transaction.h" #include "rpmostreed-utils.h" +#include + +#include +#include + typedef struct _RpmostreedOSClass RpmostreedOSClass; struct _RpmostreedOS @@ -141,7 +146,7 @@ os_authorize_method (GDBusInterfaceSkeleton *interface, GDBusMethodInvocation *i else if (g_strcmp0 (method_name, "GetDeploymentBootConfig") == 0 || g_strcmp0 (method_name, "ListRepos") == 0 || g_strcmp0 (method_name, "WhatProvides") == 0 - || g_strcmp0 (method_name, "GetPackages") == 0) + || g_strcmp0 (method_name, "GetPackages") == 0 || g_strcmp0 (method_name, "Search") == 0) { /* Note: early return here because no need authentication * for these methods @@ -1138,6 +1143,110 @@ os_handle_get_packages (RPMOSTreeOS *interface, GDBusMethodInvocation *invocatio return TRUE; } +/* helper function to sort and search within a set of (const gchar *) */ +struct cstrless +{ + bool + operator() (const gchar *a, const gchar *b) const + { + return strcmp (a, b) < 0; + } +}; + +/* wrapper function to both query for packages and add them to the builder */ +static void +query_results_to_builder (HyQuery query, GVariantBuilder *builder, const gchar *id) +{ + std::set result_set; + g_autoptr (GPtrArray) pkglist = hy_query_run (query); + for (guint i = 0; i < pkglist->len && result_set.size () < 50; i++) + { + auto pkg = static_cast (g_ptr_array_index (pkglist, i)); + if (!result_set.count (dnf_package_get_name (pkg))) + { + os_add_package_info_to_builder (pkg, builder, id); + result_set.insert (dnf_package_get_name (pkg)); + } + } +} + +/* helper function to filter package query results */ +static void +search_packages_by_filter (HyQuery query, GVariantBuilder *builder, const gchar *const *names, + std::vector keynames, const gchar *id) +{ + /* case insensitive exact match between search term and package */ + hy_query_clear (query); + for (guint j = 0; j < keynames.size (); j++) + { + for (guint i = 0; names[i] != NULL; i++) + { + if (!hy_is_glob_pattern (names[i])) + { + hy_query_filter (query, keynames[j], HY_EQ | HY_ICASE, names[i]); + } + else + { + hy_query_filter (query, keynames[j], HY_GLOB | HY_ICASE, names[i]); + } + } + } + query_results_to_builder (query, builder, id); + + /* case insensitive substring match of search term within package */ + hy_query_clear (query); + for (guint j = 0; j < keynames.size (); j++) + { + for (guint i = 0; names[i] != NULL; i++) + { + if (!hy_is_glob_pattern (names[i])) + { + hy_query_filter (query, keynames[j], HY_SUBSTR | HY_ICASE, names[i]); + } + else + { + hy_query_filter (query, keynames[j], HY_GLOB | HY_ICASE, names[i]); + } + } + } + query_results_to_builder (query, builder, id); +} + +static gboolean +os_handle_search (RPMOSTreeOS *interface, GDBusMethodInvocation *invocation, + const gchar *const *names) +{ + GError *local_error = NULL; + g_autoptr (GCancellable) cancellable = NULL; + + sd_journal_print (LOG_INFO, "Handling Search for caller %s", + g_dbus_method_invocation_get_sender (invocation)); + + g_autoptr (DnfContext) dnfctx + = os_create_dnf_context_simple (interface, TRUE, cancellable, &local_error); + if (dnfctx == NULL) + return os_throw_dbus_invocation_error (invocation, &local_error); + + hy_autoquery HyQuery query = hy_query_create (dnf_context_get_sack (dnfctx)); + + GVariantBuilder builder; + g_variant_builder_init (&builder, (const GVariantType *)"aa{sv}"); + + std::vector keynames_a = { HY_PKG_NAME, HY_PKG_SUMMARY }; + search_packages_by_filter (query, &builder, names, keynames_a, "match_group_a"); + + std::vector keynames_b = { HY_PKG_NAME }; + search_packages_by_filter (query, &builder, names, keynames_b, "match_group_b"); + + std::vector keynames_c = { HY_PKG_SUMMARY }; + search_packages_by_filter (query, &builder, names, keynames_c, "match_group_c"); + + GVariant *pkgs_result = g_variant_builder_end (&builder); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@aa{sv})", pkgs_result)); + + return TRUE; +} + /* This is an older variant of Cleanup, kept for backcompat */ static gboolean os_handle_clear_rollback_target (RPMOSTreeOS *interface, GDBusMethodInvocation *invocation, @@ -1813,6 +1922,7 @@ rpmostreed_os_iface_init (RPMOSTreeOSIface *iface) iface->handle_finalize_deployment = os_handle_finalize_deployment; iface->handle_what_provides = os_handle_what_provides; iface->handle_get_packages = os_handle_get_packages; + iface->handle_search = os_handle_search; /* legacy cleanup API; superseded by Cleanup() */ iface->handle_clear_rollback_target = os_handle_clear_rollback_target; /* legacy deployment change API; superseded by UpdateDeployment() */ From dc3d8a251f42b37492518d88f2fc0584c104eb1b Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 5 Jul 2023 11:46:13 +0800 Subject: [PATCH 20/28] sysuers: fix error if running `groupadd` with `-f` According to Colin's pointer, this is to fix the error when running `rpm-ostree install libvirt` in container, ``` bash# env RPMOSTREE_EXP_BRIDGE_SYSUSERS=1 rpm-ostree install libvirt ... + test -v RPMOSTREE_EXP_BRIDGE_SYSUSERS + rpm-ostree scriptlet-intercept groupadd -- /sbin/groupadd -f -g 107 -r qemu error: a value is required for '--force ' but none was supplied For more information, try '--help'. ``` --- rust/src/builtins/scriptlet_intercept/groupadd.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rust/src/builtins/scriptlet_intercept/groupadd.rs b/rust/src/builtins/scriptlet_intercept/groupadd.rs index 0b74a0a463..ef9e6dc393 100644 --- a/rust/src/builtins/scriptlet_intercept/groupadd.rs +++ b/rust/src/builtins/scriptlet_intercept/groupadd.rs @@ -46,7 +46,12 @@ fn cli_cmd() -> Command { Command::new(name) .bin_name(name) .about("create a new group") - .arg(Arg::new("force").short('f').long("force")) + .arg( + Arg::new("force") + .short('f') + .long("force") + .action(ArgAction::SetTrue), + ) .arg( Arg::new("gid") .short('g') From 684facf025fa01d581e1382cfeb485b0f1ccb0e6 Mon Sep 17 00:00:00 2001 From: Luke Yang Date: Thu, 29 Jun 2023 13:21:25 -0400 Subject: [PATCH 21/28] Add `kola` tests and fix `Name & Summary` search `kola` tests added to test basic search functionality (name, summary, name & summary, and glob matches). Small fix for the duplicate removal feature. The `set` used to store existing query results needed to be passed as a pointer to the `query_results_to_builder` function. This allowed the data within the `set` to persist outside the function call. A large was change made to the `Name & Summary` search feature. Previously, the function would only return results that contained ALL search terms within BOTH the name and summary. With this commit, results in which search terms match EITHER the name or summary will be returned. This better matches `dnf`/`yum` CLI functionality. --- src/app/rpmostree-pkg-builtins.cxx | 4 +- src/daemon/rpmostreed-os.cxx | 119 +++++++++++++++++++++----- tests/kolainst/nondestructive/misc.sh | 33 +++++++ 3 files changed, 134 insertions(+), 22 deletions(-) diff --git a/src/app/rpmostree-pkg-builtins.cxx b/src/app/rpmostree-pkg-builtins.cxx index ec8790360f..1ca3564c83 100644 --- a/src/app/rpmostree-pkg-builtins.cxx +++ b/src/app/rpmostree-pkg-builtins.cxx @@ -406,8 +406,8 @@ rpmostree_builtin_search (int argc, char **argv, RpmOstreeCommandInvocation *inv if (query_set.size () == 0) { - g_print ("No matches found."); + g_print ("No matches found.\n"); } return TRUE; -} \ No newline at end of file +} diff --git a/src/daemon/rpmostreed-os.cxx b/src/daemon/rpmostreed-os.cxx index 2275c8f2db..52185c663b 100644 --- a/src/daemon/rpmostreed-os.cxx +++ b/src/daemon/rpmostreed-os.cxx @@ -1155,61 +1155,140 @@ struct cstrless /* wrapper function to both query for packages and add them to the builder */ static void -query_results_to_builder (HyQuery query, GVariantBuilder *builder, const gchar *id) +query_results_to_builder (HyQuery query, GVariantBuilder *builder, const gchar *id, + std::set *result_set) { - std::set result_set; g_autoptr (GPtrArray) pkglist = hy_query_run (query); - for (guint i = 0; i < pkglist->len && result_set.size () < 50; i++) + for (guint i = 0; i < pkglist->len && (*result_set).size () < 50; i++) { auto pkg = static_cast (g_ptr_array_index (pkglist, i)); - if (!result_set.count (dnf_package_get_name (pkg))) + if (!(*result_set).count (dnf_package_get_name (pkg))) { os_add_package_info_to_builder (pkg, builder, id); - result_set.insert (dnf_package_get_name (pkg)); + (*result_set).insert (dnf_package_get_name (pkg)); } } } +/* helper function to apply Name/Summary or HY_EQ/HY_SUBSTR filters on search term */ +static void +apply_search_filter (HyQuery *query, int keyname, const gchar *const name, int cmp_type) +{ + if (!hy_is_glob_pattern (name)) + { + hy_query_filter (*query, keyname, cmp_type | HY_ICASE, name); + } + else + { + hy_query_filter (*query, keyname, HY_GLOB | HY_ICASE, name); + } +} + /* helper function to filter package query results */ static void search_packages_by_filter (HyQuery query, GVariantBuilder *builder, const gchar *const *names, std::vector keynames, const gchar *id) { - /* case insensitive exact match between search term and package */ - hy_query_clear (query); - for (guint j = 0; j < keynames.size (); j++) + std::set result_set; + HyQuery intermediate_query = hy_query_clone (query); + HyQuery final_query = hy_query_clone (query); + + int names_count = 0; + for (guint i = 0; names[i] != NULL; i++) { + names_count++; + } + + /* Name/Summary matches */ + if (keynames.size () < 2) + { + hy_query_clear (query); for (guint i = 0; names[i] != NULL; i++) { - if (!hy_is_glob_pattern (names[i])) + apply_search_filter (&query, keynames[0], names[i], HY_EQ); + } + query_results_to_builder (query, builder, id, &result_set); + + hy_query_clear (query); + for (guint i = 0; names[i] != NULL; i++) + { + apply_search_filter (&query, keynames[0], names[i], HY_SUBSTR); + } + query_results_to_builder (query, builder, id, &result_set); + } + + /* Name AND Summary matches for more than one search term */ + /* ========================================================================================= + For each search term, apply a query with the keyname filter (Name or Summary) and unions the + results. This allows multi-term searches to return matches when search terms are found in + either the Name or Summary of a package. After this, return the intersection of the results + for each search term to filter out results that do not contain all matching terms. + ========================================================================================= */ + else if (keynames.size () >= 2 && names_count >= 2) + { + + for (guint i = 0; names[i] != NULL; i++) + { + hy_query_clear (intermediate_query); + for (guint j = 0; j < keynames.size (); j++) + { + hy_query_clear (query); + apply_search_filter (&query, keynames[j], names[i], HY_EQ); + + if (j != 0) + { + hy_query_union (intermediate_query, query); + } + else + { + intermediate_query = hy_query_clone (query); + } + + hy_query_clear (query); + apply_search_filter (&query, keynames[j], names[i], HY_SUBSTR); + hy_query_union (intermediate_query, query); + } + + if (i != 0) { - hy_query_filter (query, keynames[j], HY_EQ | HY_ICASE, names[i]); + hy_query_intersection (final_query, intermediate_query); } else { - hy_query_filter (query, keynames[j], HY_GLOB | HY_ICASE, names[i]); + final_query = hy_query_clone (intermediate_query); } } + query_results_to_builder (final_query, builder, id, &result_set); } - query_results_to_builder (query, builder, id); - /* case insensitive substring match of search term within package */ - hy_query_clear (query); - for (guint j = 0; j < keynames.size (); j++) + /* Name AND Summary matches for only one search term */ + /* ========================================================================================= + For the case of a single search term, return the intersection of both Name and Summary matches + of the search term (instead of the union for multi-term searches). + ========================================================================================= */ + else if (keynames.size () >= 2 && names_count < 2) { - for (guint i = 0; names[i] != NULL; i++) + for (guint i = 0; i < keynames.size (); i++) { - if (!hy_is_glob_pattern (names[i])) + hy_query_clear (query); + apply_search_filter (&query, keynames[i], names[0], HY_EQ); + intermediate_query = hy_query_clone (query); + + hy_query_clear (query); + apply_search_filter (&query, keynames[i], names[0], HY_SUBSTR); + hy_query_union (intermediate_query, query); + + if (i != 0) { - hy_query_filter (query, keynames[j], HY_SUBSTR | HY_ICASE, names[i]); + hy_query_intersection (final_query, intermediate_query); } else { - hy_query_filter (query, keynames[j], HY_GLOB | HY_ICASE, names[i]); + final_query = hy_query_clone (intermediate_query); } } + query_results_to_builder (final_query, builder, id, &result_set); } - query_results_to_builder (query, builder, id); } static gboolean diff --git a/tests/kolainst/nondestructive/misc.sh b/tests/kolainst/nondestructive/misc.sh index 6965b2f280..223bd45d61 100755 --- a/tests/kolainst/nondestructive/misc.sh +++ b/tests/kolainst/nondestructive/misc.sh @@ -101,6 +101,39 @@ rpmostree_busctl_call_os GetPackages as 1 should-not-exist-p-equals-np > out.txt assert_file_has_content_literal out.txt 'aa{sv} 0' echo "ok dbus GetPackages" +rpmostree_busctl_call_os Search as 1 testdaemon > out.txt +assert_file_has_content_literal out.txt '"epoch" t 0' +assert_file_has_content_literal out.txt '"reponame" s "libtest"' +assert_file_has_content_literal out.txt '"nevra" s "testdaemon' +rpmostree_busctl_call_os Search as 1 should-not-exist-p-equals-np > out.txt +assert_file_has_content_literal out.txt 'aa{sv} 0' +echo "ok dbus Search" + +rpm-ostree search testdaemon > out.txt +assert_file_has_content_literal out.txt '===== Name Matched =====' +assert_file_has_content_literal out.txt 'testdaemon : awesome-daemon-for-testing' +echo "ok Search name match" + +rpm-ostree search awesome-daemon > out.txt +assert_file_has_content_literal out.txt '===== Summary Matched =====' +assert_file_has_content_literal out.txt 'testdaemon : awesome-daemon-for-testing' +echo "ok Search summary match" + +rpm-ostree search testdaemon awesome-daemon > out.txt +assert_file_has_content_literal out.txt '===== Summary & Name Matched =====' +assert_file_has_content_literal out.txt 'testdaemon : awesome-daemon-for-testing' +echo "ok Search name and summary match" + +rpm-ostree search "test*" > out.txt +assert_file_has_content_literal out.txt '===== Summary & Name Matched =====' +assert_file_has_content_literal out.txt '===== Name Matched =====' +assert_file_has_content_literal out.txt '===== Summary Matched =====' +assert_file_has_content_literal out.txt 'testdaemon : awesome-daemon-for-testing' +assert_file_has_content_literal out.txt 'testpkg-etc : testpkg-etc' +assert_file_has_content_literal out.txt 'testpkg-post-infinite-loop : testpkg-post-infinite-loop' +assert_file_has_content_literal out.txt 'testpkg-touch-run : testpkg-touch-run' +echo "ok Search glob pattern match" + # Verify operations as non-root runuser -u core rpm-ostree status echo "ok status doesn't require root" From 88864071ea8dc95c606f69d48d77e5c05a45604b Mon Sep 17 00:00:00 2001 From: Eric Curtin Date: Mon, 10 Jul 2023 10:14:52 +0100 Subject: [PATCH 22/28] kernel: Specify multiple kernel or initramfs in error message It sometimes happens during osbuild that there are two kernel rpms installed while setting up the initial error message, leading to something like: error: Finalizing rootfs: During kernel processing: Multiple vmlinuz- in usr/lib/ostree-boot With the user unsure what the two kernel versions were. With this change we print the kernel versions. --- src/libpriv/rpmostree-kernel.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libpriv/rpmostree-kernel.cxx b/src/libpriv/rpmostree-kernel.cxx index 2cf6d00fa8..e5dcb8f1f3 100644 --- a/src/libpriv/rpmostree-kernel.cxx +++ b/src/libpriv/rpmostree-kernel.cxx @@ -89,7 +89,8 @@ find_kernel_and_initramfs_in_bootdir (int rootfs_dfd, const char *bootdir, char if (out_ksuffix ? g_str_has_prefix (name, "vmlinuz-") : g_str_equal (name, "vmlinuz")) { if (ret_kernel) - return glnx_throw (error, "Multiple vmlinuz%s in %s", out_ksuffix ? "-" : "", bootdir); + return glnx_throw (error, "Multiple vmlinuz%s in %s, occurrences '%s' and '%s/%s'", + out_ksuffix ? "-" : "", bootdir, ret_kernel, bootdir, name); if (out_ksuffix) ret_ksuffix = g_strdup (name + strlen ("vmlinuz-")); ret_kernel = g_strconcat (bootdir, "/", name, NULL); @@ -97,7 +98,8 @@ find_kernel_and_initramfs_in_bootdir (int rootfs_dfd, const char *bootdir, char else if (g_str_equal (name, "initramfs.img") || g_str_has_prefix (name, "initramfs-")) { if (ret_initramfs) - return glnx_throw (error, "Multiple initramfs- in %s", bootdir); + return glnx_throw (error, "Multiple initramfs- in %s, occurrences '%s' and '%s/%s'", + bootdir, ret_initramfs, bootdir, name); ret_initramfs = g_strconcat (bootdir, "/", name, NULL); } } From ff002a39ab6ca3042bf6e39ce1f83fec0da85710 Mon Sep 17 00:00:00 2001 From: Joseph Marrero Date: Mon, 10 Jul 2023 13:55:48 -0400 Subject: [PATCH 23/28] ci/test-container.sh: use f37 ignition for replace test - Use the fedora 37 ignition rpm for the override replace test - Drop f36 and f37 tests --- ci/test-container.sh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/ci/test-container.sh b/ci/test-container.sh index 0a5a0ba3e2..c7490e9044 100755 --- a/ci/test-container.sh +++ b/ci/test-container.sh @@ -58,8 +58,6 @@ versionid=$(. /usr/lib/os-release && echo $VERSION_ID) # Let's start by trying to install a bona fide module. # NOTE: If changing this also change the layering-modules test case $versionid in - 36) module=cri-o:1.23/default;; - 37) module=cri-o:1.24/default;; 38) module=cri-o:1.25/default;; *) assert_not_reached "Unsupported Fedora version: $versionid";; esac @@ -77,16 +75,8 @@ fi versionid=$(grep -E '^VERSION_ID=' /etc/os-release) versionid=${versionid:11} # trim off VERSION_ID= case $versionid in - 37) - url_suffix=2.14.0/3.fc37/x86_64/ignition-2.14.0-3.fc37.x86_64.rpm - # 2.14.0-4 - koji_url="https://koji.fedoraproject.org/koji/buildinfo?buildID=2013062" - koji_kernel_url="https://koji.fedoraproject.org/koji/buildinfo?buildID=2084352" - kver=6.0.7 - krev=301 - ;; 38) - url_suffix=2.15.0/2.fc38/x86_64/ignition-2.15.0-2.fc38.x86_64.rpm + url_suffix=2.15.0/4.fc37/x86_64/ignition-2.15.0-4.fc37.x86_64.rpm # 2.15.0-3 koji_url="https://koji.fedoraproject.org/koji/buildinfo?buildID=2158585" koji_kernel_url="https://koji.fedoraproject.org/koji/buildinfo?buildID=2174317" From 99505c0bfc2b97b7eee5f1e70193ec1ee17fca3f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 11 Jul 2023 13:51:16 -0400 Subject: [PATCH 24/28] container: Clarify error for nonexistent previous manifest file This would have likely slightly helped debug https://github.com/coreos/coreos-assembler/pull/3508#issuecomment-1629913936 --- rust/src/container.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/src/container.rs b/rust/src/container.rs index e6a3729416..468ced8809 100644 --- a/rust/src/container.rs +++ b/rust/src/container.rs @@ -426,7 +426,10 @@ pub fn container_encapsulate(args: Vec) -> CxxResult<()> { let package_structure = opt .previous_build_manifest .as_ref() - .map(|p| oci_spec::image::ImageManifest::from_file(&p).map_err(anyhow::Error::new)) + .map(|p| { + oci_spec::image::ImageManifest::from_file(&p) + .map_err(|e| anyhow::anyhow!("Failed to read previous manifest {p}: {e}")) + }) .transpose()?; let mut copy_meta_keys = opt.copy_meta_keys; From dd704c3d66ee0fffa874f3ddbce8d38588276518 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 07:15:03 +0000 Subject: [PATCH 25/28] build(deps): bump clap from 4.3.3 to 4.3.12 Bumps [clap](https://github.com/clap-rs/clap) from 4.3.3 to 4.3.12. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.3.3...v4.3.12) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79d1334778..0829e2bab7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,9 +323,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.3" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" +checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" dependencies = [ "clap_builder", "clap_derive", @@ -334,22 +334,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.3" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" +checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" dependencies = [ "anstream", "anstyle", - "bitflags 1.3.2", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", From d085f9717f0ff56a80ebcfb132a68c1ca736f29b Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Wed, 12 Jul 2023 17:41:44 +0800 Subject: [PATCH 26/28] passwd: Rename func `data_from_json` to `write_data_from_treefile` and add comment --- rust/src/passwd.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs index 9348f8627d..6a6dbf8409 100644 --- a/rust/src/passwd.rs +++ b/rust/src/passwd.rs @@ -315,8 +315,8 @@ fn passwd_compose_prep_impl( rootfs.create_dir_with(dest, &db)?; // TODO(lucab): consider reworking these to avoid boolean results. - let found_passwd_data = data_from_json(rootfs, treefile, dest, "passwd")?; - let found_groups_data = data_from_json(rootfs, treefile, dest, "group")?; + let found_passwd_data = write_data_from_treefile(rootfs, treefile, dest, "passwd")?; + let found_groups_data = write_data_from_treefile(rootfs, treefile, dest, "group")?; // We should error if we are getting passwd data from JSON and group from // previous commit, or vice versa, as that'll confuse everyone when it goes @@ -340,7 +340,9 @@ fn passwd_compose_prep_impl( Ok(()) } -fn data_from_json( +// This function writes the static passwd/group data from the treefile to the +// target root filesystem. +fn write_data_from_treefile( rootfs: &Dir, treefile: &mut Treefile, dest_path: &str, From fdb879c8775c996cfab148c81b5ea5e48f5fc3e8 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Mon, 17 Jul 2023 22:27:01 +0800 Subject: [PATCH 27/28] passwd: sync `etc/{,g}shadow` according to `etc/{passwd,group}` Refer to https://github.com/coreos/rpm-ostree/issues/49#issuecomment-1612626563, do testing: 1. Remove bin line in group and passwd 2. Build FCOS, see logs: ``` systemd.post: Creating group 'bin' with GID 1. systemd.post: Creating user 'bin' (bin) with UID 1 and GID 1. systemd.post: /etc/gshadow: Group "bin" already exists. ``` According to @cgwalters 's pointer: The above log will lead systemd-sysusers (during systemd.post) exit early before saving the updated `/etc/{passwd,group}` refer to [code](https://github.com/systemd/systemd/blob/main/src/sysusers/sysusers.c#L820), and bin user/group will not be saved finally. The root cause is that `gshadow` is not consistent with group, `gshadow` is from setup, and we override group according to https://github.com/coreos/fedora-coreos-config/blob/testing-devel/manifests/group. The `shadow` is also from setup, and is not consistent with passwd, we should also sync it. Fix https://github.com/coreos/fedora-coreos-tracker/issues/1525 --- rust/src/passwd.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs index 6a6dbf8409..74893761ac 100644 --- a/rust/src/passwd.rs +++ b/rust/src/passwd.rs @@ -389,6 +389,40 @@ fn write_data_from_treefile( }) .with_context(|| format!("failed to write /{}", &target_etc_filename))?; + // Regenerate etc/{,g}shadow to sync with etc/{password,group} + let db = rootfs.open(target_etc_filename).map(BufReader::new)?; + let shadow_name = if target == "passwd" { + "shadow" + } else { + "gshadow" + }; + let target_etc_shadow = format!("{}{}", dest_path, shadow_name); + + match shadow_name { + "shadow" => { + let entries = nameservice::passwd::parse_passwd_content(db)?; + rootfs + .atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> { + for user in entries { + writeln!(target_shadow, "{}:*::0:99999:7:::", user.name)?; + } + Ok(()) + }) + .with_context(|| format!("Writing {target_etc_shadow}"))?; + } + "gshadow" => { + let entries = nameservice::group::parse_group_content(db)?; + rootfs + .atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> { + for group in entries { + writeln!(target_shadow, "{}:::", group.name)?; + } + Ok(()) + }) + .with_context(|| format!("Writing {target_etc_shadow}"))?; + } + _ => unreachable!("invalid file path: {}", target_etc_shadow), + } Ok(true) } From d498bac1dd00344b23ccb2aa8d590c34acc691e2 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Tue, 18 Jul 2023 10:56:31 +0800 Subject: [PATCH 28/28] passwd: add `enum PasswdKind` Refer to https://github.com/coreos/rpm-ostree/pull/4503#discussion_r1265759880 --- rust/src/passwd.rs | 103 +++++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/rust/src/passwd.rs b/rust/src/passwd.rs index 74893761ac..4bedf107bc 100644 --- a/rust/src/passwd.rs +++ b/rust/src/passwd.rs @@ -315,8 +315,8 @@ fn passwd_compose_prep_impl( rootfs.create_dir_with(dest, &db)?; // TODO(lucab): consider reworking these to avoid boolean results. - let found_passwd_data = write_data_from_treefile(rootfs, treefile, dest, "passwd")?; - let found_groups_data = write_data_from_treefile(rootfs, treefile, dest, "group")?; + let found_passwd_data = write_data_from_treefile(rootfs, treefile, dest, &PasswdKind::User)?; + let found_groups_data = write_data_from_treefile(rootfs, treefile, dest, &PasswdKind::Group)?; // We should error if we are getting passwd data from JSON and group from // previous commit, or vice versa, as that'll confuse everyone when it goes @@ -340,88 +340,109 @@ fn passwd_compose_prep_impl( Ok(()) } +// PasswdKind includes 2 types: user and group. +#[derive(Debug)] +enum PasswdKind { + User, + Group, +} + +impl PasswdKind { + // Get user/group passwd file + fn passwd_file(&self) -> &'static str { + return match *self { + PasswdKind::User => "passwd", + PasswdKind::Group => "group", + }; + } + // Get user/group shadow file + fn shadow_file(&self) -> &'static str { + return match *self { + PasswdKind::User => "shadow", + PasswdKind::Group => "gshadow", + }; + } +} + // This function writes the static passwd/group data from the treefile to the // target root filesystem. fn write_data_from_treefile( rootfs: &Dir, treefile: &mut Treefile, dest_path: &str, - target: &str, + target: &PasswdKind, ) -> Result { anyhow::ensure!(!dest_path.is_empty(), "missing destination path"); let append_unique_entries = match target { - "passwd" => passwd_append_unique, - "group" => group_append_unique, - x => anyhow::bail!("invalid merge target '{}'", x), + PasswdKind::User => passwd_append_unique, + PasswdKind::Group => group_append_unique, }; - let target_etc_filename = format!("{}{}", dest_path, target); + let passwd_name = target.passwd_file(); + let target_passwd_path = format!("{}{}", dest_path, passwd_name); // Migrate the check data from the specified file to /etc. - let mut src_file = if target == "passwd" { - let check_passwd_file = match treefile.parsed.get_check_passwd() { - CheckPasswd::File(cfg) => cfg, - _ => return Ok(false), - }; - treefile.externals.passwd_file_mut(check_passwd_file)? - } else if target == "group" { - let check_groups_file = match treefile.parsed.get_check_groups() { - CheckGroups::File(cfg) => cfg, - _ => return Ok(false), - }; - treefile.externals.group_file_mut(check_groups_file)? - } else { - unreachable!("impossible merge target '{}'", target); + let mut src_file = match target { + PasswdKind::User => { + let check_passwd_file = match treefile.parsed.get_check_passwd() { + CheckPasswd::File(cfg) => cfg, + _ => return Ok(false), + }; + treefile.externals.passwd_file_mut(check_passwd_file)? + } + PasswdKind::Group => { + let check_groups_file = match treefile.parsed.get_check_groups() { + CheckGroups::File(cfg) => cfg, + _ => return Ok(false), + }; + treefile.externals.group_file_mut(check_groups_file)? + } }; let mut seen_names = HashSet::new(); rootfs - .atomic_replace_with(&target_etc_filename, |dest_bufwr| -> Result<()> { + .atomic_replace_with(&target_passwd_path, |dest_bufwr| -> Result<()> { dest_bufwr .get_mut() .as_file_mut() .set_permissions(DEFAULT_PERMS.clone())?; let mut buf_rd = BufReader::new(&mut src_file); - append_unique_entries(&mut buf_rd, &mut seen_names, dest_bufwr) - .with_context(|| format!("failed to process '{}' content from JSON", &target))?; + append_unique_entries(&mut buf_rd, &mut seen_names, dest_bufwr).with_context(|| { + format!("failed to process '{}' content from JSON", &passwd_name) + })?; Ok(()) }) - .with_context(|| format!("failed to write /{}", &target_etc_filename))?; + .with_context(|| format!("failed to write /{}", &target_passwd_path))?; - // Regenerate etc/{,g}shadow to sync with etc/{password,group} - let db = rootfs.open(target_etc_filename).map(BufReader::new)?; - let shadow_name = if target == "passwd" { - "shadow" - } else { - "gshadow" - }; - let target_etc_shadow = format!("{}{}", dest_path, shadow_name); + // Regenerate etc/{,g}shadow to sync with etc/{passwd,group} + let db = rootfs.open(target_passwd_path).map(BufReader::new)?; + let shadow_name = target.shadow_file(); + let target_shadow_path = format!("{}{}", dest_path, shadow_name); - match shadow_name { - "shadow" => { + match target { + PasswdKind::User => { let entries = nameservice::passwd::parse_passwd_content(db)?; rootfs - .atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> { + .atomic_replace_with(&target_shadow_path, |target_shadow| -> Result<()> { for user in entries { writeln!(target_shadow, "{}:*::0:99999:7:::", user.name)?; } Ok(()) }) - .with_context(|| format!("Writing {target_etc_shadow}"))?; + .with_context(|| format!("Writing {target_shadow_path}"))?; } - "gshadow" => { + PasswdKind::Group => { let entries = nameservice::group::parse_group_content(db)?; rootfs - .atomic_replace_with(&target_etc_shadow, |target_shadow| -> Result<()> { + .atomic_replace_with(&target_shadow_path, |target_shadow| -> Result<()> { for group in entries { writeln!(target_shadow, "{}:::", group.name)?; } Ok(()) }) - .with_context(|| format!("Writing {target_etc_shadow}"))?; + .with_context(|| format!("Writing {target_shadow_path}"))?; } - _ => unreachable!("invalid file path: {}", target_etc_shadow), } Ok(true) }