Skip to content

fix: preserve xattrs in layers#1016

Open
bepri wants to merge 4 commits into
mainfrom
work/use-gnu-tar/ROCKCRAFT-282
Open

fix: preserve xattrs in layers#1016
bepri wants to merge 4 commits into
mainfrom
work/use-gnu-tar/ROCKCRAFT-282

Conversation

@bepri
Copy link
Copy Markdown
Member

@bepri bepri commented Oct 30, 2025

  • Have you followed the guidelines for contributing?
  • Have you signed the CLA?
  • Have you successfully run make lint && make test?

Prototype implementation of xattr preservation using GNU tar in Rockcraft. The fix was tested locally using the reproducer in the linked issue. If reviewers are happy with the final implementation, I'll add a spread test confirming this behavior.

Closes #683.
ROCKCRAFT-282

@bepri bepri requested a review from a team October 30, 2025 21:11
@bepri bepri self-assigned this Oct 30, 2025
@bepri bepri requested a review from tigarmo as a code owner October 30, 2025 21:11
Copy link
Copy Markdown
Contributor

@upils upils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that adding a spread test would be very welcomed because with the current tests I am very unsure of what this implementation does.

Maybe the unit tests can be expanded to check the behavior of the added for loop (since it does not depend on the call to tar).

Comment thread rockcraft/layers.py Outdated
Comment on lines +50 to +51
if not temp_tar_file.parent.exists():
temp_tar_file.parent.mkdir(parents=True)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: was it done transparently by tarfile.open() before? I expected the caller of archive_layer() to make sure the directory holding temp_tar_file existed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the previous code assumed the directory existed; we can preserve that assumption and perhaps document it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. This was one of the first lines I added and it did fix things, but it looks like it isn't needed anymore. It's removed now

Comment thread rockcraft/layers.py Outdated
Comment on lines +65 to +77
for arcname in sorted(layer_paths, reverse=True):
filepath = layer_paths[arcname]
emit.debug(f"Adding to layer: {filepath} as '{arcname}'")
tar_file.add(filepath, arcname=arcname, recursive=False)
emit.debug(f"Adding to layer: {filepath} as {arcname!r}")

# Construct a new file at `arcname` with the same contents as `filepath`.
# This emulates the `arcname` parameter of `tarfile.open()`, which is not
# present in GNU tar.
new_path = tmppath / arcname
layer_contents.append(new_path.relative_to(tmppath))
if new_path.is_dir() and new_path.exists():
continue
new_path.parent.mkdir(parents=True, exist_ok=True)
filepath.rename(new_path)
Copy link
Copy Markdown
Contributor

@upils upils Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole piece is confusing me. Despite the comment I am very unsure what it is doing. By recreating directories are we not risking losing permissions/attributes on them?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, and possibly why so many spread tests are failing:

2025-10-30 23:03:44 Failed tasks: 48

@bepri maybe we should look into using the transform command line arg as an 'arcname' substitute

@upils upils requested a review from a team October 31, 2025 08:54
Comment thread rockcraft/layers.py Outdated
Comment on lines +50 to +51
if not temp_tar_file.parent.exists():
temp_tar_file.parent.mkdir(parents=True)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the previous code assumed the directory existed; we can preserve that assumption and perhaps document it

Comment thread rockcraft/layers.py Outdated
Comment on lines +65 to +77
for arcname in sorted(layer_paths, reverse=True):
filepath = layer_paths[arcname]
emit.debug(f"Adding to layer: {filepath} as '{arcname}'")
tar_file.add(filepath, arcname=arcname, recursive=False)
emit.debug(f"Adding to layer: {filepath} as {arcname!r}")

# Construct a new file at `arcname` with the same contents as `filepath`.
# This emulates the `arcname` parameter of `tarfile.open()`, which is not
# present in GNU tar.
new_path = tmppath / arcname
layer_contents.append(new_path.relative_to(tmppath))
if new_path.is_dir() and new_path.exists():
continue
new_path.parent.mkdir(parents=True, exist_ok=True)
filepath.rename(new_path)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, and possibly why so many spread tests are failing:

2025-10-30 23:03:44 Failed tasks: 48

@bepri maybe we should look into using the transform command line arg as an 'arcname' substitute

@tigarmo
Copy link
Copy Markdown
Collaborator

tigarmo commented Nov 12, 2025

I think we should try this AI suggestion next

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File capabilities (xattrs) are not preserved in final ROCK image layers.

3 participants