Skip to content

Conversation

thaJeztah
Copy link
Member

Issue was reported in moby/moby#34645 (comment), and relates to moby/moby#38599, which addressed this issue for the classic builder.

When copying files between stages, file ownership should be preserved;

FROM busybox:latest as build
RUN touch x && chown 1:1 x

FROM busybox:latest
RUN touch y && chown 1:1 y
COPY --from=build x ./

However, when running with user namespaces enabled:

# grep dockremap /etc/sub*id
/etc/subgid:dockremap:500000:65536
/etc/subuid:dockremap:500000:65536

A build would fail, because BuildKit is trying to map the container's UID/GID to the host:

ERROR: failed to copy file info: failed to chown /var/lib/docker/500000.500000/overlay2/mu5zpgelkig84eo9rlbqdhnn9/merged/x: Container ID 500001 cannot be mapped to a host ID

When looking at the code, I found that (fb *Backend) Copy() takes a action
argument (pb.FileActionCopy), one of its options is wether or not the owner
should be overridden:

buildkit/solver/pb/ops.pb.go

Lines 1457 to 1458 in 226a5db

// optional owner override
Owner *ChownOpt `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`

That argument is passed on to docopy() (which is called from (fb *Backend) Copy()), however inside docopy(), user-mapping is performed, irregardless if Owner was set or not:

ch, err := mapUserToChowner(u, idmap)
if err != nil {
return err
}
opt := []copy.Opt{
func(ci *copy.CopyInfo) {
ci.Chown = ch

This patch makes that step optional, and only performs mapUserToChowner if action.Owner is specified, hopefully addressing the issue.

Issue was reported in moby/moby issue 34645, and relates to moby/moby PR 38599,
which addressed this issue for the classic builder.

When copying files between stages, file ownership should be preserved;

    FROM busybox:latest as build
    RUN touch x && chown 1:1 x

    FROM busybox:latest
    RUN touch y && chown 1:1 y
    COPY --from=build x ./

However, when running with user namespaces enabled:

    # grep dockremap /etc/sub*id
    /etc/subgid:dockremap:500000:65536
    /etc/subuid:dockremap:500000:65536

A build would fail, because BuildKit is trying to map the container's UID/GID
to the host:

    ERROR: failed to copy file info: failed to chown /var/lib/docker/500000.500000/overlay2/mu5zpgelkig84eo9rlbqdhnn9/merged/x: Container ID 500001 cannot be mapped to a host ID

When looking at the code, I found that `(fb *Backend) Copy()` takes a `action`
argument (`pb.FileActionCopy`), one of its options is wether or not the owner
should be overridden:

    // optional owner override
    Owner *ChownOpt `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`)

That argument is passed on to `docopy()` (which is called from `(fb *Backend) Copy()`),
however inside `docopy()`, user-mapping is performed, irregardless if `Owner` was set
or not:

    ch, err := mapUserToChowner(u, idmap)
    if err != nil {
    	return err
    }

    opt := []copy.Opt{
    	func(ci *copy.CopyInfo) {
    		ci.Chown = ch

This patch makes that step optional, and only performs `mapUserToChowner` if
`action.Owner` is specified.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah
Copy link
Member Author

@tonistiigi @AkihiroSuda PTAL: no idea if this is the right fix (and if we have testing in place for user-namespaces); it's just from browsing the code and suspecting this might be the cause of the problem.

if err != nil {
return err
var ch copy.Chowner
if action.Owner != nil {
Copy link
Member

Choose a reason for hiding this comment

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

this check here definitely isn't correct. First, action (including owner) is already parsed before calling this function and the result *copy.User passed to this function directly (with a nil check in map). Secondly, this object being nil doesn't carry any meaning as it is just a combination of two possibly nil pointers.

This issue looks to be regression from #1342

@tonistiigi
Copy link
Member

replaced by #1477

@tonistiigi tonistiigi closed this May 8, 2020
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.

2 participants