-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interfaces: disable udev backend when inside a container #14930
base: master
Are you sure you want to change the base?
Conversation
interfaces/backends/backends.go
Outdated
@@ -33,6 +35,14 @@ import ( | |||
apparmor_sandbox "github.com/snapcore/snapd/sandbox/apparmor" | |||
) | |||
|
|||
func isContainer() bool { | |||
cmd := exec.Command("systemd-detect-virt", "--container", "--quiet") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are doing this from other places, maybe time to have something in osutil?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I saw we check for non-contianer virt as well. I'll have a look at a common helper used in both places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a helper but one remaining call site is hard to adjust (squashfs) as it introduces dependency loops. I think this is fine for now. Without forcing a package split to resolve that.
A quick run locally shows only unrelated failures:
|
Fri Jan 17 17:28:22 UTC 2025 Failures:Preparing:
Executing:
Restoring:
|
We need know if we are running in a container in quite a few places in the code. It's time to add a helper and call it instead of doing it by hand. Signed-off-by: Zygmunt Krynicki <[email protected]>
Signed-off-by: Zygmunt Krynicki <[email protected]>
6748117
to
3b289f6
Compare
Devices are not namespace-aware in Linux, thus udev inside containers does not really do anything sensible and is set to not execute if /sys is not mounted as a writable file system. This solves the issue where snapd is failing to install snaps in LXD, demanding workarounds like installing the snap twice, hoping that once-generated files are intact and not trigger a udev rule reload. Fixes: https://bugs.launchpad.net/snapd/+bug/1712808 Fixes: https://bugs.launchpad.net/snapd/+bug/1865503 Jira: https://warthogs.atlassian.net/browse/SNAPDENG-24757 Signed-off-by: Zygmunt Krynicki <[email protected]>
3b289f6
to
82721e8
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #14930 +/- ##
==========================================
- Coverage 78.20% 78.06% -0.15%
==========================================
Files 1151 1135 -16
Lines 151396 152387 +991
==========================================
+ Hits 118402 118955 +553
- Misses 25662 26097 +435
- Partials 7332 7335 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are 2 more
// IsContainer returns true if the system is running in a container. | ||
// | ||
// The implementation calls: systemd-detect-virt --quiet --container. It can | ||
// be mocked with testutil.MockCommand. The zero exit code indicates that | ||
// system _is_ running a container. Ensuring that --container is passed is | ||
// important. | ||
func IsContainer() bool { | ||
err := exec.Command("systemd-detect-virt", "--quiet", "--container").Run() | ||
return err == nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// IsContainer returns true if the system is running in a container. | |
// | |
// The implementation calls: systemd-detect-virt --quiet --container. It can | |
// be mocked with testutil.MockCommand. The zero exit code indicates that | |
// system _is_ running a container. Ensuring that --container is passed is | |
// important. | |
func IsContainer() bool { | |
err := exec.Command("systemd-detect-virt", "--quiet", "--container").Run() | |
return err == nil | |
} | |
// IsContainer returns true if the system is running in a container as detected | |
// by systemd helper tool systemd-detect-virt. | |
func IsContainer() bool { | |
// it's imperative to pass --container, zero exit code indicates thatsystem _is_ | |
// running a container | |
err := exec.Command("systemd-detect-virt", "--quiet", "--container").Run() | |
return err == nil | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept the comment on how to mock it in the documentation because that shows up in IDEs.
* | ||
*/ | ||
|
||
package systemd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not entirely convinced this should be in systemd
package. What about osutil
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would it be in osutil? It's literally calling systemd. Osutil is a bag with endless OS code and I'd rather not append to it.
@@ -149,7 +149,7 @@ func loadAppArmorProfiles() error { | |||
|
|||
func isContainer() bool { | |||
// systemd's implementation may fail on WSL2 with custom kernels | |||
return release.OnWSL || (exec.Command("systemd-detect-virt", "--quiet", "--container").Run() == nil) | |||
return release.OnWSL || systemd.IsContainer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are 2 more call locations: osutil/squashfs/fstype.go and daemon/api_general.go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I know.
- squashfs cannot import systemd, I've mentioned that in the comment above.
- daemon doesn't check for containers so I left it out, the signature would be
systemd.VirtualizationType
but this is orthogonal to this fix.
Devices are not namespace-aware in Linux, thus udev inside containers does not really do anything sensible and is set to not execute if /sys is not mounted as a writable file system.
This solves the issue where snapd is failing to install snaps in LXD, demanding workarounds like installing the snap twice, hoping that once-generated files are intact and not trigger a udev rule reload.
Fixes: https://bugs.launchpad.net/snapd/+bug/1712808
Fixes: https://bugs.launchpad.net/snapd/+bug/1865503
Jira: https://warthogs.atlassian.net/browse/SNAPDENG-24757