mirror of https://github.com/docker/cli.git
Merge pull request #1275 from AntaresS/buildkit-support
[enhancement] enable buildkit from daemon side
This commit is contained in:
commit
2461cd618d
|
@ -208,6 +208,7 @@ func (cli *DockerCli) initializeFromClient() {
|
||||||
cli.serverInfo = ServerInfo{
|
cli.serverInfo = ServerInfo{
|
||||||
HasExperimental: ping.Experimental,
|
HasExperimental: ping.Experimental,
|
||||||
OSType: ping.OSType,
|
OSType: ping.OSType,
|
||||||
|
BuildkitVersion: ping.BuilderVersion,
|
||||||
}
|
}
|
||||||
cli.client.NegotiateAPIVersionPing(ping)
|
cli.client.NegotiateAPIVersionPing(ping)
|
||||||
}
|
}
|
||||||
|
@ -241,6 +242,7 @@ func (cli *DockerCli) NewContainerizedEngineClient(sockPath string) (containeriz
|
||||||
type ServerInfo struct {
|
type ServerInfo struct {
|
||||||
HasExperimental bool
|
HasExperimental bool
|
||||||
OSType string
|
OSType string
|
||||||
|
BuildkitVersion types.BuilderVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientInfo stores details about the supported features of the client
|
// ClientInfo stores details about the supported features of the client
|
||||||
|
|
|
@ -189,6 +189,8 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
||||||
if enableBuildkit {
|
if enableBuildkit {
|
||||||
return runBuildBuildKit(dockerCli, options)
|
return runBuildBuildKit(dockerCli, options)
|
||||||
}
|
}
|
||||||
|
} else if dockerCli.ServerInfo().BuildkitVersion == types.BuilderBuildKit {
|
||||||
|
return runBuildBuildKit(dockerCli, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -279,7 +281,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
||||||
excludes = build.TrimBuildFilesFromExcludes(excludes, relDockerfile, options.dockerfileFromStdin())
|
excludes = build.TrimBuildFilesFromExcludes(excludes, relDockerfile, options.dockerfileFromStdin())
|
||||||
buildCtx, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
|
buildCtx, err = archive.TarWithOptions(contextDir, &archive.TarOptions{
|
||||||
ExcludePatterns: excludes,
|
ExcludePatterns: excludes,
|
||||||
ChownOpts: &idtools.IDPair{UID: 0, GID: 0},
|
ChownOpts: &idtools.Identity{UID: 0, GID: 0},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -12,7 +12,7 @@ github.com/cpuguy83/go-md2man v1.0.8
|
||||||
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 # v1.1.0
|
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 # v1.1.0
|
||||||
github.com/dgrijalva/jwt-go a2c85815a77d0f951e33ba4db5ae93629a1530af
|
github.com/dgrijalva/jwt-go a2c85815a77d0f951e33ba4db5ae93629a1530af
|
||||||
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
|
github.com/docker/distribution 83389a148052d74ac602f5f1d62f86ff2f3c4aa5
|
||||||
github.com/docker/docker a7ff19d69a90dfe152abd146221c8b9b46a0903d
|
github.com/docker/docker 991682749612d6613d5f49035f62e2a479c0dc59
|
||||||
github.com/docker/docker-credential-helpers 5241b46610f2491efdf9d1c85f1ddf5b02f6d962
|
github.com/docker/docker-credential-helpers 5241b46610f2491efdf9d1c85f1ddf5b02f6d962
|
||||||
# the docker/go package contains a customized version of canonical/json
|
# the docker/go package contains a customized version of canonical/json
|
||||||
# and is used by Notary. The package is periodically rebased on current Go versions.
|
# and is used by Notary. The package is periodically rebased on current Go versions.
|
||||||
|
|
|
@ -105,6 +105,7 @@ type Ping struct {
|
||||||
APIVersion string
|
APIVersion string
|
||||||
OSType string
|
OSType string
|
||||||
Experimental bool
|
Experimental bool
|
||||||
|
BuilderVersion BuilderVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentVersion describes the version information for a specific component.
|
// ComponentVersion describes the version information for a specific component.
|
||||||
|
@ -204,6 +205,7 @@ type Info struct {
|
||||||
RuncCommit Commit
|
RuncCommit Commit
|
||||||
InitCommit Commit
|
InitCommit Commit
|
||||||
SecurityOptions []string
|
SecurityOptions []string
|
||||||
|
ProductLicense string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyValue holds a key/value pair
|
// KeyValue holds a key/value pair
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ping pings the server and returns the value of the "Docker-Experimental", "OS-Type" & "API-Version" headers
|
// Ping pings the server and returns the value of the "Docker-Experimental", "Builder-Version", "OS-Type" & "API-Version" headers
|
||||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
var ping types.Ping
|
var ping types.Ping
|
||||||
req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||||
|
@ -27,6 +27,9 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
ping.Experimental = true
|
ping.Experimental = true
|
||||||
}
|
}
|
||||||
ping.OSType = serverResp.header.Get("OSType")
|
ping.OSType = serverResp.header.Get("OSType")
|
||||||
|
if bv := serverResp.header.Get("Builder-Version"); bv != "" {
|
||||||
|
ping.BuilderVersion = types.BuilderVersion(bv)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ping, cli.checkResponseErr(serverResp)
|
return ping, cli.checkResponseErr(serverResp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ type (
|
||||||
NoLchown bool
|
NoLchown bool
|
||||||
UIDMaps []idtools.IDMap
|
UIDMaps []idtools.IDMap
|
||||||
GIDMaps []idtools.IDMap
|
GIDMaps []idtools.IDMap
|
||||||
ChownOpts *idtools.IDPair
|
ChownOpts *idtools.Identity
|
||||||
IncludeSourceDir bool
|
IncludeSourceDir bool
|
||||||
// WhiteoutFormat is the expected on disk format for whiteout files.
|
// WhiteoutFormat is the expected on disk format for whiteout files.
|
||||||
// This format will be converted to the standard format on pack
|
// This format will be converted to the standard format on pack
|
||||||
|
@ -73,12 +73,12 @@ type (
|
||||||
// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
|
// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
|
||||||
type Archiver struct {
|
type Archiver struct {
|
||||||
Untar func(io.Reader, string, *TarOptions) error
|
Untar func(io.Reader, string, *TarOptions) error
|
||||||
IDMappingsVar *idtools.IDMappings
|
IDMapping *idtools.IdentityMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDefaultArchiver returns a new Archiver without any IDMappings
|
// NewDefaultArchiver returns a new Archiver without any IdentityMapping
|
||||||
func NewDefaultArchiver() *Archiver {
|
func NewDefaultArchiver() *Archiver {
|
||||||
return &Archiver{Untar: Untar, IDMappingsVar: &idtools.IDMappings{}}
|
return &Archiver{Untar: Untar, IDMapping: &idtools.IdentityMapping{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// breakoutError is used to differentiate errors related to breaking out
|
// breakoutError is used to differentiate errors related to breaking out
|
||||||
|
@ -421,8 +421,8 @@ type tarAppender struct {
|
||||||
|
|
||||||
// for hardlink mapping
|
// for hardlink mapping
|
||||||
SeenFiles map[uint64]string
|
SeenFiles map[uint64]string
|
||||||
IDMappings *idtools.IDMappings
|
IdentityMapping *idtools.IdentityMapping
|
||||||
ChownOpts *idtools.IDPair
|
ChownOpts *idtools.Identity
|
||||||
|
|
||||||
// For packing and unpacking whiteout files in the
|
// For packing and unpacking whiteout files in the
|
||||||
// non standard format. The whiteout files defined
|
// non standard format. The whiteout files defined
|
||||||
|
@ -431,12 +431,12 @@ type tarAppender struct {
|
||||||
WhiteoutConverter tarWhiteoutConverter
|
WhiteoutConverter tarWhiteoutConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts *idtools.IDPair) *tarAppender {
|
func newTarAppender(idMapping *idtools.IdentityMapping, writer io.Writer, chownOpts *idtools.Identity) *tarAppender {
|
||||||
return &tarAppender{
|
return &tarAppender{
|
||||||
SeenFiles: make(map[uint64]string),
|
SeenFiles: make(map[uint64]string),
|
||||||
TarWriter: tar.NewWriter(writer),
|
TarWriter: tar.NewWriter(writer),
|
||||||
Buffer: pools.BufioWriter32KPool.Get(nil),
|
Buffer: pools.BufioWriter32KPool.Get(nil),
|
||||||
IDMappings: idMapping,
|
IdentityMapping: idMapping,
|
||||||
ChownOpts: chownOpts,
|
ChownOpts: chownOpts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,14 +502,12 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
||||||
//handle re-mapping container ID mappings back to host ID mappings before
|
//handle re-mapping container ID mappings back to host ID mappings before
|
||||||
//writing tar headers/files. We skip whiteout files because they were written
|
//writing tar headers/files. We skip whiteout files because they were written
|
||||||
//by the kernel and already have proper ownership relative to the host
|
//by the kernel and already have proper ownership relative to the host
|
||||||
if !isOverlayWhiteout &&
|
if !isOverlayWhiteout && !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IdentityMapping.Empty() {
|
||||||
!strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) &&
|
|
||||||
!ta.IDMappings.Empty() {
|
|
||||||
fileIDPair, err := getFileUIDGID(fi.Sys())
|
fileIDPair, err := getFileUIDGID(fi.Sys())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
hdr.Uid, hdr.Gid, err = ta.IDMappings.ToContainer(fileIDPair)
|
hdr.Uid, hdr.Gid, err = ta.IdentityMapping.ToContainer(fileIDPair)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -572,7 +570,7 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.IDPair, inUserns bool) error {
|
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.Identity, inUserns bool) error {
|
||||||
// hdr.Mode is in linux format, which we can use for sycalls,
|
// 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,
|
// but for os.Foo() calls we need the mode converted to os.FileMode,
|
||||||
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
|
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
|
||||||
|
@ -652,7 +650,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
|
||||||
// Lchown is not supported on Windows.
|
// Lchown is not supported on Windows.
|
||||||
if Lchown && runtime.GOOS != "windows" {
|
if Lchown && runtime.GOOS != "windows" {
|
||||||
if chownOpts == nil {
|
if chownOpts == nil {
|
||||||
chownOpts = &idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid}
|
chownOpts = &idtools.Identity{UID: hdr.Uid, GID: hdr.Gid}
|
||||||
}
|
}
|
||||||
if err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil {
|
if err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -901,8 +899,8 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err
|
||||||
defer pools.BufioReader32KPool.Put(trBuf)
|
defer pools.BufioReader32KPool.Put(trBuf)
|
||||||
|
|
||||||
var dirs []*tar.Header
|
var dirs []*tar.Header
|
||||||
idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
||||||
rootIDs := idMappings.RootPair()
|
rootIDs := idMapping.RootPair()
|
||||||
whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat)
|
whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat)
|
||||||
|
|
||||||
// Iterate through the files in the archive.
|
// Iterate through the files in the archive.
|
||||||
|
@ -981,7 +979,7 @@ loop:
|
||||||
}
|
}
|
||||||
trBuf.Reset(tr)
|
trBuf.Reset(tr)
|
||||||
|
|
||||||
if err := remapIDs(idMappings, hdr); err != nil {
|
if err := remapIDs(idMapping, hdr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,8 +1066,8 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
|
||||||
}
|
}
|
||||||
defer archive.Close()
|
defer archive.Close()
|
||||||
options := &TarOptions{
|
options := &TarOptions{
|
||||||
UIDMaps: archiver.IDMappingsVar.UIDs(),
|
UIDMaps: archiver.IDMapping.UIDs(),
|
||||||
GIDMaps: archiver.IDMappingsVar.GIDs(),
|
GIDMaps: archiver.IDMapping.GIDs(),
|
||||||
}
|
}
|
||||||
return archiver.Untar(archive, dst, options)
|
return archiver.Untar(archive, dst, options)
|
||||||
}
|
}
|
||||||
|
@ -1082,8 +1080,8 @@ func (archiver *Archiver) UntarPath(src, dst string) error {
|
||||||
}
|
}
|
||||||
defer archive.Close()
|
defer archive.Close()
|
||||||
options := &TarOptions{
|
options := &TarOptions{
|
||||||
UIDMaps: archiver.IDMappingsVar.UIDs(),
|
UIDMaps: archiver.IDMapping.UIDs(),
|
||||||
GIDMaps: archiver.IDMappingsVar.GIDs(),
|
GIDMaps: archiver.IDMapping.GIDs(),
|
||||||
}
|
}
|
||||||
return archiver.Untar(archive, dst, options)
|
return archiver.Untar(archive, dst, options)
|
||||||
}
|
}
|
||||||
|
@ -1104,7 +1102,7 @@ func (archiver *Archiver) CopyWithTar(src, dst string) error {
|
||||||
// if this Archiver is set up with ID mapping we need to create
|
// if this Archiver is set up with ID mapping we need to create
|
||||||
// the new destination directory with the remapped root UID/GID pair
|
// the new destination directory with the remapped root UID/GID pair
|
||||||
// as owner
|
// as owner
|
||||||
rootIDs := archiver.IDMappingsVar.RootPair()
|
rootIDs := archiver.IDMapping.RootPair()
|
||||||
// Create dst, copy src's content into it
|
// Create dst, copy src's content into it
|
||||||
logrus.Debugf("Creating dest directory: %s", dst)
|
logrus.Debugf("Creating dest directory: %s", dst)
|
||||||
if err := idtools.MkdirAllAndChownNew(dst, 0755, rootIDs); err != nil {
|
if err := idtools.MkdirAllAndChownNew(dst, 0755, rootIDs); err != nil {
|
||||||
|
@ -1164,7 +1162,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
||||||
hdr.Name = filepath.Base(dst)
|
hdr.Name = filepath.Base(dst)
|
||||||
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
|
hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
|
||||||
|
|
||||||
if err := remapIDs(archiver.IDMappingsVar, hdr); err != nil {
|
if err := remapIDs(archiver.IDMapping, hdr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,13 +1190,13 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDMappings returns the IDMappings of the archiver.
|
// IdentityMapping returns the IdentityMapping of the archiver.
|
||||||
func (archiver *Archiver) IDMappings() *idtools.IDMappings {
|
func (archiver *Archiver) IdentityMapping() *idtools.IdentityMapping {
|
||||||
return archiver.IDMappingsVar
|
return archiver.IDMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
func remapIDs(idMappings *idtools.IDMappings, hdr *tar.Header) error {
|
func remapIDs(idMapping *idtools.IdentityMapping, hdr *tar.Header) error {
|
||||||
ids, err := idMappings.ToHost(idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid})
|
ids, err := idMapping.ToHost(idtools.Identity{UID: hdr.Uid, GID: hdr.Gid})
|
||||||
hdr.Uid, hdr.Gid = ids.UID, ids.GID
|
hdr.Uid, hdr.Gid = ids.UID, ids.GID
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,13 +68,13 @@ func getInodeFromStat(stat interface{}) (inode uint64, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
func getFileUIDGID(stat interface{}) (idtools.Identity, error) {
|
||||||
s, ok := stat.(*syscall.Stat_t)
|
s, ok := stat.(*syscall.Stat_t)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return idtools.IDPair{}, errors.New("cannot convert stat value to syscall.Stat_t")
|
return idtools.Identity{}, errors.New("cannot convert stat value to syscall.Stat_t")
|
||||||
}
|
}
|
||||||
return idtools.IDPair{UID: int(s.Uid), GID: int(s.Gid)}, nil
|
return idtools.Identity{UID: int(s.Uid), GID: int(s.Gid)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
|
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
|
||||||
|
|
|
@ -61,7 +61,7 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
|
func getFileUIDGID(stat interface{}) (idtools.Identity, error) {
|
||||||
// no notion of file ownership mapping yet on Windows
|
// no notion of file ownership mapping yet on Windows
|
||||||
return idtools.IDPair{UID: 0, GID: 0}, nil
|
return idtools.Identity{UID: 0, GID: 0}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
||||||
if options.ExcludePatterns == nil {
|
if options.ExcludePatterns == nil {
|
||||||
options.ExcludePatterns = []string{}
|
options.ExcludePatterns = []string{}
|
||||||
}
|
}
|
||||||
idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
||||||
|
|
||||||
aufsTempdir := ""
|
aufsTempdir := ""
|
||||||
aufsHardlinks := make(map[string]*tar.Header)
|
aufsHardlinks := make(map[string]*tar.Header)
|
||||||
|
@ -192,7 +192,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
|
||||||
srcData = tmpFile
|
srcData = tmpFile
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := remapIDs(idMappings, srcHdr); err != nil {
|
if err := remapIDs(idMapping, srcHdr); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,23 +37,23 @@ const (
|
||||||
// MkdirAllAndChown creates a directory (include any along the path) and then modifies
|
// MkdirAllAndChown creates a directory (include any along the path) and then modifies
|
||||||
// ownership to the requested uid/gid. If the directory already exists, this
|
// ownership to the requested uid/gid. If the directory already exists, this
|
||||||
// function will still change ownership to the requested uid/gid pair.
|
// function will still change ownership to the requested uid/gid pair.
|
||||||
func MkdirAllAndChown(path string, mode os.FileMode, owner IDPair) error {
|
func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error {
|
||||||
return mkdirAs(path, mode, owner.UID, owner.GID, true, true)
|
return mkdirAs(path, mode, owner, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid.
|
// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid.
|
||||||
// If the directory already exists, this function still changes ownership.
|
// If the directory already exists, this function still changes ownership.
|
||||||
// Note that unlike os.Mkdir(), this function does not return IsExist error
|
// Note that unlike os.Mkdir(), this function does not return IsExist error
|
||||||
// in case path already exists.
|
// in case path already exists.
|
||||||
func MkdirAndChown(path string, mode os.FileMode, owner IDPair) error {
|
func MkdirAndChown(path string, mode os.FileMode, owner Identity) error {
|
||||||
return mkdirAs(path, mode, owner.UID, owner.GID, false, true)
|
return mkdirAs(path, mode, owner, false, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies
|
// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies
|
||||||
// ownership ONLY of newly created directories to the requested uid/gid. If the
|
// ownership ONLY of newly created directories to the requested uid/gid. If the
|
||||||
// directories along the path exist, no change of ownership will be performed
|
// directories along the path exist, no change of ownership will be performed
|
||||||
func MkdirAllAndChownNew(path string, mode os.FileMode, owner IDPair) error {
|
func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error {
|
||||||
return mkdirAs(path, mode, owner.UID, owner.GID, true, false)
|
return mkdirAs(path, mode, owner, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
|
// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.
|
||||||
|
@ -102,22 +102,23 @@ func toHost(contID int, idMap []IDMap) (int, error) {
|
||||||
return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID)
|
return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDPair is a UID and GID pair
|
// Identity is either a UID and GID pair or a SID (but not both)
|
||||||
type IDPair struct {
|
type Identity struct {
|
||||||
UID int
|
UID int
|
||||||
GID int
|
GID int
|
||||||
|
SID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IDMappings contains a mappings of UIDs and GIDs
|
// IdentityMapping contains a mappings of UIDs and GIDs
|
||||||
type IDMappings struct {
|
type IdentityMapping struct {
|
||||||
uids []IDMap
|
uids []IDMap
|
||||||
gids []IDMap
|
gids []IDMap
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIDMappings takes a requested user and group name and
|
// NewIdentityMapping takes a requested user and group name and
|
||||||
// using the data from /etc/sub{uid,gid} ranges, creates the
|
// using the data from /etc/sub{uid,gid} ranges, creates the
|
||||||
// proper uid and gid remapping ranges for that user/group pair
|
// proper uid and gid remapping ranges for that user/group pair
|
||||||
func NewIDMappings(username, groupname string) (*IDMappings, error) {
|
func NewIdentityMapping(username, groupname string) (*IdentityMapping, error) {
|
||||||
subuidRanges, err := parseSubuid(username)
|
subuidRanges, err := parseSubuid(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -133,7 +134,7 @@ func NewIDMappings(username, groupname string) (*IDMappings, error) {
|
||||||
return nil, fmt.Errorf("No subgid ranges found for group %q", groupname)
|
return nil, fmt.Errorf("No subgid ranges found for group %q", groupname)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &IDMappings{
|
return &IdentityMapping{
|
||||||
uids: createIDMap(subuidRanges),
|
uids: createIDMap(subuidRanges),
|
||||||
gids: createIDMap(subgidRanges),
|
gids: createIDMap(subgidRanges),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -141,21 +142,21 @@ func NewIDMappings(username, groupname string) (*IDMappings, error) {
|
||||||
|
|
||||||
// NewIDMappingsFromMaps creates a new mapping from two slices
|
// NewIDMappingsFromMaps creates a new mapping from two slices
|
||||||
// Deprecated: this is a temporary shim while transitioning to IDMapping
|
// Deprecated: this is a temporary shim while transitioning to IDMapping
|
||||||
func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IDMappings {
|
func NewIDMappingsFromMaps(uids []IDMap, gids []IDMap) *IdentityMapping {
|
||||||
return &IDMappings{uids: uids, gids: gids}
|
return &IdentityMapping{uids: uids, gids: gids}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RootPair returns a uid and gid pair for the root user. The error is ignored
|
// RootPair returns a uid and gid pair for the root user. The error is ignored
|
||||||
// because a root user always exists, and the defaults are correct when the uid
|
// because a root user always exists, and the defaults are correct when the uid
|
||||||
// and gid maps are empty.
|
// and gid maps are empty.
|
||||||
func (i *IDMappings) RootPair() IDPair {
|
func (i *IdentityMapping) RootPair() Identity {
|
||||||
uid, gid, _ := GetRootUIDGID(i.uids, i.gids)
|
uid, gid, _ := GetRootUIDGID(i.uids, i.gids)
|
||||||
return IDPair{UID: uid, GID: gid}
|
return Identity{UID: uid, GID: gid}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToHost returns the host UID and GID for the container uid, gid.
|
// ToHost returns the host UID and GID for the container uid, gid.
|
||||||
// Remapping is only performed if the ids aren't already the remapped root ids
|
// Remapping is only performed if the ids aren't already the remapped root ids
|
||||||
func (i *IDMappings) ToHost(pair IDPair) (IDPair, error) {
|
func (i *IdentityMapping) ToHost(pair Identity) (Identity, error) {
|
||||||
var err error
|
var err error
|
||||||
target := i.RootPair()
|
target := i.RootPair()
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ func (i *IDMappings) ToHost(pair IDPair) (IDPair, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToContainer returns the container UID and GID for the host uid and gid
|
// ToContainer returns the container UID and GID for the host uid and gid
|
||||||
func (i *IDMappings) ToContainer(pair IDPair) (int, int, error) {
|
func (i *IdentityMapping) ToContainer(pair Identity) (int, int, error) {
|
||||||
uid, err := toContainer(pair.UID, i.uids)
|
uid, err := toContainer(pair.UID, i.uids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, -1, err
|
return -1, -1, err
|
||||||
|
@ -183,19 +184,19 @@ func (i *IDMappings) ToContainer(pair IDPair) (int, int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty returns true if there are no id mappings
|
// Empty returns true if there are no id mappings
|
||||||
func (i *IDMappings) Empty() bool {
|
func (i *IdentityMapping) Empty() bool {
|
||||||
return len(i.uids) == 0 && len(i.gids) == 0
|
return len(i.uids) == 0 && len(i.gids) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// UIDs return the UID mapping
|
// UIDs return the UID mapping
|
||||||
// TODO: remove this once everything has been refactored to use pairs
|
// TODO: remove this once everything has been refactored to use pairs
|
||||||
func (i *IDMappings) UIDs() []IDMap {
|
func (i *IdentityMapping) UIDs() []IDMap {
|
||||||
return i.uids
|
return i.uids
|
||||||
}
|
}
|
||||||
|
|
||||||
// GIDs return the UID mapping
|
// GIDs return the UID mapping
|
||||||
// TODO: remove this once everything has been refactored to use pairs
|
// TODO: remove this once everything has been refactored to use pairs
|
||||||
func (i *IDMappings) GIDs() []IDMap {
|
func (i *IdentityMapping) GIDs() []IDMap {
|
||||||
return i.gids
|
return i.gids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,12 @@ var (
|
||||||
getentCmd string
|
getentCmd string
|
||||||
)
|
)
|
||||||
|
|
||||||
func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error {
|
func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error {
|
||||||
// make an array containing the original path asked for, plus (for mkAll == true)
|
// make an array containing the original path asked for, plus (for mkAll == true)
|
||||||
// all path components leading up to the complete path that don't exist before we MkdirAll
|
// all path components leading up to the complete path that don't exist before we MkdirAll
|
||||||
// so that we can chown all of them properly at the end. If chownExisting is false, we won't
|
// so that we can chown all of them properly at the end. If chownExisting is false, we won't
|
||||||
// chown the full directory path if it exists
|
// chown the full directory path if it exists
|
||||||
|
|
||||||
var paths []string
|
var paths []string
|
||||||
|
|
||||||
stat, err := system.Stat(path)
|
stat, err := system.Stat(path)
|
||||||
|
@ -38,7 +39,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
|
||||||
}
|
}
|
||||||
|
|
||||||
// short-circuit--we were called with an existing directory and chown was requested
|
// short-circuit--we were called with an existing directory and chown was requested
|
||||||
return lazyChown(path, ownerUID, ownerGID, stat)
|
return lazyChown(path, owner.UID, owner.GID, stat)
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
@ -69,7 +70,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
|
||||||
// even if it existed, we will chown the requested path + any subpaths that
|
// even if it existed, we will chown the requested path + any subpaths that
|
||||||
// didn't exist when we called MkdirAll
|
// didn't exist when we called MkdirAll
|
||||||
for _, pathComponent := range paths {
|
for _, pathComponent := range paths {
|
||||||
if err := lazyChown(pathComponent, ownerUID, ownerGID, nil); err != nil {
|
if err := lazyChown(pathComponent, owner.UID, owner.GID, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
|
||||||
|
|
||||||
// CanAccess takes a valid (existing) directory and a uid, gid pair and determines
|
// CanAccess takes a valid (existing) directory and a uid, gid pair and determines
|
||||||
// if that uid, gid pair has access (execute bit) to the directory
|
// if that uid, gid pair has access (execute bit) to the directory
|
||||||
func CanAccess(path string, pair IDPair) bool {
|
func CanAccess(path string, pair Identity) bool {
|
||||||
statInfo, err := system.Stat(path)
|
statInfo, err := system.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -6,9 +6,11 @@ import (
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Platforms such as Windows do not support the UID/GID concept. So make this
|
// This is currently a wrapper around MkdirAll, however, since currently
|
||||||
// just a wrapper around system.MkdirAll.
|
// permissions aren't set through this path, the identity isn't utilized.
|
||||||
func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chownExisting bool) error {
|
// Ownership is handled elsewhere, but in the future could be support here
|
||||||
|
// too.
|
||||||
|
func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error {
|
||||||
if err := system.MkdirAll(path, mode, ""); err != nil {
|
if err := system.MkdirAll(path, mode, ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -18,6 +20,6 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
|
||||||
// CanAccess takes a valid (existing) directory and a uid, gid pair and determines
|
// CanAccess takes a valid (existing) directory and a uid, gid pair and determines
|
||||||
// if that uid, gid pair has access (execute bit) to the directory
|
// if that uid, gid pair has access (execute bit) to the directory
|
||||||
// Windows does not require/support this function, so always return true
|
// Windows does not require/support this function, so always return true
|
||||||
func CanAccess(path string, pair IDPair) bool {
|
func CanAccess(path string, identity Identity) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,62 @@ package system // import "github.com/docker/docker/pkg/system"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
OWNER_SECURITY_INFORMATION = 0x00000001
|
||||||
|
GROUP_SECURITY_INFORMATION = 0x00000002
|
||||||
|
DACL_SECURITY_INFORMATION = 0x00000004
|
||||||
|
SACL_SECURITY_INFORMATION = 0x00000008
|
||||||
|
LABEL_SECURITY_INFORMATION = 0x00000010
|
||||||
|
ATTRIBUTE_SECURITY_INFORMATION = 0x00000020
|
||||||
|
SCOPE_SECURITY_INFORMATION = 0x00000040
|
||||||
|
PROCESS_TRUST_LABEL_SECURITY_INFORMATION = 0x00000080
|
||||||
|
ACCESS_FILTER_SECURITY_INFORMATION = 0x00000100
|
||||||
|
BACKUP_SECURITY_INFORMATION = 0x00010000
|
||||||
|
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
|
||||||
|
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000
|
||||||
|
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
|
||||||
|
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SE_UNKNOWN_OBJECT_TYPE = iota
|
||||||
|
SE_FILE_OBJECT
|
||||||
|
SE_SERVICE
|
||||||
|
SE_PRINTER
|
||||||
|
SE_REGISTRY_KEY
|
||||||
|
SE_LMSHARE
|
||||||
|
SE_KERNEL_OBJECT
|
||||||
|
SE_WINDOW_OBJECT
|
||||||
|
SE_DS_OBJECT
|
||||||
|
SE_DS_OBJECT_ALL
|
||||||
|
SE_PROVIDER_DEFINED_OBJECT
|
||||||
|
SE_WMIGUID_OBJECT
|
||||||
|
SE_REGISTRY_WOW64_32KEY
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ContainerAdministratorSidString = "S-1-5-93-2-1"
|
||||||
|
ContainerUserSidString = "S-1-5-93-2-2"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
||||||
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
||||||
procGetProductInfo = modkernel32.NewProc("GetProductInfo")
|
procGetProductInfo = modkernel32.NewProc("GetProductInfo")
|
||||||
|
procSetNamedSecurityInfo = modadvapi32.NewProc("SetNamedSecurityInfoW")
|
||||||
|
procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl")
|
||||||
)
|
)
|
||||||
|
|
||||||
// OSVersion is a wrapper for Windows version information
|
// OSVersion is a wrapper for Windows version information
|
||||||
|
@ -125,3 +171,23 @@ func HasWin32KSupport() bool {
|
||||||
// APIs.
|
// APIs.
|
||||||
return ntuserApiset.Load() == nil
|
return ntuserApiset.Load() == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetNamedSecurityInfo(objectName *uint16, objectType uint32, securityInformation uint32, sidOwner *windows.SID, sidGroup *windows.SID, dacl *byte, sacl *byte) (result error) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfo.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(sidOwner)), uintptr(unsafe.Pointer(sidGroup)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
result = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSecurityDescriptorDacl(securityDescriptor *byte, daclPresent *uint32, dacl **byte, daclDefaulted *uint32) (result error) {
|
||||||
|
r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(securityDescriptor)), uintptr(unsafe.Pointer(daclPresent)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclDefaulted)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
result = syscall.Errno(e1)
|
||||||
|
} else {
|
||||||
|
result = syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ google.golang.org/grpc v1.12.0
|
||||||
|
|
||||||
# This does not need to match RUNC_COMMIT as it is used for helper packages but should be newer or equal
|
# This does not need to match RUNC_COMMIT as it is used for helper packages but should be newer or equal
|
||||||
github.com/opencontainers/runc ad0f5255060d36872be04de22f8731f38ef2d7b1
|
github.com/opencontainers/runc ad0f5255060d36872be04de22f8731f38ef2d7b1
|
||||||
github.com/opencontainers/runtime-spec v1.0.1
|
github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce # v1.0.1-43-gd810dbc
|
||||||
github.com/opencontainers/image-spec v1.0.1
|
github.com/opencontainers/image-spec v1.0.1
|
||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||||
|
|
||||||
|
@ -114,12 +114,12 @@ github.com/googleapis/gax-go v2.0.0
|
||||||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||||
|
|
||||||
# containerd
|
# containerd
|
||||||
github.com/containerd/containerd b41633746ed4833f52c3c071e8edcfa2713e5677
|
github.com/containerd/containerd v1.2.0-beta.0
|
||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||||
github.com/containerd/continuity 0377f7d767206f3a9e8881d0f02267b0d89c7a62
|
github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
|
||||||
github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
|
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
|
||||||
github.com/containerd/console 5d1b48d6114b8c9666f0c8b916f871af97b0a761
|
github.com/containerd/console 4d8a41f4ce5b9bae77c41786ea2458330f43f081
|
||||||
github.com/containerd/go-runc f271fa2021de855d4d918dbef83c5fe19db1bdd
|
github.com/containerd/go-runc edcf3de1f4971445c42d61f20d506b30612aa031
|
||||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||||
github.com/containerd/ttrpc 94dde388801693c54f88a6596f713b51a8b30b2d
|
github.com/containerd/ttrpc 94dde388801693c54f88a6596f713b51a8b30b2d
|
||||||
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||||
|
|
Loading…
Reference in New Issue