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"
|
#include "ostree-repo-private.h"
|
||||||
|
|
||||||
#define WHITEOUT_PREFIX ".wh."
|
#define WHITEOUT_PREFIX ".wh."
|
||||||
|
#define OPAQUE_WHITEOUT_NAME ".wh..wh..opq"
|
||||||
|
|
||||||
/* Per-checkout call state/caching */
|
/* Per-checkout call state/caching */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -879,6 +880,7 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean did_exist = FALSE;
|
gboolean did_exist = FALSE;
|
||||||
|
gboolean is_opaque_whiteout = FALSE;
|
||||||
const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs;
|
const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs;
|
||||||
g_autoptr(GVariant) dirtree = NULL;
|
g_autoptr(GVariant) dirtree = NULL;
|
||||||
g_autoptr(GVariant) dirmeta = NULL;
|
g_autoptr(GVariant) dirmeta = NULL;
|
||||||
@ -912,6 +914,22 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
|||||||
return TRUE; /* Note early return */
|
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
|
/* First, make the directory. Push a new scope in case we end up using
|
||||||
* setfscreatecon().
|
* setfscreatecon().
|
||||||
*/
|
*/
|
||||||
@ -931,6 +949,13 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
|||||||
return FALSE;
|
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
|
/* Create initially with mode 0700, then chown/chmod only when we're
|
||||||
* done. This avoids anyone else being able to operate on partially
|
* done. This avoids anyone else being able to operate on partially
|
||||||
* constructed dirs.
|
* constructed dirs.
|
||||||
|
@ -1034,7 +1034,7 @@ echo "ok test error pre commit/bootid"
|
|||||||
# Whiteouts
|
# Whiteouts
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
mkdir -p overlay/baz/
|
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
|
touch overlay/anewfile
|
||||||
mkdir overlay/anewdir/
|
mkdir overlay/anewdir/
|
||||||
touch overlay/anewdir/blah
|
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_not_has_dir overlay-co/deeper
|
||||||
assert_has_file overlay-co/anewdir/blah
|
assert_has_file overlay-co/anewdir/blah
|
||||||
assert_has_file overlay-co/anewfile
|
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
|
# And test replacing a directory wholesale with a symlink as well as a regular file
|
||||||
mkdir overlay
|
mkdir overlay
|
||||||
|
Loading…
Reference in New Issue
Block a user