Skip to content

Decouple pkg/archive from pkg/system#49072

Merged
thaJeztah merged 6 commits intomoby:masterfrom
dmcgowan:decouple-archive-system
Dec 19, 2024
Merged

Decouple pkg/archive from pkg/system#49072
thaJeztah merged 6 commits intomoby:masterfrom
dmcgowan:decouple-archive-system

Conversation

@dmcgowan
Copy link
Member

@dmcgowan dmcgowan commented Dec 12, 2024

Decouples the pkg/archive and pkg/system to prepare pkg/archive for moving.

This also allowed quite a bit of cleanup due to unnecessary interfaces and workarounds for older versions of the unix package.

@dmcgowan dmcgowan force-pushed the decouple-archive-system branch from d0a8986 to 670cc2d Compare December 12, 2024 07:38
@dmcgowan dmcgowan marked this pull request as ready for review December 12, 2024 08:17
@thaJeztah thaJeztah added status/2-code-review kind/refactor PR's that refactor, or clean-up code area/go-sdk labels Dec 13, 2024
@thaJeztah thaJeztah added this to the 28.0.0 milestone Dec 13, 2024
}

if !system.IsAbs(linkTarget) {
if !filepath.IsAbs(linkTarget) {
Copy link
Member

Choose a reason for hiding this comment

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

Possibly we need to copy the system.IsAbs here for cross platform; see

// IsAbs is a platform-agnostic wrapper for filepath.IsAbs.
//
// On Windows, golang filepath.IsAbs does not consider a path \windows\system32
// as absolute as it doesn't start with a drive-letter/colon combination. However,
// in docker we need to verify things such as WORKDIR /windows/system32 in
// a Dockerfile (which gets translated to \windows\system32 when being processed
// by the daemon). This SHOULD be treated as absolute from a docker processing
// perspective.
func IsAbs(path string) bool {
return filepath.IsAbs(path) || strings.HasPrefix(path, string(os.PathSeparator))
}

Copy link
Member

Choose a reason for hiding this comment

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

☝️ looks like I wrote that up earlier today, but didn't submit. Per discussion in the call; we may not need this, or indeed can create a local copy of it.

Copy link
Member Author

Choose a reason for hiding this comment

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

We shouldn't need it here since we are not running it on non-sanitized input

Comment on lines 44 to 58
// lsetxattr sets the value of the extended attribute identified by attr
// and associated with the given path in the file system.
func lsetxattr(path string, attr string, data []byte, flags int) error {
return unix.Lsetxattr(path, attr, data, flags)
}
Copy link
Member

@thaJeztah thaJeztah Dec 15, 2024

Choose a reason for hiding this comment

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

Looks like this implementation of set/get xattr didn't preserve the improvements that were made to provide more information about the name of the attribute that failed;

Should we preserve that?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll put the path error back and just wrap the error there. Introducing a new error type is not needed and creates another dependency.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I don't think the error-type was matched anywhere, but it was purely for formatting (?)

@thaJeztah
Copy link
Member

did a quick rebase after #49098 was merged

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

Looks like this needs to add back some platform-specific implementations that were provided by pkg/system (see comments)

Comment on lines 112 to 111
return system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor)))
return unix.Mknod(path, mode, int(unix.Mkdev(uint32(hdr.Devmajor), uint32(hdr.Devminor))))
Copy link
Member

Choose a reason for hiding this comment

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

This needs differentiation, because the new implementation doesn't support (Free)BSD; moby/buildkit#5602

49.21 # github.com/docker/docker/pkg/archive
49.21 vendor/github.com/docker/docker/pkg/archive/archive_unix.go:111:32: cannot use int(unix.Mkdev(uint32(hdr.Devmajor), uint32(hdr.Devminor))) (value of type int) as uint64 value in argument to unix.Mknod

Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines 38 to 40
if errors.Is(err, unix.ENODATA) {
return nil, nil
}
Copy link
Member

Choose a reason for hiding this comment

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

Here as well; looks like this doesn't support (Free)BSD; moby/buildkit#5602

49.21 vendor/github.com/docker/docker/pkg/archive/path_unix.go:38:26: undefined: unix.ENODATA

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like FreeBSD has ENOATTR instead:

If the named attribute does not exist, or the process has no access to this attribute, errno is set to ENOATTR.

87 ENOATTR Attribute not found. The specified extended attribute does not exist.

Comment on lines 28 to 29
// Buffer too small, use zero-sized buffer to get the actual size
sz, err = unix.Lgetxattr(path, attr, []byte{})
Copy link
Member

Choose a reason for hiding this comment

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

More failures in the buildx repository, which also runs on OpenBSD (looks like xattrs are not supported there);

#25 [linux/amd64->openbsd/amd64 buildx-build 1/1] RUN --mount=type=bind,target=.   --mount=type=cache,target=/root/.cache   --mount=type=cache,target=/go/pkg/mod   --mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT (set -e...)
#25 0.070 + CGO_ENABLED=0 go build -mod vendor -trimpath -ldflags '-X github.com/docker/buildx/version.Version=53dca9a -X github.com/docker/buildx/version.Revision=53dca9a8946feca5ba7a63cb96140d94f2067656 -X github.com/docker/buildx/version.Package=github.com/docker/buildx -s -w' -o /usr/bin/docker-buildx ./cmd/buildx
#25 35.10 # github.com/docker/docker/pkg/archive
#25 35.10 vendor/github.com/docker/docker/pkg/archive/path_unix.go:25:18: undefined: unix.Lgetxattr
#25 35.10 vendor/github.com/docker/docker/pkg/archive/path_unix.go:29:18: undefined: unix.Lgetxattr
#25 35.10 vendor/github.com/docker/docker/pkg/archive/path_unix.go:34:18: undefined: unix.Lgetxattr
#25 35.10 vendor/github.com/docker/docker/pkg/archive/path_unix.go:38:26: undefined: unix.ENODATA
#25 35.10 vendor/github.com/docker/docker/pkg/archive/path_unix.go:50:53: undefined: unix.Lsetxattr

Copy link
Contributor

Choose a reason for hiding this comment

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

Previously this code was in _linux.go file, so the xattrs were not used on BSD before. I think we can leave making the BSD work for a follow up.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated, it should match what is defined in golang.org/x/sys/unix now

@dmcgowan dmcgowan force-pushed the decouple-archive-system branch from efd6a9f to 95a218f Compare December 17, 2024 18:20
@dmcgowan
Copy link
Member Author

Updated, @thaJeztah can you bump the golang sys package in that buildx PR

Copy link
Contributor

@vvoland vvoland left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

overall LGTM

Left one question (before blaming myself not asking), and some minor nits; no blockers AFAICS, just "touching up" in case you're doing another push.

Comment on lines 5 to 31
const maxSeconds = (1<<63 - 1) / int64(1e9)

func sanitizeTime(t time.Time) time.Time {
if ut := t.Unix(); ut < 0 || ut > maxSeconds {
return time.Unix(0, 0)
}
return t
}
Copy link
Member

Choose a reason for hiding this comment

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

Just to make sure I blame myself not asking; I recall there was some special handling for 32-bit; is that no longer needed, or was that only needed for Windows situations?

// Used by Chtimes
var unixEpochTime, unixMaxTime time.Time
func init() {
unixEpochTime = time.Unix(0, 0)
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
// This is a 64 bit timespec
// os.Chtimes limits time to the following
//
// Note that this intentionally sets nsec (not sec), which sets both sec
// and nsec internally in time.Unix();
// https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380
unixMaxTime = time.Unix(0, 1<<63-1)
} else {
// This is a 32 bit timespec
unixMaxTime = time.Unix(1<<31-1, 0)
}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm just going to pull in containerd's implementation for this, at some point we should have this unified


import "golang.org/x/sys/unix"

var mknod = unix.Mknod
Copy link
Member

Choose a reason for hiding this comment

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

More a "comment" than "need to change". I took this approach as well in some cases, but found that sometimes it became confusing, because this will be listed under variables in GoDoc, not under functions. Less relevant for non-exported functions, but for that reason I sometimes started to lean towards adding a wrapper function instead, i.e..

func mknod(path string, mode uint32, dev uint64)) error {
	return unix.Mknod(path, mode, dev)
}

(no need to change, fine as-is IMO)

Update archive time logic to mirror containerd's

Signed-off-by: Derek McGowan <[email protected]>
These were previously only used for pkg/archive

Signed-off-by: Derek McGowan <[email protected]>
Signed-off-by: Derek McGowan <[email protected]>
@dmcgowan dmcgowan force-pushed the decouple-archive-system branch from 95a218f to 315891d Compare December 19, 2024 18:16
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@thaJeztah thaJeztah merged commit b677cf9 into moby:master Dec 19, 2024
@thaJeztah thaJeztah deleted the decouple-archive-system branch December 19, 2024 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/go-sdk kind/refactor PR's that refactor, or clean-up code status/2-code-review

Projects

Development

Successfully merging this pull request may close these issues.

4 participants