mirror of
https://github.com/ostreedev/ostree.git
synced 2024-10-27 01:55:35 +03:00
checkout: honor opaque checkouts
if a file ".wh..wh..opq" is present in a directory, delete anything from lower layers that is already in that directory. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com> Closes: #1486 Approved by: cgwalters
This commit is contained in:
parent
04da47a5fb
commit
51752baf0e
@ -35,6 +35,7 @@
|
||||
#include "ostree-repo-private.h"
|
||||
|
||||
#define WHITEOUT_PREFIX ".wh."
|
||||
#define OPAQUE_WHITEOUT_NAME ".wh..wh..opq"
|
||||
|
||||
/* Per-checkout call state/caching */
|
||||
typedef struct {
|
||||
@ -879,6 +880,7 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
||||
GError **error)
|
||||
{
|
||||
gboolean did_exist = FALSE;
|
||||
gboolean is_opaque_whiteout = FALSE;
|
||||
const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs;
|
||||
g_autoptr(GVariant) dirtree = NULL;
|
||||
g_autoptr(GVariant) dirmeta = NULL;
|
||||
@ -912,6 +914,22 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
||||
return TRUE; /* Note early return */
|
||||
}
|
||||
|
||||
if (options->process_whiteouts)
|
||||
{
|
||||
g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0);
|
||||
GVariantIter viter;
|
||||
const char *fname;
|
||||
g_autoptr(GVariant) contents_csum_v = NULL;
|
||||
g_variant_iter_init (&viter, dir_file_contents);
|
||||
while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v))
|
||||
{
|
||||
is_opaque_whiteout = (g_str_equal (fname, OPAQUE_WHITEOUT_NAME));
|
||||
if (is_opaque_whiteout)
|
||||
break;
|
||||
}
|
||||
contents_csum_v = NULL; /* iter_loop freed it */
|
||||
}
|
||||
|
||||
/* First, make the directory. Push a new scope in case we end up using
|
||||
* setfscreatecon().
|
||||
*/
|
||||
@ -931,6 +949,13 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If it is an opaque whiteout, ensure the destination is empty first. */
|
||||
if (is_opaque_whiteout)
|
||||
{
|
||||
if (!glnx_shutil_rm_rf_at (destination_parent_fd, destination_name, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create initially with mode 0700, then chown/chmod only when we're
|
||||
* done. This avoids anyone else being able to operate on partially
|
||||
* constructed dirs.
|
||||
|
@ -1034,7 +1034,7 @@ echo "ok test error pre commit/bootid"
|
||||
# Whiteouts
|
||||
cd ${test_tmpdir}
|
||||
mkdir -p overlay/baz/
|
||||
if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper; then
|
||||
if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper && touch overlay/baz/another/.wh..wh..opq; then
|
||||
touch overlay/anewfile
|
||||
mkdir overlay/anewdir/
|
||||
touch overlay/anewdir/blah
|
||||
@ -1050,6 +1050,7 @@ if touch overlay/baz/.wh.cow && touch overlay/.wh.deeper; then
|
||||
assert_not_has_dir overlay-co/deeper
|
||||
assert_has_file overlay-co/anewdir/blah
|
||||
assert_has_file overlay-co/anewfile
|
||||
assert_not_has_file overlay-co/baz/another/y
|
||||
|
||||
# And test replacing a directory wholesale with a symlink as well as a regular file
|
||||
mkdir overlay
|
||||
|
Loading…
Reference in New Issue
Block a user