From e6e4fe3b4a984e61ff6184a549fcf1cf4100cc30 Mon Sep 17 00:00:00 2001 From: syokensyo Date: Tue, 29 Aug 2023 14:16:03 +0800 Subject: [PATCH 1/2] add conditinal compile cfg to fix compile error on windows which inroduced by file caps feature --- Cargo.toml | 1 + src/rpm/builder.rs | 4 ++++ src/rpm/headers/types.rs | 8 ++++++++ src/tests.rs | 27 +++++++++++++++------------ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70d97cb3..0c2d672e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ itertools = "0.11" hex = { version = "0.4", features = ["std"] } zstd = "0.12" xz2 = "0.1" +[target.'cfg(unix)'.dependencies] capctl = "0.2.3" [dev-dependencies] diff --git a/src/rpm/builder.rs b/src/rpm/builder.rs index 5b1ce21c..44cd62c8 100644 --- a/src/rpm/builder.rs +++ b/src/rpm/builder.rs @@ -349,6 +349,7 @@ impl PackageBuilder { link: options.symlink, modified_at, dir: dir.clone(), + #[cfg(unix)] // Convert the caps to a string, so that we can store it in the header. // We do this so that it's possible to verify that caps are correct when provided // and then later check if any were set @@ -578,6 +579,7 @@ impl PackageBuilder { let files_len = self.files.len(); let mut file_sizes = Vec::with_capacity(files_len); let mut file_modes = Vec::with_capacity(files_len); + #[cfg(unix)] let mut file_caps = Vec::with_capacity(files_len); let mut file_rdevs = Vec::with_capacity(files_len); let mut file_mtimes = Vec::with_capacity(files_len); @@ -599,6 +601,7 @@ impl PackageBuilder { combined_file_sizes += entry.size; file_sizes.push(entry.size); file_modes.push(entry.mode.into()); + #[cfg(unix)] file_caps.push(entry.caps.to_owned()); // I really do not know the difference. It seems like file_rdevice is always 0 and file_device number always 1. // Who knows, who cares. @@ -976,6 +979,7 @@ impl PackageBuilder { IndexData::StringArray(self.directories.into_iter().collect()), ), ]); + #[cfg(unix)] if file_caps.iter().any(|caps| caps.is_some()) { actual_records.extend([IndexEntry::new( IndexTag::RPMTAG_FILECAPS, diff --git a/src/rpm/headers/types.rs b/src/rpm/headers/types.rs index 17be7941..67c3c74f 100644 --- a/src/rpm/headers/types.rs +++ b/src/rpm/headers/types.rs @@ -1,7 +1,9 @@ //! A collection of types used in various header records. +#[cfg(unix)] use std::str::FromStr; use crate::{constants::*, errors, Timestamp}; +#[cfg(unix)] use capctl::FileCaps; use digest::Digest; @@ -28,6 +30,7 @@ pub struct PackageFileEntry { pub group: String, pub base_name: String, pub dir: String, + #[cfg(unix)] pub caps: Option, pub(crate) content: Vec, } @@ -198,6 +201,7 @@ pub struct FileOptions { pub(crate) mode: FileMode, pub(crate) flag: FileFlags, pub(crate) inherit_permissions: bool, + #[cfg(unix)] pub(crate) caps: Option, } @@ -213,6 +217,7 @@ impl FileOptions { mode: FileMode::regular(0o664), flag: FileFlags::empty(), inherit_permissions: true, + #[cfg(unix)] caps: None, }, } @@ -246,6 +251,7 @@ impl FileOptionsBuilder { self } + #[cfg(unix)] pub fn caps(mut self, caps: impl Into) -> Result { // verify capabilities self.inner.caps = match FileCaps::from_str(&caps.into()) { @@ -490,12 +496,14 @@ mod test { Ok(()) } + #[cfg(unix)] #[test] fn test_verify_capabilities_valid() { let blank_file = crate::FileOptions::new("/usr/bin/awesome"); blank_file.caps("cap_net_admin,cap_net_raw+p").unwrap(); } + #[cfg(unix)] #[test] fn test_verify_capabilities_invalid() -> Result<(), crate::errors::Error> { let blank_file = crate::FileOptions::new("/usr/bin/awesome"); diff --git a/src/tests.rs b/src/tests.rs index 6fbe39f4..0834f03b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -13,7 +13,7 @@ fn cargo_manifest_dir() -> std::path::PathBuf { fn test_rpm_builder() -> Result<(), Box> { let mut buff = std::io::Cursor::new(Vec::::new()); - let pkg = PackageBuilder::new("test", "1.0.0", "MIT", "x86_64", "some awesome package") + let builder = PackageBuilder::new("test", "1.0.0", "MIT", "x86_64", "some awesome package") .compression(rpm::CompressionType::Gzip) .with_file( "Cargo.toml", @@ -21,14 +21,6 @@ fn test_rpm_builder() -> Result<(), Box> { )? // file mode is inherited from source file .with_file("Cargo.toml", FileOptions::new("/usr/bin/awesome"))? - .with_file( - "Cargo.toml", - // you can set a custom mode and custom user too - FileOptions::new("/etc/awesome/second.toml") - .mode(0o100744) - .caps("cap_sys_admin,cap_sys_ptrace=pe")? - .user("hugo"), - )? .with_file( "./test_assets/empty_file_for_symlink_create", FileOptions::new("/usr/bin/awesome_link") @@ -41,9 +33,17 @@ fn test_rpm_builder() -> Result<(), Box> { .requires(Dependency::any("wget")) .vendor("dummy vendor") .url("dummy url") - .vcs("dummy vcs") - .build()?; - + .vcs("dummy vcs"); + #[cfg(unix)] + let builder = builder.with_file( + "Cargo.toml", + // you can set a custom mode and custom user too + FileOptions::new("/etc/awesome/second.toml") + .mode(0o100744) + .caps("cap_sys_admin,cap_sys_ptrace=pe")? + .user("hugo"), + )?; + let pkg = builder.build()?; pkg.write(&mut buff)?; // check that generated packages has source rpm tag @@ -55,14 +55,17 @@ fn test_rpm_builder() -> Result<(), Box> { // check various metadata on the files pkg.metadata.get_file_entries()?.iter().for_each(|f| { if f.path.as_os_str() == "/etc/awesome/second.toml" { + #[cfg(unix)] assert_eq!( f.clone().caps.unwrap(), "cap_sys_ptrace,cap_sys_admin=ep".to_string() ); assert_eq!(f.ownership.user, "hugo".to_string()); } else if f.path.as_os_str() == "/etc/awesome/config.toml" { + #[cfg(unix)] assert_eq!(f.caps, Some("".to_string())); } else if f.path.as_os_str() == "/usr/bin/awesome" { + #[cfg(unix)] assert_eq!(f.mode, FileMode::from(0o100644)); } else if f.path.as_os_str() == "/usr/bin/awesome_link" { assert_eq!(f.mode, FileMode::from(0o120644)); From cd0f293200b61b775fa8fcb9f84e8dabf3f4162e Mon Sep 17 00:00:00 2001 From: syokensyo Date: Tue, 29 Aug 2023 14:31:53 +0800 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 802d4fd1..bf73f635 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `PackageMetadata::get_file_entries` method can get capability headers for each file. - Support for symbolic link in file mode. - Make file type const `REGULAR_FILE_TYPE` `DIR_FILE_TYPE` `SYMBOLIC_LINK_FILE_TYPE` public, because `FileMode::file_type` is public, sometimes we need this const to determin file type. +- Fix compile error on Windows which introduced by file capabilities support feature. ## 0.12.0