Commit Graph

300 Commits

Author SHA1 Message Date
Colin Walters 3e30e72d33 lib: Change read_commit_detached_metadata to be nullable
Hit this while working on some Rust code.
2021-08-25 21:29:51 -04:00
Luca BRUNO 3e2360e3bb
lib/commit: automatically skip xattrs in bare-user-only mode 2021-08-24 07:56:46 +00:00
Luca BRUNO 8a5241dd6a
lib/commit: autofix permissions for bare-user-only
This tweaks commit logic to detect bare-user-only repositories and
canonicalize permissions automatically.
2021-08-20 16:11:04 +00:00
Luca BRUNO 70a8f56ce1
lib/commit: respect SOURCE_DATE_EPOCH for commit timestamp
This tweaks `ostree_repo_write_commit` so that it checks for the
envinroment variable `SOURCE_DATE_EPOCH` as a way to override
the current time, which is used as the commit timestamp.

Ref: https://reproducible-builds.org/docs/source-date-epoch/
Ref: https://reproducible-builds.org/specs/source-date-epoch/
2021-06-22 12:15:18 +00:00
Dan Nicholson c3ada6fa7a repo: Require lock type in ostree_repo_lock_pop
This simplifies the lock state management considerably since the
previously pushed type doesn't need to be tracked. Instead, 2 counters
are kept to track how many times each lock type has been pushed. When
the number of exclusive locks drops to 0, the lock transitions back to
shared.
2021-06-05 09:07:39 -06:00
Colin Walters 0f36d8c221 repo: Make locking APIs public
Doing anything even somewhat sophisticated requires this;
turns out our own `ostree prune` CLI wants this, e.g.
https://github.com/ostreedev/ostree/issues/2337

Closes: https://github.com/ostreedev/ostree/issues/2286
2021-06-05 09:00:21 -06:00
Colin Walters 9b4bffc454 repo: Ensure we set the size for regfile inline
Need to clean up the internal APIs for this.
2021-04-09 22:29:55 +00:00
Colin Walters 6f84aff0ae repo: Add ostree_repo_write_regfile
This API is push rather than pull, which makes it much more
suitable to use cases like parsing a tar file from external
code.

Now, we have a large mess in this area internally because
the original file writing code was pull based, but static
deltas hit the same problem of wanting a push API, so I added
this special `OstreeRepoBareContent` just for writing regular
files from a push API.

Eventually...I'd like to deprecate the pull based API,
and rework things so that for regular files the push API
is the default, and then `write_content_object()` would
be split up into archive/bare cases.

In this world the `ostree_repo_write_content()` API would
then need to hackily bridge pull to push and it'd be
less efficient.

Anyways for now due to this bifurcation, this API only
works on non-archive repositories, but that's fine for
now because that's what I want for the `ostree-ext-container`
bits.
2021-04-09 21:54:44 +00:00
Colin Walters fce69cdf70 repo: Add ostree_repo_write_symlink
Continuation of the addition of `ostree_repo_write_regfile_inline()`.
This will be helpful for ostree-rs-ext and importing from tar, it's
quite inefficient and awkward for small files to end up creating
a whole `GInputStream` and `GFileInfo` and etc. for small files.
2021-04-08 21:10:00 +00:00
Colin Walters 4e2a14eb0c repo: Add ostree_repo_write_regfile_inline
When working on ostree-ext and importing from tar, it's
quite inefficient and awkward for small files to end up creating
a whole `GInputStream` and `GFileInfo` and etc. for small files.

Plus the gtk-rs binding API to map from `impl Read` to Gio
https://docs.rs/gio/0.9.1/gio/struct.ReadInputStream.html
requires that the input stream is `Send` but the Rust `tar` API
isn't.

This is only 1/3 of the problem; we also need similar APIs
to directly create a symlink, and to stream large objects via
a push-based API.
2021-04-08 14:57:33 +00:00
Colin Walters 441233b51c repo: Move fsverity bits to ostree-repo-verity.c
This file will get larger when we start doing more with fsverity.
2021-01-11 14:36:40 +00:00
Colin Walters 779a901780 commit: Tighten scope of two variables
Prep for adding `-Wshadow` fixes.
2020-09-13 14:58:24 +00:00
Felix Krull d5b8929017 lib: add some missing version tags 2020-08-26 22:32:47 +02:00
Colin Walters a615d35762 pull: Add --per-object-fsync
This is the opposite of
https://github.com/ostreedev/ostree/issues/1184

Motivated by OpenShift seeing etcd performance issues during
OS updates: https://github.com/openshift/machine-config-operator/issues/1897

Basically, if we switch to invoking `fsync()` as we go, it makes
ostree performance worse (in my tests, 31s to write 2G versus 7s if we
delay sync) but it avoids *huge* outliers in `fsync()` time for etcd.
2020-07-18 14:59:01 +00:00
Jonathan Lebon 1d755f62af lib/repo: Handle EACCES for POSIX locking
If `glnx_make_lock_file` falls back to `flock`, on NFS this uses POSIX
locks (`F_SETLK`). As such, we need to be able to handle `EACCES` as
well as `EAGAIN` (see `fnctl(2)`).

I think this is what coreos-ostree-importer has been hitting, which runs
on RHEL7 in the Fedora infra and does locking over an NFS share where
multiple apps could concurrently pull things into the repo.
2020-06-30 15:09:41 -04:00
Jonathan Lebon 8ece36c28a lib/commit: Check that dirent is a directory before cleaning
I've only noticed this by inspection. But I think it's possible for
`cleanup_txn_dir` to get called with the `staging-...-lock` file since
it matches the prefix.

Make the checking here stronger by verifying that it's a directory. If
it's not a directory (lockfile), then follow the default pruning expiry
logic so that we still cleanup stray lockfiles eventually.
2020-04-17 14:29:13 -04:00
Jonathan Lebon df065ad766 lib: Rename function for staging dir check
Rename the function to more accurately reflect what it does, which is to
check whether the filename has the `staging-` prefix.
2020-04-17 14:28:20 -04:00
Jonathan Lebon bb8fd5a2c4 lib/commit: Add more error prefixing
We think we're hitting an error in that function in the Fedora infra.
Add some more error prefixing to help debugging.
2020-04-17 14:27:16 -04:00
Colin Walters b3bbbd1542 repo/commit: Add support for --selinux-policy-from-base
The [dev-overlay](332c6ab3b9/src/cmd-dev-overlay)
script shipped in coreos-assembler mostly exists to deal
with the nontrivial logic around SELinux policy.  Let's make
the use case of "commit some binaries overlaying a base tree, using
the base's selinux policy" just require a magical
`--selinux-policy-from-base` argument to `ostree commit`.

A new C API was added to implement this in the case of `--tree=ref`;
when the base directory is already checked out, we can just reuse
the existing logic that `--selinux-policy` was using.

Requires: https://github.com/ostreedev/ostree/pull/2039
2020-03-24 16:34:26 +00:00
OpenShift Merge Robot 96fb1decf4
Merge pull request #1959 from cgwalters/ostree-verity
Initial fs-verity support
2020-01-28 13:01:40 -08:00
Colin Walters 58fa579b1b Initial fs-verity support
Using fs-verity is natural for OSTree because it's file-based,
as opposed to block based (like dm-verity).  This only covers
files - not symlinks or directories.  And we clearly need to
have integrity for the deployment directories at least.

Also, what we likely need is an API that supports signing files
as they're committed.

So making this truly secure would need a lot more work.  Nevertheless,
I think it's time to start experimenting with it.  Among other things,
it does *finally* add an API that makes files immutable, which will
help against some accidental damage.

This is basic enablement work that is being driven by
Fedora CoreOS; see also https://github.com/coreos/coreos-assembler/pull/876
2020-01-27 15:44:16 +00:00
Dan Nicholson 1bbe674d91 libarchive: Support commit sizes metadata
Call the helper to set the generate_sizes boolean so that object size
data is stored while writing the mtree.
2020-01-20 20:42:27 -07:00
John Hiesey 291e9da258 lib/commit: Include object type in sizes metadata
Append a byte encoding the OSTree object type for each object in the
metadata. This allows the commit metadata to be fetched and then for the
program to see which objects it already has for an accurate calculation
of which objects need to be downloaded.

This slightly breaks the `ostree.sizes` `ay` metadata entries. However,
it's unlikely anyone was asserting the length of the entries since the
array currently ends in 2 variable length integers. As far as I know,
the only users of the sizes metadata are the ostree test suite and
Endless' eos-updater[1]. The former is updated here and the latter
already expects this format.

1. https://github.com/endlessm/eos-updater/
2020-01-20 20:42:27 -07:00
Dan Nicholson a4592678aa tests/sizes: Check duplicate file doesn't add sizes entry
A duplicate file will resolve to the same object, so it shouldn't add
any entries to the sizes metadata.
2020-01-20 20:42:27 -07:00
Dan Nicholson 44fb5e72a1 lib/commit: Make size entries for existing objects
If the object was already in the repo then the sizes metadata entry was
skipped. Move the sizes entry creation after the data has been computed
but before the early return for an existing object.
2020-01-20 20:42:27 -07:00
Dan Nicholson 8ec7d6322f lib/commit: Fix object sizes metadata for multiple commits
The object sizes hash table was only being cleared when the repo was
finalized. That means that performing multiple commits while the repo
was open would reuse all the object sizes metadata for each commit.

Clear the hash table when the sizes metadata is setup and when it's
added to a commit. This still does not fix the issue all the way since
it does nothing to prevent the program from constructing multiple
commits simultaneously. To handle that, the object sizes hash table
should be attached to the MutableTree since that has the commit state.
However, the MutableTree is gone when the commit is actually created.
The hash table would have to be transferred to the root file when
writing the MutableTree. That would be an awkward addition to
OstreeRepoFile, though. Add a FIXME to capture that.
2020-01-20 20:42:27 -07:00
Dan Nicholson 37045b4b46 lib/commit: Only set generate_sizes for archive repos
Rather than checking throughout the code, only set the boolean when
appropriate.
2020-01-20 20:42:27 -07:00
Colin Walters bc1980ca38 lib/repo: [scan-build] Quiet a dead store warning
False positive, just add a pacifier.
2019-10-18 15:07:39 +00:00
Colin Walters 806206fac2 repo: [scan-build]: Mark a variable used
We're just using this to auto-free, quiet the static analysis.
2019-10-15 12:41:27 +00:00
Jason Wessel b709c3c67b fsck: Implement a partial commit reason bitmask
After the corruption has been fixed with "ostree fsck -a --delete", a
second run of the "ostree fsck" command will print X partial commits
not verified and exit with a zero.

The zero exit code makes it hard to detect if a repair operation needs
to be run.  When ever fsck creates a partial commit it should add a
reason for the partial commit to the state file found in
state/<hash>.commitpartial.  This will allow a future execution of the
fsck to still return an error indicating that the repository is still
in the damaged state, awaiting repair.

Additional reason codes could be added in the future for why a partial
commit exists.

Text from: https://github.com/ostreedev/ostree/pull/1880
====
cgwalters commented:

To restate, the core issue is that it's valid to have partial commits
for reasons other than fsck pruned bad objects, and libostree doesn't
have a way to distinguish.

Another option perhaps is to write e.g. fsck-partial into the
statefile state/<hash>.commitpartial which would mean "partial, and
expected to exist but was pruned by fsck" and fsck would continue to
error out until the commit was re-pulled. Right now the partial stamp
file is empty, so it'd be fully compatible to write a rationale into
it.
====

Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

Closes: #1910
Approved by: cgwalters
2019-09-09 13:40:36 +00:00
Felix Krull e607e79f4e lib: add minimum version to various symbols based on libostree-released.sym
Closes: #1861
Approved by: cgwalters
2019-05-19 14:50:08 +00:00
Colin Walters 6649032a37 lib/commit: Don't set user.ostreemeta for bare → bare-user-only imports
The point of `bare-user-only` is it doesn't have xattrs; it's a
special case in import handling.

Closes: #1803
Approved by: jlebon
2019-01-16 14:37:15 +00:00
Colin Walters c63ee3cef4 lib/commit: Set xattr on correct fd for bare-user → bare-user imports
Another fix to https://github.com/ostreedev/ostree/pull/1771

Closes: #1803
Approved by: jlebon
2019-01-16 14:37:15 +00:00
Colin Walters c79d792fd5 lib/commit: Fix bare → bare imports
Regression from https://github.com/ostreedev/ostree/pull/1771

This broke rpmostreepayload in Anaconda where we import a bare repo:
https://openqa.fedoraproject.org/tests/345339#step/_do_install_and_reboot/4

Reported-by: Adam Williamson <adamwill@fedoraproject.org>

Closes: #1803
Approved by: jlebon
2019-01-16 14:37:15 +00:00
Umang Jain 963395217a lib/repo-commit: Relax min-free-space check in prepare_transaction()
We want a case where we can disable the min-free-space check. Initially,
it felt like to add a OSTREE_REPO_PULL_FLAGS_DISABLE_FREE_SPACE_CHECK but
the problem is prepare_transaction() does not have a OstreeRepoPullFlags
parameter which we can parse right here. On top of it, prepare_transaction()
enforces min-free-space check and won't let the transaction proceed if
the check failed.

This is pretty bad in conjunction with "inherit-transaction" as what
Flatpak uses. There is no way to disable this check unless we remove
it altogether from prepare_transaction.

This issue came out to light when flatpak wasn't able to write metadata
after fetching from remote:

[uajain@localhost ~]$ flatpak remote-info flathub org.kde.Platform//5.9
error: min-free-space-size 500MB would be exceeded

Metadata objects helps in housekeeping and restricting them means
restricting crucial UX (like search, new updates) functionalities
in clients like gnome-software. The error banners originated from
these issues are also abrupt and not much helpful to the user. This
is the specific instance of the issue this patches tries to address.

See https://github.com/flatpak/flatpak/issues/2139 for discussion.

Closes: #1779
Approved by: mwleeds
2018-12-10 20:04:17 +00:00
Colin Walters dc2a7de217 lib/commit: Try checksum+hardlink for untrusted local same-uid repos
This mainly helps flatpak for enabling a hardlink-able local pull
during deploy in the --system case.  We assume the files are immutable
when owned by the same uid.

See https://github.com/ostreedev/ostree/issues/1723
and https://github.com/flatpak/flatpak/pull/2342

Closes: #1776
Approved by: uajain
2018-12-04 20:38:41 +00:00
Jonathan Lebon 244d9a7ec1 lib/commit: Copy user.ostreemeta only for bare-user
When falling back to copying objects when importing them into a
bare-user repo, we only actually need to transfer over the
`user.ostreemeta` xattr.

This allows the destination repo to be on a separate filesystem that
might not even support `security.selinux`. (I hit this while importing
over virtio-9p).

Closes: #1771
Approved by: cgwalters
2018-11-13 15:15:13 +00:00
Jonathan Lebon 8eac5be030 lib/commit: Add devino_cache_hits to txn stats
I found this useful while hacking on rpm-ostree but I think it might be
useful enough to upstream. This stat is really helpful for validating
that a pipeline is hitting the devino cache sweet spot.

Closes: #1772
Approved by: cgwalters
2018-11-05 14:08:54 +00:00
Dan Nicholson 43d9cac4fc lib/commit: Don't chown objects to repo target owner
The idea is that if the process is running as root, it can change
ownership of newly written files to match the owner of the repo.
Unfortunately, it currently applies in the other direction, too - a
non-root user writing to a root owned repository. If the repo is
writable by the user but owned by root, it can still create files and
directories there, but it can't change ownership of them.

This feature comes from
https://bugzilla.gnome.org/show_bug.cgi?id=738954. As it turns out, this
feature was never completed. It only works on content objects and not
metadata objects, refs, deltas, summaries, etc. Rather than try to fix
all of those, remove the feature until someone has interest in
completing it.

Closes: #1754
Approved by: cgwalters
2018-10-12 12:34:57 +00:00
Colin Walters 2c55bc6997 Only verify OSTREE_MAX_METADATA_SIZE for HTTP fetches
There are use cases for libostree as a local content store
for content derived or delivered via other mechanisms (e.g. OCI
images, RPMs, etc.).  rpm-ostree today imports RPMs into OSTree
branches, and puts the RPM header value as commit metadata.
Some of these can be quite large because the header includes
permissions for each file.  Similarly, some OCI metadata is large.

Since there's no security issues with this, support committing
such content.

We still by default limit the size of metadata fetches, although
for good measure we make this configurable too via a new
`max-metadata-size` value.

Closes: https://github.com/ostreedev/ostree/issues/1721

Closes: #1744
Approved by: jlebon
2018-10-01 13:23:50 +00:00
Colin Walters c141fe610b lib/commit: Don't copy xattrs for metadata objects
Copying the xattrs on metadata objects is wrong in general, we
don't "own" them.  Notably this would fail in the situation of
doing a pull from e.g. a `bare-user` source to a destination
that was on a different mount point (so we couldn't hardlink),
and the source had e.g. a `security.selinux` attribute.

Closes: #1734

Closes: #1736
Approved by: jlebon
2018-09-25 14:49:22 +00:00
Umang Jain a0937b6cf0 lib/repo: Separate min-free-space-* calculation from transaction codepath
Earlier, the actual reserved space (in blocks) were calculated inside the
transaction codepath ostree_repo_prepare_transaction(). However, while
reworking on ostree_repo_get_min_free_space_bytes() API, it was realized that
this calculation can be done independently from the transaction's codepaths, hence
enabling the usage for ostree_repo_get_min_free_space_bytes() API irrespective
of whether there is an ongoing transaction or not.

https://github.com/ostreedev/ostree/issues/1720

Closes: #1722
Approved by: pwithnall
2018-09-21 15:09:12 +00:00
Umang Jain 3814d075cb lib/repo: Ensure min-free-space* config value doesn't overflow
when converted to bytes

In a subsequent commit, we add a public API to read the value of
min-free-space-* value in bytes. The value for free space check
is enforced in terms of block size instead of bytes. Therefore,
for consistency we check while preparing the transaction that the
value doesn't overflow when converted to bytes.

https://phabricator.endlessm.com/T23694

Closes: #1715
Approved by: cgwalters
2018-09-04 21:31:33 +00:00
Jonathan Lebon 521e0ec3ac lib/commit: Only auto-update summary if refs were written
Closes: #1693
Approved by: mwleeds
2018-08-01 19:59:07 +00:00
Jonathan Lebon 786ee6bdec lib/config: Rename change-update-summary to auto-...
Mildly bikeshed, though I find the name `auto-update-summary` to be
easier to grok than `change-update-summary`. I think it's because it can
be read as "verb-verb-noun" rather than "noun-verb-noun".

Closes: #1693
Approved by: mwleeds
2018-08-01 19:59:07 +00:00
Matthew Leeds 6869bada49 config: Add a core/change-update-summary option
This commits adds and implements a boolean repo config option called
"change-update-summary" which updates the summary file every time a ref
changes (additions, updates, and deletions).

The main impetus for this feature is that the `ostree create-usb` and
`flatpak create-usb` commands depend on the repo summary being up to
date. On the command line you can work around this by asking the user to
run `ostree summary --update` but in the case of GNOME Software calling
out to `flatpak create-usb` this wouldn't work because it's running as a
user and the repo is owned by root. That strategy also means flatpak
can't update the repo metadata refs for fear of invalidating the
summary.

Another use case for this relates to LAN updates. Specifically, the
component of eos-updater that generates DNS-SD records advertising ostree
refs depends on the repo summary being up to date.

Since ostree_repo_regenerate_summary() now takes an exclusive lock, this
should be safe to enable. However it's not enabled by default because of
the performance cost, and because it's more useful on clients than
servers (which likely have another mechanism for updating the summary).

Fixes https://github.com/ostreedev/ostree/issues/1664

Closes: #1681
Approved by: jlebon
2018-07-30 17:19:12 +00:00
Jonathan Lebon 9482922e5e lib: Check for NULL pointers in some more places
In `write_metadata_object()`, make sure when creating tombstone commits
that we're actually passed an expected checksum to use.

In `write_dir_entry_to_mtree_internal()`, sanity check that `dfd_iter`
is indeed not `NULL` before trying to dereference it.

Discovered by Coverity.

Closes: #1692
Approved by: cgwalters
2018-07-26 21:01:19 +00:00
Matthew Leeds be07c04e63 lib/repo-commit: Fix min-free-space error message
Since min_free_space_size_mb is considered before min_free_space_percent
in min_free_space_calculate_reserved_blocks(), it has to be considered
first when generating the error message in order for it to be accurate.

Closes: #1691
Approved by: jlebon
2018-07-25 13:16:18 +00:00
William Manley c7b12a8730 ostree repo commit: Speed up composing trees with `--tree=ref`
Running `ostree commit --tree=ref=a --tree=dir=b` involves reading the
whole of a into an `OstreeMutableTree` before composing `b` on top.  This
is inefficient if a is a complete rootfs and b is just touching one file.
We process O(size of a + size of b) directories rather than
O(number of touched dirs).

This commit makes `ostree commit` more efficient at composing multiple
directories together.  With `ostree_mutable_tree_fill_empty_from_dirtree`
we create a lazy `OstreeMutableTree` which only reads the underlying
information from disk when needed.  We don't need to read all the
subdirectories just to get the checksum of a tree already checked into the
repo.

This provides great speedups when composing a rootfs out of multiple other
rootfs as we do in our build system.  We compose multiple containers
together with:

    ostree commit --tree=ref=base-rootfs --tree=ref=container1 --tree=ref=container2

and it is much faster now.

As a test I ran

    time ostree --repo=... commit --orphan --tree=ref=big-rootfs --tree=dir=modified_etc

Where modified_etc contained a modified sudoers file under /etc.  I used
`strace` to count syscalls and I seperatly took timing measurements.  To
test with a cold cache I ran

    sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Results:

|                      | Before | After |
| -------------------- | ------ | ----- |
| Time (cold cache)    |   8.1s | 0.12s |
| Time (warm cache)    |   3.7s | 0.08s |
| `openat` calls       |  53589 |   246 |
| `fgetxattr` calls    |  78916 |     0 |

I'm not sure if this will have some negative interaction with the
`_ostree_repo_commit_modifier_apply` which is short-circuited here.  I
think it was disabled for `--tree=ref=` anyway, but I'm not certain.  All
the tests pass anyway.

I originally implemented this in terms of the `OstreeRepoFile` APIs, but
it was *way* less efficient, opening and reading many files unnecessarily.

Closes: #1643
Approved by: cgwalters
2018-07-09 13:10:51 +00:00
Umang Jain 4c023a9585 lib/repo-commit: Factor out min-free-space-size error reporting
Improves code readability.

Closes: #1671
Approved by: jlebon
2018-07-06 19:59:10 +00:00