From f836a09c77a4d00411ccfae722eeed8c5f30c4cc Mon Sep 17 00:00:00 2001 From: Daniel Alley Date: Fri, 22 Dec 2023 11:03:13 -0500 Subject: [PATCH] Add support for rpm 4.19 auto-creation of users and groups closes #206 --- CHANGELOG.md | 1 + src/rpm/builder.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c93ffb4..4411c925 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `Dependency::script_pre()`, `Dependency::script_post()`, `Dependency::script_preun()`, `Dependency::script_postun()` +- Added support for the automatic user/group creation feature in rpm 4.19 ## 0.13.1 diff --git a/src/rpm/builder.rs b/src/rpm/builder.rs index 9a49a17f..4a64467b 100644 --- a/src/rpm/builder.rs +++ b/src/rpm/builder.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::TryInto; use std::fs; @@ -663,6 +663,8 @@ impl PackageBuilder { let mut file_verify_flags = Vec::with_capacity(files_len); let mut dir_indixes = Vec::with_capacity(files_len); let mut base_names = Vec::with_capacity(files_len); + let mut users_to_create = HashSet::new(); + let mut groups_to_create = HashSet::new(); let mut combined_file_sizes: u64 = 0; let mut uses_file_capabilities = false; @@ -672,6 +674,12 @@ impl PackageBuilder { if entry.caps.is_some() { uses_file_capabilities = true; } + if &entry.user != "root" { + users_to_create.insert(entry.user.clone()); + } + if &entry.group != "root" { + groups_to_create.insert(entry.group.clone()); + } file_sizes.push(entry.size); file_modes.push(entry.mode.into()); file_caps.push(entry.caps.to_owned()); @@ -752,6 +760,24 @@ impl PackageBuilder { "4.6.1-1".to_owned(), )); } + // TODO: as per https://rpm-software-management.github.io/rpm/manual/users_and_groups.html, + // at some point in the future this might make sense as hard requirements, but since it's a new feature, + // they have to be weak requirements to avoid breaking things. + for user in &users_to_create { + self.recommends.push(Dependency::new( + format!("user({})", user), + DependencyFlags::SCRIPT_PRE | DependencyFlags::SCRIPT_POSTUN, + "".to_owned(), + )) + } + + for group in &groups_to_create { + self.recommends.push(Dependency::new( + format!("group({})", group), + DependencyFlags::SCRIPT_PRE | DependencyFlags::SCRIPT_POSTUN, + "".to_owned(), + )) + } let mut provide_names = Vec::new(); let mut provide_flags = Vec::new(); @@ -837,6 +863,8 @@ impl PackageBuilder { let small_package = combined_file_sizes <= u32::MAX.into(); let mut actual_records = vec![ + // Existence of this tag is how rpm decides whether or not a package is a source rpm or binary rpm + // If the SOURCERPM tag is set, then the package is seen as a binary rpm. IndexEntry::new( IndexTag::RPMTAG_SOURCERPM, offset,