Giter Club home page Giter Club logo

cargo-generate-rpm's Introduction

cargo-generate-rpm

Cargo helper command to generate a binary RPM package (.rpm) from Cargo project.

This command does not depend on rpmbuild and generates an RPM package file without a spec file by using the rpm crate.

Rust cargo-generate-rpm at crates.io

Install

cargo install cargo-generate-rpm

Usage

cargo build --release
strip -s target/release/XXX
cargo generate-rpm

Upon run cargo generate-rpm on your cargo project, a binary RPM package file will be created in target/generate-rpm/XXX.rpm. You can change the RPM package file location using -o option.

In advance, run cargo run --release and strip the debug symbols (strip -s target/release/XXX), because these are not run upon cargo generate-rpm as of now.

Configuration

This command generates RPM metadata from the Cargo.toml file:

[package.metadata.generate-rpm] options

  • name: the package name. If not present, package.name is used.
  • version: the package version. If not present, package.version is used.
  • license: the package license. If not present, package.license is used.
  • summary: the package summary/description. If not present, package.description is used.
  • url: the package homepage url. If not present, package.homepage is used. If neither present, package.repository is used.
  • assets: (mandatory) the array of the files to be included in the package
    • source: the location of that asset in the Rust project. (e.g. target/release/XXX) Wildcard character * is allowed.
    • dest: the install-destination. (e.g. /usr/bin/XXX) It shall be a file path or a directory path ending /. If source contains wildcard character *, it must be a directory, not a file path.
    • mode: the permissions as octal string. (e.g. 755 to indicate -rwxr-xr-x)
    • config: set true if it is a configuration file. Set the string "noreplace" instead to avoid overwriting an existing file that have been modified. (Not supported for "missingok" as of now)
    • doc: set true if it is a document file.
    • user: the owner of the file.
    • group: the group owner of the file.
    • caps: optional string of capabilities. (e.g. cap_sys_admin=pe)
  • release: optional string of release.
  • epoch: optional number of epoch.
  • pre_install_script: optional string or file path of pre_install_script.
    • pre_install_script_flags: optional integer value to set scriptlet flags.
    • pre_install_script_prog: optional string array to set scriptlet interpreter/arguments.
  • pre_uninstall_script: optional string or file path of pre_uninstall_script.
    • pre_uninstall_script_flags: optional integer value to set scriptlet flags.
    • pre_uninstall_script_prog: optional string array to set scriptlet interpreter/arguments.
  • pre_trans_script: optional string or file path of pre_trans_script.
    • pre_trans_script_flags: optional integer value to set scriptlet flags.
    • pre_trans_script_prog: optional string array to set scriptlet interpreter/arguments.
  • pre_untrans_script: optional string or file path of pre_untrans_script.
    • pre_untrans_script_flags: optional integer value to set scriptlet flags.
    • pre_untrans_script_prog: optional string array to set scriptlet interpreter/arguments.
  • post_install_script: optional string or file path of post_install_script.
    • post_install_script_flags: optional integer value to set scriptlet flags.
    • post_install_script_prog: optional string array to set scriptlet interpreter/arguments.
  • post_uninstall_script: optional string or file path of post_uninstall_script.
    • post_uninstall_script_flags: optional integer value to set scriptlet flags.
    • post_uninstall_script_prog: optional string array to set scriptlet interpreter/arguments.
  • post_trans_script: optional string or file path of post_trans_script.
    • post_trans_script_flags: optional integer value to set scriptlet flags.
    • post_trans_script_prog: optional string array to set scriptlet interpreter/arguments.
  • post_untrans_script: optional string or file path of post_untrans_script.
    • post_untrans_script_flags: optional integer value to set scriptlet flags.
    • post_untrans_script_prog: optional string array to set scriptlet interpreter/arguments.
  • requires: optional list of Requires
  • auto-req: optional string "no" to disable the automatic dependency process
  • require-sh: optional boolean false to omit /bin/sh from Requirements
  • obsoletes: optional list of Obsoletes
  • conflicts: optional list of Conflicts
  • provides: optional list of Provides
  • vendor: optional string of Vendor

Adding assets such as the binary file, .desktop file, or icons, shall be written in the following way.

[package.metadata.generate-rpm]
assets = [
    { source = "target/release/XXX", dest = "/usr/bin/XXX", mode = "755" },
    { source = "<path_relative_to_project_root>/XXX.desktop", dest = "/usr/share/applications/XXX.desktop", mode = "644" },
    { source = "<path_relative_to_project_root>/*/apps/XXX.png", dest = "/usr/share/icons/hicolor/", mode = "644" },
]

[package.metadata.generate-rpm.{requires,obsoletes,conflicts,provides}] options

Dependencies such as "requires", "obsoletes", "conflicts", and "provides" shall be written in similar way as dependencies in Cargo.toml.

[package.metadata.generate-rpm.requires]
alternative = "*"
filesystem = ">= 3"

This example states that the package requires with any versions of alternative and all versions of filesystem 3.0 or higher.

Following table lists the version comparisons:

Comparison Meaning
package = "*" A package at any version number
package = "< version" A package with a version number less than version
package = "<= version" A package with a version number less than or equal to version
package = "= version" A package with a version number equal to version
package = "> version" A package with a version number greater than version
package = ">= version" A package with a version number greater than or equal to version

It is necessary to place a space between version and symbols such as <, <=, etc... package = "version" is not accepted, instead use package = "= version".

This command automatically determines what shared libraries a package requires. There may be times when the automatic dependency processing is not desired. In this case, the package author may set package.metadata.generate-rpm.auto-req to "no" or the user who executes this command may specify command line option --auto-req no.

  • --auto-req auto: The following rules are used to determine the preferred automatic dependency process:
    • If package.metadata.generate-rpm.auto-req set to "no" or "disabled", the process is disabled.
    • If /usr/lib/rpm/find-requires exists, it is used (same behaviour as --auto-req /usr/lib/rpm/find-requires).
    • Otherwise, builtin procedure is used (same behaviour as --auto-req builtin).
  • --auto-req builtin: the builtin procedure using ldd is used.
  • --auto-req /path/to/find-requires: the specified external program is used. This behavior is the same as the original rpmbuild.
  • --auto-req no: the process is disabled.

/bin/sh is always added to the package requirements. To disable it, set package.metadata.generate-rpm.require-sh to false. You should not do this if you use scripts such as pre_install_script or if your assets contain shell scripts.

Overwrite configuration

[package.metadata.generate-rpm] can be overwritten. The following command line options are used:

  • --metadata-overwrite=TOML_FILE.toml : Overwrite the [package.metadata.generate-rpm] options with the contents of the specified TOML file.
  • --metadata-overwrite=TOML_FILE.toml#TOML.PATH : Overwrites the [package.metadata.generate-rpm] options with the table specified in the TOML path of the TOML file. Only a sequence of bare keys connected by dots is acceptable for the TOML path. Path containing quoted keys (such as metadata."παραλλαγή") cannot be acceptable.
  • -s 'toml "text"' or --set-metadata='toml "text"' : Overwrite the [package.metadata.generate-rpm] options with inline TOML text. The argument text --- inline TOML text must be enclosed in quotation marks since it contains spaces.
  • --variant=VARIANT : Overwrites the [package.metadata.generate-rpm] options with the table specified in [package.metadata.generate-rpm.variants.VARIANT] of the TOML file. It is a shortcut to --metadata-overwrite=path/to/Cargo.toml#package.metadata.generate-rpm.variants.VARIANT. It is intended for providing multiple variants of the metadata in a Cargo.toml and ability for the users to select the variant using --variant=name option.

These options can be specified more than once, with the last written one specified being applied. For example, the arguments -s 'release = "alpha"' --metadata-overwrite=beta.toml where beta.toml contains release = "beta" gives release = "beta".

Advanced Usage

Workspace

To generate an RPM package from a member of a workspace, execute cargo generate-rpm in the workspace directory with specifying the package (directory path) with option -p:

cargo build --release
strip -s target/release/XXX
cargo generate-rpm -p XXX

[package.metadata.generate-rpm] options should be written in XXX/Cargo.toml.

When the option -p specified, first, the asset file source shall be treated as a relative path from the current directory. If not found, it shall be treated as a relative path from the directory of the package. If both not found, cargo generate-rpm shall fail with an error.

For example, source = target/bin/XXX would usually be treated as a relative path from the current directory. Because all packages in the workspace share a common output directory that is located target in workspace directory.

Cross compilation

This command supports --target-dir, --target, and --profile options like cargo build. Depending on these options, this command changes the RPM package file location and replaces target/release/ of the source locations of the assets.

cargo build --release --target x86_64-unknown-linux-gnu
cargo generate-rpm --target x86_64-unknown-linux-gnu

When --target-dir TARGET-DIR and --target x86_64-unknown-linux-gnu are specified, a binary RPM file will be created at TARGET-DIR/x86_64-unknown-linux-gnu/generate-rpm/XXX.rpm instead of target/generate-rpm/XXX.rpm. In this case, the source of the asset { source = "target/release/XXX", dest = "/usr/bin/XXX" } will be treated as TARGET-DIR/x86_64-unknown-linux-gnu/release/XXX instead of target/release/XXX.

You can use CARGO_BUILD_TARGET environment variable instead of --target option and CARGO_BUILD_TARGET_DIR or CARGO_TARGET_DIR instead of --target-dir.

Similarly, if using a custom build profile with, for example, --profile custom the source of the asset { source = "target/release/XXX" } will be treated as target/custom/XXX.

Payload compress type

The default payload compress type of the generated RPM file is zstd. You can specify the payload compress type with --payload-compress TYPE: none, gzip, or zstd.

For the legacy system (e.g. centos7), specify legacy compress type explicitly e.g. --payload-compress none.

Scriptlet Flags and Prog Settings

Scriptlet settings can be configured via *_script_flags and *_script_prog settings.

Scriptlet Flags

Flag Setting Value Description Example Usage
RPMSCRIPT_FLAG_EXPAND 1 Enables macro expansion pre_install_script_flags = 0b001
RPMSCRIPT_FLAG_QFORMAT 2 Enables header query format expansion pre_install_script_flags = 0b010
RPMSCRIPT_FLAG_CRITICAL 4 Enables critical severity for scriplet success or failure pre_install_script_flags = 0b100

Example

pre_install_script = """
echo preinstall
"""
pre_install_script_flags = 0b011 # Enables EXPAND and QFORMAT flags
pre_install_script_prog = ["/bin/blah/bash", "-c"] # Sets the interpreter/argument settings for the scriptlet

cargo-generate-rpm's People

Contributors

bksalman avatar cat-in-136 avatar drahnr avatar dsteeley avatar jpgrayson avatar jtk18 avatar juliusl avatar kianmeng avatar newpavlov avatar orhun avatar rocketjas avatar rtczza avatar runlevel5 avatar striezel avatar tofay avatar will-shanks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cargo-generate-rpm's Issues

Error raised on workspace inheritance of `package.edition`

"value from workspace hasn't been set" error raised when workspace inheritance is used and its toml has package.edition.

#44 (comment)

@cat-in-136 Did some testing. When I use the workspace for the version / license it works fine. But adding the edition, will result in the above error. First gut feeling is that somethings is going wrong in the toml_edit lib, as the generate-rpm code is not using the edition field. That would suggest things go wrong on line 73: manifest.inherit_workspace(&workspace_manifest, p.as_ref())?;, some context to the errors would help.

It is caused by the cargo_toml bug https://gitlab.com/crates.rs/cargo_toml/-/issues/20

deploy to crates.io

... so that users can install it by executingcargo install cargo-generate-rpm

Could not generate generate-rpm in case of --target specified

@cat-in-136

v0.12.0 is not working, please check, thanks

$ cargo generate-rpm -p xxx --target x86_64-unknown-linux-gnu

# new generated file
$ ll x86_64-unknown-linux-gnu 
-rw-r--r-- 1 vkill vkill 17M Aug 10 13:28 x86_64-unknown-linux-gnu

$ ll target/x86_64-unknown-linux-gnu/generate-rpm
ls: cannot access 'target/x86_64-unknown-linux-gnu/generate-rpm': No such file or directory

rpmlint warnings

Hi,

When I run rpmlint on my generated RPM I get some warnings which I think I have no control over as they refer to missing spec fields that are not generated by cargo-generate-rpm, e.g.:

  • routinator.x86_64: W: manpage-not-compressed gz /usr/share/man/man1/routinator.1

It's a bit ugly to either store the man page compressed in my Git repo. I could compress it before invoking cargo generate-rpm, but as cargo-generate-rpm is aware of "doc" assets perhaps it could compress it for me?

  • routinator.x86_64: E: no-buildhost-tag
  • routinator.x86_64: E: no-changelogname-tag
  • routinator.x86_64: W: no-url-tag

Unless I am mistaken I see no way to provide these via the Cargo.toml syntax supported by cargo-generate-rpm.

  • routinator.x86_64: E: no-binary

Do you have any idea why even though I have binary assets installed to /usr/bin/ it complains that I do not have a binary?

  • routinator.x86_64: W: conffile-without-noreplace-flag /etc/routinator/routinator.conf

I assume this refers to some setting that I have no control over?

Thanks,

Ximon

using glob pattern in workspace

Hello,
I think there is a bug when using glob pattern in assets in combination with a workspace project.

When I use this assets:

...
{ source = "../public/**/*", dest = "/usr/share/ffplayout/public/", mode = "644" },
...

and run cargo generate-rpm --target=x86_64-unknown-linux-musl -p ffplayout-engine -o ffplayout-0.12.0-1.x86_64.rpm, the public folder get ignored. Only when I cd into ffplayout-engine and run the generation without a project flag it works like it should.

RPM is not readable by rpmlint

A RPM created with cargo generate-rpm is installable, but cannot be investigated with rpmlint.

$ rpmlint target/generate-rpm/hello-world-0.1.0-1.x86_64.rpm 
(none): E: fatal error while reading target/generate-rpm/hello-world-0.1.0-1.x86_64.rpm: list index out of range

With verbose output, the following is printed:

$ rpmlint -v target/generate-rpm/hello-world-0.1.0-1.x86_64.rpm 
files over 4GB not supported by cpio, use rpm2archive instead
cpio: premature end of archive
(none): E: fatal error while reading target/generate-rpm/hello-world-0.1.0-1.x86_64.rpm: list index out of range
Traceback (most recent call last):
  File "/bin/rpmlint", line 8, in <module>
    sys.exit(lint())
             ^^^^^^
  File "/usr/lib/python3.11/site-packages/rpmlint/cli.py", line 177, in lint
    sys.exit(lint.run())
             ^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/rpmlint/lint.py", line 105, in run
    return self._run()
           ^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/rpmlint/lint.py", line 76, in _run
    self.validate_files(self.options['rpmfile'])
  File "/usr/lib/python3.11/site-packages/rpmlint/lint.py", line 237, in validate_files
    self.validate_file(pkg, pkg == packages[-1])
  File "/usr/lib/python3.11/site-packages/rpmlint/lint.py", line 261, in validate_file
    raise e
  File "/usr/lib/python3.11/site-packages/rpmlint/lint.py", line 251, in validate_file
    with Pkg(pname, self.config.configuration['ExtractDir'],
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/rpmlint/pkg.py", line 423, in __init__
    self.files = self._gather_files_info()
                 ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/rpmlint/pkg.py", line 576, in _gather_files_info
    pkgfile.size = sizes[idx]
                   ~~~~~^^^^^
IndexError: list index out of range

To reproduce:
Create a new project using cargo new hello-world. Then adjust the Cargo.toml like this:

[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"
authors = ["Cargo"]
description = "A hello-world program"
license = "MIT"
homepage = "https://my-hello-world.com"
repository = "https://github.com/fake/hello-world"

[package.metadata.generate-rpm]
assets = [
    { source = "target/release/hello-world", dest = "/usr/bin/hello-world", mode = "755" }
]

Finally generate the RPM and try to lint it with rpmlint.

Or am I'm doing something wrong here?


Environment:

  • Fedora 38
  • cargo 1.70.0 (ec8a8a0ca 2023-04-25)
  • cargo-generate-rpm 0.11.1

Inappropriate behavior package.metadata.generate-rpm.{name,version,license,summary} member presence

  • If package.metadata.generate-rpm.name exists but package.name absent, package.metadata.generate-rpm.name should be used but the program actually exit by error.
  • If package.metadata.generate-rpm.version exists but package.version absent, package.metadata.generate-rpm.version should be used but the program actually exit by error.
  • If package.metadata.generate-rpm.license exists but package.license absent, package.metadata.generate-rpm.license should be used but the program actually exit by error.
  • If package.metadata.generate-rpm.summary exists but package.description absent, package.metadata.generate-rpm.summary should be used but the program actually exit by error.

build/install failures due to yanked crate and also with Rust 1.53.0

Our CI job just started failing to run cargo install cargo-generate-rpm --version 0.4.0. This has been working fine until now. It fails due to a yanked aesni crate version, see https://github.com/NLnetLabs/routinator/runs/3171059667#step:9:17:

Caused by:
  failed to select a version for the requirement `aesni = "^0.7"`
  candidate versions found which didn't match: 0.99.99, 0.10.0, 0.9.0, ...

Running with --locked fails for a different reason:

cargo install cargo-generate-rpm --version 0.4.0 --locked
    Updating crates.io index
  Installing cargo-generate-rpm v0.4.0
warning: package `aes-soft v0.4.0` in Cargo.lock is yanked in registry `crates.io`, consider running without --locked
warning: package `aesni v0.7.0` in Cargo.lock is yanked in registry `crates.io`, consider running without --locked
   Compiling autocfg v1.0.1
...
   Compiling rand_core v0.5.1
error[E0308]: mismatched types
  --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bhcomp.rs:62:24
   |
62 |     let bytes = bits / Limb::BITS;
   |                        ^^^^^^^^^^ expected `usize`, found `u32`

Works with Rust older than 1.53.0:

One final note: Both my local machine and our CI build both used Rust 1.53.0. When I tried cargo build locally using Rust 1.47.0 and Rust 1.52.0, both succeeded!

In a clean Docker Ubuntu 18:04 container the following worked for me:

# rustup toolchain install 1.52.0
# cargo +1.52.0 install cargo-generate-rpm --version 0.4.0 --locked

Building rpm for `foo-bar` package means `foo-bar/Cargo.toml` must exists?

$ cargo generate-rpm -p foo-service
No such file or directory (os error 2): foo-service/Cargo.toml

In workspace's Cargo.toml file, foo-service is in foo/service folder i.e. foo/service/Cargo.toml exits. Its a bit non-standard location but I was expecting the tool to figure it out by itself.

PS: Looks like it. Package name and its potential location is tightly linked. Package path is not being read from workspace members list.

    let config = if let Some(p) = &args.package {
        Config::new(Path::new(p), Some(Path::new("")), &extra_metadata)?
    } else {
        Config::new(Path::new(""), None, &extra_metadata)?
    };

Issue with generate RPM not matching the PowerPC64 LE architecture

Impacted version

0.12.1

System

  • Fedora 39 (6.5.0 ppc64le kernel)
  • Hardware: Raptor Computing Blackbird with IBM POWER9 Sforza CPU

Steps to reproduce

# I am trying to build amdgpu_top package
$ git clone https://github.com/Umio-Yasuno/amdgpu_top
$ cd amdgpu_top
$ cargo install --locked --path . --no-default-features --features="tui"
$ cargo build --release --target powerpc64le-unknown-linux-gnu # target ppc64le architecture
$ file ./target/release/amdgpu_top 
./target/release/amdgpu_top: ELF 64-bit LSB pie executable, 64-bit PowerPC or cisco 7500, OpenPOWER ELF V2 ABI, version 1 (SYSV), dynamically linked, interpreter /lib64/ld64.so.2, BuildID[sha1]=a6b0d839eb4db3d50d33cb9eb25f58723f00d224, for GNU/Linux 3.10.0, stripped
# Looks good ^ the binary is great and working
# let's try to package it
# firstly all config can be found in https://github.com/Umio-Yasuno/amdgpu_top/blob/main/Cargo.toml#L51
$ cargo generate-rpm --target powerpc64le-unknown-linux-gnu -a ppc64le
# let's try to install it
$ sudo rpm -i target/powerpc64le-unknown-linux-gnu/generate-rpm/amdgpu_top-0.2.0-1.powerpc64le.rpm 
# got error
#	package amdgpu_top-0:0.2.0-1.powerpc64le is intended for a different architecture
# let's double check the RPM one more time
$ sudo rpm -qip target/powerpc64le-unknown-linux-gnu/generate-rpm/amdgpu_top-0.2.0-1.powerpc64le.rpm 
Name        : amdgpu_top
Epoch       : 0
Version     : 0.2.0
Release     : 1
Architecture: powerpc64le
Install Date: (not installed)
Group       : Unspecified
Size        : 13658190
License     : MIT
Signature   : (none)
Source RPM  : (none)
Build Date  : Sat 02 Sep 2023 17:31:33
Build Host  : (none)
URL         : https://github.com/Umio-Yasuno/amdgpu_top
Summary     : Tool to displays AMDGPU usage.
The tool displays information gathered from performance counters (GRBM, GRBM2), sensors, fdinfo, gpu_metrics and AMDGPU driver.

Description :
Tool to displays AMDGPU usage.
The tool displays information gathered from performance counters (GRBM, GRBM2), sensors, fdinfo, gpu_metrics and AMDGPU driver.

Unsure if it is the fault of cargo-generate-rpm or rpm itself?

Keep basename of source when it is a file and dest is directory

When specifying an asset such as

assets = [
    { source = "/usr/bin/foo", dest = "/usr/bin/", mode = "755" }
]

The result is a file named /usr/bin, even though the dest specified a path ending with a directory separator implying the path is a directory.

It would be nice if generate-rpm did the smart thing here which is to assume I want a file named foo in a directory /usr/bin/.
If dest is a directory path and source is a file path, then the basename of dest should keep the basename of source.

Missing Cargo.lock

Cargo.lock should be committed to the repository since this is a binary application.

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

setting `CARGO_TARGET_DIR` and using auto-req results in malformed RPM

If :

  • CARGO_TARGET_DIR is set to something other than target
  • there are assets containing files to e.g target/release
  • auto-req function is used

then the resulting RPM will contain a blank line requires, causing dnf/rpm errors.

This reproduces on cargo-generate-rpm itself by running CARGO_TARGET_DIR=foo cargo run

Empty requirement causes install failure

After using cargo generate-rpm I end up with an rpm that has an empty "requires":

[root@6794b4c1c5ee tmp]# rpm -q --requires /cli/target/cloudtruth-0.2.0-1.x86_64.rpm

/bin/sh

This causes install to fail:

[root@6794b4c1c5ee tmp]# rpm -i /cli/target/cloudtruth-0.2.0-1.x86_64.rpm
error: Failed dependencies:
         is needed by cloudtruth-0:0.2.0-1.x86_64

Any idea what could be causing this?

Getting SIGSEGV: invalid memory reference for `config::test::test_table_to_dependencies`

Hello! 🐻

I'm getting the following error during cargo test:

running 20 tests
test auto_req::builtin::test_is_executable ... ok
test build_target::test::test_build_target_path ... ok
test build_target::test::test_target_path ... ok
test auto_req::test_try_from_for_auto_req_mode ... ok
test auto_req::builtin::test_find_require_of_shebang ... ok
test auto_req::builtin::test_elf_info_new ... ok
test config::file_info::test::test_get_base_from_glob ... ok
test config::file_info::test::test_expand_glob ... ok
test config::metadata::test::test_compound_metadata_config ... ok
test config::file_info::test::test_generate_rpm_file_path ... ok
test config::metadata::toml_dotted_bare_key_parser::test_parse_dotted_bare_keys ... ok
test auto_req::script::test_find_requires ... ok
test config::metadata::test::test_metadata_config ... ok
error: test failed, to rerun pass `--bin cargo-generate-rpm`

Caused by:
  process didn't exit successfully: `/build/cargo-generate-rpm/src/cargo-generate-rpm-0.10.0/target/debug/deps/cargo_generate_rpm-d9297d9e484dcd0e` (signal: 11, SIGSEGV: invalid memory reference)

This is probably due to config::test::test_table_to_dependencies having an unsafe transmutation:

#[test]
fn test_table_to_dependencies() {
fn dependency_to_u8_slice(dep: &Dependency) -> &[u8] {
unsafe { std::mem::transmute_copy(dep) }
}

Running that test individually also fails:

$ cargo test -- "config::test::test_table_to_dependencies"

Caused by:
  process didn't exit successfully: `/build/cargo-generate-rpm/src/cargo-generate-rpm-0.10.0/target/debug/deps/cargo_generate_rpm-d9297d9e484dcd0e 'config::test::test_table_to_dependencies'` (signal: 11, SIGSEGV: invalid memory reference)

I think it would be the best if we could find a better way of comparing structs rather than using unsafe.

Feature request: Support directories with --output

Add support for --output argument values that end in / ala cargo-deb.

Without this if I wish to generate the RPM file in a different output directory I also have to either lose the detals contained in the generated file name (e.g. routinator-0.10.0-dev-1.x86_64.rpm) or do extra work to try and mimic that file name structure myself.

Looking at the code it seems that this would require some minor changes to main::process(), if I get time I'll try to submit a PR.

example of adding assets

Hello, I'm trying to use cargo-generate-rpm but I don't quite understand the toml structure described in the README.md

I'm trying to add assets, but not sure how to, I think an example of that would be helpful, just like the example for requires

[package.metadata.generate-rpm.requires]
alternative = "*"
filesystem = ">= 3"

Future-incompatibilities warning

When install cargo-generate-rpm I'm starting to see this,

warning: the following packages contain code that will be rejected by a future version of Rust: buf_redux v0.8.4, nom v4.2.3

Add support for workspace inheritance for version and other properties

Rust 1.64 added support for workspace inheritance making it possible to inherit the version and other properties from the workspace.toml.

# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["bar"]

[workspace.package]
version = "1.2.3"
authors = ["Nice Folks"]
description = "A short description of my package"
documentation = "https://example.com/bar"
# [PROJECT_DIR]/bar/Cargo.toml
[package]
name = "bar"
version.workspace = true
authors.workspace = true
description.workspace = true
documentation.workspace = true

Unfortunately cargo-generate-rpm currently does not support these.

Install different files for different targets

Hi,

How would I use cargo generate-rpm to install a different systemd service file on an older RHEL/CentOS release than on a newer release? For comparison, with cargo deb I used the "variants" support in Cargo.toml to define different assets to install in different "variants".

Thanks,

Ximon

Release Binaries

Hello! I'm using cargo-generate-rpm in the release workflow for cloudtruth/cloudtruth-cli. I've been able to speed up the build considerably by downloading prebuilt binaries of cross and cargo-deb rather than building from source, but I am unable to do the same with cargo-generate-rpm because there are no binaries available it would be nice to be able to quickly download a release binary with cargo-binstall or cargo-quickinstall rather than compiling from source each build.

Using `-ih` on Centos7 causes many hash marks and a locked RPM db

This only happens on centos 7 afaict.

Steps to reproduce:

  1. git clone https://github.com/cat-in-136/cargo-generate-rpm.git
  2. cd cargo-generate-rpm
  3. cargo install --path .
  4. cargo build --release
  5. cargo strip -s target/release/cargo-generate-rpm
  6. cargo generate-rpm --payload-compress none --auto-req no
  7. docker run --rm -v $PWD:/workdir centos:7 rpm -ih /workdir/target/generate-rpm/cargo-generate-rpm-0.6.0-1.x86_64.rpm

Adding -i -t to the above docker run command will produce infinite hashmarks and lock the rpm db

I tested using almalinux:8, centos:6, and centos:8 and they all function as expected. I'm pretty sure this is an issue with centos 7 itself, but users of the library should be aware of this issue.

RPM install fails with cpio bad magic

Steps to reproduce on a centos 7 machine with Rust installed already:

  1. git clone https://github.com/cat-in-136/cargo-generate-rpm.git; cd cargo-generate-rpm
  2. cargo install cargo-generate-rpm
  3. cargo build --release; strip -s target/release/cargo-generate-rpm
  4. cargo generate-rpm
  5. rpm -i target/generate-rpm/cargo-generate-rpm-0.5.0-1.x86_64.rpm

Result:

error: unpacking of archive failed: cpio: Bad magic
error: cargo-generate-rpm-0:0.5.0-1.x86_64: install failed

I'm fairly certain it's the rpm-rs crate, of course, but I thought I'd report it to you first to see if you had any ideas? Thank you very much!

Using multi-line scripts

Hi,

The README.md says:

pre_install_script: optional string of pre_install_script.
pre_uninstall_script: optional string of pre_uninstall_script.
post_install_script: optional string of post_install_script.
post_uninstall_script: optional string of post_uninstall_script.

How could I instead execute entire scripts instead of single commands?

The context for this question is an RPM that needs to install systemd services and create user accounts etc.

I "hacked' around this limitation in a test by including the scripts as assets with a /tmp destination and then used the "xxx_script" hooks to execute the script from /tmp/. However, the script then also needs to take care of removing itself which is a bit ugly.

Any suggestions welcome.

Thanks,

Ximon

Support custom and auto requires

Hi,

I need to specify a require when building an RPM but, unless I missed something, to do that with this crate I have to fork the crate and invoke requires myself, e.g.:

builder = builder.requires(rpm::Dependency::eq("openssl-libs", "1:1.1.1g-12.el8_3"));

It occurs to me that the cargo-deb crate supports specification of Deb package dependencies in Cargo.toml, and has Rust code for invoking ldd and dpkg -S (disclaimer: I use cargo-deb and contributed to it as well) to identify the packages the built binaries depend on and for using those if the user specifies either no dependencies or includes "$auto" in the list of dependencies.

Thus I would like a way to specify dependencies myself in the Cargo.toml file ala cargo-deb, and even better the $auto depends functionality too. For RPMs that could be done with parsing the output of ldd and then using rpm -qf </path/to/lib> to work out the package that provides the lib.

Is this of interest? Would you be open to a pull request? I could check with the author of cargo-deb if he minds code being copied from that project and modified for use here. Alternatively, and I'm dubious about the benefits of this, perhaps looking further ahead if there is sufficient commonality between this project and cargo-deb there could be a way to share code (factor out common elements to a support crate?) or combine the projects even (not sure that is wise, logic added for RPMs might have unintended consequences for DEB packaging or vice versa, automated testing would have to be quite thorough to avoid such inadvertent mistakes).

Ximon

Handling RC versions

Hi,

RPM package versioning policy supports the tilda character to denote a pre-release version. However, Cargo.toml doesn't permit a tilda in the version string.

With cargo-deb we have the same issue for DEB packaging policy but we pass the version in as a --dev-version command line argument when running cargo deb. With cargo generate-rpm I have to hack the Cargo.toml file after I have run cargo build but before I run cargo generate-rpm so that I can replace -rcN with ~rcN.

Do you have any better suggestions on how to handle this scenario?

Thanks,

Ximon

do you plan to support multiple config?

sometime a package has some bins, so it exists demand to config each bin.do you plan to support it or mind other submit pr. the confis like:

[package.metadata.generate-rpm.A]
assets = [
    { source = "target/release/a", dest = "/usr/local/bin/a", mode = "0755"},
[package.metadata.generate-rpm.B]
assets = [
    { source = "target/release/b", dest = "/usr/local/bin/b", mode = "0755"},

Release Should Accept Strings

In the read-me it states that release takes a strings but when I tried this it only takes numerics.

It should use strings to allow for pre-release versions etc. I'll create a PR for this now hopefully.

[Feature-Request] Add `%pretrans %posttrans`?

When RPM upgrades a package it will run all the post/pre install scripts before the post/pre uninstall scripts will run. This means that if you remove files in a pre uninstall but create the same files in post install, those files end up getting deleted when the old package is uninstalled.

It appears the way to handle this properly is to use pre/post trans scriptlets. Would it be possible to add options for these?

Please create example directory and provide more buildable *.toml

I have a learning project to create a vaultwarden rpm that can be deployed using rpm, not docker.

  • cargo-generate-rpm did the job and I got rpm like following
[me@t430 vaultwarden]$ ls target/generate-rpm/
vaultwarden-1.0.0-1.x86_64.rpm
[me@t430 vaultwarden]$ rpm -qlp target/generate-rpm/vaultwarden-1.0.0-1.x86_64.rpm
/usr/bin/vaultwarden
/usr/share/doc/vaultwarden/LICENSE
/usr/share/doc/vaultwarden/README.md
[me@t430 vaultwarden]$
  • But I like to add more assets into the rpm by {pre|post}-install scripts and systemd service file.
    I have to go through the readme file without working example .toml files provided by this project.
  • Please consider to open up examples directory and then newcomers can just do "cargo build --examples" to generate example rpms with different assets.

mc cannot read resulting rpm file

The Midnight Commander (mc) tool is nice for inspecting RPM files. Unfortunately, for some reason, mc cannot open the RPM files resulting from "cargo generate-rpm". mc writes a number of error messages like "Cannot parse: -r--r--r-- 1 root root 495 e) HEADER", see attached screenshot: sshot_genrpm_error

Attached is also some code which can be used to reproduce the issue: genrpm.tar.gz

Perhaps generate-rpm is not be producing metadata which mc needs? Some may see this as an issue in mc, but there could be other RPM-related tools which will also trip over this, hence this ticket.
The related mc code seems to be this script, but I don't see anything obviously wrong in it: https://github.com/MidnightCommander/mc/blob/master/src/vfs/extfs/helpers/rpm

Support for --target on asset sources (cross targets)

The cargo-deb project allows asset sources to start with "target/release/" and if a cross target is being used, the location of the source is automatically corrected to "target/release//". This makes it easier to use carbo-deb with multiple cross targets. A similar mechanism in cargo-generate-rpm would make it easier as well.

Failed dependencies: libc.so.6(GLIBC_2.29)(64bit) is needed when install generated .rpm package

I built a .rpm package from my Rust source code within Docker Ubuntu:22.04 image then install it on the Centos:8 container and got this error:

[root@a4fe360dca8b ~]# yum install glibc
Last metadata expiration check: 16:04:45 ago on Mon 21 Aug 2023 01:09:05 PM UTC.
Package glibc-2.28-164.el8.x86_64 is already installed.

[root@a4fe360dca8b ~]# rpm -ivh strend-0.2.1-1.x86_64.rpm
error: Failed dependencies:
	libc.so.6(GLIBC_2.29)(64bit) is needed by strend-0:0.2.1-1.x86_64

Not sure what libs in my package required a higher glibc version, any way to find out?

Additional info

Build on Mac M1

Reproducible builds

Right now by default generate-rpm crates non-reproducible RPMs. It can be worked around by using --payload-compress none and manually setting modification time of included artifacts right before RPM generation. Ideally, it should be handled by a simple flag.

Also I don't quite understand why enabling compression makes builds non-reproducible.

Relevant issue: rpm-rs/rpm#117

Cannot publish to crates.io by git+rev dependency of PR #23

In PR #23 and issue #21, git+rev dependency was added to Cargo.toml but it is not acceptable for publishing to crates.io.

$ cargo publish --dry-run
    Updating crates.io index
error: all dependencies must have a version specified when publishing.
dependency `rpm-rs` does not specify a version
Note: The published dependency will use the version from crates.io,
the `git` specification will be removed from the dependency declaration.

Unable to use custom rpm package version

We have custom package version format, for example: 3.0.A.1 ...when adding this version into Cargo.toml version field:

[package]
version = "3.0.A.1"

this will fail with:

Caused by:
unexpected character 'A' while parsing patch version number for key package.version

The same is happening when building DEBIAN package with cargo-deb BUT cargo-deb has special option that can be used to pass in any custom version:

cargo deb --deb-version 3.0.A.1 # this one works for DEBIAN packages

Could you please create a workaround for this, so any custom version format can be used, perhaps similar behavior (cmdline option) as cargo-deb tool has?

Thank you very much

Support for `summary` silently dropped

The README still says:

summary: the package summary/description. If not present, package.description is used.

However, PR #46 removed support for this and was included in release v0.9.0, but no mention of this was made in the release notes and the README was not updated.

Worse, using summary doesn't cause an error or warning, it just doesn't have the desired effect.

I only found this because rpmlint complains about my description being too long even though I set summary to a shorter text.

Support for rpm file which does not have a dependency on /bin/sh

All RPMs generated by cargo-generate-rpm require /bin/sh.

This seems unnecessary, as Rust binaries don't universally require a shell. In my case I'm trying to build distroless-like containers from RPMs generated by cargo-generate-rpm, and this is causing a shell and it's dependencies to be pulled in unnecessarily.

This behaviour comes from by rpm-rs, which appears to not be maintained at present: Richterrettich/rpm-rs#54. I've raised a PR to rpm-rs/rpm#7 - which is a community fork that isn't yet publishing to crates-io.

Conditional dependecies

Hello,

I'm making an rpm package for an app that depends on ffmpeg,

but since ffmpeg is removed from fedora's default repos, I want to check if the user already has ffmpeg or has access to it from a different repo, and download it,

if NOT then install ffmpeg-free since it does what I need

something similar to Requires: (ffmpeg or ffmpeg-free) in the spec file

I want to do that because if I just download ffmpeg-free regardless, it will conflict with ffmpeg as I tested on my machine,

how do I do conditional dependencies in this situation?

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.