Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ require (
github.com/coreos/go-oidc/v3 v3.18.0
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/distribution/distribution/v3 v3.0.0-20230519140516-983358f8e250
github.com/docker/docker v28.5.2+incompatible
github.com/docker/go-units v0.5.0
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7
github.com/elazarl/goproxy v1.8.2
github.com/fsnotify/fsnotify v1.9.0
github.com/fsouza/go-dockerclient v1.10.0
github.com/fsouza/go-dockerclient v1.13.2
github.com/ghodss/yaml v1.0.0
github.com/go-ldap/ldap/v3 v3.4.11
github.com/gonum/graph v0.0.0-20170401004347-50b27dea7ebb
github.com/google/go-cmp v0.7.0
github.com/int128/oauth2cli v1.18.0
github.com/joelanford/ignore v0.1.1
github.com/moby/buildkit v0.12.5
github.com/moby/go-archive v0.2.0
github.com/moby/sys/sequential v0.6.0
github.com/moby/sys/user v0.4.0
github.com/moby/term v0.5.2
github.com/onsi/ginkgo/v2 v2.27.2
github.com/onsi/gomega v1.38.2
Expand Down Expand Up @@ -106,7 +107,6 @@ require (
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/docker-credential-helpers v0.9.7 // indirect
github.com/docker/go-connections v0.7.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
Expand Down Expand Up @@ -153,20 +153,16 @@ require (
github.com/lithammer/dedent v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.1.0 // indirect
github.com/moby/moby/api v1.54.2 // indirect
github.com/moby/moby/client v0.4.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/sys/capability v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/runtime-spec v1.3.0 // indirect
Expand Down
22 changes: 8 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ github.com/docker/cli v29.5.1+incompatible h1:NiufLAJoRcPauFoBNYthfuM4REFwM8H2h9
github.com/docker/cli v29.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.9.7 h1:jaPIxEIDz5bQeghNAdzz0ETwMMnM4vzjZlxz3pWP4JA=
github.com/docker/docker-credential-helpers v0.9.7/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c=
Expand All @@ -152,8 +150,8 @@ github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88=
github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fsouza/go-dockerclient v1.10.0 h1:ppSBsbR60I1DFbV4Ag7LlHlHakHFRNLk9XakATW1yVQ=
github.com/fsouza/go-dockerclient v1.10.0/go.mod h1:+iNzAW78AzClIBTZ6WFjkaMvOgz68GyCJ236b1opLTs=
github.com/fsouza/go-dockerclient v1.13.2 h1:u+jAOuR9TZ3PAx2pdHA+ALt1ZZhS8Qx+A4d964IqXtw=
github.com/fsouza/go-dockerclient v1.13.2/go.mod h1:SJu2b0vfcF8sbsWs9VVG03iEjsogvo7JADvsi2wVYAI=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
Expand Down Expand Up @@ -302,18 +300,16 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/moby/buildkit v0.12.5 h1:RNHH1l3HDhYyZafr5EgstEu8aGNCwyfvMtrQDtjH9T0=
github.com/moby/buildkit v0.12.5/go.mod h1:YGwjA2loqyiYfZeEo8FtI7z4x5XponAaIWsWcSjWwso=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg=
github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY=
github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ=
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U=
github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
Expand All @@ -336,8 +332,6 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/admin/release/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"time"

"github.com/blang/semver"
"github.com/docker/docker/pkg/archive"
"github.com/ghodss/yaml"
"github.com/moby/go-archive/compression"
digest "github.com/opencontainers/go-digest"
"github.com/spf13/cobra"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -1142,7 +1142,7 @@ func (o *NewOptions) write(r io.Reader, is *imageapi.ImageStream, now time.Time)
if err := os.MkdirAll(o.ToDir, 0777); err != nil {
return err
}
r, err := archive.DecompressStream(r)
r, err := compression.DecompressStream(r)
if err != nil {
return err
}
Expand Down
85 changes: 58 additions & 27 deletions pkg/cli/image/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ package archive

import (
"archive/tar"
"bufio"
"fmt"
"io"
"os"
"os/user"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"

"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/pools"
"github.com/docker/docker/pkg/system"
"github.com/moby/go-archive"
"github.com/moby/go-archive/compression"
"github.com/moby/sys/sequential"
moby_user "github.com/moby/sys/user"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi, I would prefer to have this labeled as mobyuser. I don't think underscores are very often used.

)

var bufioReader32KPool = sync.Pool{
New: func() any { return bufio.NewReaderSize(nil, 32*1024) },
}

type (
// Compression is the state represents if compressed or not.
Compression int
Expand All @@ -26,14 +32,11 @@ type (

// TarOptions wraps the tar options.
TarOptions struct {
IncludeFiles []string
ExcludePatterns []string
Compression Compression
NoLchown bool
// REMOVED: use remap instead
//UIDMaps []idtools.IDMap
//GIDMaps []idtools.IDMap
ChownOpts *idtools.Identity
IncludeFiles []string
ExcludePatterns []string
Compression Compression
NoLchown bool
ChownOpts *Identity
IncludeSourceDir bool
// WhiteoutFormat is the expected on disk format for whiteout files.
// This format will be converted to the standard format on pack
Expand Down Expand Up @@ -69,21 +72,27 @@ type AlterHeader interface {
Alter(*tar.Header) (bool, error)
}

// Identity holds a UID and GID pair.
type Identity struct {
UID int
GID int
}

type RemapIDs struct {
mappings *idtools.IdentityMapping
mappings *moby_user.IdentityMapping
}

func (r RemapIDs) Alter(hdr *tar.Header) (bool, error) {
ids, err := r.mappings.ToHost(idtools.Identity{UID: hdr.Uid, GID: hdr.Gid})
hdr.Uid, hdr.Gid = ids.UID, ids.GID
uid, gid, err := r.mappings.ToHost(hdr.Uid, hdr.Gid)
hdr.Uid, hdr.Gid = uid, gid
return true, err
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// ApplyLayer is copied from github.com/docker/docker/pkg/archive
func ApplyLayer(dest string, layer io.Reader, options *TarOptions) (int64, error) {
dest = filepath.Clean(dest)
var err error
layer, err = archive.DecompressStream(layer)
layer, err = compression.DecompressStream(layer)
if err != nil {
return 0, err
}
Expand All @@ -96,8 +105,12 @@ func ApplyLayer(dest string, layer io.Reader, options *TarOptions) (int64, error
// Returns the size in bytes of the contents of the layer.
func unpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, err error) {
tr := tar.NewReader(layer)
trBuf := pools.BufioReader32KPool.Get(tr)
defer pools.BufioReader32KPool.Put(trBuf)
trBuf := bufioReader32KPool.Get().(*bufio.Reader)
trBuf.Reset(tr)
defer func() {
trBuf.Reset(nil)
bufioReader32KPool.Put(trBuf)
}()

var dirs []*tar.Header
unpackedPaths := make(map[string]struct{})
Expand Down Expand Up @@ -183,7 +196,7 @@ func unpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
parentPath := filepath.Join(dest, parent)

if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
err = system.MkdirAll(parentPath, 0600)
err = os.MkdirAll(parentPath, 0600)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -301,15 +314,15 @@ func unpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,

for _, hdr := range dirs {
path := filepath.Join(dest, hdr.Name)
if err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {
if err := chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {
return 0, err
}
}

return size, nil
}

func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.Identity, inUserns bool, currentUser *user.User) error {
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *Identity, inUserns bool, currentUser *user.User) error {
// hdr.Mode is in linux format, which we can use for sycalls,
// but for os.Foo() calls we need the mode converted to os.FileMode,
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
Expand Down Expand Up @@ -388,7 +401,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
// Lchown is not supported on Windows.
if Lchown && runtime.GOOS != "windows" {
if chownOpts == nil {
chownOpts = &idtools.Identity{UID: hdr.Uid, GID: hdr.Gid}
chownOpts = &Identity{UID: hdr.Uid, GID: hdr.Gid}
}
if err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil {
return err
Expand All @@ -401,8 +414,8 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
if key == "security.capability" && currentUser != nil && currentUser.Username != "root" {
continue
}
if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil {
if err == system.ErrNotSupportedPlatform {
if err := lsetxattr(path, key, []byte(value), 0); err != nil {
if err == errNotSupportedPlatform {
// we ignore not supported platform errors
// to proceed archiving on platforms like darwin.
continue
Expand Down Expand Up @@ -434,19 +447,37 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
// system.Chtimes doesn't support a NOFOLLOW flag atm
if hdr.Typeflag == tar.TypeLink {
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
if err := system.Chtimes(path, aTime, hdr.ModTime); err != nil {
if err := chtimes(path, aTime, hdr.ModTime); err != nil {
return err
}
}
} else if hdr.Typeflag != tar.TypeSymlink {
if err := system.Chtimes(path, aTime, hdr.ModTime); err != nil {
if err := chtimes(path, aTime, hdr.ModTime); err != nil {
return err
}
} else {
ts := []syscall.Timespec{timeToTimespec(aTime), timeToTimespec(hdr.ModTime)}
if err := system.LUtimesNano(path, ts); err != nil && err != system.ErrNotSupportedPlatform {
if err := lutimesNano(path, ts); err != nil && err != errNotSupportedPlatform {
return err
}
}
return nil
}

var (
unixEpoch = time.Unix(0, 0)
unixMaxTime = time.Unix(0, 1<<63-1)
)

// chtimes clamps atime/mtime to a valid Unix range before calling os.Chtimes.
// os.Chtimes has undefined behavior for times outside [epoch, max], so we
// default out-of-range values to the epoch.
func chtimes(name string, atime, mtime time.Time) error {
if atime.Before(unixEpoch) || atime.After(unixMaxTime) {
atime = unixEpoch
}
if mtime.Before(unixEpoch) || mtime.After(unixMaxTime) {
mtime = unixEpoch
}
return os.Chtimes(name, atime, mtime)
}
45 changes: 42 additions & 3 deletions pkg/cli/image/archive/archive_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,54 @@ package archive

import (
"archive/tar"
"errors"
"os"
"path/filepath"
"strings"
"syscall"

"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/system"
"github.com/moby/go-archive"
"golang.org/x/sys/unix"
)

var errNotSupportedPlatform = errors.New("platform and architecture is not supported")

func lgetxattr(path, attr string) ([]byte, error) {
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
for errors.Is(errno, unix.ERANGE) {
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}
dest = make([]byte, sz)
sz, errno = unix.Lgetxattr(path, attr, dest)
}
if errors.Is(errno, unix.ENODATA) {
return nil, nil
}
if errno != nil {
return nil, errno
}
return dest[:sz], nil
}

func lsetxattr(path, attr string, data []byte, flags int) error {
return unix.Lsetxattr(path, attr, data, flags)
}

func lutimesNano(path string, ts []syscall.Timespec) error {
uts := []unix.Timespec{
unix.NsecToTimespec(syscall.TimespecToNsec(ts[0])),
unix.NsecToTimespec(syscall.TimespecToNsec(ts[1])),
}
err := unix.UtimesNanoAt(unix.AT_FDCWD, path, uts, unix.AT_SYMLINK_NOFOLLOW)
if err != nil && !errors.Is(err, unix.ENOSYS) {
return err
}
return nil
}

func getWhiteoutConverter(format archive.WhiteoutFormat) tarWhiteoutConverter {
if format == archive.OverlayWhiteoutFormat {
return overlayWhiteoutConverter{}
Expand All @@ -33,7 +72,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os

if fi.Mode()&os.ModeDir != 0 {
// convert opaque dirs to AUFS format by writing an empty file with the prefix
opaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
opaque, err := lgetxattr(path, "trusted.overlay.opaque")
if err != nil {
return nil, err
}
Expand Down
Loading