Giter Club home page Giter Club logo

rpm's Introduction

crates.io docs.rs MSRV

RPM-RS

A pure rust library for parsing and creating RPM files.

Goals

  • Easy to use API
  • Pure rust to make it easy to use in larger Projects
  • Independence of Spec files. Pure programmatic interface for Packaging.
  • Compatibility from Enterprise Linux 8 (RHEL, Alma, Rocky, CentOS Stream) to Fedora (I may extend test cases for SUSE)

Non Goals

RPM has a lot of cryptic features. I do not want to re-implement all of them. This library focuses on the ones that I assume as useful. This library does not build software like rpmbuild. It is meant for finished artifacts that need to be packaged as RPM.

Status

  • RPM Creation
  • Basic RPM Reading
  • RPM Signing and Signature Verification
  • High Level API for RPM Reading

Examples

use rpm::signature::pgp::{Signer, Verifier};

let raw_secret_key = std::fs::read("./test_assets/secret_key.asc")?;
// It's recommended to use timestamp of last commit in your VCS
let source_date = 1_600_000_000;
let pkg = rpm::PackageBuilder::new("test", "1.0.0", "MIT", "x86_64", "some awesome package")
    .compression(rpm::CompressionType::Gzip)
    .with_file(
        "./test_assets/awesome.toml",
        rpm::FileOptions::new("/etc/awesome/config.toml")
            .is_config()
            .is_no_replace(),
    )?
    // file mode is inherited from source file
    .with_file(
        "./test_assets/awesome.py",
        rpm::FileOptions::new("/usr/bin/awesome"),
    )?
    .with_file(
        "./test_assets/awesome.toml",
        // you can set a custom mode and custom user too
        rpm::FileOptions::new("/etc/awesome/second.toml")
            .mode(rpm::FileMode::regular(0o644))
            .caps("cap_sys_admin,cap_net_admin=pe")?
            .user("hugo"),
    )?
    .pre_install_script("echo preinst")
    // Alternatively, use scriptlet builder api to specify flags and interpreter/arguments
    .post_trans_script(
        Scriptlet::new("echo posttrans")
            .flags(ScriptletFlags::EXPAND)
            .prog(vec!["/bin/blah/bash", "-c"])
    )
    // If you don't need reproducible builds,
    // you can remove the following line
    .source_date(source_date)
    .build_host(gethostname::gethostname().to_str().unwrap_or("host"))
    .add_changelog_entry(
        "Max Mustermann <[email protected]> - 0.1-29",
        "- was awesome, eh?",
        chrono::DateTime::parse_from_rfc2822("Wed, 19 Apr 2023 23:16:09 GMT")
            .expect("Date 1 is correct. qed"),
    )
    .add_changelog_entry(
        "Charlie Yom <[email protected]> - 0.1-28",
        "- yeah, it was",
        // Raw timestamp for 1996-08-14 05:20:00
        840_000_000,
    )
    .requires(rpm::Dependency::any("wget"))
    .vendor("corporation or individual")
    .url("www.github.com/repo")
    .vcs("git:repo=example_repo:branch=example_branch:sha=example_sha")
    .build_and_sign(Signer::load_from_asc_bytes(&raw_secret_key)?)?;

pkg.write_file("./awesome.rpm")?;

// reading
let raw_pub_key = std::fs::read("/path/to/gpg.key.pub")?;
let pkg = rpm::Package::open("test_assets/389-ds-base-devel-1.3.8.4-15.el7.x86_64.rpm")?;

let name = pkg.metadata.get_name()?;
let version = pkg.metadata.get_version()?;
let release = pkg.metadata.get_release()?;
let arch = pkg.metadata.get_arch()?;

println!("{}-{}-{}.{}", name, version, release, arch);

for changelog in pkg.metadata.get_changelog_entries()? {
    println!("{}\n{}\n", changelog.name, changelog.description);
}

// verifying
pkg.verify_signature(Verifier::load_from_asc_bytes(&raw_pub_key)?)?;

rpm's People

Contributors

dralley avatar drahnr avatar richterrettich avatar dependabot[bot] avatar juliusl avatar marxin avatar olivierlemasle avatar cmeister2 avatar newpavlov avatar ikrivosheev avatar udoprog avatar tommylike avatar lunarequest avatar puiterwijk avatar yybit avatar syokensyo avatar dsteeley avatar troelsarvin avatar tofay avatar swagadon avatar mstg avatar wzzrd avatar volker-raschek avatar kianmeng avatar rocketjas avatar ibasurto avatar indygreg avatar albertobrusa avatar

Stargazers

Diana avatar Tomasz Durda avatar  avatar fuwx avatar  avatar Muhammad Mominul Huque avatar Veronica  avatar SteveLauC avatar Seonghyun Park avatar  avatar Kaan Büyükerdem avatar HTGAzureX1212. avatar  avatar Harry Mallon avatar  avatar madomado avatar Artem Polishchuk avatar Exploding Dragon avatar Umio Yasuno avatar Federico Damián Schonborn avatar Chris avatar  avatar amy null avatar casoul avatar Rumia_Chnnel avatar Generalworks Inc. avatar  avatar Soc Virnyl S. Estela avatar  avatar Andrejs Agejevs avatar  Bəxtiyar avatar Masanori Ogino avatar Shabbir Hasan avatar Vladimir avatar Sal Sal avatar Orhun Parmaksız avatar Ximon Eighteen avatar Thomas L. Kjeldsen avatar André "decko" de Brito avatar Akira Hayakawa avatar Nicola Coretti avatar Felix Wang avatar Salman Abuhaimed avatar Bhuvan Sankar Andela avatar Aakash Sen Sharma avatar  avatar

Watchers

 avatar  avatar  avatar Ximon Eighteen avatar

rpm's Issues

Roadmap of this project?

Will more features be supported in the future? which features are on the list and when will be supported? Do we have a roadmap?

`test-with-podman` tests don't run in CI

I just tried running test-with-podman tests locally and they didn't compile. I don't think the CI is currently set up to do the testing either - it probably should.

Use proper flag semantics instead of passing around integers

There are a couple of places where raw integers are passed around as "flags", where individual bits of would be considered to set various flags. Most of this functionality behind those flags is missing, but in any case we ought to evaluate how to most ergonomically expose it, e.g. using something like the bitflags crate instead of plain integers.

Add rpm-lint integration test

Most users expect a rpm-lint run of a generated package to be flawless. We should aim for full compatibility. A first step would be to add a (currently failing) regression test against the builder API.

Get back detailed results on which signatures are present vs. not present, match vs mismatch

The functions which verify digests and signatures ought to provide some way to inspect the results of the verification in a more detailed way.

e.g. something like

struct DigestReport {
     payloaddigest: DigestStatus,
     sha256header: DigestStatus,
     sha1header: DigestStatus,
     // etc.
}

enum DigestStatus {
    Success,
    NotPresent,
    Mismatch(String, String),
}

where the report can be easily collapsed into a single Result<...: RPMError> for success or failure

Signature validation failed when sign rpm with rpm-rs library

The signature validation commands(rpm -Kv) shows there is some issue when sign rpm with rpm-rs library:

❯ rpm -Kv CUnit-rust-2.1.3-21.oe1.x86_64.rpm
CUnit-rust-2.1.3-21.oe1.x86_64.rpm:
    Header V4 RSA/SHA256 Signature, key ID d419ba44: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    V4 RSA/SHA256 Signature, key ID d419ba44: BAD
    MD5 digest: OK

BTW, I am not sure what exactly the signature header that rpm tool is checking:

Header V4 RSA/SHA256 Signature, key ID d419ba44: OK  ->check the sig header of  `RPMSIGTAG_RSA` which looks good?
V4 RSA/SHA256 Signature, key ID d419ba44: BAD -> check the sig header of `RPMSIGTAG_PGP` which has issue inside?

rich operators / boolean dependencies

Hello,

in my project I have an app that requires ffmpeg, but not everyone has a repo that provides it,

so I wanted to make it a conditional dependency, if they can install it then install it, if NOT install ffmpeg-free, like the boolean dependencies

however, I don't think it's yet implemented in rpm-rs, would this feature be worked on in the future?

I would help implement it if I knew how, but I don't understand the RPM format and how to do it

Integer tag data should be stored and accessed as unsigned values

RPM tags only use unsigned integer types despite calling them "int":

https://github.com/rpm-software-management/rpm/blob/dd4f2c68a0059d66b1807d504faaeed84973d49a/docs/manual/tags.md#scalar-types=

https://github.com/rpm-software-management/rpm/blob/c4a6a3a9a6b664fd7b7f3d06dd23b93d0b1b4a1b/include/rpm/rpmtd.h#L223=

But many accessors e.g. get_epoch(), get_install_time() return signed integers and many structs (e.g. IndexData) are using signed integers. I believe this is incorrect.

Comparison tests between rpm-rs and rpm

It would be nice to do some comparison tests of header reading between the canonical RPM implementation and rpm-rs

The rpm command has an --xml flag which dumps a serialized textual representation of header contents as XML, this might be a promising approach.

We could possibly use the same approach for validating the writing of headers using rpm-rs, but I'm not sure how much value that would provide as passing validation tests for reading headers means that round-tripping using rpm-rs would probably be equally fine.

Is futures::AsyncRead better to integrate than tokio::AsyncRead?

As per title. The two are (afaik) incompatible, and I would like to think it makes more sense to integrate with futures than just tokio's version. I believe also there's a compatibility layer in tokio if you do want to use something that impls tokio::AsyncRead with futures version.

Ability to create reproducable builds

We need to have the same knobs that rpmbuild has to enable reproducible package builds. Timestamps and various other things get in the way.

As far as I know the needed features are (equivalents to):

# Have SOURCE_DATE_EPOCH value set
%source_date_epoch_from_changelog 1
# Ensure no file timestamps are later than SOURCE_DATE_EPOCH
%clamp_mtime_to_source_date_epoch 1
# Force build timestamp to SOURCE_DATE_EPOCH
%use_source_date_epoch_as_buildtime 1
# Make the hostname deterministic
%_buildhost mockbuild

SOURCE_DATE_EPOCH is referring to https://reproducible-builds.org/docs/source-date-epoch/

Add package build timestamp

Some tools have trouble with the RPMs which are built using rpm-rs, because the packages currently do not contain a build timestamp: cat-in-136/cargo-generate-rpm#59
I propose the build timestamp be added.

In the C code for RPM, the build timestamp has type rpm_time_t which is an unsigned 32-bit integer: https://github.com/rpm-software-management/rpm/blob/master/include/rpm/rpmtypes.h and rpm-rs already partly knows about it in the form of tag constant RPMTAG_BUILDTIME, see https://github.com/rpm-rs/rpm/blob/master/src/constants.rs

Perhaps a Rust type should be added corresponding to rpm_time_t, but it can also just be handled as an u32.

RPMBuilder and similar types should be named as RpmBuilder

Per Rust API guidelines:

In UpperCamelCase, acronyms and contractions of compound words count as one word: use Uuid rather than UUID, Usize rather than USize or Stdin rather than StdIn. In snake_case, acronyms and contractions are lower-cased: is_xid_start.

Alternatively, we can simply drop the RPM prefix and use the types like rpm::Builder.

package name

I'm unable to locate the new package name for this project. Could someone link it?

Support forum

Should we create a matrix room for questions / general collaboration discussions?

Work with ecosystem stakeholders on a generally useful set of signing and verification APIs

By "generally useful" I mean that they would potentially be usable projects like DNF, ostree, and so forth, as described by Neal Walfield here

(what we have already might be perfectly fine for Rust, but maybe there are additional cases to handle, or maybe an additional C-API would be useful)

rpm's OpenPGP API is not great (see e.g., rpm-software-management/rpm#2041, and this thread). Initially we wanted to wholesale replace it, but because the OpenPGP API is part of rpm's public API, that would require an soname bump, which is not scheduled for a while. As such, we decided to reimplement the existing API in terms of Sequoia. In the future, we hope to completely redesign the API. The new API would not be rpm specific, but would be designed to also be used by other projects like dnf, ostree, etc. We'd like to get started on that as soon as possible, but without a sponsor like RedHat, we don't have the resources to undertake that project right now. Until that happens, if you need to use this API, but use it via librpmio.

It would be great if we can develop those APIs here, and work with those parties to polish them into something that could be broadly useful as described above.

Drop "cpio" libraries and write something semi-custom, because RPM doesn't use vanilla CPIO

See the "Payload" section of the website: https://rpm-software-management.github.io/rpm/manual/format.html

Payload

The Payload is currently a cpio archive, gzipped by default. The cpio archive type used is SVR4 with a CRC checksum.

As cpio is limited to 4 GB (32 bit unsigned) file sizes RPM since version 4.12 uses a stripped down version of cpio for packages with files > 4 GB. This format uses 07070X as magic bytes and the file header otherwise only contains the index number of the file in the RPM header as 8 byte hex string. The file metadata that is normally found in a cpio file header - including the file name - is completely omitted as it is stored in the RPM header already.

So, we should fork cpio-rs (providing the appropriate credits of course), strip it down to the subset we need, and change the magic bytes constant.

Luckily the CPIO format is pretty simple and the library only a few hundred lines, so it's not a big deal.

Subsequently we need to change the PAYLOADFORMAT tag, but upstream RPM still uses cpio as the name, so we'll have to wait until they pick something.

Don't enable async by default

See discussion at the end here: #57

TL;DR at best the async support will only be of ergonomic benefit, and only (I expect) for a small number of users. It shouldn't be enabled by default because it pulls in heavy dependencies that most users will not need or be using already.

Relicense as Apache 2.0 + MIT or some similarly permissive combination

Currently this project is licensed as Apache 2.0, however Apache 2.0 licensing alone prevents use with GPL 2.0 licensed projects (this is contested, but at least the FSF seems to think they are incompatible licenses), which is why most projects in the Rust ecosystem nowadays use an Apache 2.0 + MIT dual-licensing scheme to improve compatibility.

To do this, realistically we would we need consent from all contributors.

RPM macros

Could we add RPM macro support for rpm-rs? This will make packaging somewhat easier as we can just evaluate them on build time.

We can also use it for dynamic install paths, like _libdir or _bindir

Only parse as much of files as needed

In fez I added an RpmPkgReader class (https://github.com/cmeister2/fez/blob/main/src/rpm/package.rs#L233) which allowed for "on-demand" reading of RPM files - if you only wanted to read the metadata, you could, without having to download the whole package first.

I tried for a while to come up with a sensible design for this, with several issues:

  • the mutability of the Read object needs to be taken into account
  • working out what data has been read and what data has not been read, and caching the data that has been read, made for a confusing time. I didn't find a wonderfully smooth solution here.

It'd be nice if it didn't have to be a separate class, if possible.

Unable to read & update package header outside of rpm crate

Background
I am trying to do a remote pgp sign by utilizing this rpm package, but it seems the header and signature functions are public to crate only, how can we read&update these sections outside of rpm package?

package.metadata.header.**write**(&mut header_bytes)?;
package.metadata.signature = Header::<IndexSignatureTag>::**new_signature_header**();

Sort out ergonomics of reproducable builds

re: #117

Reproducable builds are possible now, if you provide both a build_time and a source_date. But it would be best if users didn't need to know all the knobs. In RPM, those knobs are:

  • clamping file mtimes to a "source date epoch" value
  • overriding the build time with the value of "source date epoch"
  • deriving "source date epoch" from the changelogs, which are static
  • use a deterministic hostname

We avoid 4 by virtue of not setting the hostname by default. We now have the ability to perform 1. But we force the user to provide both source_date and a build_time manually and we don't provide a changelog shortcut, so it's not as simple as it could potentially be.

  1. Is it OK to consolidate the options?
    • Is it OK to assume that the user is always ok with file mtime clamping behavior?
    • Is it OK to assume that build_time and source_date (the clamp value) ought to be the same in all cases?
  2. Should we provide some way to derive source_date from the changelogs automatically?

Potential validity issues with generated RPMs

Let's take this dummy library as an example. By running cargo build --release and cargo generate-rpm we get libdummyadd-0.1.0-1.x86_64.rpm. It can be installed and uninstalled without issues. But if we run rpm --rebuilddb after installation, we get the following warning: error: header #2054 in the database is bad -- skipping.. Now the packet is not listed as installed, e.g. we can no longer remove it using packet manager. Additionally, mc can not open generated packets, while it handles packets generated by rpmbuild just fine. This behavior can be reproduced on at least CentOS 7 and Fedora 32.

This can be reproduced by using the latest version of rpm crate directly:

Expand
let pkg = rpm::RPMBuilder::new(
    "libdummyadd",
    "0.1.0",
    "UNLICENSE",
    "x86_64",
    "Dummy library for testing RPM generation",
)
.compression(rpm::CompressionType::None)
.with_file(
    "/path/to/libdummyadd/target/release/libdummyadd.so",
    rpm::RPMFileOptions::new("/usr/lib64/libdummyadd.so"),
)?
.build_time(rpm::chrono::Utc::now())
.build_host("host".to_string())
.vendor("NA")
.build()?;

let mut f = std::fs::File::create("libdummyadd.rpm")?;
pkg.write(&mut f)?;

If my understanding is correct, the headers added after installation of the package are considered invalid by RPM, meaning that RPMs generated by this crate may not be completely valid.

question: any good first issue?

Hello. I am planning to learn Rust (again) because my schedule now allows me to do so. Are there any good first issue for this project that I can contribute to and some resources about rpm? I have written lots rpm specfiles for openSUSE and I am now interested in this project for my package manager project in Rust. Sorry if I sound stupid!

Develop cargo-rpm as part of the rpm-rs org?

carg-rpm is currently unmaintained, but still used relatively widely. @tarcieri is willing to transfer ownership of the crate. I think it would make sense to maintain a Cargo plugin around the rpm crate as part of the rpm-rs org. Having it part of the org should help with keeping the plugin updated on new rpm releases and improve discoverability.

I think it can start as transfer of the cargo-generate-rpm crate, of course assuming @cat-in-136 is willing to join the org.

Defer file reading until package build time

with_file() and with_file_async() currently read out the contents of the file into a buffer and persist them inside of RPMFileEntry structs, which are stored in the builder struct, until the package is built. This is simple and convenient but terribly inefficient, as all of the the uncompressed file contents will be stored in memory. Additionally this API allows little possibility of parallelism when building a single package - since each package can be dealing with dozens, hundreds or thousands of files and only a few packages are generally built at a time, this is probably a bad trade.

Instead of storing a collection of eagerly-processed RPMFileEntrys inside the builder, we should probably try to store only the filename and RPMFileOptions, and process all of the files at once during build time, which would make it easier to parallelize using a threadpool or async primitives.

This will allow the files to be read and written directly into the archive using smaller buffers, and we can calculate details like file metadata, digests, signatures and such at the same time.

Compatability with CentOS 7

By using the same library and snippet as in #147 I get libdummyadd.rpm. When I try to install it on CentOS 7, I get the following error:

Running transaction
Error unpacking rpm package libdummyadd-0.1.0-1.x86_64
  Installing : libdummyadd-0.1.0-1.x86_64                                   1/1 
error: unpacking of archive failed on file /usr/lib64/libdummyadd.so;6476433e: cpio: Digest mismatch
  Verifying  : libdummyadd-0.1.0-1.x86_64                                   1/1 

Failed:
  libdummyadd.x86_64 0:0.1.0-1    

rpm -v --checksig libdummyadd.rpm returns:

libdummyadd.rpm:
    Header SHA1 digest: OK (77492d16c6b099e0bc74cc864fe316c7f7dfe6b6)
    MD5 digest: OK (7decf15b91517ed4fb2edc616914dbe2)

Running rpm -qp --xml libdummyadd.rpm I get:

Expand
<rpmHeader>
  <rpmTag name="Headeri18ntable">
	<string>C</string>
  </rpmTag>
  <rpmTag name="Sigmd5">
	<base64>CcK1Fb+YZqLtn6QTsd0GRQ==
</base64>
  </rpmTag>
  <rpmTag name="Sha1header">
	<string>f4e9822feed5995e8234a1525bbcb742955f7937</string>
  </rpmTag>
  <rpmTag name="Longsigsize">
	<integer>15401</integer>
  </rpmTag>
  <rpmTag name="Name">
	<string>libdummyadd</string>
  </rpmTag>
  <rpmTag name="Version">
	<string>0.1.0</string>
  </rpmTag>
  <rpmTag name="Release">
	<string>1</string>
  </rpmTag>
  <rpmTag name="Epoch">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Summary">
	<string>Dummy library for testing RPM generation</string>
  </rpmTag>
  <rpmTag name="Description">
	<string>Dummy library for testing RPM generation</string>
  </rpmTag>
  <rpmTag name="Buildtime">
	<integer>1685472520</integer>
  </rpmTag>
  <rpmTag name="Buildhost">
	<string>host</string>
  </rpmTag>
  <rpmTag name="Vendor">
	<string>NA</string>
  </rpmTag>
  <rpmTag name="License">
	<string>UNLICENSE</string>
  </rpmTag>
  <rpmTag name="Group">
	<string>Unspecified</string>
  </rpmTag>
  <rpmTag name="Os">
	<string>linux</string>
  </rpmTag>
  <rpmTag name="Arch">
	<string>x86_64</string>
  </rpmTag>
  <rpmTag name="Filemodes">
	<integer>33188</integer>
  </rpmTag>
  <rpmTag name="Filerdevs">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Filemtimes">
	<integer>1685446558</integer>
  </rpmTag>
  <rpmTag name="Filedigests">
	<string>0ac32c56c20ac2e18885b817ccf1fdf59221ed0c6c410126e97c2c3c1524aca7</string>
  </rpmTag>
  <rpmTag name="Filelinktos">
	<string/>
  </rpmTag>
  <rpmTag name="Fileflags">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Fileusername">
	<string>root</string>
  </rpmTag>
  <rpmTag name="Filegroupname">
	<string>root</string>
  </rpmTag>
  <rpmTag name="Sourcerpm">
	<string>(none)</string>
  </rpmTag>
  <rpmTag name="Fileverifyflags">
	<integer>4026565119</integer>
  </rpmTag>
  <rpmTag name="Providename">
	<string>libdummyadd</string>
	<string>libdummyadd(x86_64)</string>
  </rpmTag>
  <rpmTag name="Requireflags">
	<integer>16777224</integer>
	<integer>16777224</integer>
	<integer>16777224</integer>
  </rpmTag>
  <rpmTag name="Requirename">
	<string>rpmlib(CompressedFileNames)</string>
	<string>rpmlib(FileDigests)</string>
	<string>rpmlib(PayloadFilesHavePrefix)</string>
  </rpmTag>
  <rpmTag name="Requireversion">
	<string>3.0.4-1</string>
	<string>4.6.0-1</string>
	<string>4.0-1</string>
  </rpmTag>
  <rpmTag name="Filedevices">
	<integer>1</integer>
  </rpmTag>
  <rpmTag name="Fileinodes">
	<integer>1</integer>
  </rpmTag>
  <rpmTag name="Filelangs">
	<string/>
  </rpmTag>
  <rpmTag name="Provideflags">
	<integer>8</integer>
	<integer>8</integer>
  </rpmTag>
  <rpmTag name="Provideversion">
	<string>0.1.0</string>
	<string>0.1.0</string>
  </rpmTag>
  <rpmTag name="Dirindexes">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Basenames">
	<string>libdummyadd.so</string>
  </rpmTag>
  <rpmTag name="Dirnames">
	<string>/usr/lib64/</string>
  </rpmTag>
  <rpmTag name="Payloadformat">
	<string>cpio</string>
  </rpmTag>
  <rpmTag name="Longfilesizes">
	<integer>13768</integer>
  </rpmTag>
  <rpmTag name="Longsize">
	<integer>13768</integer>
  </rpmTag>
  <rpmTag name="Filedigestalgo">
	<integer>8</integer>
  </rpmTag>
  <rpmTag name="(unknown)">
	<string>utf-8</string>
  </rpmTag>
  <rpmTag name="(unknown)">
	<string>7806d7ab151d7bb9be3e771f03f6e5b35543322d5f9130d7009cda1f8e3542ac</string>
  </rpmTag>
  <rpmTag name="(unknown)">
	<integer>8</integer>
  </rpmTag>
  <rpmTag name="(unknown)">
	<string>7806d7ab151d7bb9be3e771f03f6e5b35543322d5f9130d7009cda1f8e3542ac</string>
  </rpmTag>
</rpmHeader>

It looks like the older RPM version (4.11.3) used by CentOS 7 does not recognize the payload tags (Encoding, Payloaddigest, Payloaddigestalgo) which results in the digest check failure.

Packet generated by cargo-generate-rpm using rpm v0.9.0-alpha.1 can be installed just fine (but it suffers from #147). Here is output of rpm -qp --xml for it:

Expand
<rpmHeader>
  <rpmTag name="Headeri18ntable">
	<string>C</string>
  </rpmTag>
  <rpmTag name="Sigsize">
	<integer>6924</integer>
  </rpmTag>
  <rpmTag name="Sigmd5">
	<base64>IqqkWf92M+TU+/kvoH7blw==
</base64>
  </rpmTag>
  <rpmTag name="Sha1header">
	<string>ab8a051feb21c26a5ae615495e0e15d76c1b71e7</string>
  </rpmTag>
  <rpmTag name="Name">
	<string>libdummyadd</string>
  </rpmTag>
  <rpmTag name="Version">
	<string>0.1.0</string>
  </rpmTag>
  <rpmTag name="Release">
	<string>1</string>
  </rpmTag>
  <rpmTag name="Epoch">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Summary">
	<string>Dummy library for testing RPM generation</string>
  </rpmTag>
  <rpmTag name="Description">
	<string>Dummy library for testing RPM generation</string>
  </rpmTag>
  <rpmTag name="Size">
	<integer>5664</integer>
  </rpmTag>
  <rpmTag name="License">
	<string>UNLICENSE</string>
  </rpmTag>
  <rpmTag name="Group">
	<string>Unspecified</string>
  </rpmTag>
  <rpmTag name="Os">
	<string>linux</string>
  </rpmTag>
  <rpmTag name="Arch">
	<string>x86_64</string>
  </rpmTag>
  <rpmTag name="Filesizes">
	<integer>5664</integer>
  </rpmTag>
  <rpmTag name="Filemodes">
	<integer>33188</integer>
  </rpmTag>
  <rpmTag name="Filerdevs">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Filemtimes">
	<integer>1685473437</integer>
  </rpmTag>
  <rpmTag name="Filedigests">
	<string>6fef19b830770d7ebc3d4de02a6ebaccb1860b2a41277f230e164be0626f4074</string>
  </rpmTag>
  <rpmTag name="Filelinktos">
	<string/>
  </rpmTag>
  <rpmTag name="Fileflags">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Fileusername">
	<string>root</string>
  </rpmTag>
  <rpmTag name="Filegroupname">
	<string>root</string>
  </rpmTag>
  <rpmTag name="Sourcerpm">
	<string>(none)</string>
  </rpmTag>
  <rpmTag name="Fileverifyflags">
	<integer>4294967295</integer>
  </rpmTag>
  <rpmTag name="Providename">
	<string>libdummyadd</string>
	<string>libdummyadd(x86_64)</string>
  </rpmTag>
  <rpmTag name="Requireflags">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Requirename">
	<string>/bin/sh</string>
  </rpmTag>
  <rpmTag name="Requireversion">
	<string/>
  </rpmTag>
  <rpmTag name="Filedevices">
	<integer>1</integer>
  </rpmTag>
  <rpmTag name="Fileinodes">
	<integer>1</integer>
  </rpmTag>
  <rpmTag name="Filelangs">
	<string/>
  </rpmTag>
  <rpmTag name="Provideflags">
	<integer>8</integer>
	<integer>8</integer>
  </rpmTag>
  <rpmTag name="Provideversion">
	<string>0.1.0</string>
	<string>0.1.0</string>
  </rpmTag>
  <rpmTag name="Dirindexes">
	<integer>0</integer>
  </rpmTag>
  <rpmTag name="Basenames">
	<string>libdummyadd.so</string>
  </rpmTag>
  <rpmTag name="Dirnames">
	<string>/usr/lib64/</string>
  </rpmTag>
  <rpmTag name="Payloadformat">
	<string>cpio</string>
  </rpmTag>
  <rpmTag name="Filedigestalgo">
	<integer>8</integer>
  </rpmTag>
</rpmHeader>

Is it possible to generate CentOS 7 compatible packet using rpm v0.11?

Eliminate as many uses of unwrap() and expect() and other sources of panics as possible

We should be returning errors to the user to the greatest extent possible rather than crashing their programs outright. unwrap() and expect() are useful for speeding up development but they're not great practice for a library long-term.

In some places it may be unavoidable or the best option, I'm not convinced we need to ban them outright, but it would be a good exercise to take a look at where we're using them and fix it up. I definitely see a few that could be improved.

Consider using rpm-sequioa for PGP related code

The official RPM library has adopted a Sequoia-based PGP backend written in Rust. If we can use the same code, it may provide benefits for compatibility, maintenance, reduced dependencies, and so forth.

https://github.com/rpm-software-management/rpm-sequoia
rpm-software-management/rpm#2043

See: rpm-software-management/rpm-sequoia#10

We should instead consider creating and iterating those APIs ourselves and contributing them back to the official implementation.

Support RPM "extension tag" functionality

RPM has the concept of extension tags which do not exist within the header as entries in and of themselves, but rather they are constructed on the fly when requested if the user passed in the flags to allow them to be used.

https://github.com/rpm-software-management/rpm/blob/master/docs/manual/tags.md#extensions

These are basically just helpers which have been dropped into the same query system as the rest of the RPM tags.

I don't actually think we should handle this the same way, I would prefer we just add functions to the RPMPackageMetadata object for this stuff.

Support EdDSA / Ed25519 package signatures

Support the creation and verification of Ed25519 package signatures. These are header-only signatures which are stored in the RPMSIGTAG_DSA signature header tag. They work identically to signatures stored in RPMSIGTAG_RSA except for of course the algorithm used.

Rename `master` to `main`

The default branch name is now main for github repositories. Should we update the main branch to be called main?

Raises an error during parsing when encountering unknown tags

If an RPM being parsed contains any tag which isn't in the hardcoded enum definition for IndexTag or IndexSignatureTag, an error is raised.

That's a bit problematic from a forwards compatibility perspective, there's no real reason to raise an error in that situation because we could otherwise roundtrip just fine. The mere fact that an unknown tag exists shouldn't generally prevent it from being read or written.

The challenge will be making that happen without losing the nice ergonomics and debug output of the enum.

One possible approach: have e.g. an (possibly #[repr(u32)]) enum ID { ... } that only contains currently known values and a #[repr(transparent)] struct RawID { value: u32 } that supports all values,and have RawID: From and ID: TryFrom<RawID, Error = UnrecognizedID>

rpm-rs doesn't build with some features turned off

It should be possible to compile the codebase with cargo build --no-default-features. After #1 is merged, we still have the following errors:

error[E0599]: no function or associated item named `builder` found for struct `header::Header` in the current scope
   --> src/rpm/builder.rs:304:58
    |
304 |         let digest_header = Header::<IndexSignatureTag>::builder()
    |                                                          ^^^^^^^ function or associated item not found in `header::Header<constants::IndexSignatureTag>`
    |
   ::: src/rpm/headers/header.rs:38:1
    |
38  | pub struct Header<T: num::FromPrimitive> {
    | ---------------------------------------- function or associated item `builder` not found for this

warning: unused import: `std::io::Read`
  --> src/rpm/package.rs:17:5
   |
17 | use std::io::Read;
   |     ^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.