Merge pull request #4 from thaJeztah/18.06-backport-register-oci-mediatypes
[18.06] Register OCI image media types
diff --git a/api/server/backend/build/backend.go b/api/server/backend/build/backend.go
index 546ad5f..5e04e83 100644
--- a/api/server/backend/build/backend.go
+++ b/api/server/backend/build/backend.go
@@ -73,7 +73,7 @@
return "", err
}
if config.ProgressWriter.AuxFormatter != nil {
- if err = config.ProgressWriter.AuxFormatter.Emit(types.BuildResult{ID: imageID}); err != nil {
+ if err = config.ProgressWriter.AuxFormatter.Emit("moby.image.id", types.BuildResult{ID: imageID}); err != nil {
return "", err
}
}
diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go
index 071402a..c4699f3 100644
--- a/api/server/router/build/build_routes.go
+++ b/api/server/router/build/build_routes.go
@@ -14,7 +14,6 @@
"strings"
"sync"
- "github.com/containerd/containerd/platforms"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
@@ -24,8 +23,7 @@
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
- "github.com/docker/docker/pkg/system"
- "github.com/docker/go-units"
+ units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -72,17 +70,7 @@
options.Target = r.FormValue("target")
options.RemoteContext = r.FormValue("remote")
if versions.GreaterThanOrEqualTo(version, "1.32") {
- apiPlatform := r.FormValue("platform")
- if apiPlatform != "" {
- sp, err := platforms.Parse(apiPlatform)
- if err != nil {
- return nil, err
- }
- if err := system.ValidatePlatform(sp); err != nil {
- return nil, err
- }
- options.Platform = &sp
- }
+ options.Platform = r.FormValue("platform")
}
if r.Form.Get("shmsize") != "" {
@@ -243,6 +231,10 @@
return errdefs.InvalidParameter(errors.New("squash is only supported with experimental mode"))
}
+ if buildOptions.Version == types.BuilderBuildKit && !br.daemon.HasExperimental() {
+ return errdefs.InvalidParameter(errors.New("buildkit is only supported with experimental mode"))
+ }
+
out := io.Writer(output)
if buildOptions.SuppressOutput {
out = notVerboseBuffer
@@ -255,10 +247,6 @@
return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", buildOptions.RemoteContext)
}
- if buildOptions.Version == types.BuilderBuildKit && !br.daemon.HasExperimental() {
- return errdefs.InvalidParameter(errors.New("buildkit is only supported with experimental mode"))
- }
-
wantAux := versions.GreaterThanOrEqualTo(version, "1.30")
imgID, err := br.backend.Build(ctx, backend.BuildConfig{
diff --git a/api/types/client.go b/api/types/client.go
index 33bc98e..3b698c2 100644
--- a/api/types/client.go
+++ b/api/types/client.go
@@ -7,8 +7,7 @@
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
- "github.com/docker/go-units"
- specs "github.com/opencontainers/image-spec/specs-go/v1"
+ units "github.com/docker/go-units"
)
// CheckpointCreateOptions holds parameters to create a checkpoint from a container
@@ -181,7 +180,7 @@
ExtraHosts []string // List of extra hosts
Target string
SessionID string
- Platform *specs.Platform
+ Platform string
// Version specifies the version of the unerlying builder to use
Version BuilderVersion
// BuildID is an optional identifier that can be passed together with the
diff --git a/builder/builder-next/adapters/containerimage/pull.go b/builder/builder-next/adapters/containerimage/pull.go
index f76ac5a..2b6c214 100644
--- a/builder/builder-next/adapters/containerimage/pull.go
+++ b/builder/builder-next/adapters/containerimage/pull.go
@@ -644,7 +644,7 @@
// featured.
type jobs struct {
name string
- added map[digest.Digest]job
+ added map[digest.Digest]*job
mu sync.Mutex
resolved bool
}
@@ -658,7 +658,7 @@
func newJobs(name string) *jobs {
return &jobs{
name: name,
- added: make(map[digest.Digest]job),
+ added: make(map[digest.Digest]*job),
}
}
@@ -669,17 +669,17 @@
if _, ok := j.added[desc.Digest]; ok {
return
}
- j.added[desc.Digest] = job{
+ j.added[desc.Digest] = &job{
Descriptor: desc,
started: time.Now(),
}
}
-func (j *jobs) jobs() []job {
+func (j *jobs) jobs() []*job {
j.mu.Lock()
defer j.mu.Unlock()
- descs := make([]job, 0, len(j.added))
+ descs := make([]*job, 0, len(j.added))
for _, j := range j.added {
descs = append(descs, j)
}
diff --git a/builder/builder-next/builder.go b/builder/builder-next/builder.go
index 5a82cdd..b1d31a5 100644
--- a/builder/builder-next/builder.go
+++ b/builder/builder-next/builder.go
@@ -2,7 +2,6 @@
import (
"context"
- "encoding/json"
"io"
"strings"
"sync"
@@ -14,7 +13,8 @@
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/builder"
"github.com/docker/docker/daemon/images"
- "github.com/docker/docker/pkg/jsonmessage"
+ "github.com/docker/docker/pkg/streamformatter"
+ "github.com/docker/docker/pkg/system"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/control"
"github.com/moby/buildkit/identity"
@@ -209,8 +209,17 @@
frontendAttrs["no-cache"] = ""
}
- if opt.Options.Platform != nil {
- frontendAttrs["platform"] = platforms.Format(*opt.Options.Platform)
+ if opt.Options.Platform != "" {
+ // same as in newBuilder in builder/dockerfile.builder.go
+ // TODO: remove once opt.Options.Platform is of type specs.Platform
+ sp, err := platforms.Parse(opt.Options.Platform)
+ if err != nil {
+ return nil, err
+ }
+ if err := system.ValidatePlatform(sp); err != nil {
+ return nil, err
+ }
+ frontendAttrs["platform"] = opt.Options.Platform
}
exporterAttrs := map[string]string{}
@@ -228,6 +237,8 @@
Session: opt.Options.SessionID,
}
+ aux := streamformatter.AuxFormatter{opt.ProgressWriter.Output}
+
eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error {
@@ -240,7 +251,7 @@
return errors.Errorf("missing image id")
}
out.ImageID = id
- return nil
+ return aux.Emit("moby.image.id", types.BuildResult{ID: id})
})
ch := make(chan *controlapi.StatusResponse)
@@ -258,25 +269,9 @@
if err != nil {
return err
}
-
- auxJSONBytes, err := json.Marshal(dt)
- if err != nil {
+ if err := aux.Emit("moby.buildkit.trace", dt); err != nil {
return err
}
- auxJSON := new(json.RawMessage)
- *auxJSON = auxJSONBytes
- msgJSON, err := json.Marshal(&jsonmessage.JSONMessage{ID: "moby.buildkit.trace", Aux: auxJSON})
- if err != nil {
- return err
- }
- msgJSON = append(msgJSON, []byte("\r\n")...)
- n, err := opt.ProgressWriter.Output.Write(msgJSON)
- if err != nil {
- return err
- }
- if n != len(msgJSON) {
- return io.ErrShortWrite
- }
}
return nil
})
diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go
index b585347..ee95f23 100644
--- a/builder/dockerfile/builder.go
+++ b/builder/dockerfile/builder.go
@@ -10,6 +10,7 @@
"strings"
"time"
+ "github.com/containerd/containerd/platforms"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
@@ -25,6 +26,7 @@
"github.com/moby/buildkit/frontend/dockerfile/parser"
"github.com/moby/buildkit/frontend/dockerfile/shell"
"github.com/moby/buildkit/session"
+ specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/syncmap"
@@ -111,7 +113,11 @@
PathCache: bm.pathCache,
IDMappings: bm.idMappings,
}
- return newBuilder(ctx, builderOptions).build(source, dockerfile)
+ b, err := newBuilder(ctx, builderOptions)
+ if err != nil {
+ return nil, err
+ }
+ return b.build(source, dockerfile)
}
func (bm *BuildManager) initializeClientSession(ctx context.Context, cancel func(), options *types.ImageBuildOptions) (builder.Source, error) {
@@ -175,10 +181,11 @@
pathCache pathCache
containerManager *containerManager
imageProber ImageProber
+ platform *specs.Platform
}
// newBuilder creates a new Dockerfile builder from an optional dockerfile and a Options.
-func newBuilder(clientCtx context.Context, options builderOptions) *Builder {
+func newBuilder(clientCtx context.Context, options builderOptions) (*Builder, error) {
config := options.Options
if config == nil {
config = new(types.ImageBuildOptions)
@@ -199,7 +206,20 @@
containerManager: newContainerManager(options.Backend),
}
- return b
+ // same as in Builder.Build in builder/builder-next/builder.go
+ // TODO: remove once config.Platform is of type specs.Platform
+ if config.Platform != "" {
+ sp, err := platforms.Parse(config.Platform)
+ if err != nil {
+ return nil, err
+ }
+ if err := system.ValidatePlatform(sp); err != nil {
+ return nil, err
+ }
+ b.platform = &sp
+ }
+
+ return b, nil
}
// Build 'LABEL' command(s) from '--label' options and add to the last stage
@@ -257,7 +277,7 @@
if aux == nil || state.imageID == "" {
return nil
}
- return aux.Emit(types.BuildResult{ID: state.imageID})
+ return aux.Emit("", types.BuildResult{ID: state.imageID})
}
func processMetaArg(meta instructions.ArgCommand, shlex *shell.Lex, args *BuildArgs) error {
@@ -365,9 +385,12 @@
return nil, errdefs.InvalidParameter(err)
}
- b := newBuilder(context.Background(), builderOptions{
+ b, err := newBuilder(context.Background(), builderOptions{
Options: &types.ImageBuildOptions{NoCache: true},
})
+ if err != nil {
+ return nil, err
+ }
// ensure that the commands are valid
for _, n := range dockerfile.AST.Children {
diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go
index 7e9dc60..74e245b 100644
--- a/builder/dockerfile/copy.go
+++ b/builder/dockerfile/copy.go
@@ -87,7 +87,7 @@
pathCache: req.builder.pathCache,
download: download,
imageSource: imageSource,
- platform: req.builder.options.Platform,
+ platform: req.builder.platform,
}
}
diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go
index 1032c6c..5d72237 100644
--- a/builder/dockerfile/dispatchers.go
+++ b/builder/dockerfile/dispatchers.go
@@ -146,7 +146,7 @@
imageRefOrID = stage.Image
localOnly = true
}
- return d.builder.imageSources.Get(imageRefOrID, localOnly, d.builder.options.Platform)
+ return d.builder.imageSources.Get(imageRefOrID, localOnly, d.builder.platform)
}
// FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name]
@@ -238,7 +238,7 @@
}
if platform == nil {
- platform = d.builder.options.Platform
+ platform = d.builder.platform
}
// Windows cannot support a container with no base image unless it is LCOW.
diff --git a/builder/dockerfile/dispatchers_test.go b/builder/dockerfile/dispatchers_test.go
index 047a874..c61a45b 100644
--- a/builder/dockerfile/dispatchers_test.go
+++ b/builder/dockerfile/dispatchers_test.go
@@ -6,7 +6,6 @@
"runtime"
"testing"
- "github.com/containerd/containerd/platforms"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/backend"
"github.com/docker/docker/api/types/container"
@@ -23,8 +22,7 @@
func newBuilderWithMockBackend() *Builder {
mockBackend := &MockBackend{}
- defaultPlatform := platforms.DefaultSpec()
- opts := &types.ImageBuildOptions{Platform: &defaultPlatform}
+ opts := &types.ImageBuildOptions{}
ctx := context.Background()
b := &Builder{
options: opts,
@@ -116,7 +114,7 @@
err := initializeStage(sb, cmd)
if runtime.GOOS == "windows" && !system.LCOWSupported() {
- assert.Check(t, is.Error(err, "Windows does not support FROM scratch"))
+ assert.Check(t, is.Error(err, "Linux containers are not supported on this system"))
return
}
diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go
index 5e2c286..1b3a5b0 100644
--- a/builder/dockerfile/internals.go
+++ b/builder/dockerfile/internals.go
@@ -169,7 +169,7 @@
return err
}
- imageMount, err := b.imageSources.Get(state.imageID, true, req.builder.options.Platform)
+ imageMount, err := b.imageSources.Get(state.imageID, true, req.builder.platform)
if err != nil {
return errors.Wrapf(err, "failed to get destination image %q", state.imageID)
}
@@ -416,7 +416,9 @@
func (b *Builder) create(runConfig *container.Config) (string, error) {
logrus.Debugf("[BUILDER] Command to be executed: %v", runConfig.Cmd)
- hostConfig := hostConfigFromOptions(b.options)
+
+ isWCOW := runtime.GOOS == "windows" && b.platform != nil && b.platform.OS == "windows"
+ hostConfig := hostConfigFromOptions(b.options, isWCOW)
container, err := b.containerManager.Create(runConfig, hostConfig)
if err != nil {
return "", err
@@ -429,7 +431,7 @@
return container.ID, nil
}
-func hostConfigFromOptions(options *types.ImageBuildOptions) *container.HostConfig {
+func hostConfigFromOptions(options *types.ImageBuildOptions, isWCOW bool) *container.HostConfig {
resources := container.Resources{
CgroupParent: options.CgroupParent,
CPUShares: options.CPUShares,
@@ -457,7 +459,7 @@
// is too small for builder scenarios where many users are
// using RUN statements to install large amounts of data.
// Use 127GB as that's the default size of a VHD in Hyper-V.
- if runtime.GOOS == "windows" && options.Platform != nil && options.Platform.OS == "windows" {
+ if isWCOW {
hc.StorageOpt = make(map[string]string)
hc.StorageOpt["size"] = "127GB"
}
diff --git a/client/image_build.go b/client/image_build.go
index e501317..9add3c1 100644
--- a/client/image_build.go
+++ b/client/image_build.go
@@ -8,8 +8,8 @@
"net/http"
"net/url"
"strconv"
+ "strings"
- "github.com/containerd/containerd/platforms"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
)
@@ -30,12 +30,6 @@
}
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
- if options.Platform != nil {
- if err := cli.NewVersionError("1.32", "platform"); err != nil {
- return types.ImageBuildResponse{}, err
- }
- query.Set("platform", platforms.Format(*options.Platform))
- }
headers.Set("Content-Type", "application/x-tar")
serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers)
@@ -130,8 +124,11 @@
if options.SessionID != "" {
query.Set("session", options.SessionID)
}
- if options.Platform != nil {
- query.Set("platform", platforms.Format(*options.Platform))
+ if options.Platform != "" {
+ if err := cli.NewVersionError("1.32", "platform"); err != nil {
+ return query, err
+ }
+ query.Set("platform", strings.ToLower(options.Platform))
}
if options.BuildID != "" {
query.Set("buildid", options.BuildID)
diff --git a/distribution/pull_v2_windows.go b/distribution/pull_v2_windows.go
index 3c96458..1ae167e 100644
--- a/distribution/pull_v2_windows.go
+++ b/distribution/pull_v2_windows.go
@@ -74,11 +74,14 @@
if (manifestDescriptor.Platform.Architecture == runtime.GOARCH) &&
((p.OS != "" && manifestDescriptor.Platform.OS == p.OS) || // Explicit user request for an OS we know we support
(p.OS == "" && system.IsOSSupported(manifestDescriptor.Platform.OS))) { // No user requested OS, but one we can support
- matches = append(matches, manifestDescriptor)
- logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
if strings.EqualFold("windows", manifestDescriptor.Platform.OS) {
+ if err := checkImageCompatibility("windows", manifestDescriptor.Platform.OSVersion); err != nil {
+ continue
+ }
foundWindowsMatch = true
}
+ matches = append(matches, manifestDescriptor)
+ logrus.Debugf("found match %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, runtime.GOARCH, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
} else {
logrus.Debugf("ignoring %s/%s %s with media type %s, digest %s", manifestDescriptor.Platform.OS, manifestDescriptor.Platform.Architecture, manifestDescriptor.Platform.OSVersion, manifestDescriptor.MediaType, manifestDescriptor.Digest.String())
}
@@ -103,7 +106,8 @@
// TODO: Split version by parts and compare
// TODO: Prefer versions which have a greater version number
// Move compatible versions to the top, with no other ordering changes
- return versionMatch(mbv.list[i].Platform.OSVersion, mbv.version) && !versionMatch(mbv.list[j].Platform.OSVersion, mbv.version)
+ return (strings.EqualFold("windows", mbv.list[i].Platform.OS) && !strings.EqualFold("windows", mbv.list[j].Platform.OS)) ||
+ (versionMatch(mbv.list[i].Platform.OSVersion, mbv.version) && !versionMatch(mbv.list[j].Platform.OSVersion, mbv.version))
}
func (mbv manifestsByVersion) Len() int {
diff --git a/hack/dockerfile/install/containerd.installer b/hack/dockerfile/install/containerd.installer
index e23c8a2..792ea98 100755
--- a/hack/dockerfile/install/containerd.installer
+++ b/hack/dockerfile/install/containerd.installer
@@ -4,7 +4,7 @@
# containerd is also pinned in vendor.conf. When updating the binary
# version you may also need to update the vendor version to pick up bug
# fixes or new APIs.
-CONTAINERD_COMMIT=cbef57047e900aeb2bafe7a634919bec13f4a2a5 # v1.1.1-rc.1
+CONTAINERD_COMMIT=e5fb877b9f6c14b15f48643735a8c9764a7319d3 # v1.1.1-rc.2
install_containerd() {
echo "Install containerd version $CONTAINERD_COMMIT"
diff --git a/hack/dockerfile/install/proxy.installer b/hack/dockerfile/install/proxy.installer
index 00c2f1d..b5748b5 100755
--- a/hack/dockerfile/install/proxy.installer
+++ b/hack/dockerfile/install/proxy.installer
@@ -3,7 +3,7 @@
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
# updating the binary version, consider updating github.com/docker/libnetwork
# in vendor.conf accordingly
-LIBNETWORK_COMMIT=19279f0492417475b6bfbd0aa529f73e8f178fb5
+LIBNETWORK_COMMIT=430c00a6a6b3dfdd774f21e1abd4ad6b0216c629
install_proxy() {
case "$1" in
diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go
index 95f7ccf..a0abb67 100644
--- a/integration-cli/docker_cli_network_unix_test.go
+++ b/integration-cli/docker_cli_network_unix_test.go
@@ -610,17 +610,17 @@
// test network with multiple subnets
// bridge network doesn't support multiple subnets. hence, use a dummy driver that supports
- dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, "--subnet=192.168.0.0/16", "--subnet=192.170.0.0/16", "test6")
+ dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, "--subnet=192.170.0.0/16", "--subnet=192.171.0.0/16", "test6")
assertNwIsAvailable(c, "test6")
// test network with multiple subnets with valid ipam combinations
// also check same subnet across networks when the driver supports it.
dockerCmd(c, "network", "create", "-d", dummyNetworkDriver,
- "--subnet=192.168.0.0/16", "--subnet=192.170.0.0/16",
- "--gateway=192.168.0.100", "--gateway=192.170.0.100",
- "--ip-range=192.168.1.0/24",
- "--aux-address", "a=192.168.1.5", "--aux-address", "b=192.168.1.6",
- "--aux-address", "c=192.170.1.5", "--aux-address", "d=192.170.1.6",
+ "--subnet=192.172.0.0/16", "--subnet=192.173.0.0/16",
+ "--gateway=192.172.0.100", "--gateway=192.173.0.100",
+ "--ip-range=192.172.1.0/24",
+ "--aux-address", "a=192.172.1.5", "--aux-address", "b=192.172.1.6",
+ "--aux-address", "c=192.173.1.5", "--aux-address", "d=192.173.1.6",
"test7")
assertNwIsAvailable(c, "test7")
diff --git a/pkg/streamformatter/streamformatter.go b/pkg/streamformatter/streamformatter.go
index 2b5e713..04917d4 100644
--- a/pkg/streamformatter/streamformatter.go
+++ b/pkg/streamformatter/streamformatter.go
@@ -139,14 +139,14 @@
}
// Emit emits the given interface as an aux progress message
-func (sf *AuxFormatter) Emit(aux interface{}) error {
+func (sf *AuxFormatter) Emit(id string, aux interface{}) error {
auxJSONBytes, err := json.Marshal(aux)
if err != nil {
return err
}
auxJSON := new(json.RawMessage)
*auxJSON = auxJSONBytes
- msgJSON, err := json.Marshal(&jsonmessage.JSONMessage{Aux: auxJSON})
+ msgJSON, err := json.Marshal(&jsonmessage.JSONMessage{ID: id, Aux: auxJSON})
if err != nil {
return err
}
diff --git a/pkg/streamformatter/streamformatter_test.go b/pkg/streamformatter/streamformatter_test.go
index 4399a65..f630699 100644
--- a/pkg/streamformatter/streamformatter_test.go
+++ b/pkg/streamformatter/streamformatter_test.go
@@ -106,7 +106,7 @@
sampleAux := &struct {
Data string
}{"Additional data"}
- err := aux.Emit(sampleAux)
+ err := aux.Emit("", sampleAux)
assert.NilError(t, err)
assert.Check(t, is.Equal(`{"aux":{"Data":"Additional data"}}`+streamNewline, b.String()))
}
diff --git a/vendor.conf b/vendor.conf
index cd059b7..33e2dc8 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -1,7 +1,7 @@
# the following lines are in sorted order, FYI
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
github.com/Microsoft/hcsshim v0.6.11
-github.com/Microsoft/go-winio v0.4.7
+github.com/Microsoft/go-winio v0.4.8
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
@@ -26,7 +26,7 @@
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
# buildkit
-github.com/moby/buildkit cce2080ddbe4698912f2290892b247c83627efa8
+github.com/moby/buildkit 9acf51e49185b348608e0096b2903dd72907adcb
github.com/tonistiigi/fsutil 8abad97ee3969cdf5e9c367f46adba2c212b3ddb
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
@@ -37,14 +37,14 @@
#get libnetwork packages
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
-github.com/docker/libnetwork 19279f0492417475b6bfbd0aa529f73e8f178fb5
+github.com/docker/libnetwork 430c00a6a6b3dfdd774f21e1abd4ad6b0216c629
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c
github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
-github.com/hashicorp/go-sockaddr acd314c5781ea706c710d9ea70069fd2e110d61d
+github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9
github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go
index 82cbe7a..806fd34 100644
--- a/vendor/github.com/Microsoft/go-winio/pipe.go
+++ b/vendor/github.com/Microsoft/go-winio/pipe.go
@@ -121,6 +121,11 @@
// zero-byte message, ensure that all future Read() calls
// also return EOF.
f.readEOF = true
+ } else if err == syscall.ERROR_MORE_DATA {
+ // ERROR_MORE_DATA indicates that the pipe's read mode is message mode
+ // and the message still has more bytes. Treat this as a success, since
+ // this package presents all named pipes as byte streams.
+ err = nil
}
return n, err
}
@@ -175,16 +180,6 @@
return nil, err
}
- var state uint32
- err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0)
- if err != nil {
- return nil, err
- }
-
- if state&cPIPE_READMODE_MESSAGE != 0 {
- return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")}
- }
-
f, err := makeWin32File(h)
if err != nil {
syscall.Close(h)
diff --git a/vendor/github.com/docker/libnetwork/controller.go b/vendor/github.com/docker/libnetwork/controller.go
index fe9c4dd..5e967b7 100644
--- a/vendor/github.com/docker/libnetwork/controller.go
+++ b/vendor/github.com/docker/libnetwork/controller.go
@@ -69,6 +69,7 @@
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/osl"
"github.com/docker/libnetwork/types"
+ "github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -1252,7 +1253,7 @@
}
if err != nil {
- if err == plugins.ErrNotFound {
+ if errors.Cause(err) == plugins.ErrNotFound {
return types.NotFoundErrorf(err.Error())
}
return err
diff --git a/vendor/github.com/docker/libnetwork/ipam/allocator.go b/vendor/github.com/docker/libnetwork/ipam/allocator.go
index 29473c5..7213148 100644
--- a/vendor/github.com/docker/libnetwork/ipam/allocator.go
+++ b/vendor/github.com/docker/libnetwork/ipam/allocator.go
@@ -29,7 +29,10 @@
// Allocator provides per address space ipv4/ipv6 book keeping
type Allocator struct {
// Predefined pools for default address spaces
- predefined map[string][]*net.IPNet
+ // Separate from the addrSpace because they should not be serialized
+ predefined map[string][]*net.IPNet
+ predefinedStartIndices map[string]int
+ // The (potentially serialized) address spaces
addrSpaces map[string]*addrSpace
// stores []datastore.Datastore
// Allocated addresses in each address space's subnet
@@ -47,6 +50,9 @@
globalAddressSpace: ipamutils.PredefinedGranularNetworks,
}
+ // Initialize asIndices map
+ a.predefinedStartIndices = make(map[string]int)
+
// Initialize bitseq map
a.addresses = make(map[SubnetKey]*bitseq.Handle)
@@ -374,11 +380,24 @@
func (a *Allocator) getPredefineds(as string) []*net.IPNet {
a.Lock()
defer a.Unlock()
- l := make([]*net.IPNet, 0, len(a.predefined[as]))
- for _, pool := range a.predefined[as] {
- l = append(l, pool)
+
+ p := a.predefined[as]
+ i := a.predefinedStartIndices[as]
+ // defensive in case the list changed since last update
+ if i >= len(p) {
+ i = 0
}
- return l
+ return append(p[i:], p[:i]...)
+}
+
+func (a *Allocator) updateStartIndex(as string, amt int) {
+ a.Lock()
+ i := a.predefinedStartIndices[as] + amt
+ if i < 0 || i >= len(a.predefined[as]) {
+ i = 0
+ }
+ a.predefinedStartIndices[as] = i
+ a.Unlock()
}
func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) {
@@ -397,21 +416,26 @@
return nil, err
}
- for _, nw := range a.getPredefineds(as) {
+ predefined := a.getPredefineds(as)
+
+ aSpace.Lock()
+ for i, nw := range predefined {
if v != getAddressVersion(nw.IP) {
continue
}
- aSpace.Lock()
+ // Checks whether pool has already been allocated
if _, ok := aSpace.subnets[SubnetKey{AddressSpace: as, Subnet: nw.String()}]; ok {
- aSpace.Unlock()
continue
}
+ // Shouldn't be necessary, but check prevents IP collisions should
+ // predefined pools overlap for any reason.
if !aSpace.contains(as, nw) {
aSpace.Unlock()
+ a.updateStartIndex(as, i+1)
return nw, nil
}
- aSpace.Unlock()
}
+ aSpace.Unlock()
return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v)
}
diff --git a/vendor/github.com/docker/libnetwork/ipam/structures.go b/vendor/github.com/docker/libnetwork/ipam/structures.go
index 09a7769..455a16c 100644
--- a/vendor/github.com/docker/libnetwork/ipam/structures.go
+++ b/vendor/github.com/docker/libnetwork/ipam/structures.go
@@ -262,12 +262,13 @@
defer aSpace.Unlock()
// Check if already allocated
- if p, ok := aSpace.subnets[k]; ok {
+ if _, ok := aSpace.subnets[k]; ok {
if pdf {
return nil, types.InternalMaskableErrorf("predefined pool %s is already reserved", nw)
}
- aSpace.incRefCount(p, 1)
- return func() error { return nil }, nil
+ // This means the same pool is already allocated. updatePoolDBOnAdd is called when there
+ // is request for a pool/subpool. It should ensure there is no overlap with existing pools
+ return nil, ipamapi.ErrPoolOverlap
}
// If master pool, check for overlap
diff --git a/vendor/github.com/docker/libnetwork/network.go b/vendor/github.com/docker/libnetwork/network.go
index e283d65..70d6b1c 100644
--- a/vendor/github.com/docker/libnetwork/network.go
+++ b/vendor/github.com/docker/libnetwork/network.go
@@ -1156,18 +1156,6 @@
ep.releaseAddress()
}
}()
- // Moving updateToSTore before calling addEndpoint so that we shall clean up VETH interfaces in case
- // DockerD get killed between addEndpoint and updateSTore call
- if err = n.getController().updateToStore(ep); err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- if e := n.getController().deleteFromStore(ep); e != nil {
- logrus.Warnf("error rolling back endpoint %s from store: %v", name, e)
- }
- }
- }()
if err = n.addEndpoint(ep); err != nil {
return nil, err
@@ -1180,6 +1168,19 @@
}
}()
+ // We should perform updateToStore call right after addEndpoint
+ // in order to have iface properly configured
+ if err = n.getController().updateToStore(ep); err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err != nil {
+ if e := n.getController().deleteFromStore(ep); e != nil {
+ logrus.Warnf("error rolling back endpoint %s from store: %v", name, e)
+ }
+ }
+ }()
+
if err = ep.assignAddress(ipam, false, n.enableIPv6 && n.postIPv6); err != nil {
return nil, err
}
diff --git a/vendor/github.com/docker/libnetwork/networkdb/delegate.go b/vendor/github.com/docker/libnetwork/networkdb/delegate.go
index 9a379fe..6cd827e 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/delegate.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/delegate.go
@@ -41,7 +41,7 @@
// If the node is not known from memberlist we cannot process save any state of it else if it actually
// dies we won't receive any notification and we will remain stuck with it
if _, ok := nDB.nodes[nEvent.NodeName]; !ok {
- logrus.Error("node: %s is unknown to memberlist", nEvent.NodeName)
+ logrus.Errorf("node: %s is unknown to memberlist", nEvent.NodeName)
return false
}
diff --git a/vendor/github.com/docker/libnetwork/types/types.go b/vendor/github.com/docker/libnetwork/types/types.go
index f851d6f..5968545 100644
--- a/vendor/github.com/docker/libnetwork/types/types.go
+++ b/vendor/github.com/docker/libnetwork/types/types.go
@@ -145,7 +145,12 @@
return ret
}
-// FromString reads the PortBinding structure from string
+// FromString reads the PortBinding structure from string s.
+// String s is a triple of "protocol/containerIP:port/hostIP:port"
+// containerIP and hostIP can be in dotted decimal ("192.0.2.1") or IPv6 ("2001:db8::68") form.
+// Zoned addresses ("169.254.0.23%eth0" or "fe80::1ff:fe23:4567:890a%eth0") are not supported.
+// If string s is incorrectly formatted or the IP addresses or ports cannot be parsed, FromString
+// returns an error.
func (p *PortBinding) FromString(s string) error {
ps := strings.Split(s, "/")
if len(ps) != 3 {
@@ -167,21 +172,19 @@
}
func parseIPPort(s string) (net.IP, uint16, error) {
- pp := strings.Split(s, ":")
- if len(pp) != 2 {
- return nil, 0, BadRequestErrorf("invalid format: %s", s)
- }
-
- var ip net.IP
- if pp[0] != "" {
- if ip = net.ParseIP(pp[0]); ip == nil {
- return nil, 0, BadRequestErrorf("invalid ip: %s", pp[0])
- }
- }
-
- port, err := strconv.ParseUint(pp[1], 10, 16)
+ hoststr, portstr, err := net.SplitHostPort(s)
if err != nil {
- return nil, 0, BadRequestErrorf("invalid port: %s", pp[1])
+ return nil, 0, err
+ }
+
+ ip := net.ParseIP(hoststr)
+ if ip == nil {
+ return nil, 0, BadRequestErrorf("invalid ip: %s", hoststr)
+ }
+
+ port, err := strconv.ParseUint(portstr, 10, 16)
+ if err != nil {
+ return nil, 0, BadRequestErrorf("invalid port: %s", portstr)
}
return ip, uint16(port), nil
diff --git a/vendor/github.com/docker/libnetwork/vendor.conf b/vendor/github.com/docker/libnetwork/vendor.conf
index 9480699..5237c55 100644
--- a/vendor/github.com/docker/libnetwork/vendor.conf
+++ b/vendor/github.com/docker/libnetwork/vendor.conf
@@ -1,27 +1,28 @@
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
-github.com/Microsoft/go-winio v0.4.5
-github.com/Microsoft/hcsshim v0.6.5
+github.com/Microsoft/go-winio v0.4.7
+github.com/Microsoft/hcsshim v0.6.11
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904
github.com/codegangsta/cli a65b733b303f0055f8d324d805f393cd3e7a7904
-github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
-github.com/containerd/continuity 22694c680ee48fb8f50015b44618517e2bde77e8
+github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
+github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
github.com/coreos/etcd v3.2.1
github.com/coreos/go-semver v0.2.0
-github.com/coreos/go-systemd v4
+github.com/coreos/go-systemd v17
+github.com/coreos/pkg fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d
-github.com/docker/docker a3efe9722f34af5cf4443fe3a5c4e4e3e0457b54
-github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/docker/docker 162ba6016def672690ee4a1f3978368853a1e149
+github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
github.com/godbus/dbus v4.0.0
-github.com/gogo/protobuf v0.4
-github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
+github.com/gogo/protobuf v1.0.0
+github.com/golang/protobuf v1.1.0
github.com/gorilla/context v1.1
github.com/gorilla/mux v1.1
github.com/hashicorp/consul v0.5.2
@@ -29,27 +30,37 @@
github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c
github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
-github.com/hashicorp/go-sockaddr acd314c5781ea706c710d9ea70069fd2e110d61d
+github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
github.com/mattn/go-shellwords v1.0.3
-github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
+github.com/miekg/dns v1.0.7
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
-github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
-github.com/opencontainers/image-spec 372ad780f63454fbbbbcc7cf80e5b90245c13e13
-github.com/opencontainers/runc 0351df1c5a66838d0c392b4ac4cf9450de844e2d
-github.com/opencontainers/runtime-spec v1.0.0
-github.com/opencontainers/selinux v1.0.0-rc1
+github.com/opencontainers/go-digest v1.0.0-rc1
+github.com/opencontainers/image-spec v1.0.1
+github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
+github.com/opencontainers/runtime-spec v1.0.1
+github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
github.com/sirupsen/logrus v1.0.3
github.com/stretchr/testify dab07ac62d4905d3e48d17dc549c684ac3b7c15a
-github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
+github.com/syndtr/gocapability 33e07d32887e1e06b7c025f27ce52f62c7990bc0
github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e
github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
-golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
-golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
-golang.org/x/sys 07c182904dbd53199946ba614a412c61d3c548f5
+golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491
+golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
+golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
+
+github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73
+github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
+github.com/cyphar/filepath-securejoin v0.2.1
+github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
+github.com/hashicorp/go-immutable-radix 7f3cd4390caab3250a57f30efdb2a65dd7649ecf
+github.com/hashicorp/golang-lru 0fb14efe8c47ae851c0034ed7a448854d3d34cf3
+github.com/hashicorp/go-cleanhttp d5fe4b57a186c716b0e00b8c301cbd9b4182694d
+github.com/hashicorp/go-rootcerts 6bb64b370b90e7ef1fa532be9e591a81c3493e00
+github.com/mitchellh/go-homedir 3864e76763d94a6df2f9960b16a20a33da9f9a66
diff --git a/vendor/github.com/hashicorp/go-sockaddr/ifaddr.go b/vendor/github.com/hashicorp/go-sockaddr/ifaddr.go
index 3e4ff9f..0811b27 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/ifaddr.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/ifaddr.go
@@ -1,5 +1,7 @@
package sockaddr
+import "strings"
+
// ifAddrAttrMap is a map of the IfAddr type-specific attributes.
var ifAddrAttrMap map[AttrName]func(IfAddr) string
var ifAddrAttrs []AttrName
@@ -30,6 +32,53 @@
return ip.NetIP().String(), nil
}
+// GetPrivateIPs returns a string with all IP addresses that are part of RFC
+// 6890 (regardless of whether or not there is a default route, unlike
+// GetPublicIP). If the system can't find any RFC 6890 IP addresses, an empty
+// string will be returned instead. This function is the `eval` equivalent of:
+//
+// ```
+// $ sockaddr eval -r '{{GetAllInterfaces | include "RFC" "6890" | join "address" " "}}'
+/// ```
+func GetPrivateIPs() (string, error) {
+ ifAddrs, err := GetAllInterfaces()
+ if err != nil {
+ return "", err
+ } else if len(ifAddrs) < 1 {
+ return "", nil
+ }
+
+ ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
+ if len(ifAddrs) == 0 {
+ return "", nil
+ }
+
+ OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)
+
+ ifAddrs, _, err = IfByRFC("6890", ifAddrs)
+ if err != nil {
+ return "", err
+ } else if len(ifAddrs) == 0 {
+ return "", nil
+ }
+
+ _, ifAddrs, err = IfByRFC(ForwardingBlacklistRFC, ifAddrs)
+ if err != nil {
+ return "", err
+ } else if len(ifAddrs) == 0 {
+ return "", nil
+ }
+
+ ips := make([]string, 0, len(ifAddrs))
+ for _, ifAddr := range ifAddrs {
+ ip := *ToIPAddr(ifAddr.SockAddr)
+ s := ip.NetIP().String()
+ ips = append(ips, s)
+ }
+
+ return strings.Join(ips, " "), nil
+}
+
// GetPublicIP returns a string with a single IP address that is NOT part of RFC
// 6890 and has a default route. If the system can't determine its IP address
// or find a non RFC 6890 IP address, an empty string will be returned instead.
@@ -51,6 +100,47 @@
return ip.NetIP().String(), nil
}
+// GetPublicIPs returns a string with all IP addresses that are NOT part of RFC
+// 6890 (regardless of whether or not there is a default route, unlike
+// GetPublicIP). If the system can't find any non RFC 6890 IP addresses, an
+// empty string will be returned instead. This function is the `eval`
+// equivalent of:
+//
+// ```
+// $ sockaddr eval -r '{{GetAllInterfaces | exclude "RFC" "6890" | join "address" " "}}'
+/// ```
+func GetPublicIPs() (string, error) {
+ ifAddrs, err := GetAllInterfaces()
+ if err != nil {
+ return "", err
+ } else if len(ifAddrs) < 1 {
+ return "", nil
+ }
+
+ ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
+ if len(ifAddrs) == 0 {
+ return "", nil
+ }
+
+ OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)
+
+ _, ifAddrs, err = IfByRFC("6890", ifAddrs)
+ if err != nil {
+ return "", err
+ } else if len(ifAddrs) == 0 {
+ return "", nil
+ }
+
+ ips := make([]string, 0, len(ifAddrs))
+ for _, ifAddr := range ifAddrs {
+ ip := *ToIPAddr(ifAddr.SockAddr)
+ s := ip.NetIP().String()
+ ips = append(ips, s)
+ }
+
+ return strings.Join(ips, " "), nil
+}
+
// GetInterfaceIP returns a string with a single IP address sorted by the size
// of the network (i.e. IP addresses with a smaller netmask, larger network
// size, are sorted first). This function is the `eval` equivalent of:
@@ -91,6 +181,44 @@
return IPAddrAttr(*ip, "address"), nil
}
+// GetInterfaceIPs returns a string with all IPs, sorted by the size of the
+// network (i.e. IP addresses with a smaller netmask, larger network size, are
+// sorted first), on a named interface. This function is the `eval` equivalent
+// of:
+//
+// ```
+// $ sockaddr eval -r '{{GetAllInterfaces | include "name" <<ARG>> | sort "type,size" | join "address" " "}}'
+/// ```
+func GetInterfaceIPs(namedIfRE string) (string, error) {
+ ifAddrs, err := GetAllInterfaces()
+ if err != nil {
+ return "", err
+ }
+
+ ifAddrs, _, err = IfByName(namedIfRE, ifAddrs)
+ if err != nil {
+ return "", err
+ }
+
+ ifAddrs, err = SortIfBy("+type,+size", ifAddrs)
+ if err != nil {
+ return "", err
+ }
+
+ if len(ifAddrs) == 0 {
+ return "", err
+ }
+
+ ips := make([]string, 0, len(ifAddrs))
+ for _, ifAddr := range ifAddrs {
+ ip := *ToIPAddr(ifAddr.SockAddr)
+ s := ip.NetIP().String()
+ ips = append(ips, s)
+ }
+
+ return strings.Join(ips, " "), nil
+}
+
// IfAddrAttrs returns a list of attributes supported by the IfAddr type
func IfAddrAttrs() []AttrName {
return ifAddrAttrs
diff --git a/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go b/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go
index 8233be2..2a706c3 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go
@@ -1,8 +1,10 @@
package sockaddr
import (
+ "encoding/binary"
"errors"
"fmt"
+ "math/big"
"net"
"regexp"
"sort"
@@ -10,6 +12,14 @@
"strings"
)
+var (
+ // Centralize all regexps and regexp.Copy() where necessary.
+ signRE *regexp.Regexp = regexp.MustCompile(`^[\s]*[+-]`)
+ whitespaceRE *regexp.Regexp = regexp.MustCompile(`[\s]+`)
+ ifNameRE *regexp.Regexp = regexp.MustCompile(`^(?:Ethernet|Wireless LAN) adapter ([^:]+):`)
+ ipAddrRE *regexp.Regexp = regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`)
+)
+
// IfAddrs is a slice of IfAddr
type IfAddrs []IfAddr
@@ -91,6 +101,40 @@
return AscAddress(&p1Ptr.SockAddr, &p2Ptr.SockAddr)
}
+// AscIfDefault is a sorting function to sort IfAddrs by whether or not they
+// have a default route or not. Non-equal types are deferred in the sort.
+//
+// FIXME: This is a particularly expensive sorting operation because of the
+// non-memoized calls to NewRouteInfo(). In an ideal world the routeInfo data
+// once at the start of the sort and pass it along as a context or by wrapping
+// the IfAddr type with this information (this would also solve the inability to
+// return errors and the possibility of failing silently). Fortunately,
+// N*log(N) where N = 3 is only ~6.2 invocations. Not ideal, but not worth
+// optimizing today. The common case is this gets called once or twice.
+// Patches welcome.
+func AscIfDefault(p1Ptr, p2Ptr *IfAddr) int {
+ ri, err := NewRouteInfo()
+ if err != nil {
+ return sortDeferDecision
+ }
+
+ defaultIfName, err := ri.GetDefaultInterfaceName()
+ if err != nil {
+ return sortDeferDecision
+ }
+
+ switch {
+ case p1Ptr.Interface.Name == defaultIfName && p2Ptr.Interface.Name == defaultIfName:
+ return sortDeferDecision
+ case p1Ptr.Interface.Name == defaultIfName:
+ return sortReceiverBeforeArg
+ case p2Ptr.Interface.Name == defaultIfName:
+ return sortArgBeforeReceiver
+ default:
+ return sortDeferDecision
+ }
+}
+
// AscIfName is a sorting function to sort IfAddrs by their interface names.
func AscIfName(p1Ptr, p2Ptr *IfAddr) int {
return strings.Compare(p1Ptr.Name, p2Ptr.Name)
@@ -127,6 +171,11 @@
return -1 * AscAddress(&p1Ptr.SockAddr, &p2Ptr.SockAddr)
}
+// DescIfDefault is identical to AscIfDefault but reverse ordered.
+func DescIfDefault(p1Ptr, p2Ptr *IfAddr) int {
+ return -1 * AscIfDefault(p1Ptr, p2Ptr)
+}
+
// DescIfName is identical to AscIfName but reverse ordered.
func DescIfName(p1Ptr, p2Ptr *IfAddr) int {
return -1 * strings.Compare(p1Ptr.Name, p2Ptr.Name)
@@ -169,7 +218,15 @@
// IfAttr forwards the selector to IfAttr.Attr() for resolution. If there is
// more than one IfAddr, only the first IfAddr is used.
-func IfAttr(selectorName string, ifAddrs IfAddrs) (string, error) {
+func IfAttr(selectorName string, ifAddr IfAddr) (string, error) {
+ attrName := AttrName(strings.ToLower(selectorName))
+ attrVal, err := ifAddr.Attr(attrName)
+ return attrVal, err
+}
+
+// IfAttrs forwards the selector to IfAttrs.Attr() for resolution. If there is
+// more than one IfAddr, only the first IfAddr is used.
+func IfAttrs(selectorName string, ifAddrs IfAddrs) (string, error) {
if len(ifAddrs) == 0 {
return "", nil
}
@@ -243,10 +300,10 @@
// the `eval` equivalent of:
//
// ```
-// $ sockaddr eval -r '{{GetDefaultInterfaces | include "type" "ip" | include "flags" "forwardable|up" | sort "type,size" | include "RFC" "6890" }}'
+// $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | include "RFC" "6890" }}'
/// ```
func GetPrivateInterfaces() (IfAddrs, error) {
- privateIfs, err := GetDefaultInterfaces()
+ privateIfs, err := GetAllInterfaces()
if err != nil {
return IfAddrs{}, err
}
@@ -259,15 +316,21 @@
return IfAddrs{}, nil
}
- privateIfs, _, err = IfByFlag("forwardable|up", privateIfs)
+ privateIfs, _, err = IfByFlag("forwardable", privateIfs)
if err != nil {
return IfAddrs{}, err
}
+
+ privateIfs, _, err = IfByFlag("up", privateIfs)
+ if err != nil {
+ return IfAddrs{}, err
+ }
+
if len(privateIfs) == 0 {
return IfAddrs{}, nil
}
- OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(privateIfs)
+ OrderedIfAddrBy(AscIfDefault, AscIfType, AscIfNetworkSize).Sort(privateIfs)
privateIfs, _, err = IfByRFC("6890", privateIfs)
if err != nil {
@@ -285,10 +348,10 @@
// function is the `eval` equivalent of:
//
// ```
-// $ sockaddr eval -r '{{GetDefaultInterfaces | include "type" "ip" | include "flags" "forwardable|up" | sort "type,size" | exclude "RFC" "6890" }}'
+// $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | exclude "RFC" "6890" }}'
/// ```
func GetPublicInterfaces() (IfAddrs, error) {
- publicIfs, err := GetDefaultInterfaces()
+ publicIfs, err := GetAllInterfaces()
if err != nil {
return IfAddrs{}, err
}
@@ -301,15 +364,21 @@
return IfAddrs{}, nil
}
- publicIfs, _, err = IfByFlag("forwardable|up", publicIfs)
+ publicIfs, _, err = IfByFlag("forwardable", publicIfs)
if err != nil {
return IfAddrs{}, err
}
+
+ publicIfs, _, err = IfByFlag("up", publicIfs)
+ if err != nil {
+ return IfAddrs{}, err
+ }
+
if len(publicIfs) == 0 {
return IfAddrs{}, nil
}
- OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(publicIfs)
+ OrderedIfAddrBy(AscIfDefault, AscIfType, AscIfNetworkSize).Sort(publicIfs)
_, publicIfs, err = IfByRFC("6890", publicIfs)
if err != nil {
@@ -652,6 +721,245 @@
return includedIfs, excludedIfs, nil
}
+// IfAddrMath will return a new IfAddr struct with a mutated value.
+func IfAddrMath(operation, value string, inputIfAddr IfAddr) (IfAddr, error) {
+ // Regexp used to enforce the sign being a required part of the grammar for
+ // some values.
+ signRe := signRE.Copy()
+
+ switch strings.ToLower(operation) {
+ case "address":
+ // "address" operates on the IP address and is allowed to overflow or
+ // underflow networks, however it will wrap along the underlying address's
+ // underlying type.
+
+ if !signRe.MatchString(value) {
+ return IfAddr{}, fmt.Errorf("sign (+/-) is required for operation %q", operation)
+ }
+
+ switch sockType := inputIfAddr.SockAddr.Type(); sockType {
+ case TypeIPv4:
+ // 33 == Accept any uint32 value
+ // TODO(seanc@): Add the ability to parse hex
+ i, err := strconv.ParseInt(value, 10, 33)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ ipv4 := *ToIPv4Addr(inputIfAddr.SockAddr)
+ ipv4Uint32 := uint32(ipv4.Address)
+ ipv4Uint32 += uint32(i)
+ return IfAddr{
+ SockAddr: IPv4Addr{
+ Address: IPv4Address(ipv4Uint32),
+ Mask: ipv4.Mask,
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ case TypeIPv6:
+ // 64 == Accept any int32 value
+ // TODO(seanc@): Add the ability to parse hex. Also parse a bignum int.
+ i, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ ipv6 := *ToIPv6Addr(inputIfAddr.SockAddr)
+ ipv6BigIntA := new(big.Int)
+ ipv6BigIntA.Set(ipv6.Address)
+ ipv6BigIntB := big.NewInt(i)
+
+ ipv6Addr := ipv6BigIntA.Add(ipv6BigIntA, ipv6BigIntB)
+ ipv6Addr.And(ipv6Addr, ipv6HostMask)
+
+ return IfAddr{
+ SockAddr: IPv6Addr{
+ Address: IPv6Address(ipv6Addr),
+ Mask: ipv6.Mask,
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ default:
+ return IfAddr{}, fmt.Errorf("unsupported type for operation %q: %T", operation, sockType)
+ }
+ case "network":
+ // "network" operates on the network address. Positive values start at the
+ // network address and negative values wrap at the network address, which
+ // means a "-1" value on a network will be the broadcast address after
+ // wrapping is applied.
+
+ if !signRe.MatchString(value) {
+ return IfAddr{}, fmt.Errorf("sign (+/-) is required for operation %q", operation)
+ }
+
+ switch sockType := inputIfAddr.SockAddr.Type(); sockType {
+ case TypeIPv4:
+ // 33 == Accept any uint32 value
+ // TODO(seanc@): Add the ability to parse hex
+ i, err := strconv.ParseInt(value, 10, 33)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ ipv4 := *ToIPv4Addr(inputIfAddr.SockAddr)
+ ipv4Uint32 := uint32(ipv4.NetworkAddress())
+
+ // Wrap along network mask boundaries. EZ-mode wrapping made possible by
+ // use of int64 vs a uint.
+ var wrappedMask int64
+ if i >= 0 {
+ wrappedMask = i
+ } else {
+ wrappedMask = 1 + i + int64(^uint32(ipv4.Mask))
+ }
+
+ ipv4Uint32 = ipv4Uint32 + (uint32(wrappedMask) &^ uint32(ipv4.Mask))
+
+ return IfAddr{
+ SockAddr: IPv4Addr{
+ Address: IPv4Address(ipv4Uint32),
+ Mask: ipv4.Mask,
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ case TypeIPv6:
+ // 64 == Accept any int32 value
+ // TODO(seanc@): Add the ability to parse hex. Also parse a bignum int.
+ i, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ ipv6 := *ToIPv6Addr(inputIfAddr.SockAddr)
+ ipv6BigInt := new(big.Int)
+ ipv6BigInt.Set(ipv6.NetworkAddress())
+
+ mask := new(big.Int)
+ mask.Set(ipv6.Mask)
+ if i > 0 {
+ wrappedMask := new(big.Int)
+ wrappedMask.SetInt64(i)
+
+ wrappedMask.AndNot(wrappedMask, mask)
+ ipv6BigInt.Add(ipv6BigInt, wrappedMask)
+ } else {
+ // Mask off any bits that exceed the network size. Subtract the
+ // wrappedMask from the last usable - 1
+ wrappedMask := new(big.Int)
+ wrappedMask.SetInt64(-1 * i)
+ wrappedMask.Sub(wrappedMask, big.NewInt(1))
+
+ wrappedMask.AndNot(wrappedMask, mask)
+
+ lastUsable := new(big.Int)
+ lastUsable.Set(ipv6.LastUsable().(IPv6Addr).Address)
+
+ ipv6BigInt = lastUsable.Sub(lastUsable, wrappedMask)
+ }
+
+ return IfAddr{
+ SockAddr: IPv6Addr{
+ Address: IPv6Address(ipv6BigInt),
+ Mask: ipv6.Mask,
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ default:
+ return IfAddr{}, fmt.Errorf("unsupported type for operation %q: %T", operation, sockType)
+ }
+ case "mask":
+ // "mask" operates on the IP address and returns the IP address on
+ // which the given integer mask has been applied. If the applied mask
+ // corresponds to a larger network than the mask of the IP address,
+ // the latter will be replaced by the former.
+ switch sockType := inputIfAddr.SockAddr.Type(); sockType {
+ case TypeIPv4:
+ i, err := strconv.ParseUint(value, 10, 32)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ if i > 32 {
+ return IfAddr{}, fmt.Errorf("parameter for operation %q on ipv4 addresses must be between 0 and 32", operation)
+ }
+
+ ipv4 := *ToIPv4Addr(inputIfAddr.SockAddr)
+
+ ipv4Mask := net.CIDRMask(int(i), 32)
+ ipv4MaskUint32 := binary.BigEndian.Uint32(ipv4Mask)
+
+ maskedIpv4 := ipv4.NetIP().Mask(ipv4Mask)
+ maskedIpv4Uint32 := binary.BigEndian.Uint32(maskedIpv4)
+
+ maskedIpv4MaskUint32 := uint32(ipv4.Mask)
+
+ if ipv4MaskUint32 < maskedIpv4MaskUint32 {
+ maskedIpv4MaskUint32 = ipv4MaskUint32
+ }
+
+ return IfAddr{
+ SockAddr: IPv4Addr{
+ Address: IPv4Address(maskedIpv4Uint32),
+ Mask: IPv4Mask(maskedIpv4MaskUint32),
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ case TypeIPv6:
+ i, err := strconv.ParseUint(value, 10, 32)
+ if err != nil {
+ return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
+ }
+
+ if i > 128 {
+ return IfAddr{}, fmt.Errorf("parameter for operation %q on ipv6 addresses must be between 0 and 64", operation)
+ }
+
+ ipv6 := *ToIPv6Addr(inputIfAddr.SockAddr)
+
+ ipv6Mask := net.CIDRMask(int(i), 128)
+ ipv6MaskBigInt := new(big.Int)
+ ipv6MaskBigInt.SetBytes(ipv6Mask)
+
+ maskedIpv6 := ipv6.NetIP().Mask(ipv6Mask)
+ maskedIpv6BigInt := new(big.Int)
+ maskedIpv6BigInt.SetBytes(maskedIpv6)
+
+ maskedIpv6MaskBigInt := new(big.Int)
+ maskedIpv6MaskBigInt.Set(ipv6.Mask)
+
+ if ipv6MaskBigInt.Cmp(maskedIpv6MaskBigInt) == -1 {
+ maskedIpv6MaskBigInt = ipv6MaskBigInt
+ }
+
+ return IfAddr{
+ SockAddr: IPv6Addr{
+ Address: IPv6Address(maskedIpv6BigInt),
+ Mask: IPv6Mask(maskedIpv6MaskBigInt),
+ },
+ Interface: inputIfAddr.Interface,
+ }, nil
+ default:
+ return IfAddr{}, fmt.Errorf("unsupported type for operation %q: %T", operation, sockType)
+ }
+ default:
+ return IfAddr{}, fmt.Errorf("unsupported math operation: %q", operation)
+ }
+}
+
+// IfAddrsMath will apply an IfAddrMath operation each IfAddr struct. Any
+// failure will result in zero results.
+func IfAddrsMath(operation, value string, inputIfAddrs IfAddrs) (IfAddrs, error) {
+ outputAddrs := make(IfAddrs, 0, len(inputIfAddrs))
+ for _, ifAddr := range inputIfAddrs {
+ result, err := IfAddrMath(operation, value, ifAddr)
+ if err != nil {
+ return IfAddrs{}, fmt.Errorf("unable to perform an IPMath operation on %s: %v", ifAddr, err)
+ }
+ outputAddrs = append(outputAddrs, result)
+ }
+ return outputAddrs, nil
+}
+
// IncludeIfs returns an IfAddrs based on the passed in selector.
func IncludeIfs(selectorName, selectorParam string, inputIfAddrs IfAddrs) (IfAddrs, error) {
var includedIfs IfAddrs
@@ -736,6 +1044,10 @@
sortFuncs[i] = AscIfAddress
case "-address":
sortFuncs[i] = DescIfAddress
+ case "+default", "default":
+ sortFuncs[i] = AscIfDefault
+ case "-default":
+ sortFuncs[i] = DescIfDefault
case "+name", "name":
// The "name" selector returns an array of IfAddrs
// ordered by the interface name.
@@ -886,7 +1198,7 @@
// Linux.
func parseDefaultIfNameFromIPCmd(routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
- re := regexp.MustCompile(`[\s]+`)
+ re := whitespaceRE.Copy()
for _, line := range lines {
kvs := re.Split(line, -1)
if len(kvs) < 5 {
@@ -929,7 +1241,7 @@
// support added.
func parseDefaultIPAddrWindowsRoute(routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
- re := regexp.MustCompile(`[\s]+`)
+ re := whitespaceRE.Copy()
for _, line := range lines {
kvs := re.Split(strings.TrimSpace(line), -1)
if len(kvs) < 3 {
@@ -949,17 +1261,17 @@
// interface name forwarding traffic to the default gateway.
func parseDefaultIfNameWindowsIPConfig(defaultIPAddr, routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
- ifNameRE := regexp.MustCompile(`^Ethernet adapter ([^\s:]+):`)
- ipAddrRE := regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`)
+ ifNameRe := ifNameRE.Copy()
+ ipAddrRe := ipAddrRE.Copy()
var ifName string
for _, line := range lines {
- switch ifNameMatches := ifNameRE.FindStringSubmatch(line); {
+ switch ifNameMatches := ifNameRe.FindStringSubmatch(line); {
case len(ifNameMatches) > 1:
ifName = ifNameMatches[1]
continue
}
- switch ipAddrMatches := ipAddrRE.FindStringSubmatch(line); {
+ switch ipAddrMatches := ipAddrRe.FindStringSubmatch(line); {
case len(ipAddrMatches) > 1 && ipAddrMatches[1] == defaultIPAddr:
return ifName, nil
}
diff --git a/vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go b/vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go
index 9f2616a..4d395dc 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go
@@ -58,7 +58,8 @@
// Strip off any bogus hex-encoded netmasks that will be mis-parsed by Go. In
// particular, clients with the Barracuda VPN client will see something like:
// `192.168.3.51/00ffffff` as their IP address.
- if match := trailingHexNetmaskRE.FindStringIndex(ipv4Str); match != nil {
+ trailingHexNetmaskRe := trailingHexNetmaskRE.Copy()
+ if match := trailingHexNetmaskRe.FindStringIndex(ipv4Str); match != nil {
ipv4Str = ipv4Str[:match[0]]
}
diff --git a/vendor/github.com/hashicorp/go-sockaddr/rfc.go b/vendor/github.com/hashicorp/go-sockaddr/rfc.go
index fd9be94..02e188f 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/rfc.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/rfc.go
@@ -3,6 +3,7 @@
// ForwardingBlacklist is a faux RFC that includes a list of non-forwardable IP
// blocks.
const ForwardingBlacklist = 4294967295
+const ForwardingBlacklistRFC = "4294967295"
// IsRFC tests to see if an SockAddr matches the specified RFC
func IsRFC(rfcNum uint, sa SockAddr) bool {
diff --git a/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go b/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go
index b33e4c0..c2ec91e 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go
@@ -5,10 +5,6 @@
"os/exec"
)
-var cmds map[string][]string = map[string][]string{
- "ip": {"/sbin/ip", "route"},
-}
-
type routeInfo struct {
cmds map[string][]string
}
@@ -16,15 +12,22 @@
// NewRouteInfo returns a Linux-specific implementation of the RouteInfo
// interface.
func NewRouteInfo() (routeInfo, error) {
+ // CoreOS Container Linux moved ip to /usr/bin/ip, so look it up on
+ // $PATH and fallback to /sbin/ip on error.
+ path, _ := exec.LookPath("ip")
+ if path == "" {
+ path = "/sbin/ip"
+ }
+
return routeInfo{
- cmds: cmds,
+ cmds: map[string][]string{"ip": {path, "route"}},
}, nil
}
// GetDefaultInterfaceName returns the interface name attached to the default
// route on the default interface.
func (ri routeInfo) GetDefaultInterfaceName() (string, error) {
- out, err := exec.Command(cmds["ip"][0], cmds["ip"][1:]...).Output()
+ out, err := exec.Command(ri.cmds["ip"][0], ri.cmds["ip"][1:]...).Output()
if err != nil {
return "", err
}
diff --git a/vendor/github.com/hashicorp/go-sockaddr/sockaddr.go b/vendor/github.com/hashicorp/go-sockaddr/sockaddr.go
index 51389eb..826c91c 100644
--- a/vendor/github.com/hashicorp/go-sockaddr/sockaddr.go
+++ b/vendor/github.com/hashicorp/go-sockaddr/sockaddr.go
@@ -1,6 +1,7 @@
package sockaddr
import (
+ "encoding/json"
"fmt"
"strings"
)
@@ -176,3 +177,30 @@
func SockAddrAttrs() []AttrName {
return sockAddrAttrs
}
+
+// Although this is pretty trivial to do in a program, having the logic here is
+// useful all around. Note that this marshals into a *string* -- the underlying
+// string representation of the sockaddr. If you then unmarshal into this type
+// in Go, all will work as expected, but externally you can take what comes out
+// and use the string value directly.
+type SockAddrMarshaler struct {
+ SockAddr
+}
+
+func (s *SockAddrMarshaler) MarshalJSON() ([]byte, error) {
+ return json.Marshal(s.SockAddr.String())
+}
+
+func (s *SockAddrMarshaler) UnmarshalJSON(in []byte) error {
+ var str string
+ err := json.Unmarshal(in, &str)
+ if err != nil {
+ return err
+ }
+ sa, err := NewSockAddr(str)
+ if err != nil {
+ return err
+ }
+ s.SockAddr = sa
+ return nil
+}
diff --git a/vendor/github.com/moby/buildkit/README.md b/vendor/github.com/moby/buildkit/README.md
index ba8525c..5679476 100644
--- a/vendor/github.com/moby/buildkit/README.md
+++ b/vendor/github.com/moby/buildkit/README.md
@@ -138,11 +138,11 @@
##### Building a Dockerfile using [external frontend](https://hub.docker.com/r/tonistiigi/dockerfile/tags/):
-During development, an external version of the Dockerfile frontend is pushed to https://hub.docker.com/r/tonistiigi/dockerfile that can be used with the gateway frontend. The source for the external frontend is currently located in `./frontend/dockerfile/cmd/dockerfile-frontend` but will move out of this repository in the future ([#163](https://github.com/moby/buildkit/issues/163)).
+During development, an external version of the Dockerfile frontend is pushed to https://hub.docker.com/r/tonistiigi/dockerfile that can be used with the gateway frontend. The source for the external frontend is currently located in `./frontend/dockerfile/cmd/dockerfile-frontend` but will move out of this repository in the future ([#163](https://github.com/moby/buildkit/issues/163)). For automatic build from master branch of this repository `tonistiigi/dockerfile:master` image can be used.
```
-buildctl build --frontend=gateway.v0 --frontend-opt=source=tonistiigi/dockerfile:v0 --local context=. --local dockerfile=.
-buildctl build --frontend gateway.v0 --frontend-opt=source=tonistiigi/dockerfile:v0 --frontend-opt=context=git://github.com/moby/moby --frontend-opt build-arg:APT_MIRROR=cdn-fastly.deb.debian.org
+buildctl build --frontend=gateway.v0 --frontend-opt=source=tonistiigi/dockerfile --local context=. --local dockerfile=.
+buildctl build --frontend gateway.v0 --frontend-opt=source=tonistiigi/dockerfile --frontend-opt=context=git://github.com/moby/moby --frontend-opt build-arg:APT_MIRROR=cdn-fastly.deb.debian.org
````
### Exporters
diff --git a/vendor/github.com/moby/buildkit/cache/remotecache/export.go b/vendor/github.com/moby/buildkit/cache/remotecache/export.go
index 40a3675..0536ba2 100644
--- a/vendor/github.com/moby/buildkit/cache/remotecache/export.go
+++ b/vendor/github.com/moby/buildkit/cache/remotecache/export.go
@@ -9,7 +9,6 @@
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
- "github.com/docker/distribution/manifest"
v1 "github.com/moby/buildkit/cache/remotecache/v1"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/solver"
@@ -17,6 +16,7 @@
"github.com/moby/buildkit/util/progress"
"github.com/moby/buildkit/util/push"
digest "github.com/opencontainers/go-digest"
+ specs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
@@ -46,7 +46,9 @@
// own type because oci type can't be pushed and docker type doesn't have annotations
type manifestList struct {
- manifest.Versioned
+ specs.Versioned
+
+ MediaType string `json:"mediaType,omitempty"`
// Manifests references platform specific manifests.
Manifests []ocispec.Descriptor `json:"manifests"`
diff --git a/vendor/github.com/moby/buildkit/executor/oci/user.go b/vendor/github.com/moby/buildkit/executor/oci/user.go
index ce755f1..ac5dbeb 100644
--- a/vendor/github.com/moby/buildkit/executor/oci/user.go
+++ b/vendor/github.com/moby/buildkit/executor/oci/user.go
@@ -2,27 +2,31 @@
import (
"context"
+ "errors"
"os"
"strconv"
"strings"
+ "github.com/containerd/containerd/containers"
+ containerdoci "github.com/containerd/containerd/oci"
"github.com/containerd/continuity/fs"
"github.com/opencontainers/runc/libcontainer/user"
+ "github.com/opencontainers/runtime-spec/specs-go"
)
-func GetUser(ctx context.Context, root, username string) (uint32, uint32, error) {
+func GetUser(ctx context.Context, root, username string) (uint32, uint32, []uint32, error) {
// fast path from uid/gid
- if uid, gid, err := ParseUser(username); err == nil {
- return uid, gid, nil
+ if uid, gid, err := ParseUIDGID(username); err == nil {
+ return uid, gid, nil, nil
}
passwdPath, err := user.GetPasswdPath()
if err != nil {
- return 0, 0, err
+ return 0, 0, nil, err
}
groupPath, err := user.GetGroupPath()
if err != nil {
- return 0, 0, err
+ return 0, 0, nil, err
}
passwdFile, err := openUserFile(root, passwdPath)
if err == nil {
@@ -35,33 +39,29 @@
execUser, err := user.GetExecUser(username, nil, passwdFile, groupFile)
if err != nil {
- return 0, 0, err
+ return 0, 0, nil, err
}
-
- return uint32(execUser.Uid), uint32(execUser.Gid), nil
+ var sgids []uint32
+ for _, g := range execUser.Sgids {
+ sgids = append(sgids, uint32(g))
+ }
+ return uint32(execUser.Uid), uint32(execUser.Gid), sgids, nil
}
-func ParseUser(str string) (uid uint32, gid uint32, err error) {
+// ParseUIDGID takes the fast path to parse UID and GID if and only if they are both provided
+func ParseUIDGID(str string) (uid uint32, gid uint32, err error) {
if str == "" {
return 0, 0, nil
}
parts := strings.SplitN(str, ":", 2)
- for i, v := range parts {
- switch i {
- case 0:
- uid, err = parseUID(v)
- if err != nil {
- return 0, 0, err
- }
- if len(parts) == 1 {
- gid = uid
- }
- case 1:
- gid, err = parseUID(v)
- if err != nil {
- return 0, 0, err
- }
- }
+ if len(parts) == 1 {
+ return 0, 0, errors.New("groups ID is not provided")
+ }
+ if uid, err = parseUID(parts[0]); err != nil {
+ return 0, 0, err
+ }
+ if gid, err = parseUID(parts[1]); err != nil {
+ return 0, 0, err
}
return
}
@@ -84,3 +84,24 @@
}
return uint32(uid), nil
}
+
+// WithUIDGID allows the UID and GID for the Process to be set
+// FIXME: This is a temporeray fix for the missing supplementary GIDs from containerd
+// once the PR in containerd is merged we should remove this function.
+func WithUIDGID(uid, gid uint32, sgids []uint32) containerdoci.SpecOpts {
+ return func(_ context.Context, _ containerdoci.Client, _ *containers.Container, s *containerdoci.Spec) error {
+ setProcess(s)
+ s.Process.User.UID = uid
+ s.Process.User.GID = gid
+ s.Process.User.AdditionalGids = sgids
+ return nil
+ }
+}
+
+// setProcess sets Process to empty if unset
+// FIXME: Same on this one. Need to be removed after containerd fix merged
+func setProcess(s *containerdoci.Spec) {
+ if s.Process == nil {
+ s.Process = &specs.Process{}
+ }
+}
diff --git a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go
index edffb5b..97eb343 100644
--- a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go
+++ b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go
@@ -133,7 +133,7 @@
}
defer mount.Unmount(rootFSPath, 0)
- uid, gid, err := oci.GetUser(ctx, rootFSPath, meta.User)
+ uid, gid, sgids, err := oci.GetUser(ctx, rootFSPath, meta.User)
if err != nil {
return err
}
@@ -143,7 +143,7 @@
return err
}
defer f.Close()
- opts := []containerdoci.SpecOpts{containerdoci.WithUIDGID(uid, gid)}
+ opts := []containerdoci.SpecOpts{oci.WithUIDGID(uid, gid, sgids)}
if system.SeccompSupported() {
opts = append(opts, seccomp.WithDefaultProfile())
}
@@ -170,9 +170,7 @@
}
if w.rootless {
- specconv.ToRootless(spec, &specconv.RootlessOpts{
- MapSubUIDGID: true,
- })
+ specconv.ToRootless(spec, nil)
// TODO(AkihiroSuda): keep Cgroups enabled if /sys/fs/cgroup/cpuset/buildkit exists and writable
spec.Linux.CgroupsPath = ""
// TODO(AkihiroSuda): ToRootless removes netns, but we should readd netns here
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go
index 00e92b3..ac70fb8 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go
@@ -91,8 +91,7 @@
metaResolver = imagemetaresolver.Default()
}
- var allDispatchStates []*dispatchState
- dispatchStatesByName := map[string]*dispatchState{}
+ allDispatchStates := newDispatchStates()
// set base state for every image
for _, st := range stages {
@@ -100,6 +99,9 @@
if err != nil {
return nil, nil, err
}
+ if name == "" {
+ return nil, nil, errors.Errorf("base name (%s) should not be blank", st.BaseName)
+ }
st.BaseName = name
ds := &dispatchState{
@@ -121,13 +123,7 @@
ds.platform = &p
}
- if d, ok := dispatchStatesByName[st.BaseName]; ok {
- ds.base = d
- }
- allDispatchStates = append(allDispatchStates, ds)
- if st.Name != "" {
- dispatchStatesByName[strings.ToLower(st.Name)] = ds
- }
+ allDispatchStates.addState(ds)
if opt.IgnoreCache != nil {
if len(opt.IgnoreCache) == 0 {
ds.ignoreCache = true
@@ -143,20 +139,20 @@
var target *dispatchState
if opt.Target == "" {
- target = allDispatchStates[len(allDispatchStates)-1]
+ target = allDispatchStates.lastTarget()
} else {
var ok bool
- target, ok = dispatchStatesByName[strings.ToLower(opt.Target)]
+ target, ok = allDispatchStates.findStateByName(opt.Target)
if !ok {
return nil, nil, errors.Errorf("target stage %s could not be found", opt.Target)
}
}
// fill dependencies to stages so unreachable ones can avoid loading image configs
- for _, d := range allDispatchStates {
+ for _, d := range allDispatchStates.states {
d.commands = make([]command, len(d.stage.Commands))
for i, cmd := range d.stage.Commands {
- newCmd, err := toCommand(cmd, dispatchStatesByName, allDispatchStates)
+ newCmd, err := toCommand(cmd, allDispatchStates)
if err != nil {
return nil, nil, err
}
@@ -165,7 +161,7 @@
if src != nil {
d.deps[src] = struct{}{}
if src.unregistered {
- allDispatchStates = append(allDispatchStates, src)
+ allDispatchStates.addState(src)
}
}
}
@@ -173,7 +169,7 @@
}
eg, ctx := errgroup.WithContext(ctx)
- for i, d := range allDispatchStates {
+ for i, d := range allDispatchStates.states {
reachable := isReachable(target, d)
// resolve image config for every stage
if d.base == nil {
@@ -239,7 +235,7 @@
buildContext := &mutableOutput{}
ctxPaths := map[string]struct{}{}
- for _, d := range allDispatchStates {
+ for _, d := range allDispatchStates.states {
if !isReachable(target, d) {
continue
}
@@ -271,17 +267,16 @@
}
opt := dispatchOpt{
- allDispatchStates: allDispatchStates,
- dispatchStatesByName: dispatchStatesByName,
- metaArgs: metaArgs,
- buildArgValues: opt.BuildArgs,
- shlex: shlex,
- sessionID: opt.SessionID,
- buildContext: llb.NewState(buildContext),
- proxyEnv: proxyEnv,
- cacheIDNamespace: opt.CacheIDNamespace,
- buildPlatforms: opt.BuildPlatforms,
- targetPlatform: *opt.TargetPlatform,
+ allDispatchStates: allDispatchStates,
+ metaArgs: metaArgs,
+ buildArgValues: opt.BuildArgs,
+ shlex: shlex,
+ sessionID: opt.SessionID,
+ buildContext: llb.NewState(buildContext),
+ proxyEnv: proxyEnv,
+ cacheIDNamespace: opt.CacheIDNamespace,
+ buildPlatforms: opt.BuildPlatforms,
+ targetPlatform: *opt.TargetPlatform,
}
if err = dispatchOnBuild(d, d.image.Config.OnBuild, opt); err != nil {
@@ -330,14 +325,14 @@
return &st, &target.image, nil
}
-func toCommand(ic instructions.Command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) (command, error) {
+func toCommand(ic instructions.Command, allDispatchStates *dispatchStates) (command, error) {
cmd := command{Command: ic}
if c, ok := ic.(*instructions.CopyCommand); ok {
if c.From != "" {
var stn *dispatchState
index, err := strconv.Atoi(c.From)
if err != nil {
- stn, ok = dispatchStatesByName[strings.ToLower(c.From)]
+ stn, ok = allDispatchStates.findStateByName(c.From)
if !ok {
stn = &dispatchState{
stage: instructions.Stage{BaseName: c.From},
@@ -346,16 +341,16 @@
}
}
} else {
- if index < 0 || index >= len(allDispatchStates) {
- return command{}, errors.Errorf("invalid stage index %d", index)
+ stn, err = allDispatchStates.findStateByIndex(index)
+ if err != nil {
+ return command{}, err
}
- stn = allDispatchStates[index]
}
cmd.sources = []*dispatchState{stn}
}
}
- if ok := detectRunMount(&cmd, dispatchStatesByName, allDispatchStates); ok {
+ if ok := detectRunMount(&cmd, allDispatchStates); ok {
return cmd, nil
}
@@ -363,17 +358,16 @@
}
type dispatchOpt struct {
- allDispatchStates []*dispatchState
- dispatchStatesByName map[string]*dispatchState
- metaArgs []instructions.ArgCommand
- buildArgValues map[string]string
- shlex *shell.Lex
- sessionID string
- buildContext llb.State
- proxyEnv *llb.ProxyEnv
- cacheIDNamespace string
- targetPlatform specs.Platform
- buildPlatforms []specs.Platform
+ allDispatchStates *dispatchStates
+ metaArgs []instructions.ArgCommand
+ buildArgValues map[string]string
+ shlex *shell.Lex
+ sessionID string
+ buildContext llb.State
+ proxyEnv *llb.ProxyEnv
+ cacheIDNamespace string
+ targetPlatform specs.Platform
+ buildPlatforms []specs.Platform
}
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
@@ -456,6 +450,43 @@
unregistered bool
}
+type dispatchStates struct {
+ states []*dispatchState
+ statesByName map[string]*dispatchState
+}
+
+func newDispatchStates() *dispatchStates {
+ return &dispatchStates{statesByName: map[string]*dispatchState{}}
+}
+
+func (dss *dispatchStates) addState(ds *dispatchState) {
+ dss.states = append(dss.states, ds)
+
+ if d, ok := dss.statesByName[ds.stage.BaseName]; ok {
+ ds.base = d
+ }
+ if ds.stage.Name != "" {
+ dss.statesByName[strings.ToLower(ds.stage.Name)] = ds
+ }
+}
+
+func (dss *dispatchStates) findStateByName(name string) (*dispatchState, bool) {
+ ds, ok := dss.statesByName[strings.ToLower(name)]
+ return ds, ok
+}
+
+func (dss *dispatchStates) findStateByIndex(index int) (*dispatchState, error) {
+ if index < 0 || index >= len(dss.states) {
+ return nil, errors.Errorf("invalid stage index %d", index)
+ }
+
+ return dss.states[index], nil
+}
+
+func (dss *dispatchStates) lastTarget() *dispatchState {
+ return dss.states[len(dss.states)-1]
+}
+
type command struct {
instructions.Command
sources []*dispatchState
@@ -474,7 +505,7 @@
if err != nil {
return err
}
- cmd, err := toCommand(ic, opt.dispatchStatesByName, opt.allDispatchStates)
+ cmd, err := toCommand(ic, opt.allDispatchStates)
if err != nil {
return err
}
@@ -570,7 +601,11 @@
for i, src := range c.Sources() {
commitMessage.WriteString(" " + src)
- if isAddCommand && (strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://")) {
+ if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") {
+ if !isAddCommand {
+ return errors.New("source can't be a URL for COPY")
+ }
+
// Resources from remote URLs are not decompressed.
// https://docs.docker.com/engine/reference/builder/#add
//
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go
index a4544e7..d764340 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_norunmount.go
@@ -7,7 +7,7 @@
"github.com/moby/buildkit/frontend/dockerfile/instructions"
)
-func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool {
+func detectRunMount(cmd *command, allDispatchStates *dispatchStates) bool {
return false
}
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go
index 61408e1..aea61b3 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_runmount.go
@@ -5,14 +5,13 @@
import (
"path"
"path/filepath"
- "strings"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/pkg/errors"
)
-func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool {
+func detectRunMount(cmd *command, allDispatchStates *dispatchStates) bool {
if c, ok := cmd.Command.(*instructions.RunCommand); ok {
mounts := instructions.GetMounts(c)
sources := make([]*dispatchState, len(mounts))
@@ -24,7 +23,7 @@
if from == "" || mount.Type == instructions.MountTypeTmpfs {
continue
}
- stn, ok := dispatchStatesByName[strings.ToLower(from)]
+ stn, ok := allDispatchStates.findStateByName(from)
if !ok {
stn = &dispatchState{
stage: instructions.Stage{BaseName: from},
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go
index e299d52..d8bf747 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go
@@ -72,7 +72,7 @@
return flag
}
-// AddString adds a string flag to BFlags that can match multiple values
+// AddStrings adds a string flag to BFlags that can match multiple values
func (bf *BFlags) AddStrings(name string) *Flag {
flag := bf.addFlag(name, stringsType)
if flag == nil {
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go
index b96010f..903353e 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go
@@ -159,7 +159,7 @@
// AddCommand : ADD foo /path
//
-// Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
+// Add the file 'foo' to '/path'. Tarball and Remote URL (http, https) handling
// exist here. If you do not wish to have this automatic handling, use COPY.
//
type AddCommand struct {
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go
index 6e3f6b8..36903ec 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go
@@ -2,8 +2,9 @@
package shell
-// EqualEnvKeys compare two strings and returns true if they are equal. On
-// Windows this comparison is case insensitive.
+// EqualEnvKeys compare two strings and returns true if they are equal.
+// On Unix this comparison is case sensitive.
+// On Windows this comparison is case insensitive.
func EqualEnvKeys(from, to string) bool {
return from == to
}
diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go
index 7780fb6..010569b 100644
--- a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go
+++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go
@@ -2,8 +2,9 @@
import "strings"
-// EqualEnvKeys compare two strings and returns true if they are equal. On
-// Windows this comparison is case insensitive.
+// EqualEnvKeys compare two strings and returns true if they are equal.
+// On Unix this comparison is case sensitive.
+// On Windows this comparison is case insensitive.
func EqualEnvKeys(from, to string) bool {
return strings.ToUpper(from) == strings.ToUpper(to)
}
diff --git a/vendor/github.com/moby/buildkit/util/imageutil/config.go b/vendor/github.com/moby/buildkit/util/imageutil/config.go
index 2c2e18b..356ed53 100644
--- a/vendor/github.com/moby/buildkit/util/imageutil/config.go
+++ b/vendor/github.com/moby/buildkit/util/imageutil/config.go
@@ -141,13 +141,17 @@
}
var mfst struct {
- Config json.RawMessage `json:"config"`
+ MediaType string `json:"mediaType"`
+ Config json.RawMessage `json:"config"`
}
if err := json.Unmarshal(p, &mfst); err != nil {
return "", err
}
+ if mfst.MediaType != "" {
+ return mfst.MediaType, nil
+ }
if mfst.Config != nil {
return images.MediaTypeDockerSchema2Manifest, nil
}