What is it?
OBS is Open Build Service, a rather magnificant tool from openSUSE. It has the ability to run additional services which are scripts or programs to aid in the building of software packages. The one I've focused on here is obs-service-cargo_vendor.
Packaging Rust apps
The reason obs-service-cargo_vendor
exists, is to aid packagers in maintaining Rust written applications. Typically these applications have many source dependencies (crates in Rust parlance) which are fetched from a crates repository. This makes developing Rust applications easier, particularly with the cargo
tooling available. However, when packaging for a Linux distro you are almost always restricted from fetching such external sources and so a cargo tool named cargo-vendor
exists - this will fetch only the required dependencies and plonk them in a ./vendor
dir in your project.
Using obs-service-cargo_vendor and OBS services
If you have a Rust app you want to package which has standard tarball style releases it is fairly easy to get started. Create your RPM packaging as normal then follow these steps:
- Create a
_service
file with the following contents:
<services> <service name="cargo_vendor" mode="disabled"> </service> </services>
This file tells OBS there is a service to use, although currently it is set to disabled
. The reason for this is only because OBS isn't completely set up to run this service on it's own yet. When it is you can change mode="disabled"
to mode="buildtime"
and OBS will run it automatically. The service can take arguments, but should autodetect everything you need.
-
Step 1 produces two artifacts in the project directory:
cargo_config
andvendor.tar.*
where the compression ofvendor.tar
is the same as the tarballed source you are using. You now need to modify the RPM spec file. -
Add the artifacts as source files:
Source1: vendor.tar.xz Source2: cargo_config
- Adjust the
%prep
step:
%setup -qa1 # extract all sources mkdir .cargo # cargo automatically uses this dir cp %{SOURCE2} .cargo/config # and automatically uses this config
- Run
osc service disabledrun
to actually generate the artifactscargo_config
andvendor.tar.*
. These need to be added to the repo withosc ar
.
And that's pretty much all there is to it. But recently I wanted to use the obs_scm
service in conjunction with cargo_vendor
and have submitted a PR add the required modifications to cargo_vendor
to make this easier. Using obs_scm
is as above but with a _service
file similar to the following:
<services> <service name="obs_scm" mode="disabled"> <param name="scm">git</param> <param name="url">https://github.com/jwilm/alacritty.git</param> <param name="versionformat">%cd</param> <param name="changesgenerate">enable</param> </service> <service name="cargo_vendor" mode="disabled"> <param name="compression">xz</param> </service> <service name="tar" mode="buildtime"/> <service name="recompress" mode="buildtime"> <param name="file">*.tar</param> <param name="compression">xz</param> </service> <service name="set_version" mode="disabled"/> </services>
A brief overview of this is obs_scm
clones the sources from github, and adjusts the package version number in the spec file to %cd
which is the current date. It also updates the package changelog with the git commit messages (you will want to edit this after). It will then run the cargo_vendor
service, followed by tar, compression, and version setting.
Where mode=
is set, this dictates when/how each service is run and helps prevent unrequired services running. buildtime
will run when the package is built by OBS, and disabled will not run unless done so manually. For both _service
examples here we need to run osc service disabledrun
on our local machine and add the artifacts to the osc
repo.
Service options and how it works
There are a few options that you can supply to the service. The default behaviour without these options is to autodetect the archive type, and in the case where a directory is found with a Cargo.toml
in the root, then the default compression of gzip
is used.
<param name="strategy">vendor</param>
The default here is vendor
which will use cargo vendor
to fetch the crate dependencies. As of this writing there is no alternative to this.
<param name="archive">archivename.tar.gz</param>
The name of the required archive. The option is used in the case where there may be multiple archives available in the package build. This can also be used to specify a directory - useful in the case of using the obs_scm
service.
<param name="compression">xz</param>
The compression to use for the vendor.tar
. If the option is not supplied it will default to gz
or the same compression as the source archive. Available compressions are those supported by tar
.
Example
<services> <service name="cargo_vendor" mode="disabled"> <param name="strategy">vendor</param> <param name="archive">some_git_repo</param> <param name="compression">xz</param> </service> </services>