Merge pull request #1275 from AntaresS/buildkit-support

[enhancement] enable buildkit from daemon side
This commit is contained in:
Andrew Hsu 2018-08-20 16:15:32 -07:00 committed by GitHub
commit 2461cd618d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 163 additions and 86 deletions

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -102,9 +102,10 @@ type ContainerStats struct {
// Ping contains response of Engine API: // Ping contains response of Engine API:
// GET "/_ping" // GET "/_ping"
type Ping struct { 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

View File

@ -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)
} }

View File

@ -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
@ -72,13 +72,13 @@ type (
// this package with a pluggable Untar function. Also, to facilitate the passing of specific id // this package with a pluggable Untar function. Also, to facilitate the passing of specific id
// 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
@ -420,9 +420,9 @@ type tarAppender struct {
Buffer *bufio.Writer Buffer *bufio.Writer
// 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,13 +431,13 @@ 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
} }

View File

@ -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

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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

View File

@ -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
} }

View File

@ -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")
procGetVersionExW = modkernel32.NewProc("GetVersionExW") modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
procGetProductInfo = modkernel32.NewProc("GetProductInfo") procGetVersionExW = modkernel32.NewProc("GetVersionExW")
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
}

View File

@ -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