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:
1 parent
04da47a5fb
commit
51752baf0e
2 files changed
+27
-1
No files matched your search
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user