Add mode, uid, and gid options for mount plugs#461
Conversation
Since the state is stored as JSON, weakly typed plug attributes can be converted from int64 to float64 when the file is attached to a task. Adding another layer of marshalling works around this. Attribute types can be important, for example plug binding uses reflect.DeepEqual to check if two plugs can be bound. Previously plugs defined in SDKs could look different from plugs defined in a workshop. A previous workaround, "Fix type mismatch when comparing workshop definitions," is no longer needed. This reverts commit 92260d7.
8ad60ec to
7add6ea
Compare
0097286 to
702cb16
Compare
dmitry-lyfar
left a comment
There was a problem hiding this comment.
I reviewed everything except fsutil which I'm going to review separately now. There was just one comment so far.
Also, smoke-tested it on both types of mounts, works as expected.
8d24252 to
4ab7732
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR adds mount interface attributes mode, uid, and gid for configuring directory ownership and permissions in mount plugs. The main purpose is to address ownership issues where intermediate directories were previously owned by root:root, making them inaccessible to the workshop user. Now mount plugs can specify proper ownership via these new attributes.
Key changes include:
- Added
mode,uid, andgidattributes to mount interface plugs for directory creation permissions - Replaced the custom
workshop.WorkshopFsinterface with a newfsutil.Fsabstraction for better filesystem operations - Made
.Xauthorityandworkshopctlmounts read-only for security
Reviewed Changes
Copilot reviewed 51 out of 52 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
internal/interfaces/builtin/mount.go |
Adds new mode, uid, gid attributes with validation and fallback logic for mount plugs |
internal/fsutil/fs.go |
New filesystem abstraction with common operations like MkdirAll, AtomicWriteTo, temp file creation |
internal/fsutil/sftp.go |
SFTP filesystem implementation with proper error handling and umask support |
internal/workshop/device.go |
Adds Mode, Owner, Group fields to Mount struct and reorders fields |
internal/interfaces/lxd_device/backend.go |
Enhanced mount preparation with proper directory ownership/permissions handling |
docs/reference/sdks.rst |
Documents new mount plug attributes for permissions and ownership |
fb71109 to
5ecca31
Compare
The new sftpFs works around a number of issues with afero/sftpfs: - Mkdir and OpenFile aren't transactional, they ignore the umask, and don't return ErrExist (required for afero.TempDir and afero.TempFile). - Paths are stripped from certain error types - On error, functions can return non-nil file handles - Sync and WriteAt aren't implemented at all - Readdir and Readdirnames don't use the open file handle The Fs wrapper also brings MkdirAll, MkdirTemp, CreateTemp, WriteFile and ReadFile in line with the standard library implementations. It turns out the only functions that sftpfs implements correctly are those which directly call the corresponding function on the client, so there's no need for sftpfs any more. But we'll continue using BasePathFs. All of these have moved to a standalone fsutil package. Co-authored-by: Dmitry Lyfar <69887876+dmitry-lyfar@users.noreply.github.com>
Co-authored-by: Artem Konev <141050460+akcano@users.noreply.github.com>
5ecca31 to
9345e20
Compare
TICS Quality Gate✔️ PassedworkshopAll conditions passedSee the results in the TICS Viewer The following files have been checked for this project
|
Description
Ties in with canonical/sdkcraft#170. The main issue addressed is for mount plugs like
~/go/pkg/mod- previously the intermediate directories (goandpkg) were owned byroot:root. Now they will be owned byworkshop:workshop. This is configurable using the interface attributesuid,gidandmode.The mount point itself should also be affected, but LXD has some issues (canonical/lxd#12648 and canonical/lxd#16264) which prevent this for now. Not a big deal since the mount point is only visible when the interface is disconnected.
Also fixes a bug where
workshop-source: $SDKrequires a trailing slash (which I thought I'd fixed already but I must have overlooked something).Fixes a recurring issue with interface attributes being different types in workshop and SDK definitions. This is potentially a breaking change (if a launch or refresh is in progress). Removes the need to work around this in the tests.
Makes
.Xauthorityandworkshopctlmounts read-only, because why not?Adds some common directories to the cloud-config:
~/.cache,~/.configand~/.localso SDKs don't need to worry about 0700 permissions~/binand~/.local/binso SDKs don't need to source.profileafter installing something thereFixes several correctness issues with
sftp. I tried to reuse as much functionality as possible, but after fixing a few things the remainingsftpfsfunctions were just directly callingsftp, so I droppedsftpfs. Summary of issues:MkdirandOpenFilearen't transactional, they ignore the umask,and don't return
ErrExist(required forafero.TempDirandafero.TempFile). The rewrites are transactional, but not atomic.They respect a hardcoded umask of 0022, which is the Ubuntu default
for
root.SyncandWriteAtaren't implemented at all. Fixed by removing from theinterface.
ReaddirandReaddirnamesdon't use the open file handle. Fixed by addingReadDirto theFsinterface.After looking at the
sftppackage, I think SFTP is ultimately the right protocolfor us, but both the client and server side need some work to implement the
osfilesystem functions correctly. Some custom extensions might be needed for
something like
os.Root.Self-review quick check
Docs
Or: