Commit Graph

825 Commits

Author SHA1 Message Date
Luca BRUNO
de7d20e43b libpriv/passwd: move UID/GID checker to Rust
This ports to Rust the logic for checking whether a directory tree
contains content owned by a given UID/GID.
2021-02-26 00:34:56 +01:00
Colin Walters
d8230bfb6d daemon: Move some "deployment variant" generation to Rust
More prep for https://github.com/coreos/rpm-ostree/pull/2388

This was actually also my first time really trying out the
latest gtk-rs `glib::Variant` API, which is one of the major
things we need to use to progress oxidation more.
2021-02-23 13:56:26 -05:00
Luca BRUNO
7283aef8af libpriv/passwd: remove unused functions
This drops some functions that used to be part of C unit-tests but
are currently dead code.
2021-02-22 13:24:41 -05:00
Luca BRUNO
9b94e85e5b libpriv/passwd: move compose preparation to Rust
This moves passwd/group compose preparation logic to Rust,
dropping all the remaining minor helpers related to JSON parsing,
file stream creation, and entries deduplication.
2021-02-22 11:44:13 -05:00
Colin Walters
04e0c4e01a Fix progress API to have "output message" separate from task
A lot of our output is outside of a "task"; the Rust binding
incorrectly made it a method on `Progress`.  This is really
just a `println!()` that is backed by our dispatch system.
2021-02-19 09:08:22 -05:00
Colin Walters
1d242ddb59 Add a C++ rpmdb-diff API wrapping the C one, bind in Rust
I'd like to compute diffs in apply-live to differentiate
between "pure layering" versus modifications/removals.
2021-02-19 09:08:22 -05:00
Colin Walters
8a62ad9f3d Add gobj_rewrap() API to pass glib-rs objects back to C++
When we started using cxxrs, most of the glib-rs objects like
`OstreeRepo`/`OstreeSysroot` were owned by C++ and passed
down into Rust.  That motivated the addition of the special
bridging infrastructure to re-create a glib-rs wrapper
type from what cxxrs wants (a `Pin<&mut T>`).

But now that we're adding more in Rust, we have the need
to pass these objects back into C++.  In fact this will
hopefully soon because the default case as more of the
binary entrypoint becomes Rust.

Add another trait with a method `gobj_rewrap()` that converts
in the other direction.  This implementation took me a number
of tries before I finally settled on simply using `mem::transmute()`.
There are a *lot* of caveats listed on the docs for that function,
but I think it really is what we want here.  See the link for pending work
on a Rust RFC to enable safe transmutes for some cases, and I believe
that would cover this use case:
https://internals.rust-lang.org/t/pre-rfc-v2-safe-transmute/11431

I've verified this works in a separate patch, but this commit
also adds a simple test case - this goes all the way from:
   Rust glib-rs `ostree::Repo` (holding strong ref)
   -> Rust `Pin<&mut ostree_sys::OstreeRepo>`
   -> (internal cxx-rs C bridge)
   -> C++ `OstreeRepo&` reference
   -> C `OstreeRepo*` pointer
Which is quite the dance if you think about it!
2021-02-18 06:29:41 -05:00
Colin Walters
764de41cc6 Switch to using cxx-rs for treefile
This is one half of https://github.com/coreos/rpm-ostree/issues/2544
which aims to drop our use of `cbindgen`.
2021-02-11 15:44:38 -05:00
Colin Walters
20178bb25a tree-wide: Include GLib headers before libdnf
Alternative fix to https://github.com/rpm-software-management/libdnf/pull/1139
aka https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1935

This way libdnf's `extern "C"` over the glib headers doesn't apply
because we already processed that header.
2021-02-10 17:05:42 -05:00
Colin Walters
6886e44425 scripts: Bind /usr/share/empty over /usr/share/rpm
Now that we inject the `%_dbpath /usr/share/rpm` macro, `rpm -q`
will start using it.  But in RPM script invocation, we don't
want them to see any RPM database at all - trying to query it
should be a clean failure.
2021-02-09 18:36:35 -05:00
Jonathan Lebon
667fdc9ff4 libpriv/rpm-util: Use /usr/share/rpm for base rpmdb query
Follow-up to previous commit: we had another path where we made a
temporary rootfs and symlinked `/var/lib/rpm` to the base rpmdb. That of
course broke now that we inject a macro to point the rpmdb to
`/usr/share/rpm`.

Rework this to use `/usr/share/rpm` since that's our canonical location
for now, but also add the compat symlinks so that this logic should keep
working even on trees without the injected macro yet.
2021-02-09 18:36:35 -05:00
Jonathan Lebon
60215ae865 libpriv/rpm-util: Add /usr/lib/sysimage/rpm symlink in rpmdb checkout
We don't technically need this yet, but it mirrors how it's set up in
our composes so that if there's code that wants to use the new location
too, it'll just work.
2021-02-09 18:36:35 -05:00
Jonathan Lebon
99486a75e8 Add /usr/lib/rpm/macros.d/macros.rpm-ostree to set %_dbpath to /usr/share/rpm
We trigger a librpm macro file load in many of our paths. Since the
default value shipped by rpm's macro file sets `_dbpath` to
`/var/lib/rpm`, we have to explicitly set that back to `/usr/share/rpm`
in those paths.

This became more problematic recently with libsolv v0.7.17 which fully
keys off of `_dbpath` to find the rpmdb path to load:

04d4d036b2

And it's not technically wrong; we really should make that macro not
lie. This is what this patch does by injecting an RPM macro file in our
composes which sets it to /usr/share/rpm. So then e.g. the `rpm` CLI
doesn't actually need the `/var/lib/rpm` backcompat link anymore, though
there's no harm in leaving it.

In the future, we should be able to drop this once we move all of Fedora
to `/usr/lib/sysimage/rpm` (see
https://github.com/coreos/fedora-coreos-tracker/issues/639).

Closes: #2548
2021-02-09 18:36:35 -05:00
Luca BRUNO
8a2f281143 libpriv/postprocess: get rid of goto statements
This removes all goto statements in the postprocess module,
replacing them with an exception catcher instead.
2021-02-09 16:43:32 +01:00
Colin Walters
2f6b5a654d Bind output core into Rust, use in apply-live
Originally the Rust apply-live code was exposed from Rust to C
via bindgen.  But when working on that, I hit the problem
that our output infrastructure was C...and the "reverse direction"
binding stuff was just ugly.

This PR again IMO shows the value of the investment in cxx-rs
because we can now seamlessly call back from the Rust side
into a "C++-ish" progress API, which the C++ side is updated
to use.

The level of indirection here is obviously pretty silly
because the main thing on the C++ output side is basically
a function dispatcher, but...I didn't want to try to rework
that into Rust fully yet.  (But, the moment we do this
whole area will get a *lot* cleaner)

Anyways, in the end this makes it easy for the apply-live
code to output progress to the user which was sorely
needed.
2021-02-09 04:43:29 -05:00
Colin Walters
c9e9269770 Rename internal Rust progress to console_
Our output system is very confusing in that we bridge over
DBus in some cases and not others.  In preparation for allowing
Rust code to call into the C++ progress system which contains
that delegation layer, rename the Rust progress to `console_`
to clearly show that it should only be invoked by code that
knows it's writing to a tty.
2021-02-09 04:43:29 -05:00
Colin Walters
dba43e201e tree-wide: Fix clang -Wgnu-designator/-Wunused-variable
clang warns about this:
https://clang.llvm.org/docs/DiagnosticsReference.html#wgnu-designator
Also fix unused variables and hard error on them.
2021-02-08 14:38:31 -05:00
Colin Walters
8ddaf0bbd6 Make failure to find packages fatal, add more error prefixing
To help debug https://bugzilla.redhat.com/show_bug.cgi?id=1925584
2021-02-08 11:20:50 -05:00
Jonathan Lebon
d22d241754 core: Don't allow noent when resolving pkgcache rev
If we get here, it's that we expect the pkgcache to be there. So don't
allow ENOENT (we weren't even checking for the ENOENT case here, which
shows that this was the intent).

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1925584
2021-02-08 11:20:50 -05:00
Colin Walters
5cefee81ff tree-wide: Squash some clang-analyzer found unused variables
We weren't using the return values, so just drop them.
2021-02-05 12:39:07 -05:00
Colin Walters
4d2a6e6de0 tree-wide: Pacify some clang-analyzer "Dead nested assignment"
It doesn't understand the "$x_owned" pattern (which is really
much like Rust's `std::borrow::Cow`).
2021-02-05 12:39:07 -05:00
Colin Walters
6a594dbe6b util: Annotate our "throw" wrappers as [[ noreturn ]]
This way the compiler and `clang-analyzer` understand and won't
issue an error if we are missing a `return` after an unconditional
`throw_gerror()`.
2021-02-05 12:39:07 -05:00
Colin Walters
a36f9716c6 tree-wide: Fix some "Dead assignment" from clang-analyzer
The `have_rpmdb` one was a leftover looks like.  In the `disabled_all_repos`
case it was clearly there for symmetry, but eh; it seems somewhat
unlikely that we add a *3rd* case there.  Also while we're
here change it to C++ `bool` so tools like analyzers know it really
is a boolean.
2021-02-05 12:39:07 -05:00
Colin Walters
7b5b35210b tree-wide: Fix some spurious "Dead assignment" from clang-analyzer
This fixes some spurious warnings from clang-analyzer (aka `scan-build`) around
"Dead assignment".  Unfortunately the analyzer doesn't understand
the side effects of `__attribute__((cleanup))` here.

More info on the `(void)` pattern: https://clang-analyzer.llvm.org/faq.html#dead_store
2021-02-05 12:39:07 -05:00
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
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
bbc72cbf6b core: Fix handling of local packages when downloading
In the core context, this is redundant with `sort_packages` because it
won't put local packages in the `pkgs_to_download` array anyway, but we
want this check even if we call `rpmostree_download_packages` directly
and pass some packages which may be local.
2021-02-03 12:22:38 -05:00
Jonathan Lebon
90c546c5dc core: Factor out function to download pkgs
I want to be able to use this function without an `RpmOstreeContext`.

Prep for future patch.
2021-02-03 12:22:38 -05:00
Jonathan Lebon
e85c86be79 core: Factor out function to set repos on pkgs
And use a hash table to make it more efficient.

Prep for future patch.
2021-02-03 12:22:38 -05:00
Colin Walters
d616f73539 scripts: Fix a stack use-after-free
I think this changed in a recent refactoring; basically since
we're passing this stack-allocated value to the child spawn
function we need to keep it alive.  This of course would
have been caught by Rust...

```
==672376==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc290d9440 at pc 0x55c88c318946 bp 0x7ffc290d8b10 sp 0x7ffc290d8b08
    #0 0x55c88c318945 in script_child_setup src/libpriv/rpmostree-scripts.cxx:272
    #1 0x7f92089da902  (/lib64/libglib-2.0.so.0+0x9f902)
    #2 0x7f92089de20f  (/lib64/libglib-2.0.so.0+0xa320f)
    #3 0x7f92089de52e  (/lib64/libglib-2.0.so.0+0xa352e)
    #4 0x7f92089def02 in g_spawn_async_with_pipes (/lib64/libglib-2.0.so.0+0xa3f02)
    #5 0x7f9208b7445f  (/lib64/libgio-2.0.so.0+0xab45f)
    #6 0x7f9208b736d8 in g_subprocess_launcher_spawnv (/lib64/libgio-2.0.so.0+0xaa6d8)
    #7 0x55c88c3831b9 in rpmostree_bwrap_execute src/libpriv/rpmostree-bwrap.cxx:504
    #8 0x55c88c3836df in rpmostree_bwrap_run_captured src/libpriv/rpmostree-bwrap.cxx:450
    #9 0x55c88c31b5f1 in rpmostree_run_script_in_bwrap_container src/libpriv/rpmostree-scripts.cxx:469
    #10 0x55c88c31ca9d in impl_run_rpm_script src/libpriv/rpmostree-scripts.cxx:588
    #11 0x55c88c31d22b in run_script src/libpriv/rpmostree-scripts.cxx:637
    #12 0x55c88c31d22b in rpmostree_script_run_sync src/libpriv/rpmostree-scripts.cxx:778
    #13 0x55c88c2ef830 in run_script_sync src/libpriv/rpmostree-core.cxx:3661
    #14 0x55c88c30afa6 in rpmostree_context_assemble src/libpriv/rpmostree-core.cxx:4422
    #15 0x55c88c34a9af in install_packages src/app/rpmostree-compose-builtin-tree.cxx:451
    #16 0x55c88c34c174 in impl_install_tree src/app/rpmostree-compose-builtin-tree.cxx:925
    #17 0x55c88c350f84 in rpmostree_compose_builtin_tree src/app/rpmostree-compose-builtin-tree.cxx:1421
    #18 0x55c88c276ec8 in rpmostree_handle_subcommand src/app/libmain.cxx:405
    #19 0x55c88c27827c in rpmostree_main_inner src/app/libmain.cxx:521
    #20 0x55c88c27827c in rpmostreecxx::rpmostree_main(rust::cxxbridge1::Slice<rust::cxxbridge1::Str const>) src/app/libmain.cxx:546
    #21 0x55c88c271c25 in operator() /var/srv/walters/src/github/coreos/rpm-ostree/rpmostree-cxxrs.cxx:1257
    #22 0x55c88c271c25 in trycatch<rpmostreecxx::rpmostreecxx$cxxbridge1$rpmostree_main(rust::cxxbridge1::Slice<const rust::cxxbridge1::Str>)::<lambda()>, rpmostreecxx::rpmostreecxx$cxxbridge1$rpmostree_main(rust::cxxbridge1::Slice<const rust::cxxbridge1::Str>)::<lambda(char const*)> > /var/srv/walters/src/github/coreos/rpm-ostree/rpmostree-cxxrs.cxx:997
    #23 0x55c88c271c25 in rpmostreecxx$cxxbridge1$rpmostree_main /var/srv/walters/src/github/coreos/rpm-ostree/rpmostree-cxxrs.cxx:1255
    #24 0x55c88c0468f7 in rpmostree_rust::ffi::rpmostree_main::hfedda48c684245ce rust/src/lib.rs:25
    #25 0x55c88c0468f7 in rpm_ostree::inner_main::hf078b99ca4b270aa rust/src/main.rs:9
    #26 0x55c88c0468f7 in rpm_ostree::main::hc0ca527cfaa3f556 rust/src/main.rs:28
    #27 0x55c88c046b22 in core::ops::function::FnOnce::call_once::h8567110dac55274e /var/home/walters/.rustup/toolchains/1.48-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227
    #28 0x55c88c046b22 in std::sys_common::backtrace::__rust_begin_short_backtrace::h1c67f2f52d05cfa0 /var/home/walters/.rustup/toolchains/1.48-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:137
    #29 0x55c88c045fd7 in main (/usr/bin/rpm-ostree+0xc9fd7)
    #30 0x7f92076091e1 in __libc_start_main (/lib64/libc.so.6+0x281e1)
    #31 0x55c88c045b9d in _start (/usr/bin/rpm-ostree+0xc9b9d)

Address 0x7ffc290d9440 is located in stack of thread T0 at offset 272 in frame
    #0 0x55c88c31a1af in rpmostree_run_script_in_bwrap_container src/libpriv/rpmostree-scripts.cxx:349
```
2021-02-03 04:30:23 -05:00
Colin Walters
83c7c90b83 tree-wide: Convert g_return.*if_fail to g_assert
See https://github.com/rpm-software-management/libdnf/pull/1127

Basically IMO the "return if fail" pattern is a carry-over
from C GTK+ apps where the idea is it's better to try to stumble
forward than have the app crash for the user.

In our case though, IMO we absolutely should just crash
if our assertions trip, because we're maintaining the user's
root filesystem.
2021-02-01 04:02: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
ea81a1ee6e compose: Remove unused treefile_rs parameter
Prep for further cleanup.
2021-01-26 22:25:43 +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
Jonathan Lebon
bc5a788366 core: Set _dbpath back to /usr/share/rpm after writing rpmdb
We temporarily set the rpmdb path to be an absolute path pointing under
the tmprootfs when writing the rpmdb. This throws off libsolv 0.7.17,
which learned to give the `_dbpath` macro precedence on where the rpmdb
is located:

04d4d036b2

So then the rpmdb sanity-check we do when exiting
`rpmostree_context_assemble()` breaks because it can't find the expected
packages.

Because RPM macros are in global state, there's no elegant way of
setting it just for the rpmdb write operation (short of forking), so
just fix this by setting `_dbpath` back to the correct value after we're
done writing the rpmdb.

Closes: https://github.com/coreos/fedora-coreos-tracker/issues/723
2021-01-25 23:20: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
Jonathan Lebon
40af45814c Revert "core: Allow overriding downloaded RPMs target dir"
This reverts commit 6a3e3d807d.

This isn't as useful in the implementation of a `rpm-ostree compose
extensions` because it doesn't account for locally cached repos where no
downloading happens.

Instead, just let libdnf download the packages to the default location
if it's a remote package and we'll just copy it over to the output dir.
2021-01-23 17:12:09 +01:00
Colin Walters
a4487578a7 Remove some uses of goto out
All of these cases are actually fine, but in general we
can't use `goto out` since we started using C++ exceptions
which will skip that control flow.
2021-01-21 21:01:45 -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
1c573200dd scripts: Rework /var/lib/rpm-state creation, port to new style
Move the creation of the directory up into core.

Avoid the use of `goto out` since we can't really
do this anymore with C++ exceptions in play.
2021-01-18 12:54:35 -05:00
Colin Walters
f0122a761e scripts: Use bwrap --ro-bind-data rather than mutating target
This is part of avoiding `goto out`, but is also just better
because we're not mutating the target system.
2021-01-18 12:54:35 -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
Jonathan Lebon
6a3e3d807d core: Allow overriding downloaded RPMs target dir
This will be useful for a follow-up patch which adds `rpm-ostree compose
extensions` where we'll want to download to a separate directory.
2021-01-15 19:03:42 -05:00
Colin Walters
1f76758513 testutils: Add script-shell, remove shell wrapper
Let's make it very convenient to reproduce the container
for our scripts even from inside a booted system.  Avoids
the need for a duplicate shell script implementation.
2021-01-14 17:55:40 -05:00
Colin Walters
d8076b1132 scripts: Pass script as a memfd
This avoids writing content to the target root, which is
good in general.

But more specifically this is prep for
`rpm-ostree testutils script-shell` which would operate
on the booted root (mounted read-only), in contrast
to the current default checkout that the compose path does.
2021-01-14 17:55:40 -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
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