Commit Graph

342 Commits

Author SHA1 Message Date
Colin Walters
588541c60d Move libdnf build over to Cargo
This is now further migration towards Cargo/Rust possible
because we switched our main binary.  We've had an internal
`libdnf-sys` crate for a while, but now it can take over
the build of the underlying library too (like many `-sys`
crates support).

This itself is just an incremental step towards migrating
the main rpm-ostree build system to e.g. cmake too (or
perhaps directly with the `cc` crate, not sure yet) and
driving it via `cargo` too.
2021-02-04 10:59:20 -05:00
Colin Walters
2128f5784a build-sys: Explicit workspace, move libdnf deps to crate
First explicitly state that we're a workspace.  AIUI
this is actually implicit today via our use of a `path`
dependency, but in the future we may have other sub-crates.
So let's make it explicit now.

Also move the libdnf dependencies directly to that sub-crate.
2021-02-04 10:59:20 -05:00
Luca BRUNO
9c3864b97e libpriv/passwd: move entries deduplication logic to Rust
This moves `group` and `passwd` merging/deduplication to Rust.
2021-02-03 15:59:38 -05:00
Jonathan Lebon
317b920667 extensions: Add support for development extensions
In RHCOS, we ship kernel development-related packages as an extension.
Those aren't really extensions that are meant to be layered onto the
host.  They're meant to be used in a build environment somewhere to
compile kernel modules.

This makes it very different from "OS extensions" in at least two
drastic ways:
1. we don't want to do any depsolving (e.g. we don't want to pull in
   `gcc` or something)
2. some of those packages may be present in the base already, but we
   still want to redownload them

Hesitated putting this functionality in rpm-ostree, but I think in the
end it cuts from the benefit of moving this code to rpm-ostree if we
can't entirely get rid of the Python script it obsoletes. Plus, being
able to use the `match-base-evr` is still really useful for this use
case.

Let's add a new `kind` key to support this. The traditional extensions
are called "OS extensions" and these new extensions are called
"development extensions".

The latter is not yet part of the state checksum, so change detection
doesn't work there. I think that's fine for now though because the
primary use case is the kernel, and there we want to match the base
version. So if the kernel changes, the base would change too. (Though
there's the corner case of adding a new package to the list while at the
same version...)
2021-02-03 12:22:38 -05:00
Jonathan Lebon
20ab52adaa rust/treefile: Drop unnecessary #[serde(rename)]
The key is already called `rpmdb`.
2021-02-03 12:22:38 -05:00
Jonathan Lebon
9d07286f3d extensions: Fix missing CxxResult 2021-02-03 12:22:38 -05:00
Jonathan Lebon
f7090358be extensions: Support enabling additional repos
We want to be able to enable more repos than those in the treefile when
downloading extensions. In RHCOS for example, the `kernel-rt` packages
come from a separate repo.

But also, once we support "development" extensions, we want to support
the case where devel packages come from another repo.
2021-02-03 12:22:38 -05:00
Colin Walters
d218f27188 Change main entrypoint to be Rust
We now have bidirectional calling between Rust and C++,
but we are generating two static libraries that we then
link together with a tiny C++ `main.cxx`.
Let's make another huge leap towards oxdiation by
having Rust be the entrypoint.  This way cargo natively
takes care of linking the internal Rust library, and
our C++ internals become the library.

In other words, we've now fully inverted from
"C app with internal Rust library"
to "Rust binary with internal C++ library".

In order to make this work though we have to finally
kill the C unit tests.  But mostly everything covered
there is either being converted to Rust, or covered
elsewhere anyways.

Now as the doc comments in `main.rs` say...this is
a bit awkward because all the CLI code is still in C++.
Porting stuff to use e.g. `structopt` natively would
be a bit of a slog.  For now, we basically rely on
the fact that the Rust-native CLIs are all hidden
commands.

Update submodule: libdnf
2021-02-01 08:17:52 -05:00
Luca BRUNO
140357d549 rust/passwd: minor cleanup, use write_file_with_sync 2021-01-29 12:41:20 -05:00
Luca BRUNO
536bfc62eb libpriv/passwd-util: move migration logic to Rust
This moves passwd/group splitting logic to Rust, also decoupling
the two implementations in order to reduce overall complexity.
2021-01-29 08:15:48 -05:00
Colin Walters
e87a64576c Bridge "next version" API to Rust, use it for unit tests
This demonstrates well the strength of the cxx-rs approach;
we can keep an API in C++ but add unit tests in Rust which
just works much more nicely.

Prep for https://github.com/coreos/rpm-ostree/pull/2502
which wants to drop the C++ unit tests.
2021-01-29 05:29:47 -05:00
Colin Walters
7ab1936814 cliwrap: Fix indentation
We need to trim the starting whitespace, otherwise
it ends up in the script.
2021-01-28 21:26:47 -05:00
Colin Walters
e88a736e55 lockfile: Note that comment is JSON
Otherwise rustc tries compile and run it as a doctest.
2021-01-27 19:36:34 -05:00
Jonathan Lebon
c98c227c0f extensions: Write JSON to output dir
Let's include the final extensions file in JSON format as part of the
output directory. A key difference from the input file (apart from YAML
vs JSON) is that this is post-filtering, so any extensions which were
removed because the architecture does not match are not present.

This JSON file will be used by cosa and the MCO. See discussions in:
https://github.com/openshift/os/issues/409
2021-01-27 00:44:42 +01:00
Colin Walters
80dc572514 rust: Add some allow(dead_code)
One is only used in the unit tests right now, the other we'll
likely use soon.
2021-01-26 18:28:58 +01:00
Colin Walters
c3da95a119 Move nevra parsing to Rust, first use of extern "C++"
Until now with cxx-rs we'd been using it effectively as a better
cbindgen - we're exposing Rust code to C++ safely.  This is
the first case of having Rust calling back into C++ using cxx-rs.
2021-01-26 13:47:56 +01:00
Luca BRUNO
867ba1eba8 rust/passwd: minor cleanup, switch to copy_file_at
This updates file copying to use the newer `copy_file_at` from
openat-ext.
2021-01-26 12:14:59 +01:00
Jonathan Lebon
49318cd950 rust: Fix clippy warnings
Mostly straightforward stuff. It taught me about the `matches!` macro,
which looks really useful.

Wanted to turn this on in CI, but there's still a bunch of clippy
warnings coming from the `cxx.rs` stuff and some of our unsafe blocks.
For example, it wants the `files` arg in `initramfs_overlay_generate` to
be `&[String]` instead of `&Vec<String>` but that would break cxx.rs (it
looks like cxx.rs does support slices, but it would require creating one
from the vector we have to create anyway).
2021-01-25 20:06:53 +01:00
Luca BRUNO
15a32c12d6 rust/passwd: finish moving group and passwd parsers
This drops the remaining C compatibility hops, moving group and
passwd parsing logic fully into Rust, under a `nameservice`
module.
2021-01-25 19:43:54 +01:00
Luca BRUNO
a0e6427bb6 testutils: port to new 'rand' library API 2021-01-25 18:51:53 +01:00
Jonathan Lebon
271954a41c app: Add rpm-ostree compose extensions
This adds support for a new `rpm-ostree compose extensions` command`
which takes a treefile, a new extensions YAML file, and an OSTree repo
and ref. It performs a depsolve and downloads the extensions to a
provided output directory.

This is intended to replace cosa's `download-extensions`:
https://github.com/coreos/coreos-assembler/blob/master/src/download-extensions

The input YAML schema matches the one accepted by that script.

Some differences from the script:
- We have a guaranteed depsolve match and thus can avoid silly issues
  we've hit in RHCOS (like downloading the wrong `libprotobuf` for
  `usbguard` -- rhbz#1889694).
- We seamlessly re-use the same repos defined in the treefile, whereas
  the cosa script uses `reposdir=$dir` which doesn't have the same
  semantics (repo enablement is in that case purely based on the
  `enabled` flag in those repos, which may be different than what the
  rpm-ostree compose ran with).
- We perform more sanity-checks against the requested extensions, such
  as whether the extension is already in the base.
- We support no-change detection via a state SHA512 file for better
  integration in cosa and pipelines.
- We support a `match-base-evr` key, which forces the extension to have
  the same EVR as the one from a base package: this is helpful in the
  case of extensions which complement a base package, esp. those which
  may not have strong enough reldeps to enforce matching EVRs by
  depsolve alone (`kernel-headers` is an example of this).
- We don't try to organize the RPMs into separate directories by
  extension because IMO it's not at the right level. Instead, we should
  work towards higher-level metadata to represent extensions (see
  https://github.com/openshift/os/issues/409 which is related to this).

Closes: #2055
2021-01-23 17:12:09 +01:00
Colin Walters
71496c0958 rust: Add a bit more info on cxx, move up StringMapping
Docs are good, and move up `StringMapping` since multiple things
are likely to use it.
2021-01-22 03:00:21 -05:00
Colin Walters
01e6c56415 rust/fedora_integration: Support export RPMOSTREE_KOJI_JSON_API_HOST=...
The service where this is hosted was intended to be temporary; support
overriding it so if it goes down in the future people can at
least use a systemd unit file override to change it easily.
2021-01-21 12:46:32 -05:00
Colin Walters
a9a4e022e6 rust: Port history to cxx-rs
Just keeping up momentum on the porting, we're getting closer
to being able to drop cbindgen entirely.
2021-01-20 17:22:29 -05:00
Luca BRUNO
21be64b3d6 libpriv/passwd: move RPM layering logic to Rust
This moves to Rust the RPM layering logic for users and groups
databases.
2021-01-19 19:32:27 -05:00
Colin Walters
a8a1317748 rust: Port progress.rs to cxx-rs
Only slightly tricky thing here was double checking which
places pass "optional &str" (represented as empty strings)
and which don't.
2021-01-18 12:07:53 -05:00
Colin Walters
a3d6c85e06 rust: Fix a pub(crate) warning, add a few doc comments
Mainly went to fix the warning but decided to add some
comments while I was in here.
2021-01-15 18:25:27 -05:00
Colin Walters
54ab9175ac rust: Add CxxResult
This is a workaround for the non-customizability of the cxx-rs
propagation of Rust result to C++ exception.  Right now we're
losing context.  Work around this by formatting on the Rust
side at exit points, explicitly converting an `anyhow::Error`
by printing it in "single line context".

Since we're likely to gain more things like this, unify
this with `cxx_bridge_gobject::` into a single `cxxrsutil::`.
2021-01-15 06:59:30 -05:00
Colin Walters
d0c6871d80 apply-live: Avoid clobbering changes in /etc
Gather the current diff of `/etc`, and filter out changes in
the tree which would overwrite it.

There is an OSTree API for diffs but it's a bit awkward, missing
some APIs in the Rust bindings and also `GFile` based unfortunately.
Doing this in Rust is nicer.  The dirdiff code obviously needs
a lot more testing, but I think it's right.
2021-01-15 05:41:53 -05:00
Timothée Ravier
6cfdb1f585 countme: Add DNF Count Me support
Add support for the DNF Count Me feature [1,2,3] as a standalone
rpm-ostree subcommand called weekly via a systemd timer.

[1] https://fedoraproject.org/wiki/Changes/DNF_Better_Counting
[2] https://dnf.readthedocs.io/en/latest/conf_ref.html?highlight=countme#options-for-both-main-and-repo
[3] https://github.com/rpm-software-management/ci-dnf-stack/blob/master/dnf-behave-tests/features/countme.feature
2021-01-13 14:53:50 -05:00
Colin Walters
0e9941495e Add a Rust helper to create a sealed memfd, use in shlib backend
Prep for other code using memfds.
2021-01-12 22:07:18 -05:00
Colin Walters
241cce1ec4 testutils: Port to cxx-rs
Another easy port like cliwrap.
2021-01-12 19:35:59 -05:00
Luca BRUNO
bdf8269dfa libpriv/passwd: move passwd database to Rust
This moves to Rust the in-memory structure holding passwd entries
(users and groups).
2021-01-12 18:50:30 -05:00
Colin Walters
803e4db50c journal: Add filters for _UID=0
This strengthens our journal filtering to ensure that we won't
read entries from e.g. a malicious process logging with a
syslog identifier `ostree`.
2021-01-12 17:13:00 -05:00
Colin Walters
6c66bf1072 Rename livefs → apply-live in more places
Keep up the renaming momentum by using the new name in more
places.

Prep for further work.
2021-01-12 03:15:49 -05:00
Colin Walters
9f590fa155 Also print Rust-side features/cfg in rpm-ostree --version
Let's make it obvious whether the `fedora-infrastructure` feature
is compiled in.
2021-01-11 13:03:04 -05:00
Colin Walters
29d051e895 Add fedora-integration: Support override replace https://bodhi/...
This adds support for e.g.:

```
$ rpm-ostree override replace https://bodhi.fedoraproject.org/updates/FEDORA-2020-2908628031
```

This will find the Koji builds from the listed update, download
all the RPMs (that aren't debuginfo) and pass them for overrides
in the same way we support `override replace http://somewebserver/foo.rpm`
now.

We also support directly linking a Koji build:
```
$ rpm-ostree override replace https://koji.fedoraproject.org/koji/buildinfo?buildID=1625029
```

Bodhi has a modern HTTP+JSON API, and the lack of a Koji equivalent
drove me to create https://github.com/cgwalters/koji-sane-json-api
and we currently depend on an instance set up in the OpenShift CI
cluster.

I hope it shouldn't take long to deploy this in Fedora Infra,
but I don't want to block on it.

Also notably this still downloads *all* the other RPMs even
ones that aren't installed.  Handling that truly correctly
would require moving this logic to the daemon and core.

All of this functionality is keyed off a `cfg(feature = "fedora-integration")`
that is detected by a Rust `build.rs` which parses the build environment's
`/etc/os-release` for now.
2021-01-11 13:03:04 -05:00
Colin Walters
9d080fc1fa Port Rust journal bits to cxx-rs
This is cleaner if we move the "catch and print errors" into
the Rust side.  We lose the "print errors as red" part but
eh we can readd that later Rust side.
2021-01-09 11:41:41 -05:00
Colin Walters
4b233daca7 Port composepost to cxx-rs
This one was easy.
2021-01-07 20:50:43 -05:00
Colin Walters
52eaa6b6b6 Port cliwrap FFI to cxx-rs
The example of how the `cliwrap_entrypoint()` function
can just be directly bound with this is a great
example of the cleanup.
2021-01-07 17:05:41 -05:00
Colin Walters
92a1fa5bc3 Complete move to cxx-rs for utils
This makes the C++ side a bit uglier because the "variable mapping"
is more Rust-native but we only use it Rust side anyways.
(We can't yet move the basearch bits to rust because it depends on
 libdnf, which requires buildsystem unification)

But all the unsafe FFI conversion drops out, as do the duplicated
C unit tests.
2021-01-07 11:46:52 -05:00
Colin Walters
cba87eaf87 Move some client argument handling to Rust
Prep for the [fedora-integration PR](https://github.com/coreos/rpm-ostree/pull/2420).

This also generalizes the "fetch URL to tempfile" code into
supporting multiple at once - it's much more efficient to do
it that way because we can reuse a TCP connection to servers,
parsed certificates etc.
2021-01-06 12:40:06 -05:00
Colin Walters
fd88e8aba7 Port initramfs Rust code to cxx-rs
Also adds support for passing through `GCancellable`.
2021-01-05 19:59:24 -05:00
Colin Walters
62464ed438 Use cxx-rs for live-apply
(I'm going to start calling it `live-apply` instead of "livefs")

On one hand, this drops the unsafe bindgen glue.  On the other
hand it demonstrates a notable current ergonomic shortfall of
cxx-rs in that it doesn't support `Option<T>`, so we represent
optional strings by converting them to empty strings.

(Relatedly I discovered in C++ there is `std::optional<>` but it's in C++17.
 I assume we can depend on that but let's for now match libdnf's
 usage of `-std=c++14` because we know that works everywhere)
2021-01-05 10:26:00 -05:00
Colin Walters
ec1e248b11 Add support for some GObject bridging to cxx-rs
cxx-rs has support for bridging types, but it's more awkward
for us because those types are defined in other crates, so
we need to do a newtype dance.  Further cxx-rs doesn't currently
support automatically generating wrappers, so add a custom
`gobj_wrap()` for now.
2021-01-05 10:26:00 -05:00
Colin Walters
b5ad234b59 Add a partial reimplementation of origin parsing in Rust
Let's land the half-completed Rust code so we can iterate on
and improve it while other patches land that might conflict
with work on the C++ side.
2021-01-04 13:54:38 +01:00
Colin Walters
562acedbaa Move "ignored script list" to Rust, drop gperf
Rust has a nice crate for doing perfect hashing.  Move that
code into Rust and drop the dependency on `gperf`.  This also
helps move away from Autotools.
2020-12-24 16:37:04 +01:00
Colin Walters
6579ab791b Use cxx-rs instead of gresources
The way gresources work using a constructor function started
failing when I was refactoring the build system, and I couldn't
figure it out.  It's just easier to use Rust for this which
has nice toolchain-integrated functionality for this.
2020-12-23 17:45:29 +01:00
Colin Walters
8ab6a1f4f0 Use cxx-rs for utils.rs download_to_fd
A step towards converting all of utils.
2020-12-23 17:45:29 +01:00
Colin Walters
9565c19ef0 Use cxx-rs for core.rs
This is much better than bindgen because it's fully safe.  It's
much more ergonomic too:

 - Invoke Rust methods-on-structs just like C++ methods-on-structs
 - Rust `Result<>` is translated automatically to exceptions

See https://cxx.rs/context.html for more.
2020-12-23 17:45:29 +01:00