c8d: Fix image commit with userns mapping#46938
Conversation
| if cerrdefs.IsAlreadyExists(err) { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
This check was removed in the new location, that's correct?
| if !errors.Is(err, syscall.EOPNOTSUPP) { | ||
| return err | ||
| } | ||
| break |
There was a problem hiding this comment.
Curious if we must break here, or continue with the next attribute; is it possible some extended attributes are not supported, and we would now be skipping the remaining ones?
I also recall this PR from @corhere where we were silently swallowing errors, and wondering if discarding attributes is the right thing to do;
Also looking at this existing code, which is not ignoring these;
moby/daemon/graphdriver/copy/copy.go
Lines 90 to 106 in 0751141
There was a problem hiding this comment.
The EOPNOTSUPP errors is returned if Extended attributes are not supported by the filesystem, or are disabled. so if one fails, all will fail, that's why I break. The copyXattr is ingoring it, it returns nil if it can't copy the xattrs.
Regarding Cory's PR, Cory is right, we should fail. But his PR doesn't cover all the cases, as you can see with the copyXattr case you just linked. If I fail here, do we want an escape hatch like the one in Cory's PR?
There was a problem hiding this comment.
The EOPNOTSUPP errors is returned if Extended attributes are not supported by the filesystem, or are disabled. so if one fails, all will fail,
Gotcha! It wasn't immediately clear to me if this would "fail for some (but not all)" or always for all.
If I fail here, do we want an escape hatch like the one in Cory's PR?
As the containerd image store is "new territory", and assuming this would only happen in a "broken" setup (unsupported filesystem, so not "because user-NS"), I suggest that we should not provide an escape-hatch out of the box. Worst case, we add one later if there's many complaints, but (as that escape hatch communicates through its ridiculous i_want_broken_containers name) we really shouldn't.
w.r.t. "xattrs are supported", I'm wondering if this is also information that snapshotters should provide and/or if they should somehow detect this and mark themselves as "not supported". I guess some of that may be more complicated with containerd being less opinionated (storage location and such, which may mean "any location could be used?")
Based on the above;
- I think we should probably bail out if it's not supported (return an error that extended attributes are not supported).
- If we do want to "continue", at least it should be logged, and we should have a comment in code describing the intent "if the first one fails.. all of them will fail; it's not supported). So that it's clear that the intent is not to "skip some".
| xattrs := make(map[string][]byte, len(xattrKeys)) | ||
|
|
||
| for _, xattr := range xattrKeys { | ||
| data, err := sysx.LGetxattr(path, xattr) |
There was a problem hiding this comment.
How does continuity's sysx.LGetxattr() differ from our pkg/system.LGetxattr() ? I haven't dug into it, but curious why one is used instead of the other.
There was a problem hiding this comment.
The two are the same, I'm using sysx here because it's the only one that has LListxattr so I thought I should use the same package for everything
There was a problem hiding this comment.
I'm using sysx here because it's the only one that has LListxattr so I thought I should use the same package for everything
Ah! So I noticed that this is the first use of this package in our code, and everything else uses pkg/system. We should look at that;
- consider if "continuity" is the right place for this (I know it's become a bit of a grab-bag of things)
- check what the origin of the "continuity" code is (was it forked from our
pkg/systemor vice-versa?) - consider if we should move that functionality of
pkg/systemelsewhere (perhaps a module in https://github.com/moby/sys) - in either case, consolidate those packages if they really overlap 90%, deprecate one (adding temporary aliases) and remove after.
From a quick look (see the copyXattr function I linked above), this appears to be because we only copy specific attributes;
moby/daemon/graphdriver/copy/copy.go
Line 218 in 581cba2
moby/daemon/graphdriver/copy/copy.go
Line 275 in 581cba2
☝️ that leaves me the question; must we copy all attributes, or is this one of those cases where we should only copy specific ones?
For additional fun and giggles; https://github.com/tonistiigi/fsutil has a copyXattrs (which uses sysx) https://github.com/tonistiigi/fsutil/blob/797bd683d5a28a87bea5421f51db1e112ac2edd4/copy/copy_nowindows.go#L15C1-L32.
| if !errors.Is(err, syscall.EOPNOTSUPP) { | ||
| return err | ||
| } |
There was a problem hiding this comment.
I guess technically the error return should be here (not when reading the attributes), but in practice they should be symmetrical (you cannot either read and write them), but if we decide to produce an error, we should do for both. (similar to https://github.com/tonistiigi/fsutil/blob/797bd683d5a28a87bea5421f51db1e112ac2edd4/copy/copy_nowindows.go#L15C1-L32)
|
Don't merge yet; some things we discussed on Slack;
Also to be looked at; if we should always apply xattrs unfiltered or if there's only specific ones we can safely re-apply after UID/GID changed (but that may need more looking) |
|
@rumpl if you have some time, could you look at the above? (perhaps we can get this one moving then) |
The remapping in the commit code was in the wrong place, we would create a diff and then remap the snapshot, but the descriptor created in "CreateDiff" was still pointing to the old snapshot, we now remap the snapshot before creating a diff. Also make sure we don't lose any capabilities, they used to be lost after the chown. Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
38d267b to
cf5a3bc
Compare
My main concern is that the Some solutions I can think of here ranging from less effort to more effort
|
|
Closing this one in favor of #46972 |
- What I did
Fixed image commit with userns mapping
The remapping in the commit code was in the wrong place, we would create a diff and then remap the snapshot, but the descriptor created in "CreateDiff" was still pointing to the old snapshot, we now remap the snapshot before creating a diff. Also make sure we don't lose any capabilities, they used to be lost after the chown.
Somewhat related to #41724
- How I did it
- How to verify it
The test
TestBuildUserNamespaceValidateCapabilitiesAreV2should pass now$ make DOCKER_GRAPHDRIVER=overlayfs TEST_FILTER=TestBuildUserNamespaceValidateCapabilitiesAreV2 TEST_INTEGRATION_USE_SNAPSHOTTER=1 TEST_IGNORE_CGROUP_CHECK=1 test-integration- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)