New upstream version 2018.9.1
This commit is contained in:
commit
854d02fbe3
|
|
@ -39,7 +39,10 @@ endif
|
|||
|
||||
if BUILDOPT_SYSTEMD
|
||||
systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
|
||||
src/boot/ostree-remount.service src/boot/ostree-finalize-staged.service
|
||||
src/boot/ostree-remount.service \
|
||||
src/boot/ostree-finalize-staged.service \
|
||||
src/boot/ostree-finalize-staged.path \
|
||||
$(NULL)
|
||||
systemdtmpfilesdir = $(prefix)/lib/tmpfiles.d
|
||||
dist_systemdtmpfiles_DATA = src/boot/ostree-tmpfiles.conf
|
||||
|
||||
|
|
@ -64,6 +67,7 @@ EXTRA_DIST += src/boot/dracut/module-setup.sh \
|
|||
src/boot/dracut/ostree.conf \
|
||||
src/boot/mkinitcpio/ostree \
|
||||
src/boot/ostree-prepare-root.service \
|
||||
src/boot/ostree-finalize-staged.path \
|
||||
src/boot/ostree-remount.service \
|
||||
src/boot/ostree-finalize-staged.service \
|
||||
src/boot/grub2/grub2-15_ostree \
|
||||
|
|
|
|||
|
|
@ -2075,6 +2075,7 @@ EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \
|
|||
src/boot/dracut/module-setup.sh src/boot/dracut/ostree.conf \
|
||||
src/boot/mkinitcpio/ostree \
|
||||
src/boot/ostree-prepare-root.service \
|
||||
src/boot/ostree-finalize-staged.path \
|
||||
src/boot/ostree-remount.service \
|
||||
src/boot/ostree-finalize-staged.service \
|
||||
src/boot/grub2/grub2-15_ostree \
|
||||
|
|
@ -2764,7 +2765,10 @@ tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
|
|||
@BUILDOPT_MKINITCPIO_TRUE@mkinitcpioconfdir = $(sysconfdir)
|
||||
@BUILDOPT_MKINITCPIO_TRUE@mkinitcpioconf_DATA = src/boot/mkinitcpio/ostree-mkinitcpio.conf
|
||||
@BUILDOPT_SYSTEMD_TRUE@systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
|
||||
@BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-remount.service src/boot/ostree-finalize-staged.service
|
||||
@BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-remount.service \
|
||||
@BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-finalize-staged.service \
|
||||
@BUILDOPT_SYSTEMD_TRUE@ src/boot/ostree-finalize-staged.path \
|
||||
@BUILDOPT_SYSTEMD_TRUE@ $(NULL)
|
||||
|
||||
@BUILDOPT_SYSTEMD_TRUE@systemdtmpfilesdir = $(prefix)/lib/tmpfiles.d
|
||||
@BUILDOPT_SYSTEMD_TRUE@dist_systemdtmpfiles_DATA = src/boot/ostree-tmpfiles.conf
|
||||
|
|
|
|||
16
README.md
16
README.md
|
|
@ -74,6 +74,22 @@ The [BuildStream](https://gitlab.com/BuildStream/buildstream) build and
|
|||
integration tool uses libostree as a caching system to store and share
|
||||
built artifacts.
|
||||
|
||||
Language bindings
|
||||
----
|
||||
|
||||
libostree is accessible via [GObject Introspection](https://gi.readthedocs.io/en/latest/);
|
||||
any language which has implemented the GI binding model should work.
|
||||
For example, Both [pygobject](https://pygobject.readthedocs.io/en/latest/)
|
||||
and [gjs](https://gitlab.gnome.org/GNOME/gjs) are known to work
|
||||
and further are actually used in libostree's test suite today.
|
||||
|
||||
Some bindings take the approach of using GI as a lower level and
|
||||
write higher level manual bindings on top; this is more common
|
||||
for statically compiled languages. Here's a list of such bindings:
|
||||
|
||||
- [ostree-go](https://github.com/ostreedev/ostree-go/)
|
||||
- [rust-libostree](https://gitlab.com/fkrull/rust-libostree/)
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
|
|
|
|||
|
|
@ -2420,17 +2420,17 @@ ostree_check_version (<em class="parameter"><code><span class="type">guint</span
|
|||
<a name="OSTREE-MAX-METADATA-SIZE:CAPS"></a><h3>OSTREE_MAX_METADATA_SIZE</h3>
|
||||
<pre class="programlisting">#define OSTREE_MAX_METADATA_SIZE (10 * 1024 * 1024)
|
||||
</pre>
|
||||
<p>Maximum permitted size in bytes of metadata objects. This is an
|
||||
arbitrary number, but really, no one should be putting humongous
|
||||
data in metadata.</p>
|
||||
<p>Default limit for maximum permitted size in bytes of metadata objects fetched
|
||||
over HTTP (including repo/config files, refs, and commit/dirtree/dirmeta
|
||||
objects). This is an arbitrary number intended to mitigate disk space
|
||||
exhaustion attacks.</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="OSTREE-MAX-METADATA-WARN-SIZE:CAPS"></a><h3>OSTREE_MAX_METADATA_WARN_SIZE</h3>
|
||||
<pre class="programlisting">#define OSTREE_MAX_METADATA_WARN_SIZE (7 * 1024 * 1024)
|
||||
</pre>
|
||||
<p>Objects committed above this size will be allowed, but a warning
|
||||
will be emitted.</p>
|
||||
<p>This variable is no longer meaningful, it is kept only for compatibility.</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@
|
|||
<span class="returnvalue">gboolean</span>
|
||||
</td>
|
||||
<td class="function_name">
|
||||
<a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-remove" title="ostree_mutable_tree_remove ()">ostree_mutable_tree_remove</a> <span class="c_punctuation">()</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="function_type">
|
||||
<span class="returnvalue">gboolean</span>
|
||||
</td>
|
||||
<td class="function_name">
|
||||
<a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-ensure-dir" title="ostree_mutable_tree_ensure_dir ()">ostree_mutable_tree_ensure_dir</a> <span class="c_punctuation">()</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -307,6 +315,52 @@ ostree_mutable_tree_replace_file (<em class="parameter"><code><a class="link" hr
|
|||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-mutable-tree-remove"></a><h3>ostree_mutable_tree_remove ()</h3>
|
||||
<pre class="programlisting"><span class="returnvalue">gboolean</span>
|
||||
ostree_mutable_tree_remove (<em class="parameter"><code><a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#OstreeMutableTree" title="OstreeMutableTree"><span class="type">OstreeMutableTree</span></a> *self</code></em>,
|
||||
<em class="parameter"><code>const <span class="type">char</span> *name</code></em>,
|
||||
<em class="parameter"><code><span class="type">gboolean</span> allow_noent</code></em>,
|
||||
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
|
||||
<p>Remove the file or subdirectory named <em class="parameter"><code>name</code></em>
|
||||
from the mutable tree <em class="parameter"><code>self</code></em>
|
||||
.</p>
|
||||
<div class="refsect3">
|
||||
<a name="ostree-mutable-tree-remove.parameters"></a><h4>Parameters</h4>
|
||||
<div class="informaltable"><table class="informaltable" width="100%" border="0">
|
||||
<colgroup>
|
||||
<col width="150px" class="parameters_name">
|
||||
<col class="parameters_description">
|
||||
<col width="200px" class="parameters_annotations">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="parameter_name"><p>self</p></td>
|
||||
<td class="parameter_description"><p>Tree</p></td>
|
||||
<td class="parameter_annotations"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="parameter_name"><p>name</p></td>
|
||||
<td class="parameter_description"><p>Name of file or subdirectory to remove</p></td>
|
||||
<td class="parameter_annotations"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="parameter_name"><p>allow_noent</p></td>
|
||||
<td class="parameter_description"><p>If <em class="parameter"><code>FALSE</code></em>
|
||||
, an error will be thrown if <em class="parameter"><code>name</code></em>
|
||||
does not exist in the tree</p></td>
|
||||
<td class="parameter_annotations"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="parameter_name"><p>error</p></td>
|
||||
<td class="parameter_description"><p>a <span class="type">GError</span></p></td>
|
||||
<td class="parameter_annotations"> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-mutable-tree-ensure-dir"></a><h3>ostree_mutable_tree_ensure_dir ()</h3>
|
||||
<pre class="programlisting"><span class="returnvalue">gboolean</span>
|
||||
ostree_mutable_tree_ensure_dir (<em class="parameter"><code><a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#OstreeMutableTree" title="OstreeMutableTree"><span class="type">OstreeMutableTree</span></a> *self</code></em>,
|
||||
|
|
|
|||
|
|
@ -153,6 +153,14 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="function_type">
|
||||
<span class="returnvalue">gboolean</span>
|
||||
</td>
|
||||
<td class="function_name">
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-min-free-space-bytes" title="ostree_repo_get_min_free_space_bytes ()">ostree_repo_get_min_free_space_bytes</a> <span class="c_punctuation">()</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="function_type">
|
||||
<span class="returnvalue">GKeyFile</span> *
|
||||
</td>
|
||||
<td class="function_name">
|
||||
|
|
@ -168,6 +176,13 @@
|
|||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="function_type">const <span class="returnvalue">gchar</span> * const *
|
||||
</td>
|
||||
<td class="function_name">
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-default-repo-finders" title="ostree_repo_get_default_repo_finders ()">ostree_repo_get_default_repo_finders</a> <span class="c_punctuation">()</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="function_type">
|
||||
<span class="returnvalue">guint</span>
|
||||
</td>
|
||||
|
|
@ -1209,16 +1224,18 @@
|
|||
<a name="ostree-OstreeRepo.description"></a><h2>Description</h2>
|
||||
<p>The <a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> is like git, a content-addressed object store.
|
||||
Unlike git, it records uid, gid, and extended attributes.</p>
|
||||
<p>There are three possible "modes" for an <a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a>;
|
||||
<a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-BARE:CAPS"><code class="literal">OSTREE_REPO_MODE_BARE</code></a> is very simple - content files are
|
||||
represented exactly as they are, and checkouts are just hardlinks.
|
||||
<a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-BARE-USER:CAPS"><code class="literal">OSTREE_REPO_MODE_BARE_USER</code></a> is similar, except the uid/gids are not
|
||||
set on the files, and checkouts as hardlinks hardlinks work only for user checkouts.
|
||||
A <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-ARCHIVE-Z2:CAPS"><code class="literal">OSTREE_REPO_MODE_ARCHIVE_Z2</code></a> repository in contrast stores
|
||||
<p>There are four possible "modes" for an <a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a>; <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-BARE:CAPS"><code class="literal">OSTREE_REPO_MODE_BARE</code></a>
|
||||
is very simple - content files are represented exactly as they are, and
|
||||
checkouts are just hardlinks. <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-BARE-USER:CAPS"><code class="literal">OSTREE_REPO_MODE_BARE_USER</code></a> is similar, except
|
||||
the uid/gids are not set on the files, and checkouts as hardlinks work only
|
||||
for user checkouts. <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-BARE-USER-ONLY:CAPS"><code class="literal">OSTREE_REPO_MODE_BARE_USER_ONLY</code></a> is the same as
|
||||
BARE_USER, but all metadata is not stored, so it can only be used for user
|
||||
checkouts. This mode does not require xattrs. A <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-ARCHIVE:CAPS"><code class="literal">OSTREE_REPO_MODE_ARCHIVE</code></a>
|
||||
(also known as <a class="link" href="ostree-OstreeRepo.html#OSTREE-REPO-MODE-ARCHIVE-Z2:CAPS"><code class="literal">OSTREE_REPO_MODE_ARCHIVE_Z2</code></a>) repository in contrast stores
|
||||
content files zlib-compressed. It is suitable for non-root-owned
|
||||
repositories that can be served via a static HTTP server.</p>
|
||||
<p>Creating an <a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> does not invoke any file I/O, and thus needs
|
||||
to be initialized, either from an existing contents or with a new
|
||||
to be initialized, either from existing contents or as a new
|
||||
repository. If you have an existing repo, use <a class="link" href="ostree-OstreeRepo.html#ostree-repo-open" title="ostree_repo_open ()"><code class="function">ostree_repo_open()</code></a>
|
||||
to load it from disk and check its validity. To initialize a new
|
||||
repository in the given filepath, use <a class="link" href="ostree-OstreeRepo.html#ostree-repo-create" title="ostree_repo_create ()"><code class="function">ostree_repo_create()</code></a> instead.</p>
|
||||
|
|
@ -1664,6 +1681,14 @@ ostree_repo_get_mode (<em class="parameter"><code><a class="link" href="ostree-O
|
|||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-repo-get-min-free-space-bytes"></a><h3>ostree_repo_get_min_free_space_bytes ()</h3>
|
||||
<pre class="programlisting"><span class="returnvalue">gboolean</span>
|
||||
ostree_repo_get_min_free_space_bytes (<em class="parameter"><code><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>,
|
||||
<em class="parameter"><code><span class="type">guint64</span> *out_reserved_bytes</code></em>,
|
||||
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-repo-get-config"></a><h3>ostree_repo_get_config ()</h3>
|
||||
<pre class="programlisting"><span class="returnvalue">GKeyFile</span> *
|
||||
ostree_repo_get_config (<em class="parameter"><code><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>);</pre>
|
||||
|
|
@ -1705,6 +1730,35 @@ repository (to see whether a ref was written).</p>
|
|||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-repo-get-default-repo-finders"></a><h3>ostree_repo_get_default_repo_finders ()</h3>
|
||||
<pre class="programlisting">const <span class="returnvalue">gchar</span> * const *
|
||||
ostree_repo_get_default_repo_finders (<em class="parameter"><code><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>);</pre>
|
||||
<p>Get the set of default repo finders configured. See the documentation for
|
||||
the "core.default-repo-finders" config key.</p>
|
||||
<div class="refsect3">
|
||||
<a name="ostree-repo-get-default-repo-finders.parameters"></a><h4>Parameters</h4>
|
||||
<div class="informaltable"><table class="informaltable" width="100%" border="0">
|
||||
<colgroup>
|
||||
<col width="150px" class="parameters_name">
|
||||
<col class="parameters_description">
|
||||
<col width="200px" class="parameters_annotations">
|
||||
</colgroup>
|
||||
<tbody><tr>
|
||||
<td class="parameter_name"><p>self</p></td>
|
||||
<td class="parameter_description"><p>an <a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a></p></td>
|
||||
<td class="parameter_annotations"> </td>
|
||||
</tr></tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="refsect3">
|
||||
<a name="ostree-repo-get-default-repo-finders.returns"></a><h4>Returns</h4>
|
||||
<p><code class="literal">NULL</code>-terminated array of strings. </p>
|
||||
<p><span class="annotation">[<a href="http://foldoc.org/array"><span class="acronym">array</span></a> zero-terminated=1][<a href="http://foldoc.org/element-type"><span class="acronym">element-type</span></a> utf8]</span></p>
|
||||
</div>
|
||||
<p class="since">Since: 2018.9</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="refsect2">
|
||||
<a name="ostree-repo-hash"></a><h3>ostree_repo_hash ()</h3>
|
||||
<pre class="programlisting"><span class="returnvalue">guint</span>
|
||||
ostree_repo_hash (<em class="parameter"><code><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>);</pre>
|
||||
|
|
@ -7111,6 +7165,7 @@ string to pull the latest commit for that ref</p></li>
|
|||
<li class="listitem"><p>require-static-deltas (b): Require static deltas</p></li>
|
||||
<li class="listitem"><p>override-commit-ids (as): Array of specific commit IDs to fetch for refs</p></li>
|
||||
<li class="listitem"><p>timestamp-check (b): Verify commit timestamps are newer than current (when pulling via ref); Since: 2017.11</p></li>
|
||||
<li class="listitem"><p>metadata-size-restriction (t): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9</p></li>
|
||||
<li class="listitem"><p>dry-run (b): Only print information on what will be downloaded (requires static deltas)</p></li>
|
||||
<li class="listitem"><p>override-url (s): Fetch objects from this URL if remote specifies no metalink in options</p></li>
|
||||
<li class="listitem"><p>inherit-transaction (b): Don't initiate, finish or abort a transaction, useful to do multiple pulls in one transaction.</p></li>
|
||||
|
|
@ -8127,7 +8182,8 @@ by <a class="link" href="ostree-OstreeRepo.html#ostree-repo-load-commit" title="
|
|||
gboolean no_copy_fallback;
|
||||
gboolean force_copy; /* Since: 2017.6 */
|
||||
gboolean bareuseronly_dirs; /* Since: 2017.7 */
|
||||
gboolean unused_bools[5];
|
||||
gboolean force_copy_zerosized; /* Since: 2018.9 */
|
||||
gboolean unused_bools[4];
|
||||
/* 4 byte hole on 64 bit */
|
||||
|
||||
const char *subpath;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,10 @@
|
|||
<keyword type="function" name="ostree_repo_create ()" link="ostree-OstreeRepo.html#ostree-repo-create"/>
|
||||
<keyword type="function" name="ostree_repo_get_path ()" link="ostree-OstreeRepo.html#ostree-repo-get-path"/>
|
||||
<keyword type="function" name="ostree_repo_get_mode ()" link="ostree-OstreeRepo.html#ostree-repo-get-mode"/>
|
||||
<keyword type="function" name="ostree_repo_get_min_free_space_bytes ()" link="ostree-OstreeRepo.html#ostree-repo-get-min-free-space-bytes"/>
|
||||
<keyword type="function" name="ostree_repo_get_config ()" link="ostree-OstreeRepo.html#ostree-repo-get-config"/>
|
||||
<keyword type="function" name="ostree_repo_get_dfd ()" link="ostree-OstreeRepo.html#ostree-repo-get-dfd"/>
|
||||
<keyword type="function" name="ostree_repo_get_default_repo_finders ()" link="ostree-OstreeRepo.html#ostree-repo-get-default-repo-finders" since="2018.9"/>
|
||||
<keyword type="function" name="ostree_repo_hash ()" link="ostree-OstreeRepo.html#ostree-repo-hash" since="2017.12"/>
|
||||
<keyword type="function" name="ostree_repo_equal ()" link="ostree-OstreeRepo.html#ostree-repo-equal" since="2017.12"/>
|
||||
<keyword type="function" name="ostree_repo_copy_config ()" link="ostree-OstreeRepo.html#ostree-repo-copy-config"/>
|
||||
|
|
@ -246,6 +248,7 @@
|
|||
<keyword type="function" name="ostree_mutable_tree_set_contents_checksum ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-set-contents-checksum"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_get_contents_checksum ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-get-contents-checksum"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_replace_file ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-replace-file"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_remove ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-remove"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_ensure_dir ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-ensure-dir"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_lookup ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-lookup"/>
|
||||
<keyword type="function" name="ostree_mutable_tree_ensure_parent_dirs ()" link="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-ensure-parent-dirs"/>
|
||||
|
|
|
|||
|
|
@ -539,6 +539,10 @@ ostree_collection_ref_new, function in ostree-ref
|
|||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
OSTREE_META_KEY_DEPLOY_COLLECTION_ID, macro in ostree-repo-experimental
|
||||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#OstreeMutableTree" title="OstreeMutableTree">OstreeMutableTree</a>, typedef in <a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html" title="In-memory modifiable filesystem tree">In-memory modifiable filesystem tree</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
|
|
@ -587,6 +591,10 @@ ostree_collection_ref_new, function in ostree-ref
|
|||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-remove" title="ostree_mutable_tree_remove ()">ostree_mutable_tree_remove</a>, function in <a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html" title="In-memory modifiable filesystem tree">In-memory modifiable filesystem tree</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html#ostree-mutable-tree-replace-file" title="ostree_mutable_tree_replace_file ()">ostree_mutable_tree_replace_file</a>, function in <a class="link" href="ostree-In-memory-modifiable-filesystem-tree.html" title="In-memory modifiable filesystem tree">In-memory modifiable filesystem tree</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
|
|
@ -1022,6 +1030,10 @@ ostree_repo_get_collection_id, function in ostree-misc-experimental
|
|||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-default-repo-finders" title="ostree_repo_get_default_repo_finders ()">ostree_repo_get_default_repo_finders</a>, function in <a class="link" href="ostree-OstreeRepo.html" title="OstreeRepo: Content-addressed object store">OstreeRepo</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-dfd" title="ostree_repo_get_dfd ()">ostree_repo_get_dfd</a>, function in <a class="link" href="ostree-OstreeRepo.html" title="OstreeRepo: Content-addressed object store">OstreeRepo</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
|
|
@ -1030,6 +1042,10 @@ ostree_repo_get_collection_id, function in ostree-misc-experimental
|
|||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-min-free-space-bytes" title="ostree_repo_get_min_free_space_bytes ()">ostree_repo_get_min_free_space_bytes</a>, function in <a class="link" href="ostree-OstreeRepo.html" title="OstreeRepo: Content-addressed object store">OstreeRepo</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
<dt>
|
||||
<a class="link" href="ostree-OstreeRepo.html#ostree-repo-get-mode" title="ostree_repo_get_mode ()">ostree_repo_get_mode</a>, function in <a class="link" href="ostree-OstreeRepo.html" title="OstreeRepo: Content-addressed object store">OstreeRepo</a>
|
||||
</dt>
|
||||
<dd></dd>
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ ostree_mutable_tree_get_metadata_checksum
|
|||
ostree_mutable_tree_set_contents_checksum
|
||||
ostree_mutable_tree_get_contents_checksum
|
||||
ostree_mutable_tree_replace_file
|
||||
ostree_mutable_tree_remove
|
||||
ostree_mutable_tree_ensure_dir
|
||||
ostree_mutable_tree_lookup
|
||||
ostree_mutable_tree_ensure_parent_dirs
|
||||
|
|
@ -294,8 +295,10 @@ ostree_repo_create_at
|
|||
ostree_repo_create
|
||||
ostree_repo_get_path
|
||||
ostree_repo_get_mode
|
||||
ostree_repo_get_min_free_space_bytes
|
||||
ostree_repo_get_config
|
||||
ostree_repo_get_dfd
|
||||
ostree_repo_get_default_repo_finders
|
||||
ostree_repo_hash
|
||||
ostree_repo_equal
|
||||
ostree_repo_copy_config
|
||||
|
|
@ -596,6 +599,7 @@ ostree_repo_pull_from_remotes_async
|
|||
ostree_repo_pull_from_remotes_finish
|
||||
ostree_repo_resolve_keyring_for_collection
|
||||
OSTREE_REPO_METADATA_REF
|
||||
OSTREE_META_KEY_DEPLOY_COLLECTION_ID
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
|
|
|||
23
bash/ostree
23
bash/ostree
|
|
@ -24,12 +24,6 @@
|
|||
# - Structured option arguments (e.g. --foo KEY=VALUE) are not parsed.
|
||||
#
|
||||
# - Static deltas could likely be completed. (e.g. ostree static-delta delete [TAB])
|
||||
#
|
||||
# - The "--repo PATH" option needs to come after the subcommand or it
|
||||
# won't be picked up for completion of subsequent options.
|
||||
# i.e. ostree commit --repo PATH ... <-- works
|
||||
# ostree --repo PATH commit ... <-- does not work
|
||||
# (Possibly an easy fix.)
|
||||
|
||||
|
||||
# Finds the position of the first non-flag word.
|
||||
|
|
@ -183,9 +177,16 @@ __ostree_subcommands() {
|
|||
|
||||
# This handles "ostree [TAB]" (without a subcommand).
|
||||
_ostree_ostree() {
|
||||
case "$prev" in
|
||||
--repo)
|
||||
__ostree_compreply_dirs_only
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "$main_boolean_options" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "$main_options" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W "$commands" -- "$cur" ) )
|
||||
|
|
@ -1753,6 +1754,14 @@ _ostree() {
|
|||
--verbose -v
|
||||
--version
|
||||
"
|
||||
local main_options_with_args="
|
||||
--repo
|
||||
"
|
||||
local main_options_with_args_glob=$( __ostree_to_extglob "$main_options_with_args" )
|
||||
local main_options="
|
||||
$main_boolean_options
|
||||
$main_options_with_args
|
||||
"
|
||||
|
||||
COMPREPLY=()
|
||||
local cur prev words cword
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for libostree 2018.8.
|
||||
# Generated by GNU Autoconf 2.69 for libostree 2018.9.
|
||||
#
|
||||
# Report bugs to <walters@verbum.org>.
|
||||
#
|
||||
|
|
@ -590,8 +590,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='libostree'
|
||||
PACKAGE_TARNAME='libostree'
|
||||
PACKAGE_VERSION='2018.8'
|
||||
PACKAGE_STRING='libostree 2018.8'
|
||||
PACKAGE_VERSION='2018.9'
|
||||
PACKAGE_STRING='libostree 2018.9'
|
||||
PACKAGE_BUGREPORT='walters@verbum.org'
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
|
@ -1547,7 +1547,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures libostree 2018.8 to adapt to many kinds of systems.
|
||||
\`configure' configures libostree 2018.9 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
|
@ -1617,7 +1617,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of libostree 2018.8:";;
|
||||
short | recursive ) echo "Configuration of libostree 2018.9:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
|
@ -1864,7 +1864,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
libostree configure 2018.8
|
||||
libostree configure 2018.9
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
|
@ -2336,7 +2336,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by libostree $as_me 2018.8, which was
|
||||
It was created by libostree $as_me 2018.9, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
|
@ -3204,7 +3204,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='libostree'
|
||||
VERSION='2018.8'
|
||||
VERSION='2018.9'
|
||||
|
||||
|
||||
# Some tools Automake needs.
|
||||
|
|
@ -5938,9 +5938,9 @@ test -n "$YACC" || YACC="yacc"
|
|||
|
||||
YEAR_VERSION=2018
|
||||
|
||||
RELEASE_VERSION=8
|
||||
RELEASE_VERSION=9
|
||||
|
||||
PACKAGE_VERSION=2018.8
|
||||
PACKAGE_VERSION=2018.9
|
||||
|
||||
|
||||
if echo "$CFLAGS" | grep -q -E -e '-Werror($| )'; then :
|
||||
|
|
@ -18623,7 +18623,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by libostree $as_me 2018.8, which was
|
||||
This file was extended by libostree $as_me 2018.9, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
|
@ -18689,7 +18689,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
libostree config.status 2018.8
|
||||
libostree config.status 2018.9
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ dnl update libostree-released.sym from libostree-devel.sym, and update the check
|
|||
dnl in test-symbols.sh, and also set is_release_build=yes below. Then make
|
||||
dnl another post-release commit to bump the version, and set is_release_build=no.
|
||||
m4_define([year_version], [2018])
|
||||
m4_define([release_version], [8])
|
||||
m4_define([release_version], [9])
|
||||
m4_define([package_version], [year_version.release_version])
|
||||
AC_INIT([libostree], [package_version], [walters@verbum.org])
|
||||
is_release_build=yes
|
||||
|
|
|
|||
|
|
@ -83,11 +83,6 @@ Boston, MA 02111-1307, USA.
|
|||
USB mounts use signed per-repo and per-commit metadata instead of
|
||||
summary signatures.
|
||||
</para>
|
||||
<para>
|
||||
This command relies on the summary file in the source repo, so you
|
||||
may want to run <command>ostree summary -u</command> before running
|
||||
this command.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
@ -112,6 +107,15 @@ Boston, MA 02111-1307, USA.
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--commit</option>=COMMIT</term>
|
||||
|
||||
<listitem><para>
|
||||
Pull COMMIT instead of whatever REF points to. This can only
|
||||
be used if a single ref is specified.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,38 @@ Boston, MA 02111-1307, USA.
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>locking</varname></term>
|
||||
<listitem><para>Boolean value controlling whether or not OSTree does
|
||||
repository locking internally. This uses file locks and is
|
||||
hence for multiple process exclusion (e.g. Flatpak and OSTree
|
||||
writing to the same repository separately). This is enabled by
|
||||
default since 2018.5.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>lock-timeout-secs</varname></term>
|
||||
<listitem><para>Integer value controlling the number of seconds to
|
||||
block while attempting to acquire a lock (see above). A value
|
||||
of -1 means block indefinitely. The default value is 30.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>default-repo-finders</varname></term>
|
||||
<listitem><para>Semicolon separated default list of finders (sources
|
||||
for refs) to use when pulling. This can be used to disable
|
||||
pulling from mounted filesystems, peers on the local network,
|
||||
or the Internet. However note that it only applies when a set
|
||||
of finders isn't explicitly specified, either by a consumer of
|
||||
libostree API or on the command line. Possible values:
|
||||
<literal>config</literal>, <literal>lan</literal>, and
|
||||
<literal>mount</literal> (or any combination thereof). If unset, this
|
||||
defaults to <literal>config;mount;</literal> (since the LAN finder is
|
||||
costly).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ depends() {
|
|||
install() {
|
||||
dracut_install /usr/lib/ostree/ostree-prepare-root
|
||||
inst_simple "${systemdsystemunitdir}/ostree-prepare-root.service"
|
||||
mkdir -p "${initdir}${systemdsystemconfdir}/initrd-switch-root.target.wants"
|
||||
mkdir -p "${initdir}${systemdsystemconfdir}/initrd-root-fs.target.wants"
|
||||
ln_r "${systemdsystemunitdir}/ostree-prepare-root.service" \
|
||||
"${systemdsystemconfdir}/initrd-switch-root.target.wants/ostree-prepare-root.service"
|
||||
"${systemdsystemconfdir}/initrd-root-fs.target.wants/ostree-prepare-root.service"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright (C) 2018 Red Hat, Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# For some implementation discussion, see:
|
||||
# https://lists.freedesktop.org/archives/systemd-devel/2018-March/040557.html
|
||||
[Unit]
|
||||
Description=OSTree Monitor Staged Deployment
|
||||
Documentation=man:ostree(1)
|
||||
|
||||
[Path]
|
||||
PathExists=/run/ostree/staged-deployment
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
# https://lists.freedesktop.org/archives/systemd-devel/2018-March/040557.html
|
||||
[Unit]
|
||||
Description=OSTree Finalize Staged Deployment
|
||||
Documentation=man:ostree(1)
|
||||
ConditionPathExists=/run/ostree-booted
|
||||
DefaultDependencies=no
|
||||
|
||||
|
|
@ -31,6 +32,7 @@ Conflicts=final.target
|
|||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStop=/usr/bin/ostree admin finalize-staged
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
# This is a quite long timeout intentionally; the failure mode
|
||||
# here is that people don't get an upgrade. We need to handle
|
||||
# cases with slow rotational media, etc.
|
||||
TimeoutStopSec=5m
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
[Unit]
|
||||
Description=OSTree Prepare OS/
|
||||
Documentation=man:ostree(1)
|
||||
DefaultDependencies=no
|
||||
ConditionKernelCommandLine=ostree
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
OnFailure=emergency.target
|
||||
After=initrd-switch-root.target
|
||||
Before=initrd-switch-root.service
|
||||
Before=plymouth-switch-root.service
|
||||
After=sysroot.mount
|
||||
Before=initrd-root-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
|
@ -31,3 +31,4 @@ ExecStart=/usr/lib/ostree/ostree-prepare-root /sysroot
|
|||
StandardInput=null
|
||||
StandardOutput=syslog
|
||||
StandardError=syslog+console
|
||||
RemainAfterExit=yes
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
[Unit]
|
||||
Description=OSTree Remount OS/ bind mounts
|
||||
Description=OSTree Remount OS/ Bind Mounts
|
||||
Documentation=man:ostree(1)
|
||||
DefaultDependencies=no
|
||||
ConditionKernelCommandLine=ostree
|
||||
OnFailure=emergency.target
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@
|
|||
***/
|
||||
|
||||
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
||||
LIBOSTREE_2018.9 {
|
||||
} LIBOSTREE_2018.7;
|
||||
|
||||
/* Stub section for the stable release *after* this development one; don't
|
||||
* edit this other than to update the last number. This is just a copy/paste
|
||||
|
|
|
|||
|
|
@ -536,6 +536,12 @@ global:
|
|||
|
||||
/* No new symbols in 2018.8 */
|
||||
|
||||
LIBOSTREE_2018.9 {
|
||||
ostree_mutable_tree_remove;
|
||||
ostree_repo_get_min_free_space_bytes;
|
||||
ostree_repo_get_default_repo_finders;
|
||||
} LIBOSTREE_2018.7;
|
||||
|
||||
/* NOTE: Only add more content here in release commits! See the
|
||||
* comments at the top of this file.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ idle_invoke_async_progress (gpointer user_data)
|
|||
OstreeAsyncProgress *self = user_data;
|
||||
|
||||
g_mutex_lock (&self->lock);
|
||||
self->idle_source = NULL;
|
||||
g_clear_pointer (&self->idle_source, g_source_unref);
|
||||
g_mutex_unlock (&self->lock);
|
||||
|
||||
g_signal_emit (self, signals[CHANGED], 0);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ struct _OstreeBootloaderGrub2
|
|||
GObject parent_instance;
|
||||
|
||||
OstreeSysroot *sysroot;
|
||||
GFile *config_path_bios;
|
||||
GFile *config_path_bios_1;
|
||||
GFile *config_path_bios_2;
|
||||
GFile *config_path_efi;
|
||||
gboolean is_efi;
|
||||
};
|
||||
|
|
@ -77,7 +78,8 @@ _ostree_bootloader_grub2_query (OstreeBootloader *bootloader,
|
|||
OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
|
||||
|
||||
/* Look for the BIOS path first */
|
||||
if (g_file_query_exists (self->config_path_bios, NULL))
|
||||
if (g_file_query_exists (self->config_path_bios_1, NULL) ||
|
||||
g_file_query_exists (self->config_path_bios_2, NULL))
|
||||
{
|
||||
/* If we found it, we're done */
|
||||
*out_is_active = TRUE;
|
||||
|
|
@ -460,7 +462,8 @@ _ostree_bootloader_grub2_finalize (GObject *object)
|
|||
OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (object);
|
||||
|
||||
g_clear_object (&self->sysroot);
|
||||
g_clear_object (&self->config_path_bios);
|
||||
g_clear_object (&self->config_path_bios_1);
|
||||
g_clear_object (&self->config_path_bios_2);
|
||||
g_clear_object (&self->config_path_efi);
|
||||
|
||||
G_OBJECT_CLASS (_ostree_bootloader_grub2_parent_class)->finalize (object);
|
||||
|
|
@ -493,6 +496,9 @@ _ostree_bootloader_grub2_new (OstreeSysroot *sysroot)
|
|||
{
|
||||
OstreeBootloaderGrub2 *self = g_object_new (OSTREE_TYPE_BOOTLOADER_GRUB2, NULL);
|
||||
self->sysroot = g_object_ref (sysroot);
|
||||
self->config_path_bios = g_file_resolve_relative_path (self->sysroot->path, "boot/grub2/grub.cfg");
|
||||
/* Used by (at least) Debian */
|
||||
self->config_path_bios_1 = g_file_resolve_relative_path (self->sysroot->path, "boot/grub/grub.cfg");
|
||||
/* Used by (at least) Fedora */
|
||||
self->config_path_bios_2 = g_file_resolve_relative_path (self->sysroot->path, "boot/grub2/grub.cfg");
|
||||
return self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,17 +32,17 @@ G_BEGIN_DECLS
|
|||
/**
|
||||
* OSTREE_MAX_METADATA_SIZE:
|
||||
*
|
||||
* Maximum permitted size in bytes of metadata objects. This is an
|
||||
* arbitrary number, but really, no one should be putting humongous
|
||||
* data in metadata.
|
||||
* Default limit for maximum permitted size in bytes of metadata objects fetched
|
||||
* over HTTP (including repo/config files, refs, and commit/dirtree/dirmeta
|
||||
* objects). This is an arbitrary number intended to mitigate disk space
|
||||
* exhaustion attacks.
|
||||
*/
|
||||
#define OSTREE_MAX_METADATA_SIZE (10 * 1024 * 1024)
|
||||
|
||||
/**
|
||||
* OSTREE_MAX_METADATA_WARN_SIZE:
|
||||
*
|
||||
* Objects committed above this size will be allowed, but a warning
|
||||
* will be emitted.
|
||||
* This variable is no longer meaningful, it is kept only for compatibility.
|
||||
*/
|
||||
#define OSTREE_MAX_METADATA_WARN_SIZE (7 * 1024 * 1024)
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,9 @@ _ostree_fetcher_finalize (GObject *object)
|
|||
|
||||
curl_multi_cleanup (self->multi);
|
||||
g_free (self->remote_name);
|
||||
g_free (self->tls_ca_db_path);
|
||||
g_free (self->tls_client_cert_path);
|
||||
g_free (self->tls_client_key_path);
|
||||
g_free (self->cookie_jar_path);
|
||||
g_free (self->proxy);
|
||||
g_assert_cmpint (g_hash_table_size (self->outstanding_requests), ==, 0);
|
||||
|
|
@ -319,15 +322,13 @@ check_multi_info (OstreeFetcher *fetcher)
|
|||
{
|
||||
/* Handle file not found */
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
"%s",
|
||||
curl_easy_strerror (curlres));
|
||||
"%s", curl_easy_strerror (curlres));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "[%u] %s",
|
||||
curlres,
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"While fetching %s: [%u] %s", eff_url, curlres,
|
||||
curl_easy_strerror (curlres));
|
||||
if (req->fetcher->remote_name)
|
||||
_ostree_fetcher_journal_failure (req->fetcher->remote_name,
|
||||
eff_url, curl_easy_strerror (curlres));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ _ostree_fetcher_journal_failure (const char *remote_name,
|
|||
"MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_HTTP_FAILURE_ID),
|
||||
"OSTREE_REMOTE=%s", remote_name,
|
||||
"OSTREE_URL=%s", url,
|
||||
"PRIORITY=%i", LOG_ERR,
|
||||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,31 +305,57 @@ ostree_mutable_tree_replace_file (OstreeMutableTree *self,
|
|||
const char *checksum,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (!_ostree_mutable_tree_make_whole (self, NULL, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (g_hash_table_lookup (self->subdirs, name))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Can't replace directory with file: %s", name);
|
||||
goto out;
|
||||
}
|
||||
return glnx_throw (error, "Can't replace directory with file: %s", name);
|
||||
|
||||
invalidate_contents_checksum (self);
|
||||
g_hash_table_replace (self->files,
|
||||
g_strdup (name),
|
||||
g_strdup (checksum));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
/**
|
||||
* ostree_mutable_tree_remove:
|
||||
* @self: Tree
|
||||
* @name: Name of file or subdirectory to remove
|
||||
* @allow_noent: If @FALSE, an error will be thrown if @name does not exist in the tree
|
||||
* @error: a #GError
|
||||
*
|
||||
* Remove the file or subdirectory named @name from the mutable tree @self.
|
||||
*/
|
||||
gboolean
|
||||
ostree_mutable_tree_remove (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
gboolean allow_noent,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
return FALSE;
|
||||
|
||||
if (!_ostree_mutable_tree_make_whole (self, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
if (!g_hash_table_remove (self->files, name) &&
|
||||
!g_hash_table_remove (self->subdirs, name))
|
||||
{
|
||||
if (allow_noent)
|
||||
return TRUE; /* NB: early return */
|
||||
return set_error_noent (error, name);
|
||||
}
|
||||
|
||||
invalidate_contents_checksum (self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -348,25 +374,19 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
|
|||
OstreeMutableTree **out_subdir,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(OstreeMutableTree) ret_dir = NULL;
|
||||
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!ot_util_filename_validate (name, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (!_ostree_mutable_tree_make_whole (self, NULL, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (g_hash_table_lookup (self->files, name))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Can't replace file with directory: %s", name);
|
||||
goto out;
|
||||
}
|
||||
return glnx_throw (error, "Can't replace file with directory: %s", name);
|
||||
|
||||
ret_dir = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name));
|
||||
g_autoptr(OstreeMutableTree) ret_dir =
|
||||
ot_gobject_refz (g_hash_table_lookup (self->subdirs, name));
|
||||
if (!ret_dir)
|
||||
{
|
||||
ret_dir = ostree_mutable_tree_new ();
|
||||
|
|
@ -374,10 +394,9 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
|
|||
insert_child_mtree (self, name, g_object_ref (ret_dir));
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_subdir, &ret_dir);
|
||||
out:
|
||||
return ret;
|
||||
if (out_subdir)
|
||||
*out_subdir = g_steal_pointer (&ret_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -387,29 +406,24 @@ ostree_mutable_tree_lookup (OstreeMutableTree *self,
|
|||
OstreeMutableTree **out_subdir,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(OstreeMutableTree) ret_subdir = NULL;
|
||||
g_autofree char *ret_file_checksum = NULL;
|
||||
|
||||
if (!_ostree_mutable_tree_make_whole (self, NULL, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
ret_subdir = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name));
|
||||
g_autofree char *ret_file_checksum = NULL;
|
||||
g_autoptr(OstreeMutableTree) ret_subdir =
|
||||
ot_gobject_refz (g_hash_table_lookup (self->subdirs, name));
|
||||
if (!ret_subdir)
|
||||
{
|
||||
ret_file_checksum = g_strdup (g_hash_table_lookup (self->files, name));
|
||||
if (!ret_file_checksum)
|
||||
{
|
||||
set_error_noent (error, name);
|
||||
goto out;
|
||||
}
|
||||
return set_error_noent (error, name);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_file_checksum, &ret_file_checksum);
|
||||
ot_transfer_out_value (out_subdir, &ret_subdir);
|
||||
out:
|
||||
return ret;
|
||||
if (out_file_checksum)
|
||||
*out_file_checksum = g_steal_pointer (&ret_file_checksum);
|
||||
if (out_subdir)
|
||||
*out_subdir = g_steal_pointer (&ret_subdir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -430,30 +444,22 @@ ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self,
|
|||
OstreeMutableTree **out_parent,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int i;
|
||||
OstreeMutableTree *subdir = self; /* nofree */
|
||||
g_autoptr(OstreeMutableTree) ret_parent = NULL;
|
||||
g_assert (metadata_checksum != NULL);
|
||||
|
||||
if (!_ostree_mutable_tree_make_whole (self, NULL, error))
|
||||
goto out;
|
||||
|
||||
g_assert (metadata_checksum != NULL);
|
||||
return FALSE;
|
||||
|
||||
if (!self->metadata_checksum)
|
||||
ostree_mutable_tree_set_metadata_checksum (self, metadata_checksum);
|
||||
|
||||
for (i = 0; i+1 < split_path->len; i++)
|
||||
OstreeMutableTree *subdir = self; /* nofree */
|
||||
for (guint i = 0; i+1 < split_path->len; i++)
|
||||
{
|
||||
OstreeMutableTree *next;
|
||||
const char *name = split_path->pdata[i];
|
||||
|
||||
if (g_hash_table_lookup (subdir->files, name))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Can't replace file with directory: %s", name);
|
||||
goto out;
|
||||
}
|
||||
return glnx_throw (error, "Can't replace file with directory: %s", name);
|
||||
|
||||
next = g_hash_table_lookup (subdir->subdirs, name);
|
||||
if (!next)
|
||||
|
|
@ -467,12 +473,9 @@ ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self,
|
|||
subdir = next;
|
||||
}
|
||||
|
||||
ret_parent = g_object_ref (subdir);
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_parent, &ret_parent);
|
||||
out:
|
||||
return ret;
|
||||
if (out_parent)
|
||||
*out_parent = g_object_ref (subdir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char empty_tree_csum[] = "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d";
|
||||
|
|
|
|||
|
|
@ -77,6 +77,12 @@ gboolean ostree_mutable_tree_replace_file (OstreeMutableTree *self,
|
|||
const char *checksum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_remove (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
gboolean allow_noent,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ static gboolean
|
|||
create_file_copy_from_input_at (OstreeRepo *repo,
|
||||
OstreeRepoCheckoutAtOptions *options,
|
||||
CheckoutState *state,
|
||||
const char *checksum,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream *input,
|
||||
|
|
@ -358,8 +359,35 @@ create_file_copy_from_input_at (OstreeRepo *repo,
|
|||
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST;
|
||||
break;
|
||||
case OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL:
|
||||
/* We don't support copying in union identical */
|
||||
g_assert_not_reached ();
|
||||
{
|
||||
replace_mode = GLNX_LINK_TMPFILE_NOREPLACE;
|
||||
struct stat dest_stbuf;
|
||||
if (!glnx_fstatat_allow_noent (destination_dfd, destination_name, &dest_stbuf,
|
||||
AT_SYMLINK_NOFOLLOW, error))
|
||||
return FALSE;
|
||||
if (errno == 0)
|
||||
{
|
||||
/* We do a checksum comparison; see also equivalent code in
|
||||
* checkout_file_hardlink().
|
||||
*/
|
||||
OstreeChecksumFlags flags = 0;
|
||||
if (repo->disable_xattrs)
|
||||
flags |= OSTREE_CHECKSUM_FLAGS_IGNORE_XATTRS;
|
||||
|
||||
g_autofree char *actual_checksum = NULL;
|
||||
if (!ostree_checksum_file_at (destination_dfd, destination_name,
|
||||
&dest_stbuf, OSTREE_OBJECT_TYPE_FILE,
|
||||
flags, &actual_checksum, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (g_str_equal (checksum, actual_checksum))
|
||||
return TRUE;
|
||||
|
||||
/* Otherwise, fall through and do the link, we should
|
||||
* get EEXIST.
|
||||
*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -586,6 +614,7 @@ checkout_one_file_at (OstreeRepo *repo,
|
|||
const gboolean is_symlink = (g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK);
|
||||
const gboolean is_whiteout = (!is_symlink && options->process_whiteouts &&
|
||||
g_str_has_prefix (destination_name, WHITEOUT_PREFIX));
|
||||
const gboolean is_reg_zerosized = (!is_symlink && g_file_info_get_size (source_info) == 0);
|
||||
|
||||
/* First, see if it's a Docker whiteout,
|
||||
* https://github.com/docker/docker/blob/1a714e76a2cb9008cd19609059e9988ff1660b78/pkg/archive/whiteouts.go
|
||||
|
|
@ -604,6 +633,10 @@ checkout_one_file_at (OstreeRepo *repo,
|
|||
|
||||
need_copy = FALSE;
|
||||
}
|
||||
else if (options->force_copy_zerosized && is_reg_zerosized)
|
||||
{
|
||||
need_copy = TRUE;
|
||||
}
|
||||
else if (!options->force_copy)
|
||||
{
|
||||
HardlinkResult hardlink_res = HARDLINK_RESULT_NOT_SUPPORTED;
|
||||
|
|
@ -699,6 +732,7 @@ checkout_one_file_at (OstreeRepo *repo,
|
|||
if (can_cache
|
||||
&& !is_whiteout
|
||||
&& !is_symlink
|
||||
&& !is_reg_zerosized
|
||||
&& need_copy
|
||||
&& repo->mode == OSTREE_REPO_MODE_ARCHIVE
|
||||
&& options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
|
||||
|
|
@ -762,12 +796,12 @@ checkout_one_file_at (OstreeRepo *repo,
|
|||
* succeeded at hardlinking above.
|
||||
*/
|
||||
if (options->no_copy_fallback)
|
||||
g_assert (is_bare_user_symlink);
|
||||
g_assert (is_bare_user_symlink || is_reg_zerosized);
|
||||
if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!create_file_copy_from_input_at (repo, options, state, source_info, xattrs, input,
|
||||
if (!create_file_copy_from_input_at (repo, options, state, checksum, source_info, xattrs, input,
|
||||
destination_dfd, destination_name,
|
||||
cancellable, error))
|
||||
return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name);
|
||||
|
|
|
|||
|
|
@ -245,16 +245,7 @@ commit_loose_regfile_object (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
/* We may be writing as root to a non-root-owned repository; if so,
|
||||
* automatically inherit the non-root ownership.
|
||||
*/
|
||||
if (self->mode == OSTREE_REPO_MODE_ARCHIVE
|
||||
&& self->target_owner_uid != -1)
|
||||
{
|
||||
if (fchown (tmpf->fd, self->target_owner_uid, self->target_owner_gid) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fchown");
|
||||
}
|
||||
else if (self->mode == OSTREE_REPO_MODE_BARE)
|
||||
if (self->mode == OSTREE_REPO_MODE_BARE)
|
||||
{
|
||||
if (TEMP_FAILURE_RETRY (fchown (tmpf->fd, uid, gid)) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fchown");
|
||||
|
|
@ -1336,18 +1327,6 @@ write_metadata_object (OstreeRepo *self,
|
|||
gsize len;
|
||||
const guint8 *bufp = g_bytes_get_data (buf, &len);
|
||||
|
||||
/* Do the size warning here, to avoid warning for already extant metadata */
|
||||
if (G_UNLIKELY (len > OSTREE_MAX_METADATA_WARN_SIZE))
|
||||
{
|
||||
g_autofree char *metasize = g_format_size (len);
|
||||
g_autofree char *warnsize = g_format_size (OSTREE_MAX_METADATA_WARN_SIZE);
|
||||
g_autofree char *maxsize = g_format_size (OSTREE_MAX_METADATA_SIZE);
|
||||
g_warning ("metadata object %s is %s, which is larger than the warning threshold of %s." \
|
||||
" The hard limit on metadata size is %s. Put large content in the tree itself, not in metadata.",
|
||||
actual_checksum,
|
||||
metasize, warnsize, maxsize);
|
||||
}
|
||||
|
||||
/* Write the metadata to a temporary file */
|
||||
g_auto(GLnxTmpfile) tmpf = { 0, };
|
||||
if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC,
|
||||
|
|
@ -1536,25 +1515,6 @@ devino_cache_lookup (OstreeRepo *self,
|
|||
return dev_ino_val->checksum;
|
||||
}
|
||||
|
||||
static guint64
|
||||
min_free_space_calculate_reserved_blocks (OstreeRepo *self, struct statvfs *stvfsbuf)
|
||||
{
|
||||
guint64 reserved_blocks = 0;
|
||||
|
||||
if (self->min_free_space_mb > 0)
|
||||
{
|
||||
reserved_blocks = (self->min_free_space_mb << 20) / stvfsbuf->f_bsize;
|
||||
}
|
||||
else if (self->min_free_space_percent > 0)
|
||||
{
|
||||
/* Convert fragment to blocks to compute the total */
|
||||
guint64 total_blocks = (stvfsbuf->f_frsize * stvfsbuf->f_blocks) / stvfsbuf->f_bsize;
|
||||
reserved_blocks = ((double)total_blocks) * (self->min_free_space_percent/100.0);
|
||||
}
|
||||
|
||||
return reserved_blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_scan_hardlinks:
|
||||
* @self: An #OstreeRepo
|
||||
|
|
@ -1626,6 +1586,7 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
|
|||
GError **error)
|
||||
{
|
||||
g_autoptr(_OstreeRepoAutoTransaction) txn = NULL;
|
||||
guint64 reserved_bytes = 0;
|
||||
|
||||
g_return_val_if_fail (self->in_transaction == FALSE, FALSE);
|
||||
|
||||
|
|
@ -1650,11 +1611,17 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
|
|||
|
||||
g_mutex_lock (&self->txn_lock);
|
||||
self->txn.blocksize = stvfsbuf.f_bsize;
|
||||
guint64 reserved_blocks = min_free_space_calculate_reserved_blocks (self, &stvfsbuf);
|
||||
if (!ostree_repo_get_min_free_space_bytes (self, &reserved_bytes, error))
|
||||
{
|
||||
g_mutex_unlock (&self->txn_lock);
|
||||
return FALSE;
|
||||
}
|
||||
self->reserved_blocks = reserved_bytes / self->txn.blocksize;
|
||||
|
||||
/* Use the appropriate free block count if we're unprivileged */
|
||||
guint64 bfree = (getuid () != 0 ? stvfsbuf.f_bavail : stvfsbuf.f_bfree);
|
||||
if (bfree > reserved_blocks)
|
||||
self->txn.max_blocks = bfree - reserved_blocks;
|
||||
if (bfree > self->reserved_blocks)
|
||||
self->txn.max_blocks = bfree - self->reserved_blocks;
|
||||
else
|
||||
{
|
||||
self->cleanup_stagedir = TRUE;
|
||||
|
|
@ -2290,25 +2257,6 @@ ostree_repo_abort_transaction (OstreeRepo *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* These limits were introduced since in some cases we may be processing
|
||||
* malicious metadata, and we want to make disk space exhaustion attacks harder.
|
||||
*/
|
||||
static gboolean
|
||||
metadata_size_valid (OstreeObjectType objtype,
|
||||
gsize len,
|
||||
GError **error)
|
||||
{
|
||||
if (G_UNLIKELY (len > OSTREE_MAX_METADATA_SIZE))
|
||||
{
|
||||
g_autofree char *input_bytes = g_format_size (len);
|
||||
g_autofree char *max_bytes = g_format_size (OSTREE_MAX_METADATA_SIZE);
|
||||
return glnx_throw (error, "Metadata object of type '%s' is %s; maximum metadata size is %s",
|
||||
ostree_object_type_to_string (objtype), input_bytes, max_bytes);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_write_metadata:
|
||||
* @self: Repo
|
||||
|
|
@ -2361,9 +2309,6 @@ ostree_repo_write_metadata (OstreeRepo *self,
|
|||
normalized = g_variant_get_normal_form (object);
|
||||
}
|
||||
|
||||
if (!metadata_size_valid (objtype, g_variant_get_size (normalized), error))
|
||||
return FALSE;
|
||||
|
||||
/* For untrusted objects, verify their structure here */
|
||||
if (expected_checksum)
|
||||
{
|
||||
|
|
@ -2401,9 +2346,6 @@ ostree_repo_write_metadata_stream_trusted (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
if (length > 0 && !metadata_size_valid (objtype, length, error))
|
||||
return FALSE;
|
||||
|
||||
/* This is all pretty ridiculous, but we're keeping this API for backwards
|
||||
* compatibility, it doesn't really need to be fast.
|
||||
*/
|
||||
|
|
@ -4305,11 +4247,12 @@ import_one_object_direct (OstreeRepo *dest_repo,
|
|||
}
|
||||
|
||||
/* Don't want to copy xattrs for archive repos, nor for
|
||||
* bare-user-only.
|
||||
* bare-user-only. We also only do this for content
|
||||
* objects.
|
||||
*/
|
||||
const gboolean src_is_bare_or_bare_user =
|
||||
G_IN_SET (src_repo->mode, OSTREE_REPO_MODE_BARE, OSTREE_REPO_MODE_BARE_USER);
|
||||
if (src_is_bare_or_bare_user)
|
||||
if (src_is_bare_or_bare_user && !OSTREE_OBJECT_TYPE_IS_META(objtype))
|
||||
{
|
||||
g_autoptr(GVariant) xattrs = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -509,6 +509,16 @@ fill_refs_and_checksums_from_summary (GVariant *summary,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_null_checksum_refs_cb (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *checksum = value;
|
||||
|
||||
return (checksum == NULL);
|
||||
}
|
||||
|
||||
/* Given a summary file (@summary_bytes), extract the refs it lists, and use that
|
||||
* to fill in the checksums in the @supported_ref_to_checksum map. This includes
|
||||
* the main refs list in the summary, and the map of collection IDs to further
|
||||
|
|
@ -520,12 +530,11 @@ fill_refs_and_checksums_from_summary (GVariant *summary,
|
|||
static gboolean
|
||||
get_refs_and_checksums_from_summary (GBytes *summary_bytes,
|
||||
GHashTable *supported_ref_to_checksum /* (element-type OstreeCollectionRef utf8) */,
|
||||
OstreeRemote *remote,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GVariant) summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE));
|
||||
GHashTableIter iter;
|
||||
const OstreeCollectionRef *ref;
|
||||
const gchar *checksum;
|
||||
guint removed_refs;
|
||||
|
||||
if (!g_variant_is_normal_form (summary))
|
||||
{
|
||||
|
|
@ -544,20 +553,20 @@ get_refs_and_checksums_from_summary (GBytes *summary_bytes,
|
|||
if (!fill_refs_and_checksums_from_summary (summary, supported_ref_to_checksum, error))
|
||||
return FALSE;
|
||||
|
||||
/* Check that at least one of the refs has a non-%NULL checksum set, otherwise
|
||||
* we can discard this peer. */
|
||||
g_hash_table_iter_init (&iter, supported_ref_to_checksum);
|
||||
while (g_hash_table_iter_next (&iter,
|
||||
(gpointer *) &ref,
|
||||
(gpointer *) &checksum))
|
||||
{
|
||||
if (checksum != NULL)
|
||||
return TRUE;
|
||||
}
|
||||
removed_refs = g_hash_table_foreach_remove (supported_ref_to_checksum, remove_null_checksum_refs_cb, NULL);
|
||||
if (removed_refs > 0)
|
||||
g_debug ("Removed %d refs from the list resolved from ‘%s’ (possibly bloom filter false positives)",
|
||||
removed_refs, remote->name);
|
||||
|
||||
/* If none of the refs had a non-%NULL checksum set, we can discard this peer. */
|
||||
if (g_hash_table_size (supported_ref_to_checksum) == 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
"No matching refs were found in the summary file");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Download the summary file from @remote, and return the bytes of the file in
|
||||
|
|
@ -661,7 +670,7 @@ get_checksums (OstreeRepoFinderAvahi *finder,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, error);
|
||||
return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, remote, error);
|
||||
}
|
||||
|
||||
/* Build some #OstreeRepoFinderResults out of the given #OstreeAvahiService by
|
||||
|
|
|
|||
|
|
@ -149,10 +149,9 @@ struct OstreeRepo {
|
|||
dev_t device;
|
||||
ino_t inode;
|
||||
uid_t owner_uid; /* Cache of repo's owner uid */
|
||||
uid_t target_owner_uid; /* Ensure files are chowned to this uid/gid */
|
||||
gid_t target_owner_gid;
|
||||
guint min_free_space_percent; /* See the min-free-space-percent config option */
|
||||
guint64 min_free_space_mb; /* See the min-free-space-size config option */
|
||||
guint64 reserved_blocks;
|
||||
gboolean cleanup_stagedir;
|
||||
|
||||
guint test_error_flags; /* OstreeRepoTestErrorFlags */
|
||||
|
|
@ -169,6 +168,7 @@ struct OstreeRepo {
|
|||
gint lock_timeout_seconds;
|
||||
guint64 payload_link_threshold;
|
||||
gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */
|
||||
gchar **repo_finders;
|
||||
|
||||
OstreeRepo *parent_repo;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ typedef struct {
|
|||
|
||||
gboolean timestamp_check; /* Verify commit timestamps */
|
||||
int maxdepth;
|
||||
guint64 max_metadata_size;
|
||||
guint64 start_time;
|
||||
|
||||
gboolean is_mirror;
|
||||
|
|
@ -2193,7 +2194,7 @@ start_fetch (OtPullData *pull_data,
|
|||
if (expected_max_size_p)
|
||||
expected_max_size = *expected_max_size_p;
|
||||
else if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||
expected_max_size = OSTREE_MAX_METADATA_SIZE;
|
||||
expected_max_size = pull_data->max_metadata_size;
|
||||
else
|
||||
expected_max_size = 0;
|
||||
|
||||
|
|
@ -3488,6 +3489,7 @@ initiate_request (OtPullData *pull_data,
|
|||
* * require-static-deltas (b): Require static deltas
|
||||
* * override-commit-ids (as): Array of specific commit IDs to fetch for refs
|
||||
* * timestamp-check (b): Verify commit timestamps are newer than current (when pulling via ref); Since: 2017.11
|
||||
* * metadata-size-restriction (t): Restrict metadata objects to a maximum number of bytes; 0 to disable. Since: 2018.9
|
||||
* * dry-run (b): Only print information on what will be downloaded (requires static deltas)
|
||||
* * override-url (s): Fetch objects from this URL if remote specifies no metalink in options
|
||||
* * inherit-transaction (b): Don't initiate, finish or abort a transaction, useful to do multiple pulls in one transaction.
|
||||
|
|
@ -3543,6 +3545,9 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
*/
|
||||
const char *the_ref_to_fetch = NULL;
|
||||
|
||||
/* Default */
|
||||
pull_data->max_metadata_size = OSTREE_MAX_METADATA_SIZE;
|
||||
|
||||
if (options)
|
||||
{
|
||||
int flags_i = OSTREE_REPO_PULL_FLAGS_NONE;
|
||||
|
|
@ -3570,6 +3575,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
(void) g_variant_lookup (options, "update-frequency", "u", &update_frequency);
|
||||
(void) g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos);
|
||||
(void) g_variant_lookup (options, "timestamp-check", "b", &pull_data->timestamp_check);
|
||||
(void) g_variant_lookup (options, "max-metadata-size", "t", &pull_data->max_metadata_size);
|
||||
(void) g_variant_lookup (options, "append-user-agent", "s", &pull_data->append_user_agent);
|
||||
opt_n_network_retries_set =
|
||||
g_variant_lookup (options, "n-network-retries", "u", &pull_data->n_network_retries);
|
||||
|
|
@ -4993,24 +4999,34 @@ ostree_repo_find_remotes_async (OstreeRepo *self,
|
|||
/* Are we using #OstreeRepoFinders provided by the user, or the defaults? */
|
||||
if (finders == NULL)
|
||||
{
|
||||
guint finder_index = 0;
|
||||
#ifdef HAVE_AVAHI
|
||||
guint avahi_index;
|
||||
GMainContext *context = g_main_context_get_thread_default ();
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
#endif /* HAVE_AVAHI */
|
||||
|
||||
finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ());
|
||||
finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL));
|
||||
if (g_strv_contains ((const char * const *)self->repo_finders, "config"))
|
||||
default_finders[finder_index++] = finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ());
|
||||
|
||||
if (g_strv_contains ((const char * const *)self->repo_finders, "mount"))
|
||||
default_finders[finder_index++] = finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL));
|
||||
|
||||
#ifdef HAVE_AVAHI
|
||||
finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context));
|
||||
if (g_strv_contains ((const char * const *)self->repo_finders, "lan"))
|
||||
{
|
||||
avahi_index = finder_index;
|
||||
default_finders[finder_index++] = finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context));
|
||||
}
|
||||
#endif /* HAVE_AVAHI */
|
||||
|
||||
default_finders[0] = finder_config;
|
||||
default_finders[1] = finder_mount;
|
||||
default_finders[2] = finder_avahi;
|
||||
|
||||
/* self->repo_finders is guaranteed to be non-empty */
|
||||
g_assert (default_finders != NULL);
|
||||
finders = default_finders;
|
||||
|
||||
#ifdef HAVE_AVAHI
|
||||
if (finder_avahi != NULL)
|
||||
{
|
||||
ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi),
|
||||
&local_error);
|
||||
|
||||
|
|
@ -5030,9 +5046,10 @@ ostree_repo_find_remotes_async (OstreeRepo *self,
|
|||
else
|
||||
g_warning ("Avahi finder failed abnormally; removing it: %s", local_error->message);
|
||||
|
||||
default_finders[2] = NULL;
|
||||
default_finders[avahi_index] = NULL;
|
||||
g_clear_object (&finder_avahi);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_AVAHI */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,17 +90,19 @@ G_STATIC_ASSERT(sizeof(OstreeRepoPruneOptions) ==
|
|||
* The #OstreeRepo is like git, a content-addressed object store.
|
||||
* Unlike git, it records uid, gid, and extended attributes.
|
||||
*
|
||||
* There are three possible "modes" for an #OstreeRepo;
|
||||
* %OSTREE_REPO_MODE_BARE is very simple - content files are
|
||||
* represented exactly as they are, and checkouts are just hardlinks.
|
||||
* %OSTREE_REPO_MODE_BARE_USER is similar, except the uid/gids are not
|
||||
* set on the files, and checkouts as hardlinks hardlinks work only for user checkouts.
|
||||
* A %OSTREE_REPO_MODE_ARCHIVE_Z2 repository in contrast stores
|
||||
* There are four possible "modes" for an #OstreeRepo; %OSTREE_REPO_MODE_BARE
|
||||
* is very simple - content files are represented exactly as they are, and
|
||||
* checkouts are just hardlinks. %OSTREE_REPO_MODE_BARE_USER is similar, except
|
||||
* the uid/gids are not set on the files, and checkouts as hardlinks work only
|
||||
* for user checkouts. %OSTREE_REPO_MODE_BARE_USER_ONLY is the same as
|
||||
* BARE_USER, but all metadata is not stored, so it can only be used for user
|
||||
* checkouts. This mode does not require xattrs. A %OSTREE_REPO_MODE_ARCHIVE
|
||||
* (also known as %OSTREE_REPO_MODE_ARCHIVE_Z2) repository in contrast stores
|
||||
* content files zlib-compressed. It is suitable for non-root-owned
|
||||
* repositories that can be served via a static HTTP server.
|
||||
*
|
||||
* Creating an #OstreeRepo does not invoke any file I/O, and thus needs
|
||||
* to be initialized, either from an existing contents or with a new
|
||||
* to be initialized, either from existing contents or as a new
|
||||
* repository. If you have an existing repo, use ostree_repo_open()
|
||||
* to load it from disk and check its validity. To initialize a new
|
||||
* repository in the given filepath, use ostree_repo_create() instead.
|
||||
|
|
@ -452,9 +454,9 @@ pop_repo_lock (OstreeRepo *self,
|
|||
* state is not changed and the stack is simply updated.
|
||||
*
|
||||
* ostree_repo_lock_push() waits for the lock depending on the repository's
|
||||
* lock-timeout configuration. When lock-timeout is -1, a blocking lock is
|
||||
* lock-timeout-secs configuration. When lock-timeout-secs is -1, a blocking lock is
|
||||
* attempted. Otherwise, the lock is taken non-blocking and
|
||||
* ostree_repo_lock_push() will sleep synchronously up to lock-timeout seconds
|
||||
* ostree_repo_lock_push() will sleep synchronously up to lock-timeout-secs seconds
|
||||
* attempting to acquire the lock. If the lock cannot be acquired within the
|
||||
* timeout, a %G_IO_ERROR_WOULD_BLOCK error is returned.
|
||||
*
|
||||
|
|
@ -542,9 +544,9 @@ _ostree_repo_lock_push (OstreeRepo *self,
|
|||
* lock.
|
||||
*
|
||||
* ostree_repo_lock_pop() waits for the lock depending on the repository's
|
||||
* lock-timeout configuration. When lock-timeout is -1, a blocking lock is
|
||||
* lock-timeout-secs configuration. When lock-timeout-secs is -1, a blocking lock is
|
||||
* attempted. Otherwise, the lock is removed non-blocking and
|
||||
* ostree_repo_lock_pop() will sleep synchronously up to lock-timeout seconds
|
||||
* ostree_repo_lock_pop() will sleep synchronously up to lock-timeout-secs seconds
|
||||
* attempting to remove the lock. If the lock cannot be removed within the
|
||||
* timeout, a %G_IO_ERROR_WOULD_BLOCK error is returned.
|
||||
*
|
||||
|
|
@ -1033,6 +1035,7 @@ ostree_repo_finalize (GObject *object)
|
|||
g_mutex_clear (&self->cache_lock);
|
||||
g_mutex_clear (&self->txn_lock);
|
||||
g_free (self->collection_id);
|
||||
g_strfreev (self->repo_finders);
|
||||
|
||||
g_clear_pointer (&self->remotes, g_hash_table_destroy);
|
||||
g_mutex_clear (&self->remotes_lock);
|
||||
|
|
@ -2653,6 +2656,37 @@ get_remotes_d_dir (OstreeRepo *self,
|
|||
return g_file_resolve_relative_path (sysroot, SYSCONF_REMOTES);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_free_space_calculate_reserved_bytes (OstreeRepo *self, guint64 *bytes, GError **error)
|
||||
{
|
||||
guint64 reserved_bytes = 0;
|
||||
|
||||
struct statvfs stvfsbuf;
|
||||
if (TEMP_FAILURE_RETRY (fstatvfs (self->repo_dir_fd, &stvfsbuf)) < 0)
|
||||
return glnx_throw_errno_prefix (error, "fstatvfs");
|
||||
|
||||
if (self->min_free_space_mb > 0)
|
||||
{
|
||||
if (self->min_free_space_mb > (G_MAXUINT64 >> 20))
|
||||
return glnx_throw (error, "min-free-space value is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
|
||||
(G_MAXUINT64 >> 20));
|
||||
|
||||
reserved_bytes = self->min_free_space_mb << 20;
|
||||
}
|
||||
else if (self->min_free_space_percent > 0)
|
||||
{
|
||||
if (stvfsbuf.f_frsize > (G_MAXUINT64 / stvfsbuf.f_blocks))
|
||||
return glnx_throw (error, "Filesystem's size is greater than the maximum allowed value of %" G_GUINT64_FORMAT " bytes",
|
||||
(G_MAXUINT64 / stvfsbuf.f_blocks));
|
||||
|
||||
guint64 total_bytes = (stvfsbuf.f_frsize * stvfsbuf.f_blocks);
|
||||
reserved_bytes = ((double)total_bytes) * (self->min_free_space_percent/100.0);
|
||||
}
|
||||
|
||||
*bytes = reserved_bytes;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_free_space_size_validate_and_convert (OstreeRepo *self,
|
||||
const char *min_free_space_size_str,
|
||||
|
|
@ -2799,7 +2833,7 @@ reload_core_config (OstreeRepo *self,
|
|||
&lock_timeout_seconds, error))
|
||||
return FALSE;
|
||||
|
||||
self->lock_timeout_seconds = g_ascii_strtoull (lock_timeout_seconds, NULL, 10);
|
||||
self->lock_timeout_seconds = g_ascii_strtoll (lock_timeout_seconds, NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2905,6 +2939,40 @@ reload_core_config (OstreeRepo *self,
|
|||
self->payload_link_threshold = g_ascii_strtoull (payload_threshold, NULL, 10);
|
||||
}
|
||||
|
||||
{ g_auto(GStrv) configured_finders = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
configured_finders = g_key_file_get_string_list (self->config, "core", "default-repo-finders",
|
||||
NULL, &local_error);
|
||||
if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
|
||||
g_clear_error (&local_error);
|
||||
else if (local_error != NULL)
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (configured_finders != NULL && *configured_finders == NULL)
|
||||
return glnx_throw (error, "Invalid empty default-repo-finders configuration");
|
||||
|
||||
for (char **iter = configured_finders; iter && *iter; iter++)
|
||||
{
|
||||
const char *repo_finder = *iter;
|
||||
|
||||
if (strcmp (repo_finder, "config") != 0 &&
|
||||
strcmp (repo_finder, "lan") != 0 &&
|
||||
strcmp (repo_finder, "mount") != 0)
|
||||
return glnx_throw (error, "Invalid configured repo-finder '%s'", repo_finder);
|
||||
}
|
||||
|
||||
/* Fall back to a default set of finders */
|
||||
if (configured_finders == NULL)
|
||||
configured_finders = g_strsplit ("config;mount", ";", -1);
|
||||
|
||||
g_clear_pointer (&self->repo_finders, g_strfreev);
|
||||
self->repo_finders = g_steal_pointer (&configured_finders);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -3047,16 +3115,6 @@ ostree_repo_open (OstreeRepo *self,
|
|||
return FALSE;
|
||||
self->owner_uid = stbuf.st_uid;
|
||||
|
||||
if (stbuf.st_uid != getuid () || stbuf.st_gid != getgid ())
|
||||
{
|
||||
self->target_owner_uid = stbuf.st_uid;
|
||||
self->target_owner_gid = stbuf.st_gid;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->target_owner_uid = self->target_owner_gid = -1;
|
||||
}
|
||||
|
||||
if (self->writable)
|
||||
{
|
||||
/* Always try to recreate the tmpdir to be nice to people
|
||||
|
|
@ -3292,6 +3350,30 @@ ostree_repo_get_mode (OstreeRepo *self)
|
|||
return self->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_min_free_space:
|
||||
* @self: Repo
|
||||
* @out_reserved_bytes: (out): Location to store the result
|
||||
* @error: Return location for a #GError
|
||||
*
|
||||
* It can be used to query the value (in bytes) of min-free-space-* config option.
|
||||
*
|
||||
* Returns: %TRUE on success, %FALSE otherwise.
|
||||
* Since: 2018.9
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_get_min_free_space_bytes (OstreeRepo *self, guint64 *out_reserved_bytes, GError **error)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE);
|
||||
g_return_val_if_fail (out_reserved_bytes != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (!min_free_space_calculate_reserved_bytes (self, out_reserved_bytes, error))
|
||||
return glnx_prefix_error (error, "Error calculating min-free-space bytes");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_parent:
|
||||
* @self: Repo
|
||||
|
|
@ -5868,3 +5950,22 @@ ostree_repo_set_collection_id (OstreeRepo *self,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_default_repo_finders:
|
||||
* @self: an #OstreeRepo
|
||||
*
|
||||
* Get the set of default repo finders configured. See the documentation for
|
||||
* the "core.default-repo-finders" config key.
|
||||
*
|
||||
* Returns: (array zero-terminated=1) (element-type utf8):
|
||||
* %NULL-terminated array of strings.
|
||||
* Since: 2018.9
|
||||
*/
|
||||
const gchar * const *
|
||||
ostree_repo_get_default_repo_finders (OstreeRepo *self)
|
||||
{
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (self), NULL);
|
||||
|
||||
return (const gchar * const *)self->repo_finders;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ gboolean ostree_repo_set_collection_id (OstreeRepo *self,
|
|||
const gchar *collection_id,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const gchar * const * ostree_repo_get_default_repo_finders (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile * ostree_repo_get_path (OstreeRepo *self);
|
||||
|
||||
|
|
@ -127,6 +130,10 @@ gboolean ostree_repo_equal (OstreeRepo *a,
|
|||
_OSTREE_PUBLIC
|
||||
OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_min_free_space_bytes (OstreeRepo *self,
|
||||
guint64 *out_reserved_bytes,
|
||||
GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile * ostree_repo_get_config (OstreeRepo *self);
|
||||
|
||||
|
|
@ -929,7 +936,8 @@ typedef struct {
|
|||
gboolean no_copy_fallback;
|
||||
gboolean force_copy; /* Since: 2017.6 */
|
||||
gboolean bareuseronly_dirs; /* Since: 2017.7 */
|
||||
gboolean unused_bools[5];
|
||||
gboolean force_copy_zerosized; /* Since: 2018.9 */
|
||||
gboolean unused_bools[4];
|
||||
/* 4 byte hole on 64 bit */
|
||||
|
||||
const char *subpath;
|
||||
|
|
@ -1395,6 +1403,29 @@ gboolean ostree_repo_regenerate_summary (OstreeRepo *self,
|
|||
*/
|
||||
#define OSTREE_REPO_METADATA_REF "ostree-metadata"
|
||||
|
||||
/**
|
||||
* OSTREE_META_KEY_DEPLOY_COLLECTION_ID:
|
||||
*
|
||||
* GVariant type `s`. This key can be used in the repo metadata which is stored
|
||||
* in OSTREE_REPO_METADATA_REF as well as in the summary. The semantics of this
|
||||
* are that the remote repository wants clients to update their remote config
|
||||
* to add this collection ID (clients can't do P2P operations involving a
|
||||
* remote without a collection ID configured on it, even if one is configured
|
||||
* on the server side). Clients must never change or remove a collection ID
|
||||
* already set in their remote config.
|
||||
*
|
||||
* Currently, OSTree does not implement changing a remote config based on this
|
||||
* key, but it may do so in a later release, and until then clients such as
|
||||
* Flatpak may implement it.
|
||||
*
|
||||
* This is a replacement for the similar metadata key implemented by flatpak,
|
||||
* `xa.collection-id`, which is now deprecated as clients which supported it had
|
||||
* bugs with their P2P implementations.
|
||||
*
|
||||
* Since: 2018.9
|
||||
*/
|
||||
#define OSTREE_META_KEY_DEPLOY_COLLECTION_ID "ostree.deploy-collection-id"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#define OSTREE_VARRELABEL_ID SD_ID128_MAKE(da,67,9b,08,ac,d3,45,04,b7,89,d9,6f,81,8e,a7,81)
|
||||
#define OSTREE_CONFIGMERGE_ID SD_ID128_MAKE(d3,86,3b,ae,c1,3e,44,49,ab,03,84,68,4a,8a,f3,a7)
|
||||
#define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1)
|
||||
#define OSTREE_DEPLOYMENT_FINALIZING_ID SD_ID128_MAKE(e8,64,6c,d6,3d,ff,46,25,b7,79,09,a8,e7,a4,09,94)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -2509,6 +2510,47 @@ sysroot_initialize_deployment (OstreeSysroot *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Get a directory fd for the /var of @deployment.
|
||||
* Before we supported having /var be a separate mount point,
|
||||
* this was easy. However, as https://github.com/ostreedev/ostree/issues/1729
|
||||
* raised, in the primary case where we're
|
||||
* doing a new deployment for the booted stateroot,
|
||||
* we need to use /var/. This code doesn't correctly
|
||||
* handle the case of `ostree admin --sysroot upgrade`,
|
||||
* nor (relatedly) the case of upgrading a separate stateroot.
|
||||
*/
|
||||
static gboolean
|
||||
get_var_dfd (OstreeSysroot *self,
|
||||
int osdeploy_dfd,
|
||||
OstreeDeployment *deployment,
|
||||
int *ret_fd,
|
||||
GError **error)
|
||||
{
|
||||
const char *booted_stateroot =
|
||||
self->booted_deployment ? ostree_deployment_get_osname (self->booted_deployment) : NULL;
|
||||
|
||||
int base_dfd;
|
||||
const char *base_path;
|
||||
/* The common case is when we're doing a new deployment for the same stateroot (osname).
|
||||
* If we have a separate mounted /var, then we need to use it - the /var in the
|
||||
* stateroot will probably just be an empty directory.
|
||||
*
|
||||
* If the stateroot doesn't match, just fall back to /var in the target's stateroot.
|
||||
*/
|
||||
if (g_strcmp0 (booted_stateroot, ostree_deployment_get_osname (deployment)) == 0)
|
||||
{
|
||||
base_dfd = AT_FDCWD;
|
||||
base_path = "/var";
|
||||
}
|
||||
else
|
||||
{
|
||||
base_dfd = osdeploy_dfd;
|
||||
base_path = "var";
|
||||
}
|
||||
|
||||
return glnx_opendirat (base_dfd, base_path, TRUE, ret_fd, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sysroot_finalize_deployment (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment,
|
||||
|
|
@ -2547,6 +2589,9 @@ sysroot_finalize_deployment (OstreeSysroot *self,
|
|||
glnx_autofd int os_deploy_dfd = -1;
|
||||
if (!glnx_opendirat (self->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error))
|
||||
return FALSE;
|
||||
glnx_autofd int var_dfd = -1;
|
||||
if (!get_var_dfd (self, os_deploy_dfd, deployment, &var_dfd, error))
|
||||
return FALSE;
|
||||
|
||||
/* Ensure that the new deployment does not have /etc/.updated or
|
||||
* /var/.updated so that systemd ConditionNeedsUpdate=/etc|/var services run
|
||||
|
|
@ -2554,7 +2599,7 @@ sysroot_finalize_deployment (OstreeSysroot *self,
|
|||
*/
|
||||
if (!ot_ensure_unlinked_at (deployment_dfd, "etc/.updated", error))
|
||||
return FALSE;
|
||||
if (!ot_ensure_unlinked_at (os_deploy_dfd, "var/.updated", error))
|
||||
if (!ot_ensure_unlinked_at (var_dfd, ".updated", error))
|
||||
return FALSE;
|
||||
|
||||
g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error);
|
||||
|
|
@ -2716,6 +2761,10 @@ ostree_sysroot_stage_tree (OstreeSysroot *self,
|
|||
if (booted_deployment == NULL)
|
||||
return glnx_throw (error, "Cannot stage a deployment when not currently booted into an OSTree system");
|
||||
|
||||
/* This is used by the testsuite to exercise the path unit, until it becomes the default
|
||||
* (which is pending on the preset making it everywhere). */
|
||||
if ((self->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH) == 0)
|
||||
{
|
||||
/* This is a bit of a hack. When adding a new service we have to end up getting
|
||||
* into the presets for downstream distros; see e.g. https://src.fedoraproject.org/rpms/ostree/pull-request/7
|
||||
*
|
||||
|
|
@ -2728,6 +2777,11 @@ ostree_sysroot_stage_tree (OstreeSysroot *self,
|
|||
return FALSE;
|
||||
if (!g_spawn_check_exit_status (estatus, error))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("test-staged-path: Not running `systemctl start`\n");
|
||||
} /* OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH */
|
||||
|
||||
g_autoptr(OstreeDeployment) deployment = NULL;
|
||||
if (!sysroot_initialize_deployment (self, osname, revision, origin, override_kernel_argv,
|
||||
|
|
@ -2818,6 +2872,21 @@ _ostree_sysroot_finalize_staged (OstreeSysroot *self,
|
|||
if (!self->staged_deployment)
|
||||
return TRUE;
|
||||
|
||||
/* Notice we send this *after* the trivial `return TRUE` above; this msg implies we've
|
||||
* committed to finalizing the deployment. */
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR,
|
||||
SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_FINALIZING_ID),
|
||||
"MESSAGE=Finalizing staged deployment",
|
||||
"OSTREE_OSNAME=%s",
|
||||
ostree_deployment_get_osname (self->staged_deployment),
|
||||
"OSTREE_CHECKSUM=%s",
|
||||
ostree_deployment_get_csum (self->staged_deployment),
|
||||
"OSTREE_DEPLOYSERIAL=%u",
|
||||
ostree_deployment_get_deployserial (self->staged_deployment),
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
g_assert (self->staged_deployment_data);
|
||||
|
||||
g_autoptr(OstreeDeployment) merge_deployment = NULL;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ typedef enum {
|
|||
OSTREE_SYSROOT_DEBUG_NO_XATTRS = 1 << 1,
|
||||
/* https://github.com/ostreedev/ostree/pull/1049 */
|
||||
OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE = 1 << 2,
|
||||
/* This is a temporary flag until we fully drop the explicit `systemctl start
|
||||
* ostree-finalize-staged.service` so that tests can exercise the new path unit. */
|
||||
OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH = 1 << 3,
|
||||
} OstreeSysrootDebugFlags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ ostree_sysroot_init (OstreeSysroot *self)
|
|||
{ "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS },
|
||||
{ "test-fifreeze", OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE },
|
||||
{ "no-xattrs", OSTREE_SYSROOT_DEBUG_NO_XATTRS },
|
||||
{ "test-staged-path", OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH },
|
||||
};
|
||||
|
||||
self->debug_flags = g_parse_debug_string (g_getenv ("OSTREE_SYSROOT_DEBUG"),
|
||||
|
|
@ -376,12 +377,11 @@ _ostree_sysroot_read_current_subbootversion (OstreeSysroot *self,
|
|||
|
||||
g_autofree char *ostree_bootdir_name = g_strdup_printf ("ostree/boot.%d", bootversion);
|
||||
struct stat stbuf;
|
||||
if (fstatat (self->sysroot_fd, ostree_bootdir_name, &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
if (!glnx_fstatat_allow_noent (self->sysroot_fd, ostree_bootdir_name, &stbuf, AT_SYMLINK_NOFOLLOW, error))
|
||||
return FALSE;
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
*out_subbootversion = 0;
|
||||
else
|
||||
return glnx_throw_errno (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -499,10 +499,10 @@ read_current_bootversion (OstreeSysroot *self,
|
|||
int ret_bootversion;
|
||||
struct stat stbuf;
|
||||
|
||||
if (fstatat (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW, error))
|
||||
return FALSE;
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
return glnx_throw_errno (error);
|
||||
ret_bootversion = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -613,6 +613,10 @@ parse_deployment (OstreeSysroot *self,
|
|||
error))
|
||||
return FALSE;
|
||||
|
||||
g_autofree char *errprefix =
|
||||
g_strdup_printf ("Parsing deployment %i in stateroot '%s'", treebootserial, osname);
|
||||
GLNX_AUTO_PREFIX_ERROR(errprefix, error);
|
||||
|
||||
const char *relative_boot_link = boot_link;
|
||||
if (*relative_boot_link == '/')
|
||||
relative_boot_link++;
|
||||
|
|
@ -976,10 +980,11 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
|
|||
/* Otherwise - check for /sysroot which should only exist in a deployment,
|
||||
* not in ${sysroot} (a metavariable for the real physical root).
|
||||
*/
|
||||
else if (fstatat (self->sysroot_fd, "sysroot", &stbuf, 0) < 0)
|
||||
else
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
return glnx_throw_errno_prefix (error, "fstatat");
|
||||
if (!glnx_fstatat_allow_noent (self->sysroot_fd, "sysroot", &stbuf, 0, error))
|
||||
return FALSE;
|
||||
if (errno == ENOENT)
|
||||
self->is_physical = TRUE;
|
||||
}
|
||||
/* Otherwise, the default is FALSE */
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_RELEASE_VERSION (8)
|
||||
#define OSTREE_RELEASE_VERSION (9)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION (2018.8)
|
||||
#define OSTREE_VERSION (2018.9)
|
||||
|
||||
/**
|
||||
* OSTREE_VERSION_S:
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
*
|
||||
* Since: 2017.4
|
||||
*/
|
||||
#define OSTREE_VERSION_S "2018.8"
|
||||
#define OSTREE_VERSION_S "2018.9"
|
||||
|
||||
#define OSTREE_ENCODE_VERSION(year,release) \
|
||||
((year) << 16 | (release))
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ static char *opt_from_file;
|
|||
static gboolean opt_disable_fsync;
|
||||
static gboolean opt_require_hardlinks;
|
||||
static gboolean opt_force_copy;
|
||||
static gboolean opt_force_copy_zerosized;
|
||||
static gboolean opt_bareuseronly_dirs;
|
||||
static char *opt_skiplist_file;
|
||||
static char *opt_selinux_policy;
|
||||
|
|
@ -84,6 +85,7 @@ static GOptionEntry options[] = {
|
|||
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
|
||||
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
|
||||
{ "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL },
|
||||
{ "force-copy-zerosized", 'z', 0, G_OPTION_ARG_NONE, &opt_force_copy_zerosized, "Do not hardlink zero-sized files", NULL },
|
||||
{ "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL },
|
||||
{ "bareuseronly-dirs", 'M', 0, G_OPTION_ARG_NONE, &opt_bareuseronly_dirs, "Suppress mode bits outside of 0775 for directories (suid, world writable, etc.)", NULL },
|
||||
{ "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" },
|
||||
|
|
@ -130,7 +132,8 @@ process_one_checkout (OstreeRepo *repo,
|
|||
* convenient infrastructure for testing C APIs with data.
|
||||
*/
|
||||
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks ||
|
||||
opt_union_add || opt_force_copy || opt_bareuseronly_dirs || opt_union_identical ||
|
||||
opt_union_add || opt_force_copy || opt_force_copy_zerosized ||
|
||||
opt_bareuseronly_dirs || opt_union_identical ||
|
||||
opt_skiplist_file || opt_selinux_policy || opt_selinux_prefix)
|
||||
{
|
||||
OstreeRepoCheckoutAtOptions options = { 0, };
|
||||
|
|
@ -218,6 +221,7 @@ process_one_checkout (OstreeRepo *repo,
|
|||
|
||||
options.no_copy_fallback = opt_require_hardlinks;
|
||||
options.force_copy = opt_force_copy;
|
||||
options.force_copy_zerosized = opt_force_copy_zerosized;
|
||||
options.bareuseronly_dirs = opt_bareuseronly_dirs;
|
||||
|
||||
if (!ostree_repo_checkout_at (repo, &options,
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
|
||||
static gboolean opt_disable_fsync = FALSE;
|
||||
static char *opt_destination_repo = NULL;
|
||||
static char *opt_commit = NULL;
|
||||
|
||||
static GOptionEntry options[] =
|
||||
{
|
||||
{ "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
|
||||
{ "destination-repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_destination_repo, "Use custom repository directory within the mount", "DEST" },
|
||||
{ "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, "Pull a specific commit (only works when a single ref is specified)", "COMMIT" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
@ -78,6 +80,12 @@ ostree_builtin_create_usb (int argc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (opt_commit && argc > 4)
|
||||
{
|
||||
ot_util_usage_error (context, "The --commit option can only be used when a single COLLECTION-ID REF pair is specified", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Open the USB stick, which must exist. Allow automounting and following symlinks. */
|
||||
const char *mount_root_path = argv[1];
|
||||
struct stat mount_root_stbuf;
|
||||
|
|
@ -102,21 +110,17 @@ ostree_builtin_create_usb (int argc,
|
|||
|
||||
/* Open the destination repository on the USB stick or create it if it doesn’t exist.
|
||||
* Check it’s below @mount_root_path, and that it’s not the same as the source
|
||||
* repository.
|
||||
*
|
||||
* If the destination file system supports xattrs (for example, ext4), we use
|
||||
* a BARE_USER repository; if it doesn’t (for example, FAT), we use ARCHIVE.
|
||||
* In either case, we want a lossless repository. */
|
||||
* repository. */
|
||||
const char *dest_repo_path = (opt_destination_repo != NULL) ? opt_destination_repo : ".ostree/repo";
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (mount_root_dfd, dest_repo_path, 0755, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
OstreeRepoMode mode = OSTREE_REPO_MODE_BARE_USER;
|
||||
|
||||
if (TEMP_FAILURE_RETRY (fgetxattr (mount_root_dfd, "user.test", NULL, 0)) < 0 &&
|
||||
(errno == ENOTSUP || errno == EOPNOTSUPP))
|
||||
mode = OSTREE_REPO_MODE_ARCHIVE;
|
||||
/* Always use the archive repo mode, which works on FAT file systems that
|
||||
* don't support xattrs, compresses files to save space, doesn't store
|
||||
* permission info directly in the file attributes, and is at least sometimes
|
||||
* more performant than bare-user */
|
||||
OstreeRepoMode mode = OSTREE_REPO_MODE_ARCHIVE;
|
||||
|
||||
g_debug ("%s: Creating repository in mode %u", G_STRFUNC, mode);
|
||||
|
||||
|
|
@ -158,7 +162,7 @@ ostree_builtin_create_usb (int argc,
|
|||
const OstreeCollectionRef *ref = g_ptr_array_index (refs, i);
|
||||
|
||||
g_variant_builder_add (&refs_builder, "(sss)",
|
||||
ref->collection_id, ref->ref_name, "");
|
||||
ref->collection_id, ref->ref_name, opt_commit ?: "");
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,8 +146,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
|
|||
|
||||
/* If we're doing aliasing, we need the full list of aliases mostly to allow
|
||||
* replacing existing aliases.
|
||||
* If we are deleting a ref, we want to make sure that it doesn't have
|
||||
* any corresponding aliases.
|
||||
*/
|
||||
if (opt_alias)
|
||||
if (opt_alias || opt_delete)
|
||||
{
|
||||
if (!ostree_repo_list_refs_ext (repo, NULL, &ref_aliases,
|
||||
OSTREE_REPO_LIST_REFS_EXT_ALIASES,
|
||||
|
|
@ -246,6 +248,17 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
|
|||
if (!ostree_parse_refspec (refspec, &remote, &ref, error))
|
||||
goto out;
|
||||
|
||||
/* Look for alias if it exists for a ref we want to delete */
|
||||
GLNX_HASH_TABLE_FOREACH_KV (ref_aliases, const char *,
|
||||
ref_alias, const char *, value)
|
||||
{
|
||||
if (!strcmp (ref, value))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Ref '%s' has an active alias: '%s'", ref, ref_alias);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (!ostree_repo_set_ref_immediate (repo, remote, ref, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -628,10 +629,7 @@ rofs_parse_opt (void *data, const char *arg, int key,
|
|||
{
|
||||
basefd = openat (AT_FDCWD, arg, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
|
||||
if (basefd == -1)
|
||||
{
|
||||
perror ("openat");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
err (1, "opening rootfs %s", arg);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -39,13 +39,40 @@
|
|||
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
static void
|
||||
do_remount (const char *target)
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (lstat (target, &stbuf) < 0)
|
||||
return;
|
||||
/* Silently ignore symbolic links; we expect these to point to
|
||||
* /sysroot, and thus there isn't a bind mount there.
|
||||
*/
|
||||
if (S_ISLNK (stbuf.st_mode))
|
||||
return;
|
||||
/* If not a mountpoint, skip it */
|
||||
struct statvfs stvfsbuf;
|
||||
if (statvfs (target, &stvfsbuf) == -1)
|
||||
return;
|
||||
/* If no read-only flag, skip it */
|
||||
if ((stvfsbuf.f_flag & ST_RDONLY) == 0)
|
||||
return;
|
||||
/* It's a mounted, read-only fs; remount it */
|
||||
if (mount (target, target, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
/* Also ignore EINVAL - if the target isn't a mountpoint
|
||||
* already, then assume things are OK.
|
||||
*/
|
||||
if (errno != EINVAL)
|
||||
err (EXIT_FAILURE, "failed to remount %s", target);
|
||||
}
|
||||
else
|
||||
printf ("Remounted: %s\n", target);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *remounts[] = { "/sysroot", "/var", NULL };
|
||||
struct stat stbuf;
|
||||
int i;
|
||||
|
||||
/* When systemd is in use this is normally created via the generator, but
|
||||
* we ensure it's created here as well for redundancy.
|
||||
*/
|
||||
|
|
@ -65,39 +92,11 @@ main(int argc, char *argv[])
|
|||
/* If / isn't writable, don't do any remounts; we don't want
|
||||
* to clear the readonly flag in that case.
|
||||
*/
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
for (i = 0; remounts[i] != NULL; i++)
|
||||
{
|
||||
const char *target = remounts[i];
|
||||
if (lstat (target, &stbuf) < 0)
|
||||
continue;
|
||||
/* Silently ignore symbolic links; we expect these to point to
|
||||
* /sysroot, and thus there isn't a bind mount there.
|
||||
*/
|
||||
if (S_ISLNK (stbuf.st_mode))
|
||||
continue;
|
||||
/* If not a mountpoint, skip it */
|
||||
struct statvfs stvfsbuf;
|
||||
if (statvfs (target, &stvfsbuf) == -1)
|
||||
continue;
|
||||
/* If no read-only flag, skip it */
|
||||
if ((stvfsbuf.f_flag & ST_RDONLY) == 0)
|
||||
continue;
|
||||
/* It's a mounted, read-only fs; remount it */
|
||||
if (mount (target, target, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
/* Also ignore EINVAL - if the target isn't a mountpoint
|
||||
* already, then assume things are OK.
|
||||
*/
|
||||
if (errno != EINVAL)
|
||||
err (EXIT_FAILURE, "failed to remount %s", target);
|
||||
}
|
||||
else
|
||||
printf ("Remounted: %s\n", target);
|
||||
}
|
||||
do_remount ("/sysroot");
|
||||
do_remount ("/var");
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..$((83 + ${extra_basic_tests:-0}))"
|
||||
echo "1..$((85 + ${extra_basic_tests:-0}))"
|
||||
|
||||
CHECKOUT_U_ARG=""
|
||||
CHECKOUT_H_ARGS="-H"
|
||||
|
|
@ -694,6 +694,35 @@ for v in bin link; do
|
|||
done
|
||||
echo "ok checkout union identical conflicts"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
rm files -rf && mkdir files
|
||||
touch files/anemptyfile
|
||||
touch files/anotheremptyfile
|
||||
$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-empty-files --tree=dir=files
|
||||
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} -z tree-with-empty-files tree-with-empty-files
|
||||
if files_are_hardlinked tree-with-empty-files/an{,other}emptyfile; then
|
||||
fatal "--force-copy-zerosized failed"
|
||||
fi
|
||||
rm tree-with-empty-files -rf
|
||||
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} tree-with-empty-files tree-with-empty-files
|
||||
assert_files_hardlinked tree-with-empty-files/an{,other}emptyfile
|
||||
rm tree-with-empty-files -rf
|
||||
echo "ok checkout --force-copy-zerosized"
|
||||
|
||||
# These should merge, they're identical
|
||||
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||
echo notempty > tree-with-empty-files/anemptyfile.new && mv tree-with-empty-files/anemptyfile{.new,}
|
||||
$CMD_PREFIX ostree --repo=repo commit --consume -b tree-with-conflicting-empty-files --tree=dir=tree-with-empty-files
|
||||
# Reset back to base
|
||||
rm tree-with-empty-files -rf
|
||||
$CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-empty-files tree-with-empty-files
|
||||
if $CMD_PREFIX ostree --repo=repo checkout ${CHECKOUT_H_ARGS} --union-identical -z tree-with-conflicting-empty-files tree-with-empty-files 2>err.txt; then
|
||||
fatal "--union-identical --force-copy-zerosized unexpectedly succeeded with non-identical files"
|
||||
fi
|
||||
assert_file_has_content err.txt 'error:.*File exists'
|
||||
echo "ok checkout --union-identical --force-copy-zerosized"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
rm files -rf && mkdir files
|
||||
mkdir files/worldwritable-dir
|
||||
|
|
|
|||
|
|
@ -430,6 +430,54 @@ test_devino_cache_xattrs (void)
|
|||
g_assert_cmpint (stats.content_objects_written, ==, 1);
|
||||
}
|
||||
|
||||
/* https://github.com/ostreedev/ostree/issues/1721
|
||||
* We should be able to commit large metadata objects now.
|
||||
*/
|
||||
static void
|
||||
test_big_metadata (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_autoptr(GFile) repo_path = g_file_new_for_path ("repo");
|
||||
|
||||
/* init as bare-user-only so we run everywhere */
|
||||
ret = ot_test_run_libtest ("setup_test_repository bare-user-only", &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path);
|
||||
ret = ostree_repo_open (repo, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_autoptr(GFile) object_to_commit = NULL;
|
||||
ret = ostree_repo_read_commit (repo, "test2", &object_to_commit, NULL, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new ();
|
||||
ret = ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, NULL,
|
||||
NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
const size_t len = 20 * 1024 * 1024;
|
||||
g_assert_cmpint (len, >, OSTREE_MAX_METADATA_SIZE);
|
||||
g_autofree char *large_buf = g_malloc (len);
|
||||
memset (large_buf, 0x42, len);
|
||||
g_autoptr(GVariantBuilder) builder =
|
||||
g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
g_autofree char *commit_checksum = NULL;
|
||||
g_variant_builder_add (builder, "{sv}", "large-value",
|
||||
g_variant_new_fixed_array ((GVariantType*)"y",
|
||||
large_buf, len, sizeof (char)));
|
||||
ret = ostree_repo_write_commit (repo, NULL, NULL, NULL, g_variant_builder_end (builder),
|
||||
OSTREE_REPO_FILE (object_to_commit), &commit_checksum, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
|
@ -447,6 +495,7 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/xattrs-devino-cache", test_devino_cache_xattrs);
|
||||
g_test_add_func ("/break-hardlink", test_break_hardlink);
|
||||
g_test_add_func ("/remotename", test_validate_remotename);
|
||||
g_test_add_func ("/big-metadata", test_big_metadata);
|
||||
|
||||
return g_test_run();
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -192,6 +192,11 @@ done
|
|||
${CMD_PREFIX} ostree --repo=repo refs -A > refs.txt
|
||||
assert_file_has_content_literal refs.txt 'exampleos/x86_64/stable/server -> exampleos/x86_64/27/server'
|
||||
|
||||
# Test that we don't delete a ref having aliases
|
||||
if ${CMD_PREFIX} ostree --repo=repo refs --delete exampleos/x86_64/27/server; then
|
||||
assert_not_reached "refs --delete unexpectedly succeeded in deleting a ref containing alias!"
|
||||
fi
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo summary -u
|
||||
|
||||
echo "ok ref symlink"
|
||||
|
|
|
|||
|
|
@ -151,6 +151,52 @@ test_repo_equal (Fixture *fixture,
|
|||
g_assert_false (ostree_repo_equal (closed_repo, closed_repo));
|
||||
}
|
||||
|
||||
static void
|
||||
test_repo_get_min_free_space (Fixture *fixture,
|
||||
gconstpointer test_data)
|
||||
{
|
||||
g_autoptr (GKeyFile) config = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
guint64 bytes = 0;
|
||||
typedef struct
|
||||
{
|
||||
const char *val;
|
||||
gboolean should_succeed;
|
||||
} min_free_space_value;
|
||||
|
||||
g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".",
|
||||
OSTREE_REPO_MODE_ARCHIVE,
|
||||
NULL,
|
||||
NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
min_free_space_value values_to_test[] = {
|
||||
{"500MB", TRUE },
|
||||
{ "0MB", TRUE },
|
||||
{ "17179869185GB", FALSE }, /* Overflow parameter: bytes > G_MAXUINT64 */
|
||||
{ NULL, FALSE }
|
||||
};
|
||||
|
||||
config = ostree_repo_copy_config (repo);
|
||||
|
||||
for (guint i = 0; values_to_test[i].val != NULL; i++)
|
||||
{
|
||||
g_key_file_remove_key (config, "core", "min-free-space-size", NULL);
|
||||
g_key_file_set_string (config, "core", "min-free-space-size", values_to_test[i].val);
|
||||
|
||||
ostree_repo_write_config (repo, config, &error);
|
||||
g_assert_no_error (error);
|
||||
ostree_repo_reload_config (repo, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
ostree_repo_get_min_free_space_bytes (repo, &bytes, &error);
|
||||
if (values_to_test[i].should_succeed)
|
||||
g_assert_no_error (error);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
|
|
@ -164,6 +210,9 @@ main (int argc,
|
|||
test_repo_hash_closed, teardown);
|
||||
g_test_add ("/repo/equal", Fixture, NULL, setup,
|
||||
test_repo_equal, teardown);
|
||||
g_test_add ("/repo/get_min_free_space", Fixture, NULL, setup,
|
||||
test_repo_get_min_free_space, teardown);
|
||||
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ echo 'ok documented symbols'
|
|||
|
||||
# ONLY update this checksum in release commits!
|
||||
cat > released-sha256.txt <<EOF
|
||||
a34e3681f1705ed3c6fcf25238e486365cb5b53ffde905ba28a2954ef6eb0269 ${released_syms}
|
||||
ae2946567160d4a47c8a7d000b87306895ee72cdd339e157d21c839e4b2c003a ${released_syms}
|
||||
EOF
|
||||
sha256sum -c released-sha256.txt
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue