Skip to content

snap/pack: ensure layout paths presence for snaps using bare or core26 and later - #16893

Merged
bboozzoo merged 4 commits into
canonical:masterfrom
bboozzoo:bboozzoo/core26-layout-presence-checks
May 6, 2026
Merged

snap/pack: ensure layout paths presence for snaps using bare or core26 and later#16893
bboozzoo merged 4 commits into
canonical:masterfrom
bboozzoo:bboozzoo/core26-layout-presence-checks

Conversation

@bboozzoo

@bboozzoo bboozzoo commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

Ensure that layout paths - sources and tmpfs targets, located under
$SNAP are actually found inside the snap directory tree.

This is an extension of validation introduced for content interface
targets, and follows the exact same rules - i.e. snaps using bare or
core26+ bases are expected to carry relevant paths.

Related: SNAPDENG-36626

Based on #16828

Thanks for helping us make a better snapd!
Have you signed the license agreement and read the contribution guide?

@codecov

codecov Bot commented Apr 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.28571% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.10%. Comparing base (3ec19b3) to head (8426d83).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
snap/pack/pack.go 94.28% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #16893      +/-   ##
==========================================
+ Coverage   79.06%   79.10%   +0.04%     
==========================================
  Files        1368     1375       +7     
  Lines      190680   191204     +524     
  Branches     2465     2465              
==========================================
+ Hits       150758   151259     +501     
- Misses      30835    30842       +7     
- Partials     9087     9103      +16     
Flag Coverage Δ
unittests 79.10% <94.28%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Apr 10, 2026

Copy link
Copy Markdown

Wed May 6 10:08:17 UTC 2026
The following results are from: https://github.com/canonical/snapd/actions/runs/25168270010

Failures:

Preparing:

  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:

Executing:

  • openstack:debian-sid-64:tests/unit/go:static
  • openstack:opensuse-tumbleweed-selinux-64:tests/main/cgroup-devices-v2

Restoring:

  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:
  • openstack:opensuse-15.6-64:

Skipped tests from snapd-testing-skip

If you wish to have any of the below tests run in your PR, in your PR description, add 'unskip:' followed by a copy-and-pasted list (without variants) of the below tests you wish to run (unskip plus test list must be valid yaml)

  • garden:ubuntu-25.10-64:tests/main/apparmor-prompting-support
  • openstack-arm:ubuntu-24.04-arm-64:tests/main/i18n
  • openstack-arm:ubuntu-core-24-arm-64:tests/main/i18n
  • openstack:centos-9-64:tests/main/selinux-clean
  • openstack:debian-sid-64:tests/main/interfaces-network-status-classic
  • openstack:fedora-42-64:tests/main/selinux-clean
  • openstack:ubuntu-24.04-64:tests/main/i18n
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-flag-restart
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_fd_single_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_path_single_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:create_write_write_same_path_single_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:download_file_conflict
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:download_file_defaults
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:download_file_safer
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:read_single_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:read_single_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:special_characters
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:timespan_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:timespan_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_allow_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_deny_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:write_single_allow
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-integration-tests:write_single_deny
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-prompt-restoration
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_allow_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_allow_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_allow_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_allow_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_deny_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_deny_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_deny_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:camera_deny_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_allow_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_allow_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_allow_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_allow_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_deny_forever
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_deny_session
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_deny_single
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-smoke:home_deny_timespan
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-snapd-startup
  • openstack:ubuntu-25.10-64:tests/main/apparmor-prompting-support
  • openstack:ubuntu-25.10-64:tests/main/interfaces-requests-activates-handlers
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-flag-restart
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_actioned_by_other_pid_always_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_multiple_not_actioned_by_other_pid_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_fd_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_chmod_same_path_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:create_write_write_same_path_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_conflict
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_defaults
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:download_file_safer
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:read_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:read_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:special_characters
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:timespan_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:timespan_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_allow_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_read_multiple_actioned_by_other_pid_deny_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_single_allow
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-integration-tests:write_single_deny
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-prompt-restoration
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:audiorecord_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:camera_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_allow_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_forever
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_session
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_single
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-smoke:home_deny_timespan
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-snapd-startup
  • openstack:ubuntu-26.04-64:tests/main/apparmor-prompting-support
  • openstack:ubuntu-26.04-64:tests/main/i18n
  • openstack:ubuntu-26.04-64:tests/main/interfaces-requests-activates-handlers

@zyga zyga left a comment

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.

Looks good.

Comment thread snap/pack/pack.go Outdated
layout := info.Layout[layoutPath]

// Determine the source path. Only check bind and bind-file;
// symlink targets and tmpfs layouts are not validated.

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.

Let's add a TODO for this but keep it as-is.

@bboozzoo bboozzoo added this to the 2.76 milestone Apr 15, 2026
Comment thread snap/pack/pack.go Outdated
Comment thread snap/pack/pack.go Outdated
@bboozzoo
bboozzoo force-pushed the bboozzoo/core26-layout-presence-checks branch from 5ee50f8 to 0919a7f Compare April 27, 2026 14:06
@bboozzoo bboozzoo changed the title snap/pack: ensure layout sources exist in the snap for core26+ snap/pack: ensure layout paths presence for snaps using bare or core26 and later Apr 27, 2026
@bboozzoo
bboozzoo force-pushed the bboozzoo/core26-layout-presence-checks branch from 0919a7f to eaa2cfe Compare April 28, 2026 06:30
@bboozzoo
bboozzoo requested a review from Copilot April 28, 2026 06:30

Copilot AI left a comment

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.

Pull request overview

Extends snap/pack skeleton validation to ensure layout-related paths under $SNAP (bind/bind-file sources and tmpfs targets) actually exist in the snap source tree when packing snaps that should carry those paths (bare / core26+).

Changes:

  • Add layout path presence validation for $SNAP-scoped layout bind/bind-file sources and $SNAP tmpfs mountpoints.
  • Refactor base gating into a shared helper used to decide when strict validation applies.
  • Add unit tests covering valid/invalid layout-path scenarios and skipping for older bases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
snap/pack/pack.go Adds validateLayoutPaths and gates strict validation via needsStrictLayoutOrContentValidation.
snap/pack/pack_test.go Adds test matrix for layout source/tmpfs path presence and old-base skip behavior.

Comment thread snap/pack/pack.go
Comment thread snap/pack/pack_test.go
@bboozzoo
bboozzoo marked this pull request as ready for review April 28, 2026 08:02
@bboozzoo bboozzoo closed this Apr 28, 2026
@bboozzoo bboozzoo reopened this Apr 28, 2026
@github-actions github-actions Bot removed the Run only one system Only runs spread tests on one system label Apr 28, 2026

@pedronis pedronis left a comment

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.

couple of comments

Comment thread snap/pack/pack.go
}
// Only $SNAP paths (or paths with no variable prefix) can be checked at
// pack time; $SNAP_DATA and $SNAP_COMMON are read-write runtime
// directories and mount points can be created as needed.

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.

why is this comment going away?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hm, I may have dropped a bit too much during rebase. Let me restore it

Comment thread snap/pack/pack.go Outdated
Comment on lines +155 to +161
relPath := strings.TrimPrefix(layoutPath, "$SNAP")
relPath = strings.TrimPrefix(relPath, "/")
if relPath == "" {
continue
}
fi, err := container.Lstat(relPath)
if err != nil || !fi.IsDir() {

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.

the other functions has also code like? maybe a small helper?

Comment thread snap/pack/pack.go Outdated
if layout.Bind != "" && (err != nil || !fi.IsDir()) {
return fmt.Errorf("layout %q source %q must exist and be a directory, ensure it is present in the snap or created before packing", layoutPath, source)
}
if layout.BindFile != "" && (err != nil || fi.IsDir()) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hm spotted a small issue here, this should be Mode().IsRegular()

@miguelpires miguelpires left a comment

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.

lgtm, thanks

…6 and later

Ensure that layout paths - sources and tmpfs targets, located under
$SNAP are actually found inside the snap directory tree.

This is an extension of validation introduced for content interface
targets, and follows the exact same rules - i.e. snaps using bare or
core26+ bases are expected to carry relevant paths.

Related: SNAPDENG-36626

Signed-off-by: Maciej Borzecki <maciej.borzecki@canonical.com>
@bboozzoo
bboozzoo force-pushed the bboozzoo/core26-layout-presence-checks branch from 61783fc to 8426d83 Compare April 29, 2026 14:23
@bboozzoo
bboozzoo requested a review from pedronis April 29, 2026 15:11
@bboozzoo bboozzoo added the Auto rerun spread Auto reruns spread up to 4 times in non-draft PRs w/ >=1 approval and <20 fails in any fund. system label Apr 30, 2026

@pedronis pedronis left a comment

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.

thank you

Comment thread snap/pack/pack.go
continue
}
relPath := strings.TrimPrefix(layoutPath, "$SNAP")
relPath = strings.TrimPrefix(relPath, "/")

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.

maybe: we could make a trimSnapPrefix(p) helper that also consider SNAP_DATA and SNAP_COMMON and returns "" in those cases too?

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.

to be clear if we do the helper that might not be the best name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll open a followup PR

@bboozzoo bboozzoo closed this Apr 30, 2026
@bboozzoo bboozzoo reopened this Apr 30, 2026
@bboozzoo
bboozzoo merged commit 5c1a72c into canonical:master May 6, 2026
1246 of 1306 checks passed
@bboozzoo
bboozzoo deleted the bboozzoo/core26-layout-presence-checks branch May 6, 2026 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Auto rerun spread Auto reruns spread up to 4 times in non-draft PRs w/ >=1 approval and <20 fails in any fund. system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants