diff --git a/cmd/crio/daemon_linux.go b/cmd/crio/daemon_linux.go
index 94ecb61f..884d3f26 100644
--- a/cmd/crio/daemon_linux.go
+++ b/cmd/crio/daemon_linux.go
@@ -3,8 +3,8 @@
package main
import (
- "github.com/Sirupsen/logrus"
systemdDaemon "github.com/coreos/go-systemd/daemon"
+ "github.com/sirupsen/logrus"
)
func sdNotify() {
diff --git a/cmd/crio/main.go b/cmd/crio/main.go
index 40fb8608..73c3bd82 100644
--- a/cmd/crio/main.go
+++ b/cmd/crio/main.go
@@ -10,11 +10,11 @@ import (
"sort"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/reexec"
"github.com/kubernetes-incubator/cri-o/libkpod"
"github.com/kubernetes-incubator/cri-o/server"
"github.com/opencontainers/selinux/go-selinux"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"golang.org/x/sys/unix"
"google.golang.org/grpc"
diff --git a/cmd/crioctl/main.go b/cmd/crioctl/main.go
index e8d30bc7..f444ce66 100644
--- a/cmd/crioctl/main.go
+++ b/cmd/crioctl/main.go
@@ -7,7 +7,7 @@ import (
"os"
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"google.golang.org/grpc"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/cmd/kpod/history.go b/cmd/kpod/history.go
index a737c342..082e6d66 100644
--- a/cmd/kpod/history.go
+++ b/cmd/kpod/history.go
@@ -11,12 +11,12 @@ import (
"strconv"
- "github.com/Sirupsen/logrus"
is "github.com/containers/image/storage"
"github.com/containers/storage"
units "github.com/docker/go-units"
"github.com/kubernetes-incubator/cri-o/libkpod/common"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go
index 5741d684..fec3f6fa 100644
--- a/cmd/kpod/main.go
+++ b/cmd/kpod/main.go
@@ -3,8 +3,8 @@ package main
import (
"os"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/reexec"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/cmd/kpod/pull.go b/cmd/kpod/pull.go
index 1ece94bd..89f74ee3 100644
--- a/cmd/kpod/pull.go
+++ b/cmd/kpod/pull.go
@@ -1,10 +1,10 @@
package main
import (
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/libkpod/common"
libkpodimage "github.com/kubernetes-incubator/cri-o/libkpod/image"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/cmd/kpod/save.go b/cmd/kpod/save.go
index ff11d084..8c7edcfb 100644
--- a/cmd/kpod/save.go
+++ b/cmd/kpod/save.go
@@ -3,10 +3,10 @@ package main
import (
"os"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage"
libkpodimage "github.com/kubernetes-incubator/cri-o/libkpod/image"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/libkpod/container.go b/libkpod/container.go
index 49344cd2..7835952d 100644
--- a/libkpod/container.go
+++ b/libkpod/container.go
@@ -4,9 +4,9 @@ import (
"fmt"
cstorage "github.com/containers/storage"
- "github.com/docker/docker/pkg/registrar"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/kubernetes-incubator/cri-o/pkg/registrar"
"github.com/pkg/errors"
)
diff --git a/libkpod/container_server.go b/libkpod/container_server.go
index 4114a1e9..c3535e9b 100644
--- a/libkpod/container_server.go
+++ b/libkpod/container_server.go
@@ -8,19 +8,19 @@ import (
"sync"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/types"
cstorage "github.com/containers/storage"
"github.com/docker/docker/pkg/ioutils"
- "github.com/docker/docker/pkg/registrar"
"github.com/docker/docker/pkg/truncindex"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/pkg/annotations"
+ "github.com/kubernetes-incubator/cri-o/pkg/registrar"
"github.com/kubernetes-incubator/cri-o/pkg/storage"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/libkpod/image/copy_ref.go b/libkpod/image/copy_ref.go
index d36c44fd..9ab88c25 100644
--- a/libkpod/image/copy_ref.go
+++ b/libkpod/image/copy_ref.go
@@ -2,6 +2,7 @@ package image
import (
"bytes"
+ "context"
"encoding/json"
"io"
"io/ioutil"
@@ -9,7 +10,6 @@ import (
"path/filepath"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/image"
is "github.com/containers/image/storage"
@@ -22,6 +22,7 @@ import (
specs "github.com/opencontainers/image-spec/specs-go"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// CopyRef handles image references used for copying images to/from remotes
@@ -415,7 +416,7 @@ func (cs *copySource) Reference() types.ImageReference {
return cs.ref
}
-func (cs *copySource) GetSignatures() ([][]byte, error) {
+func (cs *copySource) GetSignatures(context.Context) ([][]byte, error) {
return nil, nil
}
diff --git a/libkpod/sandbox/sandbox.go b/libkpod/sandbox/sandbox.go
index e3b94237..b19ff819 100644
--- a/libkpod/sandbox/sandbox.go
+++ b/libkpod/sandbox/sandbox.go
@@ -8,11 +8,11 @@ import (
"path/filepath"
"sync"
- "github.com/Sirupsen/logrus"
"github.com/containernetworking/cni/pkg/ns"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/symlink"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"k8s.io/apimachinery/pkg/fields"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/oci/oci.go b/oci/oci.go
index 75660fdc..2be42b78 100644
--- a/oci/oci.go
+++ b/oci/oci.go
@@ -13,9 +13,9 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/utils"
rspec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
diff --git a/pkg/ocicni/ocicni.go b/pkg/ocicni/ocicni.go
index 0a0e1740..0204cc2f 100644
--- a/pkg/ocicni/ocicni.go
+++ b/pkg/ocicni/ocicni.go
@@ -7,10 +7,10 @@ import (
"sort"
"sync"
- "github.com/Sirupsen/logrus"
"github.com/containernetworking/cni/libcni"
cnitypes "github.com/containernetworking/cni/pkg/types"
"github.com/fsnotify/fsnotify"
+ "github.com/sirupsen/logrus"
)
type cniNetworkPlugin struct {
diff --git a/vendor/github.com/docker/docker/pkg/registrar/registrar.go b/pkg/registrar/registrar.go
similarity index 100%
rename from vendor/github.com/docker/docker/pkg/registrar/registrar.go
rename to pkg/registrar/registrar.go
diff --git a/pkg/registrar/registrar_test.go b/pkg/registrar/registrar_test.go
new file mode 100644
index 00000000..0c1ef312
--- /dev/null
+++ b/pkg/registrar/registrar_test.go
@@ -0,0 +1,119 @@
+package registrar
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestReserve(t *testing.T) {
+ r := NewRegistrar()
+
+ obj := "test1"
+ if err := r.Reserve("test", obj); err != nil {
+ t.Fatal(err)
+ }
+
+ if err := r.Reserve("test", obj); err != nil {
+ t.Fatal(err)
+ }
+
+ obj2 := "test2"
+ err := r.Reserve("test", obj2)
+ if err == nil {
+ t.Fatalf("expected error when reserving an already reserved name to another object")
+ }
+ if err != ErrNameReserved {
+ t.Fatal("expected `ErrNameReserved` error when attempting to reserve an already reserved name")
+ }
+}
+
+func TestRelease(t *testing.T) {
+ r := NewRegistrar()
+ obj := "testing"
+
+ if err := r.Reserve("test", obj); err != nil {
+ t.Fatal(err)
+ }
+ r.Release("test")
+ r.Release("test") // Ensure there is no panic here
+
+ if err := r.Reserve("test", obj); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestGetNames(t *testing.T) {
+ r := NewRegistrar()
+ obj := "testing"
+ names := []string{"test1", "test2"}
+
+ for _, name := range names {
+ if err := r.Reserve(name, obj); err != nil {
+ t.Fatal(err)
+ }
+ }
+ r.Reserve("test3", "other")
+
+ names2, err := r.GetNames(obj)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if !reflect.DeepEqual(names, names2) {
+ t.Fatalf("Exepected: %v, Got: %v", names, names2)
+ }
+}
+
+func TestDelete(t *testing.T) {
+ r := NewRegistrar()
+ obj := "testing"
+ names := []string{"test1", "test2"}
+ for _, name := range names {
+ if err := r.Reserve(name, obj); err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ r.Reserve("test3", "other")
+ r.Delete(obj)
+
+ _, err := r.GetNames(obj)
+ if err == nil {
+ t.Fatal("expected error getting names for deleted key")
+ }
+
+ if err != ErrNoSuchKey {
+ t.Fatal("expected `ErrNoSuchKey`")
+ }
+}
+
+func TestGet(t *testing.T) {
+ r := NewRegistrar()
+ obj := "testing"
+ name := "test"
+
+ _, err := r.Get(name)
+ if err == nil {
+ t.Fatal("expected error when key does not exist")
+ }
+ if err != ErrNameNotReserved {
+ t.Fatal(err)
+ }
+
+ if err := r.Reserve(name, obj); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err = r.Get(name); err != nil {
+ t.Fatal(err)
+ }
+
+ r.Delete(obj)
+ _, err = r.Get(name)
+ if err == nil {
+ t.Fatal("expected error when key does not exist")
+ }
+ if err != ErrNameNotReserved {
+ t.Fatal(err)
+ }
+}
diff --git a/pkg/storage/runtime.go b/pkg/storage/runtime.go
index 034a6a81..bc402f41 100644
--- a/pkg/storage/runtime.go
+++ b/pkg/storage/runtime.go
@@ -5,7 +5,6 @@ import (
"fmt"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/copy"
istorage "github.com/containers/image/storage"
"github.com/containers/image/transports/alltransports"
@@ -13,6 +12,7 @@ import (
"github.com/containers/storage"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
var (
diff --git a/server/container_attach.go b/server/container_attach.go
index d81e0c32..f13596b4 100644
--- a/server/container_attach.go
+++ b/server/container_attach.go
@@ -7,9 +7,9 @@ import (
"os"
"path/filepath"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/utils"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/server/container_create.go b/server/container_create.go
index bf88789b..9e49d718 100644
--- a/server/container_create.go
+++ b/server/container_create.go
@@ -11,7 +11,6 @@ import (
"strings"
"time"
- "github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/symlink"
"github.com/kubernetes-incubator/cri-o/libkpod"
@@ -28,6 +27,7 @@ import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/server/container_exec.go b/server/container_exec.go
index d8f6c343..71dd620c 100644
--- a/server/container_exec.go
+++ b/server/container_exec.go
@@ -6,9 +6,9 @@ import (
"os"
"os/exec"
- "github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/pools"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
diff --git a/server/container_execsync.go b/server/container_execsync.go
index 3ae28088..59675353 100644
--- a/server/container_execsync.go
+++ b/server/container_execsync.go
@@ -3,8 +3,8 @@ package server
import (
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/container_list.go b/server/container_list.go
index c400d656..3589ffa5 100644
--- a/server/container_list.go
+++ b/server/container_list.go
@@ -1,8 +1,8 @@
package server
import (
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/fields"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/server/container_portforward.go b/server/container_portforward.go
index db9c5013..3e5f3d96 100644
--- a/server/container_portforward.go
+++ b/server/container_portforward.go
@@ -7,9 +7,9 @@ import (
"os/exec"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/pools"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/container_remove.go b/server/container_remove.go
index c1b62f95..86884c75 100644
--- a/server/container_remove.go
+++ b/server/container_remove.go
@@ -3,8 +3,8 @@ package server
import (
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/container_start.go b/server/container_start.go
index 020d76c7..67ea9ea7 100644
--- a/server/container_start.go
+++ b/server/container_start.go
@@ -3,8 +3,8 @@ package server
import (
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/container_status.go b/server/container_status.go
index f985a89a..a59d9630 100644
--- a/server/container_status.go
+++ b/server/container_status.go
@@ -4,10 +4,10 @@ import (
"encoding/json"
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/docker/distribution/reference"
"github.com/kubernetes-incubator/cri-o/oci"
rspec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/container_stop.go b/server/container_stop.go
index c16f967e..cff22363 100644
--- a/server/container_stop.go
+++ b/server/container_stop.go
@@ -3,8 +3,8 @@ package server
import (
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/image_list.go b/server/image_list.go
index 1cc8cb1b..9de603a8 100644
--- a/server/image_list.go
+++ b/server/image_list.go
@@ -1,7 +1,7 @@
package server
import (
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/image_pull.go b/server/image_pull.go
index 32fd01b2..a1d2af51 100644
--- a/server/image_pull.go
+++ b/server/image_pull.go
@@ -4,9 +4,9 @@ import (
"encoding/base64"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/copy"
"github.com/containers/image/types"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/image_remove.go b/server/image_remove.go
index 29d296e4..382c8046 100644
--- a/server/image_remove.go
+++ b/server/image_remove.go
@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/image_status.go b/server/image_status.go
index dd7b7b55..f7e7c4f3 100644
--- a/server/image_status.go
+++ b/server/image_status.go
@@ -4,9 +4,9 @@ import (
"fmt"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/sandbox_list.go b/server/sandbox_list.go
index faf15a6b..3e0044cf 100644
--- a/server/sandbox_list.go
+++ b/server/sandbox_list.go
@@ -1,9 +1,9 @@
package server
import (
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"k8s.io/apimachinery/pkg/fields"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/server/sandbox_remove.go b/server/sandbox_remove.go
index aed4ca65..e72e1b26 100644
--- a/server/sandbox_remove.go
+++ b/server/sandbox_remove.go
@@ -3,12 +3,12 @@ package server
import (
"fmt"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
pkgstorage "github.com/kubernetes-incubator/cri-o/pkg/storage"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/sandbox_run.go b/server/sandbox_run.go
index ced3676c..8ee1e054 100644
--- a/server/sandbox_run.go
+++ b/server/sandbox_run.go
@@ -11,7 +11,6 @@ import (
"strings"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
@@ -20,6 +19,7 @@ import (
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
"k8s.io/kubernetes/pkg/api/v1"
diff --git a/server/sandbox_status.go b/server/sandbox_status.go
index 48eb6695..17db0a98 100644
--- a/server/sandbox_status.go
+++ b/server/sandbox_status.go
@@ -1,8 +1,8 @@
package server
import (
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/oci"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)
diff --git a/server/sandbox_stop.go b/server/sandbox_stop.go
index fb112d32..7687272b 100644
--- a/server/sandbox_stop.go
+++ b/server/sandbox_stop.go
@@ -4,7 +4,6 @@ import (
"fmt"
"os"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage"
"github.com/docker/docker/pkg/mount"
"github.com/docker/docker/pkg/symlink"
@@ -12,6 +11,7 @@ import (
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"golang.org/x/sys/unix"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
diff --git a/server/server.go b/server/server.go
index 24a52471..c5e26c4f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -8,7 +8,6 @@ import (
"os"
"sync"
- "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/libkpod"
"github.com/kubernetes-incubator/cri-o/libkpod/sandbox"
"github.com/kubernetes-incubator/cri-o/oci"
@@ -17,6 +16,7 @@ import (
"github.com/kubernetes-incubator/cri-o/server/apparmor"
"github.com/kubernetes-incubator/cri-o/server/seccomp"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
knet "k8s.io/apimachinery/pkg/util/net"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"k8s.io/kubernetes/pkg/kubelet/network/hostport"
diff --git a/test/bin2img/bin2img.go b/test/bin2img/bin2img.go
index ca0e703b..b7528945 100644
--- a/test/bin2img/bin2img.go
+++ b/test/bin2img/bin2img.go
@@ -8,7 +8,6 @@ import (
"os"
"runtime"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/storage"
"github.com/containers/image/types"
sstorage "github.com/containers/storage"
@@ -16,6 +15,7 @@ import (
digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go"
"github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/test/copyimg/copyimg.go b/test/copyimg/copyimg.go
index 324477bc..f83f9276 100644
--- a/test/copyimg/copyimg.go
+++ b/test/copyimg/copyimg.go
@@ -3,7 +3,6 @@ package main
import (
"os"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/copy"
"github.com/containers/image/signature"
"github.com/containers/image/storage"
@@ -11,6 +10,7 @@ import (
"github.com/containers/image/types"
sstorage "github.com/containers/storage"
"github.com/containers/storage/pkg/reexec"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
diff --git a/vendor.conf b/vendor.conf
index fcb1f559..813f0848 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -4,16 +4,16 @@ k8s.io/client-go v3.0.0-beta.0 https://github.com/kubernetes/client-go
k8s.io/apimachinery release-1.6 https://github.com/kubernetes/apimachinery
k8s.io/apiserver release-1.6 https://github.com/kubernetes/apiserver
#
-github.com/Sirupsen/logrus v0.11.5
-github.com/containers/image 106607808da3cff168be56821e994611c919d283
+github.com/sirupsen/logrus v1.0.0
+github.com/containers/image 74e359348c7ce9e0caf4fa75aa8de3809cf41c46
github.com/ostreedev/ostree-go master
-github.com/containers/storage 5d8c2f87387fa5be9fa526ae39fbd79b8bdf27be
+github.com/containers/storage f8cff0727cf0802f0752ca58d2c05ec5270a47d5
github.com/containernetworking/cni v0.4.0
google.golang.org/grpc v1.0.1-GA https://github.com/grpc/grpc-go
github.com/opencontainers/selinux v1.0.0-rc1
github.com/opencontainers/go-digest v1.0.0-rc0
-github.com/opencontainers/runtime-tools 20db5990713e97e64bc2d340531d61f2edf4cccb
-github.com/opencontainers/runc c5ec25487693612aed95673800863e134785f946
+github.com/opencontainers/runtime-tools 6bcd3b417fd6962ea04dafdbc2c07444e750572d
+github.com/opencontainers/runc 45bde006ca8c90e089894508708bcf0e2cdf9e13
github.com/opencontainers/image-spec v1.0.0
github.com/opencontainers/runtime-spec v1.0.0
github.com/juju/ratelimit acf38b000a03e4ab89e40f20f1e548f4e6ac7f72
@@ -21,11 +21,11 @@ github.com/tchap/go-patricia v2.2.6
gopkg.in/cheggaaa/pb.v1 v1.0.7
gopkg.in/inf.v0 v0.9.0
gopkg.in/yaml.v2 v2
-github.com/docker/docker v1.13.1
+github.com/docker/docker d4f6db83c21cfc6af54fffb1f13e8acb7199f96a
github.com/docker/spdystream ed496381df8283605c435b86d4fdd6f4f20b8c6e
-github.com/docker/distribution fb0bebc4b64e3881cc52a2478d749845ed76d2a8
+github.com/docker/distribution 7a8efe719e55bbfaff7bc5718cdf0ed51ca821df
github.com/docker/go-units v0.3.1
-github.com/docker/go-connections e15c02316c12de00874640cd76311849de2aeed5
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
github.com/docker/libtrust aabc10ec26b754e797f9028f4589c5b7bd90dc20
github.com/mistifyio/go-zfs v2.1.1
github.com/ghodss/yaml 04f313413ffd65ce25f2541bfd2b2ceec5c0908c
@@ -63,9 +63,9 @@ github.com/coreos/pkg v3
github.com/golang/groupcache b710c8433bd175204919eb38776e944233235d03
github.com/fsnotify/fsnotify 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1
github.com/emicklei/go-restful 09691a3b6378b740595c1002f40c34dd5f218a22
-github.com/Azure/go-ansiterm fa152c58bc15761d0200cb75fe958b89a9d4888e
-github.com/Microsoft/go-winio v0.3.7
-github.com/Microsoft/hcsshim v0.5.11
+github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
+github.com/Microsoft/go-winio 78439966b38d69bf38227fbf57ac8a6fee70f69a
+github.com/Microsoft/hcsshim 43f9725307998e09f2e3816c2c0c36dc98f0c982
github.com/pkg/errors v0.8.0
github.com/godbus/dbus v4.0.0
github.com/urfave/cli v1.19.1
diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go
index 169f68db..3286a9cb 100644
--- a/vendor/github.com/Azure/go-ansiterm/parser.go
+++ b/vendor/github.com/Azure/go-ansiterm/parser.go
@@ -5,7 +5,7 @@ import (
"io/ioutil"
"os"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var logger *logrus.Logger
diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
index 4d858ed6..48998bb0 100644
--- a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
+++ b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
@@ -9,7 +9,7 @@ import (
"strconv"
"github.com/Azure/go-ansiterm"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var logger *logrus.Logger
diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go
index ceedee1f..2be34af4 100644
--- a/vendor/github.com/Microsoft/go-winio/backup.go
+++ b/vendor/github.com/Microsoft/go-winio/backup.go
@@ -68,10 +68,20 @@ func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
return &BackupStreamReader{r, 0}
}
-// Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if
+// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
// it was not completely read.
func (r *BackupStreamReader) Next() (*BackupHeader, error) {
if r.bytesLeft > 0 {
+ if s, ok := r.r.(io.Seeker); ok {
+ // Make sure Seek on io.SeekCurrent sometimes succeeds
+ // before trying the actual seek.
+ if _, err := s.Seek(0, io.SeekCurrent); err == nil {
+ if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ r.bytesLeft = 0
+ }
+ }
if _, err := io.Copy(ioutil.Discard, r); err != nil {
return nil, err
}
@@ -185,7 +195,6 @@ type BackupFileReader struct {
// Read will attempt to read the security descriptor of the file.
func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
r := &BackupFileReader{f, includeSecurity, 0}
- runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() })
return r
}
@@ -196,6 +205,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
if err != nil {
return 0, &os.PathError{"BackupRead", r.f.Name(), err}
}
+ runtime.KeepAlive(r.f)
if bytesRead == 0 {
return 0, io.EOF
}
@@ -207,6 +217,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
func (r *BackupFileReader) Close() error {
if r.ctx != 0 {
backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
+ runtime.KeepAlive(r.f)
r.ctx = 0
}
return nil
@@ -219,11 +230,10 @@ type BackupFileWriter struct {
ctx uintptr
}
-// NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true,
+// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,
// Write() will attempt to restore the security descriptor from the stream.
func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
w := &BackupFileWriter{f, includeSecurity, 0}
- runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() })
return w
}
@@ -234,6 +244,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
if err != nil {
return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
}
+ runtime.KeepAlive(w.f)
if int(bytesWritten) != len(b) {
return int(bytesWritten), errors.New("not all bytes could be written")
}
@@ -245,6 +256,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
func (w *BackupFileWriter) Close() error {
if w.ctx != 0 {
backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
+ runtime.KeepAlive(w.f)
w.ctx = 0
}
return nil
diff --git a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
index 182d8450..53da908f 100644
--- a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
+++ b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
@@ -36,6 +36,7 @@ const (
hdrSecurityDescriptor = "sd"
hdrRawSecurityDescriptor = "rawsd"
hdrMountPoint = "mountpoint"
+ hdrEaPrefix = "xattr."
)
func writeZeroes(w io.Writer, count int64) error {
@@ -118,6 +119,21 @@ func BasicInfoHeader(name string, size int64, fileInfo *winio.FileBasicInfo) *ta
func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size int64, fileInfo *winio.FileBasicInfo) error {
name = filepath.ToSlash(name)
hdr := BasicInfoHeader(name, size, fileInfo)
+
+ // If r can be seeked, then this function is two-pass: pass 1 collects the
+ // tar header data, and pass 2 copies the data stream. If r cannot be
+ // seeked, then some header data (in particular EAs) will be silently lost.
+ var (
+ restartPos int64
+ err error
+ )
+ sr, readTwice := r.(io.Seeker)
+ if readTwice {
+ if restartPos, err = sr.Seek(0, io.SeekCurrent); err != nil {
+ readTwice = false
+ }
+ }
+
br := winio.NewBackupStreamReader(r)
var dataHdr *winio.BackupHeader
for dataHdr == nil {
@@ -131,7 +147,9 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size
switch bhdr.Id {
case winio.BackupData:
hdr.Mode |= c_ISREG
- dataHdr = bhdr
+ if !readTwice {
+ dataHdr = bhdr
+ }
case winio.BackupSecurity:
sd, err := ioutil.ReadAll(br)
if err != nil {
@@ -151,18 +169,54 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size
hdr.Winheaders[hdrMountPoint] = "1"
}
hdr.Linkname = rp.Target
- case winio.BackupEaData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData:
+
+ case winio.BackupEaData:
+ eab, err := ioutil.ReadAll(br)
+ if err != nil {
+ return err
+ }
+ eas, err := winio.DecodeExtendedAttributes(eab)
+ if err != nil {
+ return err
+ }
+ for _, ea := range eas {
+ // Use base64 encoding for the binary value. Note that there
+ // is no way to encode the EA's flags, since their use doesn't
+ // make any sense for persisted EAs.
+ hdr.Winheaders[hdrEaPrefix+ea.Name] = base64.StdEncoding.EncodeToString(ea.Value)
+ }
+
+ case winio.BackupAlternateData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData:
// ignore these streams
default:
return fmt.Errorf("%s: unknown stream ID %d", name, bhdr.Id)
}
}
- err := t.WriteHeader(hdr)
+ err = t.WriteHeader(hdr)
if err != nil {
return err
}
+ if readTwice {
+ // Get back to the data stream.
+ if _, err = sr.Seek(restartPos, io.SeekStart); err != nil {
+ return err
+ }
+ for dataHdr == nil {
+ bhdr, err := br.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ if bhdr.Id == winio.BackupData {
+ dataHdr = bhdr
+ }
+ }
+ }
+
if dataHdr != nil {
// A data stream was found. Copy the data.
if (dataHdr.Attributes & winio.StreamSparseAttributes) == 0 {
@@ -293,6 +347,38 @@ func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) (
return nil, err
}
}
+ var eas []winio.ExtendedAttribute
+ for k, v := range hdr.Winheaders {
+ if !strings.HasPrefix(k, hdrEaPrefix) {
+ continue
+ }
+ data, err := base64.StdEncoding.DecodeString(v)
+ if err != nil {
+ return nil, err
+ }
+ eas = append(eas, winio.ExtendedAttribute{
+ Name: k[len(hdrEaPrefix):],
+ Value: data,
+ })
+ }
+ if len(eas) != 0 {
+ eadata, err := winio.EncodeExtendedAttributes(eas)
+ if err != nil {
+ return nil, err
+ }
+ bhdr := winio.BackupHeader{
+ Id: winio.BackupEaData,
+ Size: int64(len(eadata)),
+ }
+ err = bw.WriteHeader(&bhdr)
+ if err != nil {
+ return nil, err
+ }
+ _, err = bw.Write(eadata)
+ if err != nil {
+ return nil, err
+ }
+ }
if hdr.Typeflag == tar.TypeSymlink {
_, isMountPoint := hdr.Winheaders[hdrMountPoint]
rp := winio.ReparsePoint{
@@ -339,7 +425,7 @@ func WriteBackupStreamFromTarFile(w io.Writer, t *tar.Reader, hdr *tar.Header) (
bhdr := winio.BackupHeader{
Id: winio.BackupAlternateData,
Size: ahdr.Size,
- Name: ahdr.Name[len(hdr.Name)+1:] + ":$DATA",
+ Name: ahdr.Name[len(hdr.Name):] + ":$DATA",
}
err = bw.WriteHeader(&bhdr)
if err != nil {
diff --git a/vendor/github.com/Microsoft/go-winio/ea.go b/vendor/github.com/Microsoft/go-winio/ea.go
new file mode 100644
index 00000000..b37e930d
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/ea.go
@@ -0,0 +1,137 @@
+package winio
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+)
+
+type fileFullEaInformation struct {
+ NextEntryOffset uint32
+ Flags uint8
+ NameLength uint8
+ ValueLength uint16
+}
+
+var (
+ fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})
+
+ errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
+ errEaNameTooLarge = errors.New("extended attribute name too large")
+ errEaValueTooLarge = errors.New("extended attribute value too large")
+)
+
+// ExtendedAttribute represents a single Windows EA.
+type ExtendedAttribute struct {
+ Name string
+ Value []byte
+ Flags uint8
+}
+
+func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
+ var info fileFullEaInformation
+ err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
+ if err != nil {
+ err = errInvalidEaBuffer
+ return
+ }
+
+ nameOffset := fileFullEaInformationSize
+ nameLen := int(info.NameLength)
+ valueOffset := nameOffset + int(info.NameLength) + 1
+ valueLen := int(info.ValueLength)
+ nextOffset := int(info.NextEntryOffset)
+ if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
+ err = errInvalidEaBuffer
+ return
+ }
+
+ ea.Name = string(b[nameOffset : nameOffset+nameLen])
+ ea.Value = b[valueOffset : valueOffset+valueLen]
+ ea.Flags = info.Flags
+ if info.NextEntryOffset != 0 {
+ nb = b[info.NextEntryOffset:]
+ }
+ return
+}
+
+// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
+// buffer retrieved from BackupRead, ZwQueryEaFile, etc.
+func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
+ for len(b) != 0 {
+ ea, nb, err := parseEa(b)
+ if err != nil {
+ return nil, err
+ }
+
+ eas = append(eas, ea)
+ b = nb
+ }
+ return
+}
+
+func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
+ if int(uint8(len(ea.Name))) != len(ea.Name) {
+ return errEaNameTooLarge
+ }
+ if int(uint16(len(ea.Value))) != len(ea.Value) {
+ return errEaValueTooLarge
+ }
+ entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))
+ withPadding := (entrySize + 3) &^ 3
+ nextOffset := uint32(0)
+ if !last {
+ nextOffset = withPadding
+ }
+ info := fileFullEaInformation{
+ NextEntryOffset: nextOffset,
+ Flags: ea.Flags,
+ NameLength: uint8(len(ea.Name)),
+ ValueLength: uint16(len(ea.Value)),
+ }
+
+ err := binary.Write(buf, binary.LittleEndian, &info)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte(ea.Name))
+ if err != nil {
+ return err
+ }
+
+ err = buf.WriteByte(0)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write(ea.Value)
+ if err != nil {
+ return err
+ }
+
+ _, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION
+// buffer for use with BackupWrite, ZwSetEaFile, etc.
+func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {
+ var buf bytes.Buffer
+ for i := range eas {
+ last := false
+ if i == len(eas)-1 {
+ last = true
+ }
+
+ err := writeEa(&buf, &eas[i], last)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return buf.Bytes(), nil
+}
diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go
index 8c15e412..57ac3696 100644
--- a/vendor/github.com/Microsoft/go-winio/file.go
+++ b/vendor/github.com/Microsoft/go-winio/file.go
@@ -7,6 +7,7 @@ import (
"io"
"runtime"
"sync"
+ "sync/atomic"
"syscall"
"time"
)
@@ -17,6 +18,19 @@ import (
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod
+type atomicBool int32
+
+func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
+func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
+func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
+func (b *atomicBool) swap(new bool) bool {
+ var newInt int32
+ if new {
+ newInt = 1
+ }
+ return atomic.SwapInt32((*int32)(b), newInt) == 1
+}
+
const (
cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
cFILE_SKIP_SET_EVENT_ON_HANDLE = 2
@@ -33,6 +47,8 @@ func (e *timeoutError) Error() string { return "i/o timeout" }
func (e *timeoutError) Timeout() bool { return true }
func (e *timeoutError) Temporary() bool { return true }
+type timeoutChan chan struct{}
+
var ioInitOnce sync.Once
var ioCompletionPort syscall.Handle
@@ -62,9 +78,18 @@ func initIo() {
type win32File struct {
handle syscall.Handle
wg sync.WaitGroup
- closing bool
- readDeadline time.Time
- writeDeadline time.Time
+ wgLock sync.RWMutex
+ closing atomicBool
+ readDeadline deadlineHandler
+ writeDeadline deadlineHandler
+}
+
+type deadlineHandler struct {
+ setLock sync.Mutex
+ channel timeoutChan
+ channelLock sync.RWMutex
+ timer *time.Timer
+ timedout atomicBool
}
// makeWin32File makes a new win32File from an existing file handle
@@ -79,7 +104,8 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
if err != nil {
return nil, err
}
- runtime.SetFinalizer(f, (*win32File).closeHandle)
+ f.readDeadline.channel = make(timeoutChan)
+ f.writeDeadline.channel = make(timeoutChan)
return f, nil
}
@@ -89,30 +115,37 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
// closeHandle closes the resources associated with a Win32 handle
func (f *win32File) closeHandle() {
- if !f.closing {
+ f.wgLock.Lock()
+ // Atomically set that we are closing, releasing the resources only once.
+ if !f.closing.swap(true) {
+ f.wgLock.Unlock()
// cancel all IO and wait for it to complete
- f.closing = true
cancelIoEx(f.handle, nil)
f.wg.Wait()
// at this point, no new IO can start
syscall.Close(f.handle)
f.handle = 0
+ } else {
+ f.wgLock.Unlock()
}
}
// Close closes a win32File.
func (f *win32File) Close() error {
f.closeHandle()
- runtime.SetFinalizer(f, nil)
return nil
}
-// prepareIo prepares for a new IO operation
+// prepareIo prepares for a new IO operation.
+// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
func (f *win32File) prepareIo() (*ioOperation, error) {
- f.wg.Add(1)
- if f.closing {
+ f.wgLock.RLock()
+ if f.closing.isSet() {
+ f.wgLock.RUnlock()
return nil, ErrFileClosed
}
+ f.wg.Add(1)
+ f.wgLock.RUnlock()
c := &ioOperation{}
c.ch = make(chan ioResult)
return c, nil
@@ -136,47 +169,45 @@ func ioCompletionProcessor(h syscall.Handle) {
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
// the operation has actually completed.
-func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) {
+func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
if err != syscall.ERROR_IO_PENDING {
- f.wg.Done()
return int(bytes), err
- } else {
- var r ioResult
- wait := true
- timedout := false
- if f.closing {
- cancelIoEx(f.handle, &c.o)
- } else if !deadline.IsZero() {
- now := time.Now()
- if !deadline.After(now) {
- timedout = true
- } else {
- timeout := time.After(deadline.Sub(now))
- select {
- case r = <-c.ch:
- wait = false
- case <-timeout:
- timedout = true
- }
- }
- }
- if timedout {
- cancelIoEx(f.handle, &c.o)
- }
- if wait {
- r = <-c.ch
- }
+ }
+
+ if f.closing.isSet() {
+ cancelIoEx(f.handle, &c.o)
+ }
+
+ var timeout timeoutChan
+ if d != nil {
+ d.channelLock.Lock()
+ timeout = d.channel
+ d.channelLock.Unlock()
+ }
+
+ var r ioResult
+ select {
+ case r = <-c.ch:
err = r.err
if err == syscall.ERROR_OPERATION_ABORTED {
- if f.closing {
+ if f.closing.isSet() {
err = ErrFileClosed
- } else if timedout {
- err = ErrTimeout
}
}
- f.wg.Done()
- return int(r.bytes), err
+ case <-timeout:
+ cancelIoEx(f.handle, &c.o)
+ r = <-c.ch
+ err = r.err
+ if err == syscall.ERROR_OPERATION_ABORTED {
+ err = ErrTimeout
+ }
}
+
+ // runtime.KeepAlive is needed, as c is passed via native
+ // code to ioCompletionProcessor, c must remain alive
+ // until the channel read is complete.
+ runtime.KeepAlive(c)
+ return int(r.bytes), err
}
// Read reads from a file handle.
@@ -185,9 +216,16 @@ func (f *win32File) Read(b []byte) (int, error) {
if err != nil {
return 0, err
}
+ defer f.wg.Done()
+
+ if f.readDeadline.timedout.isSet() {
+ return 0, ErrTimeout
+ }
+
var bytes uint32
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
- n, err := f.asyncIo(c, f.readDeadline, bytes, err)
+ n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
+ runtime.KeepAlive(b)
// Handle EOF conditions.
if err == nil && n == 0 && len(b) != 0 {
@@ -205,17 +243,68 @@ func (f *win32File) Write(b []byte) (int, error) {
if err != nil {
return 0, err
}
+ defer f.wg.Done()
+
+ if f.writeDeadline.timedout.isSet() {
+ return 0, ErrTimeout
+ }
+
var bytes uint32
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
- return f.asyncIo(c, f.writeDeadline, bytes, err)
+ n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
+ runtime.KeepAlive(b)
+ return n, err
}
-func (f *win32File) SetReadDeadline(t time.Time) error {
- f.readDeadline = t
- return nil
+func (f *win32File) SetReadDeadline(deadline time.Time) error {
+ return f.readDeadline.set(deadline)
}
-func (f *win32File) SetWriteDeadline(t time.Time) error {
- f.writeDeadline = t
+func (f *win32File) SetWriteDeadline(deadline time.Time) error {
+ return f.writeDeadline.set(deadline)
+}
+
+func (f *win32File) Flush() error {
+ return syscall.FlushFileBuffers(f.handle)
+}
+
+func (d *deadlineHandler) set(deadline time.Time) error {
+ d.setLock.Lock()
+ defer d.setLock.Unlock()
+
+ if d.timer != nil {
+ if !d.timer.Stop() {
+ <-d.channel
+ }
+ d.timer = nil
+ }
+ d.timedout.setFalse()
+
+ select {
+ case <-d.channel:
+ d.channelLock.Lock()
+ d.channel = make(chan struct{})
+ d.channelLock.Unlock()
+ default:
+ }
+
+ if deadline.IsZero() {
+ return nil
+ }
+
+ timeoutIO := func() {
+ d.timedout.setTrue()
+ close(d.channel)
+ }
+
+ now := time.Now()
+ duration := deadline.Sub(now)
+ if deadline.After(now) {
+ // Deadline is in the future, set a timer to wait
+ d.timer = time.AfterFunc(duration, timeoutIO)
+ } else {
+ // Deadline is in the past. Cancel all pending IO now.
+ timeoutIO()
+ }
return nil
}
diff --git a/vendor/github.com/Microsoft/go-winio/fileinfo.go b/vendor/github.com/Microsoft/go-winio/fileinfo.go
index a822e431..b1d60abb 100644
--- a/vendor/github.com/Microsoft/go-winio/fileinfo.go
+++ b/vendor/github.com/Microsoft/go-winio/fileinfo.go
@@ -4,6 +4,7 @@ package winio
import (
"os"
+ "runtime"
"syscall"
"unsafe"
)
@@ -28,6 +29,7 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
}
+ runtime.KeepAlive(f)
return bi, nil
}
@@ -36,6 +38,7 @@ func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
}
+ runtime.KeepAlive(f)
return nil
}
@@ -52,5 +55,6 @@ func GetFileID(f *os.File) (*FileIDInfo, error) {
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
}
+ runtime.KeepAlive(f)
return fileID, nil
}
diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go
index b85b2eef..44340b81 100644
--- a/vendor/github.com/Microsoft/go-winio/pipe.go
+++ b/vendor/github.com/Microsoft/go-winio/pipe.go
@@ -13,17 +13,12 @@ import (
)
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
-//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
-//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
+//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
+//sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
-
-type securityAttributes struct {
- Length uint32
- SecurityDescriptor *byte
- InheritHandle uint32
-}
+//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
const (
cERROR_PIPE_BUSY = syscall.Errno(231)
@@ -87,7 +82,11 @@ func (f *win32MessageBytePipe) CloseWrite() error {
if f.writeClosed {
return errPipeWriteClosed
}
- _, err := f.win32File.Write(nil)
+ err := f.win32File.Flush()
+ if err != nil {
+ return err
+ }
+ _, err = f.win32File.Write(nil)
if err != nil {
return err
}
@@ -227,12 +226,15 @@ func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig,
mode |= cPIPE_TYPE_MESSAGE
}
- var sa securityAttributes
- sa.Length = uint32(unsafe.Sizeof(sa))
+ sa := &syscall.SecurityAttributes{}
+ sa.Length = uint32(unsafe.Sizeof(*sa))
if securityDescriptor != nil {
- sa.SecurityDescriptor = &securityDescriptor[0]
+ len := uint32(len(securityDescriptor))
+ sa.SecurityDescriptor = localAlloc(0, len)
+ defer localFree(sa.SecurityDescriptor)
+ copy((*[0xffff]byte)(unsafe.Pointer(sa.SecurityDescriptor))[:], securityDescriptor)
}
- h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa)
+ h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
if err != nil {
return 0, &os.PathError{Op: "open", Path: path, Err: err}
}
@@ -263,9 +265,9 @@ func (l *win32PipeListener) listenerRoutine() {
if err == nil {
// Wait for the client to connect.
ch := make(chan error)
- go func() {
+ go func(p *win32File) {
ch <- connectPipe(p)
- }()
+ }(p)
select {
case err = <-ch:
if err != nil {
@@ -358,8 +360,10 @@ func connectPipe(p *win32File) error {
if err != nil {
return err
}
+ defer p.wg.Done()
+
err = connectNamedPipe(p.handle, &c.o)
- _, err = p.asyncIo(c, time.Time{}, 0, err)
+ _, err = p.asyncIo(c, nil, 0, err)
if err != nil && err != cERROR_PIPE_CONNECTED {
return err
}
diff --git a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
index c5e369ba..4f7a52ee 100644
--- a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
+++ b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
@@ -11,6 +11,31 @@ import (
var _ unsafe.Pointer
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return nil
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
var (
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modwinmm = windows.NewLazySystemDLL("winmm.dll")
@@ -27,6 +52,7 @@ var (
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
+ procLocalAlloc = modkernel32.NewProc("LocalAlloc")
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
@@ -51,7 +77,7 @@ func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -64,7 +90,7 @@ func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintpt
newport = syscall.Handle(r0)
if newport == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -76,7 +102,7 @@ func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr,
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -88,7 +114,7 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -106,7 +132,7 @@ func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -114,7 +140,7 @@ func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
return
}
-func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
+func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(name)
if err != nil {
@@ -123,12 +149,12 @@ func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances ui
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
}
-func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) {
+func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
handle = syscall.Handle(r0)
if handle == syscall.InvalidHandle {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -136,7 +162,7 @@ func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances
return
}
-func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
+func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(name)
if err != nil {
@@ -145,12 +171,12 @@ func createFile(name string, access uint32, mode uint32, sa *securityAttributes,
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
}
-func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
+func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
handle = syscall.Handle(r0)
if handle == syscall.InvalidHandle {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -171,7 +197,7 @@ func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -183,7 +209,7 @@ func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSiz
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -195,7 +221,7 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -203,6 +229,12 @@ func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *u
return
}
+func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
+ r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
+ ptr = uintptr(r0)
+ return
+}
+
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(accountName)
@@ -216,7 +248,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -228,7 +260,7 @@ func convertSidToStringSid(sid *byte, str **uint16) (err error) {
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -249,7 +281,7 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -261,7 +293,7 @@ func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -284,7 +316,7 @@ func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte,
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -296,7 +328,7 @@ func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, si
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -315,7 +347,7 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou
success = r0 != 0
if true {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -327,7 +359,7 @@ func impersonateSelf(level uint32) (err error) {
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -339,7 +371,7 @@ func revertToSelf() (err error) {
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -357,7 +389,7 @@ func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool,
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -389,7 +421,7 @@ func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -410,7 +442,7 @@ func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -431,7 +463,7 @@ func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint1
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -459,7 +491,7 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
@@ -487,7 +519,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 {
if e1 != 0 {
- err = error(e1)
+ err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
diff --git a/vendor/github.com/Microsoft/hcsshim/LICENSE b/vendor/github.com/Microsoft/hcsshim/LICENSE
index b8b569d7..49d21669 100644
--- a/vendor/github.com/Microsoft/hcsshim/LICENSE
+++ b/vendor/github.com/Microsoft/hcsshim/LICENSE
@@ -18,5 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
+SOFTWARE.
\ No newline at end of file
diff --git a/vendor/github.com/Microsoft/hcsshim/activatelayer.go b/vendor/github.com/Microsoft/hcsshim/activatelayer.go
index efc4d802..6d824d7a 100644
--- a/vendor/github.com/Microsoft/hcsshim/activatelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/activatelayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// ActivateLayer will find the layer with the given id and mount it's filesystem.
// For a read/write layer, the mounted filesystem will appear as a volume on the
diff --git a/vendor/github.com/Microsoft/hcsshim/container.go b/vendor/github.com/Microsoft/hcsshim/container.go
index ba3faeb2..b924d39f 100644
--- a/vendor/github.com/Microsoft/hcsshim/container.go
+++ b/vendor/github.com/Microsoft/hcsshim/container.go
@@ -2,12 +2,13 @@ package hcsshim
import (
"encoding/json"
- "runtime"
+ "fmt"
+ "os"
"sync"
"syscall"
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var (
@@ -15,9 +16,10 @@ var (
)
const (
- pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
- statisticsQuery = `{ "PropertyTypes" : ["Statistics"]}`
- processListQuery = `{ "PropertyTypes" : ["ProcessList"]}`
+ pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
+ statisticsQuery = `{ "PropertyTypes" : ["Statistics"]}`
+ processListQuery = `{ "PropertyTypes" : ["ProcessList"]}`
+ mappedVirtualDiskQuery = `{ "PropertyTypes" : ["MappedVirtualDisk"]}`
)
type container struct {
@@ -29,21 +31,21 @@ type container struct {
// ContainerProperties holds the properties for a container and the processes running in that container
type ContainerProperties struct {
- ID string `json:"Id"`
- Name string
- SystemType string
- Owner string
- SiloGUID string `json:"SiloGuid,omitempty"`
- IsDummy bool `json:",omitempty"`
- RuntimeID string `json:"RuntimeId,omitempty"`
- IsRuntimeTemplate bool `json:",omitempty"`
- RuntimeImagePath string `json:",omitempty"`
- Stopped bool `json:",omitempty"`
- ExitType string `json:",omitempty"`
- AreUpdatesPending bool `json:",omitempty"`
- ObRoot string `json:",omitempty"`
- Statistics Statistics `json:",omitempty"`
- ProcessList []ProcessListItem `json:",omitempty"`
+ ID string `json:"Id"`
+ Name string
+ SystemType string
+ Owner string
+ SiloGUID string `json:"SiloGuid,omitempty"`
+ RuntimeID string `json:"RuntimeId,omitempty"`
+ IsRuntimeTemplate bool `json:",omitempty"`
+ RuntimeImagePath string `json:",omitempty"`
+ Stopped bool `json:",omitempty"`
+ ExitType string `json:",omitempty"`
+ AreUpdatesPending bool `json:",omitempty"`
+ ObRoot string `json:",omitempty"`
+ Statistics Statistics `json:",omitempty"`
+ ProcessList []ProcessListItem `json:",omitempty"`
+ MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
}
// MemoryStats holds the memory statistics for a container
@@ -103,8 +105,53 @@ type ProcessListItem struct {
UserTime100ns uint64 `json:",omitempty"`
}
+// MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
+type MappedVirtualDiskController struct {
+ MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
+}
+
+// Type of Request Support in ModifySystem
+type RequestType string
+
+// Type of Resource Support in ModifySystem
+type ResourceType string
+
+// RequestType const
+const (
+ Add RequestType = "Add"
+ Remove RequestType = "Remove"
+ Network ResourceType = "Network"
+)
+
+// ResourceModificationRequestResponse is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type ResourceModificationRequestResponse struct {
+ Resource ResourceType `json:"ResourceType"`
+ Data interface{} `json:"Settings"`
+ Request RequestType `json:"RequestType,omitempty"`
+}
+
+// createContainerAdditionalJSON is read from the environment at initialisation
+// time. It allows an environment variable to define additional JSON which
+// is merged in the CreateContainer call to HCS.
+var createContainerAdditionalJSON string
+
+func init() {
+ createContainerAdditionalJSON = os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON")
+}
+
// CreateContainer creates a new container with the given configuration but does not start it.
func CreateContainer(id string, c *ContainerConfig) (Container, error) {
+ return createContainerWithJSON(id, c, "")
+}
+
+// CreateContainerWithJSON creates a new container with the given configuration but does not start it.
+// It is identical to CreateContainer except that optional additional JSON can be merged before passing to HCS.
+func CreateContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
+ return createContainerWithJSON(id, c, additionalJSON)
+}
+
+func createContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
operation := "CreateContainer"
title := "HCSShim::" + operation
@@ -120,6 +167,32 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
configuration := string(configurationb)
logrus.Debugf(title+" id=%s config=%s", id, configuration)
+ // Merge any additional JSON. Priority is given to what is passed in explicitly,
+ // falling back to what's set in the environment.
+ if additionalJSON == "" && createContainerAdditionalJSON != "" {
+ additionalJSON = createContainerAdditionalJSON
+ }
+ if additionalJSON != "" {
+ configurationMap := map[string]interface{}{}
+ if err := json.Unmarshal([]byte(configuration), &configurationMap); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal %s: %s", configuration, err)
+ }
+
+ additionalMap := map[string]interface{}{}
+ if err := json.Unmarshal([]byte(additionalJSON), &additionalMap); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal %s: %s", additionalJSON, err)
+ }
+
+ mergedMap := mergeMaps(additionalMap, configurationMap)
+ mergedJSON, err := json.Marshal(mergedMap)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal merged configuration map %+v: %s", mergedMap, err)
+ }
+
+ configuration = string(mergedJSON)
+ logrus.Debugf(title+" id=%s merged config=%s", id, configuration)
+ }
+
var (
resultp *uint16
identity syscall.Handle
@@ -138,10 +211,36 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
}
logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
- runtime.SetFinalizer(container, closeContainer)
return container, nil
}
+// mergeMaps recursively merges map `fromMap` into map `ToMap`. Any pre-existing values
+// in ToMap are overwritten. Values in fromMap are added to ToMap.
+// From http://stackoverflow.com/questions/40491438/merging-two-json-strings-in-golang
+func mergeMaps(fromMap, ToMap interface{}) interface{} {
+ switch fromMap := fromMap.(type) {
+ case map[string]interface{}:
+ ToMap, ok := ToMap.(map[string]interface{})
+ if !ok {
+ return fromMap
+ }
+ for keyToMap, valueToMap := range ToMap {
+ if valueFromMap, ok := fromMap[keyToMap]; ok {
+ fromMap[keyToMap] = mergeMaps(valueFromMap, valueToMap)
+ } else {
+ fromMap[keyToMap] = valueToMap
+ }
+ }
+ case nil:
+ // merge(nil, map[string]interface{...}) -> map[string]interface{...}
+ ToMap, ok := ToMap.(map[string]interface{})
+ if ok {
+ return ToMap
+ }
+ }
+ return fromMap
+}
+
// OpenContainer opens an existing container by ID.
func OpenContainer(id string) (Container, error) {
operation := "OpenContainer"
@@ -169,7 +268,6 @@ func OpenContainer(id string) (Container, error) {
}
logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
- runtime.SetFinalizer(container, closeContainer)
return container, nil
}
@@ -396,6 +494,55 @@ func (container *container) ProcessList() ([]ProcessListItem, error) {
return properties.ProcessList, nil
}
+// MappedVirtualDisks returns a map of the controllers and the disks mapped
+// to a container.
+//
+// Example of JSON returned by the query.
+//{
+// "Id":"1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3_svm",
+// "SystemType":"Container",
+// "RuntimeOsType":"Linux",
+// "RuntimeId":"00000000-0000-0000-0000-000000000000",
+// "State":"Running",
+// "MappedVirtualDiskControllers":{
+// "0":{
+// "MappedVirtualDisks":{
+// "2":{
+// "HostPath":"C:\\lcow\\lcow\\scratch\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3.vhdx",
+// "ContainerPath":"/mnt/gcs/LinuxServiceVM/scratch",
+// "Lun":2,
+// "CreateInUtilityVM":true
+// },
+// "3":{
+// "HostPath":"C:\\lcow\\lcow\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3\\sandbox.vhdx",
+// "Lun":3,
+// "CreateInUtilityVM":true,
+// "AttachOnly":true
+// }
+// }
+// }
+// }
+//}
+func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
+ container.handleLock.RLock()
+ defer container.handleLock.RUnlock()
+ operation := "MappedVirtualDiskList"
+ title := "HCSShim::Container::" + operation
+ logrus.Debugf(title+" id=%s", container.id)
+
+ if container.handle == 0 {
+ return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
+ }
+
+ properties, err := container.properties(mappedVirtualDiskQuery)
+ if err != nil {
+ return nil, makeContainerError(container, operation, "", err)
+ }
+
+ logrus.Debugf(title+" succeeded id=%s", container.id)
+ return properties.MappedVirtualDiskControllers, nil
+}
+
// Pause pauses the execution of the container. This feature is not enabled in TP5.
func (container *container) Pause() error {
container.handleLock.RLock()
@@ -493,8 +640,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
return nil, makeContainerError(container, operation, "", err)
}
- logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
- runtime.SetFinalizer(process, closeProcess)
+ logrus.Debugf(title+" succeeded id=%s processid=%d", container.id, process.processID)
return process, nil
}
@@ -531,7 +677,6 @@ func (container *container) OpenProcess(pid int) (Process, error) {
}
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
- runtime.SetFinalizer(process, closeProcess)
return process, nil
}
@@ -557,17 +702,11 @@ func (container *container) Close() error {
}
container.handle = 0
- runtime.SetFinalizer(container, nil)
logrus.Debugf(title+" succeeded id=%s", container.id)
return nil
}
-// closeContainer wraps container.Close for use by a finalizer
-func closeContainer(container *container) {
- container.Close()
-}
-
func (container *container) registerCallback() error {
context := ¬ifcationWatcherContext{
channels: newChannels(),
@@ -624,3 +763,32 @@ func (container *container) unregisterCallback() error {
return nil
}
+
+// Modifies the System by sending a request to HCS
+func (container *container) Modify(config *ResourceModificationRequestResponse) error {
+ container.handleLock.RLock()
+ defer container.handleLock.RUnlock()
+ operation := "Modify"
+ title := "HCSShim::Container::" + operation
+
+ if container.handle == 0 {
+ return makeContainerError(container, operation, "", ErrAlreadyClosed)
+ }
+
+ requestJSON, err := json.Marshal(config)
+ if err != nil {
+ return err
+ }
+
+ requestString := string(requestJSON)
+ logrus.Debugf(title+" id=%s request=%s", container.id, requestString)
+
+ var resultp *uint16
+ err = hcsModifyComputeSystem(container.handle, requestString, &resultp)
+ err = processHcsResult(err, resultp)
+ if err != nil {
+ return makeContainerError(container, operation, "", err)
+ }
+ logrus.Debugf(title+" succeeded id=%s", container.id)
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/createlayer.go b/vendor/github.com/Microsoft/hcsshim/createlayer.go
index 9ecffb1c..035d9c39 100644
--- a/vendor/github.com/Microsoft/hcsshim/createlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/createlayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// CreateLayer creates a new, empty, read-only layer on the filesystem based on
// the parent layer provided.
diff --git a/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go b/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
index b69c3da3..7a6a8854 100644
--- a/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// CreateSandboxLayer creates and populates new read-write layer for use by a container.
// This requires both the id of the direct parent layer, as well as the full list
diff --git a/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go b/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
index c02bcb3a..fd785030 100644
--- a/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
func DeactivateLayer(info DriverInfo, id string) error {
diff --git a/vendor/github.com/Microsoft/hcsshim/destroylayer.go b/vendor/github.com/Microsoft/hcsshim/destroylayer.go
index 91ed269e..b1e3b89f 100644
--- a/vendor/github.com/Microsoft/hcsshim/destroylayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/destroylayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// DestroyLayer will remove the on-disk files representing the layer with the given
// id, including that layer's containing folder, if any.
diff --git a/vendor/github.com/Microsoft/hcsshim/errors.go b/vendor/github.com/Microsoft/hcsshim/errors.go
index 19bb97a0..d2f9cc8b 100644
--- a/vendor/github.com/Microsoft/hcsshim/errors.go
+++ b/vendor/github.com/Microsoft/hcsshim/errors.go
@@ -13,6 +13,13 @@ var (
// ErrElementNotFound is an error encountered when the object being referenced does not exist
ErrElementNotFound = syscall.Errno(0x490)
+ // ErrElementNotFound is an error encountered when the object being referenced does not exist
+ ErrNotSupported = syscall.Errno(0x32)
+
+ // ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
+ // decimal -2147024883 / hex 0x8007000d
+ ErrInvalidData = syscall.Errno(0xd)
+
// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
@@ -50,6 +57,19 @@ var (
// ErrProcNotFound is an error encountered when the the process cannot be found
ErrProcNotFound = syscall.Errno(0x7f)
+
+ // ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
+ // builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
+ ErrVmcomputeOperationAccessIsDenied = syscall.Errno(0x5)
+
+ // ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
+ ErrVmcomputeInvalidJSON = syscall.Errno(0xc037010d)
+
+ // ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
+ ErrVmcomputeUnknownMessage = syscall.Errno(0xc037010b)
+
+ // ErrNotSupported is an error encountered when hcs doesn't support the request
+ ErrPlatformNotSupported = errors.New("unsupported platform request")
)
// ProcessError is an error encountered in HCS during an operation on a Process object
@@ -192,6 +212,20 @@ func IsAlreadyStopped(err error) bool {
err == ErrProcNotFound
}
+// IsNotSupported returns a boolean indicating whether the error is caused by
+// unsupported platform requests
+// Note: Currently Unsupported platform requests can be mean either
+// ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
+// is thrown from the Platform
+func IsNotSupported(err error) bool {
+ err = getInnerError(err)
+ // If Platform doesn't recognize or support the request sent, below errors are seen
+ return err == ErrVmcomputeInvalidJSON ||
+ err == ErrInvalidData ||
+ err == ErrNotSupported ||
+ err == ErrVmcomputeUnknownMessage
+}
+
func getInnerError(err error) error {
switch pe := err.(type) {
case nil:
diff --git a/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go b/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
index e1689218..6946c6a8 100644
--- a/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
+++ b/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// ExpandSandboxSize expands the size of a layer to at least size bytes.
func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
diff --git a/vendor/github.com/Microsoft/hcsshim/exportlayer.go b/vendor/github.com/Microsoft/hcsshim/exportlayer.go
index 903e0851..d7025f20 100644
--- a/vendor/github.com/Microsoft/hcsshim/exportlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/exportlayer.go
@@ -4,11 +4,10 @@ import (
"io"
"io/ioutil"
"os"
- "runtime"
"syscall"
"github.com/Microsoft/go-winio"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// ExportLayer will create a folder at exportFolderPath and fill that folder with
@@ -143,7 +142,6 @@ func NewLayerReader(info DriverInfo, layerID string, parentLayerPaths []string)
if err != nil {
return nil, makeError(err, "ExportLayerBegin", "")
}
- runtime.SetFinalizer(r, func(r *FilterLayerReader) { r.Close() })
return r, err
}
diff --git a/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go b/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
index 41b57589..89f8079d 100644
--- a/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
+++ b/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
@@ -3,7 +3,7 @@ package hcsshim
import (
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// GetLayerMountPath will look for a mounted layer with the given id and return
diff --git a/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go b/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
index 01ab4da3..05d3d953 100644
--- a/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
+++ b/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// GetSharedBaseImages will enumerate the images stored in the common central
// image store and return descriptive info about those images for the purpose
diff --git a/vendor/github.com/Microsoft/hcsshim/hcsshim.go b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
index 3cb3a299..236ba1fa 100644
--- a/vendor/github.com/Microsoft/hcsshim/hcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
@@ -8,7 +8,7 @@ import (
"syscall"
"unsafe"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
new file mode 100644
index 00000000..92afc0c2
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
@@ -0,0 +1,318 @@
+package hcsshim
+
+import (
+ "encoding/json"
+ "fmt"
+ "net"
+
+ "github.com/sirupsen/logrus"
+)
+
+// HNSEndpoint represents a network endpoint in HNS
+type HNSEndpoint struct {
+ Id string `json:"ID,omitempty"`
+ Name string `json:",omitempty"`
+ VirtualNetwork string `json:",omitempty"`
+ VirtualNetworkName string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+ MacAddress string `json:",omitempty"`
+ IPAddress net.IP `json:",omitempty"`
+ DNSSuffix string `json:",omitempty"`
+ DNSServerList string `json:",omitempty"`
+ GatewayAddress string `json:",omitempty"`
+ EnableInternalDNS bool `json:",omitempty"`
+ DisableICC bool `json:",omitempty"`
+ PrefixLength uint8 `json:",omitempty"`
+ IsRemoteEndpoint bool `json:",omitempty"`
+}
+
+//SystemType represents the type of the system on which actions are done
+type SystemType string
+
+// SystemType const
+const (
+ ContainerType SystemType = "Container"
+ VirtualMachineType SystemType = "VirtualMachine"
+ HostType SystemType = "Host"
+)
+
+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type EndpointAttachDetachRequest struct {
+ ContainerID string `json:"ContainerId,omitempty"`
+ SystemType SystemType `json:"SystemType"`
+ CompartmentID uint16 `json:"CompartmentId,omitempty"`
+ VirtualNICName string `json:"VirtualNicName,omitempty"`
+}
+
+// EndpointResquestResponse is object to get the endpoint request response
+type EndpointResquestResponse struct {
+ Success bool
+ Error string
+}
+
+// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
+func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
+ endpoint := &HNSEndpoint{}
+ err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ return endpoint, nil
+}
+
+// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
+func HNSListEndpointRequest() ([]HNSEndpoint, error) {
+ var endpoint []HNSEndpoint
+ err := hnsCall("GET", "/endpoints/", "", &endpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ return endpoint, nil
+}
+
+// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
+func HotAttachEndpoint(containerID string, endpointID string) error {
+ return modifyNetworkEndpoint(containerID, endpointID, Add)
+}
+
+// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
+func HotDetachEndpoint(containerID string, endpointID string) error {
+ return modifyNetworkEndpoint(containerID, endpointID, Remove)
+}
+
+// ModifyContainer corresponding to the container id, by sending a request
+func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
+ container, err := OpenContainer(id)
+ if err != nil {
+ if IsNotExist(err) {
+ return ErrComputeSystemDoesNotExist
+ }
+ return getInnerError(err)
+ }
+ defer container.Close()
+ err = container.Modify(request)
+ if err != nil {
+ if IsNotSupported(err) {
+ return ErrPlatformNotSupported
+ }
+ return getInnerError(err)
+ }
+
+ return nil
+}
+
+func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
+ requestMessage := &ResourceModificationRequestResponse{
+ Resource: Network,
+ Request: request,
+ Data: endpointID,
+ }
+ err := modifyContainer(containerID, requestMessage)
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// GetHNSEndpointByID get the Endpoint by ID
+func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
+ return HNSEndpointRequest("GET", endpointID, "")
+}
+
+// GetHNSEndpointByName gets the endpoint filtered by Name
+func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
+ hnsResponse, err := HNSListEndpointRequest()
+ if err != nil {
+ return nil, err
+ }
+ for _, hnsEndpoint := range hnsResponse {
+ if hnsEndpoint.Name == endpointName {
+ return &hnsEndpoint, nil
+ }
+ }
+ return nil, fmt.Errorf("Endpoint %v not found", endpointName)
+}
+
+// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
+func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
+ operation := "Create"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ jsonString, err := json.Marshal(endpoint)
+ if err != nil {
+ return nil, err
+ }
+ return HNSEndpointRequest("POST", "", string(jsonString))
+}
+
+// Delete Endpoint by sending EndpointRequest to HNS
+func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
+ operation := "Delete"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ return HNSEndpointRequest("DELETE", endpoint.Id, "")
+}
+
+// Update Endpoint
+func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
+ operation := "Update"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ jsonString, err := json.Marshal(endpoint)
+ if err != nil {
+ return nil, err
+ }
+ err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
+
+ return endpoint, err
+}
+
+// ContainerHotAttach attaches an endpoint to a running container
+func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
+ operation := "ContainerHotAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+ return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
+}
+
+// ContainerHotDetach detaches an endpoint from a running container
+func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
+ operation := "ContainerHotDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+ return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
+}
+
+// ApplyACLPolicy applies Acl Policy on the Endpoint
+func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {
+ operation := "ApplyACLPolicy"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ jsonString, err := json.Marshal(policy)
+ if err != nil {
+ return err
+ }
+ endpoint.Policies[0] = jsonString
+ _, err = endpoint.Update()
+ return err
+}
+
+// ContainerAttach attaches an endpoint to container
+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
+ operation := "ContainerAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ ContainerID: containerID,
+ CompartmentID: compartmentID,
+ SystemType: ContainerType,
+ }
+ response := &EndpointResquestResponse{}
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// ContainerDetach detaches an endpoint from container
+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
+ operation := "ContainerDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ ContainerID: containerID,
+ SystemType: ContainerType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// HostAttach attaches a nic on the host
+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
+ operation := "HostAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ CompartmentID: compartmentID,
+ SystemType: HostType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+
+}
+
+// HostDetach detaches a nic on the host
+func (endpoint *HNSEndpoint) HostDetach() error {
+ operation := "HostDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ SystemType: HostType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// VirtualMachineNICAttach attaches a endpoint to a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
+ operation := "VirtualMachineNicAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ VirtualNICName: virtualMachineNICName,
+ SystemType: VirtualMachineType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// VirtualMachineNICDetach detaches a endpoint from a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
+ operation := "VirtualMachineNicDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ SystemType: VirtualMachineType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go b/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
index e3d8c0b1..2c1b979a 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
@@ -3,101 +3,14 @@ package hcsshim
import (
"encoding/json"
"fmt"
- "net"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
-type NatPolicy struct {
- Type string
- Protocol string
- InternalPort uint16
- ExternalPort uint16
-}
-
-type QosPolicy struct {
- Type string
- MaximumOutgoingBandwidthInBytes uint64
-}
-
-type VlanPolicy struct {
- Type string
- VLAN uint
-}
-
-type VsidPolicy struct {
- Type string
- VSID uint
-}
-
-type PaPolicy struct {
- Type string
- PA string
-}
-
-// Subnet is assoicated with a network and represents a list
-// of subnets available to the network
-type Subnet struct {
- AddressPrefix string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
-}
-
-// MacPool is assoicated with a network and represents a list
-// of macaddresses available to the network
-type MacPool struct {
- StartMacAddress string `json:",omitempty"`
- EndMacAddress string `json:",omitempty"`
-}
-
-// HNSNetwork represents a network in HNS
-type HNSNetwork struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- Type string `json:",omitempty"`
- NetworkAdapterName string `json:",omitempty"`
- SourceMac string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacPools []MacPool `json:",omitempty"`
- Subnets []Subnet `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- DNSServerCompartment uint32 `json:",omitempty"`
- ManagementIP string `json:",omitempty"`
-}
-
-// HNSEndpoint represents a network endpoint in HNS
-type HNSEndpoint struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- VirtualNetwork string `json:",omitempty"`
- VirtualNetworkName string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacAddress string `json:",omitempty"`
- IPAddress net.IP `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- EnableInternalDNS bool `json:",omitempty"`
- DisableICC bool `json:",omitempty"`
- PrefixLength uint8 `json:",omitempty"`
- IsRemoteEndpoint bool `json:",omitempty"`
-}
-
-type hnsNetworkResponse struct {
- Success bool
- Error string
- Output HNSNetwork
-}
-
-type hnsResponse struct {
- Success bool
- Error string
- Output json.RawMessage
-}
-
func hnsCall(method, path, request string, returnResponse interface{}) error {
var responseBuffer *uint16
+ logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
+
err := _hnsCall(method, path, request, &responseBuffer)
if err != nil {
return makeError(err, "hnsCall ", "")
@@ -125,36 +38,3 @@ func hnsCall(method, path, request string, returnResponse interface{}) error {
return nil
}
-
-// HNSNetworkRequest makes a call into HNS to update/query a single network
-func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
- var network HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
-
- return &network, nil
-}
-
-// HNSListNetworkRequest makes a HNS call to query the list of available networks
-func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
- var network []HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
-
- return network, nil
-}
-
-// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
-func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
- endpoint := &HNSEndpoint{}
- err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
- if err != nil {
- return nil, err
- }
-
- return endpoint, nil
-}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
new file mode 100644
index 00000000..3345bfa3
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
@@ -0,0 +1,142 @@
+package hcsshim
+
+import (
+ "encoding/json"
+ "fmt"
+ "net"
+
+ "github.com/sirupsen/logrus"
+)
+
+// Subnet is assoicated with a network and represents a list
+// of subnets available to the network
+type Subnet struct {
+ AddressPrefix string `json:",omitempty"`
+ GatewayAddress string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+}
+
+// MacPool is assoicated with a network and represents a list
+// of macaddresses available to the network
+type MacPool struct {
+ StartMacAddress string `json:",omitempty"`
+ EndMacAddress string `json:",omitempty"`
+}
+
+// HNSNetwork represents a network in HNS
+type HNSNetwork struct {
+ Id string `json:"ID,omitempty"`
+ Name string `json:",omitempty"`
+ Type string `json:",omitempty"`
+ NetworkAdapterName string `json:",omitempty"`
+ SourceMac string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+ MacPools []MacPool `json:",omitempty"`
+ Subnets []Subnet `json:",omitempty"`
+ DNSSuffix string `json:",omitempty"`
+ DNSServerList string `json:",omitempty"`
+ DNSServerCompartment uint32 `json:",omitempty"`
+ ManagementIP string `json:",omitempty"`
+ AutomaticDNS bool `json:",omitempty"`
+}
+
+type hnsNetworkResponse struct {
+ Success bool
+ Error string
+ Output HNSNetwork
+}
+
+type hnsResponse struct {
+ Success bool
+ Error string
+ Output json.RawMessage
+}
+
+// HNSNetworkRequest makes a call into HNS to update/query a single network
+func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
+ var network HNSNetwork
+ err := hnsCall(method, "/networks/"+path, request, &network)
+ if err != nil {
+ return nil, err
+ }
+
+ return &network, nil
+}
+
+// HNSListNetworkRequest makes a HNS call to query the list of available networks
+func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
+ var network []HNSNetwork
+ err := hnsCall(method, "/networks/"+path, request, &network)
+ if err != nil {
+ return nil, err
+ }
+
+ return network, nil
+}
+
+// GetHNSNetworkByID
+func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
+ return HNSNetworkRequest("GET", networkID, "")
+}
+
+// GetHNSNetworkName filtered by Name
+func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
+ hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
+ if err != nil {
+ return nil, err
+ }
+ for _, hnsnetwork := range hsnnetworks {
+ if hnsnetwork.Name == networkName {
+ return &hnsnetwork, nil
+ }
+ }
+ return nil, fmt.Errorf("Network %v not found", networkName)
+}
+
+// Create Network by sending NetworkRequest to HNS.
+func (network *HNSNetwork) Create() (*HNSNetwork, error) {
+ operation := "Create"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+
+ jsonString, err := json.Marshal(network)
+ if err != nil {
+ return nil, err
+ }
+ return HNSNetworkRequest("POST", "", string(jsonString))
+}
+
+// Delete Network by sending NetworkRequest to HNS
+func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
+ operation := "Delete"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+
+ return HNSNetworkRequest("DELETE", network.Id, "")
+}
+
+// Creates an endpoint on the Network.
+func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
+ return &HNSEndpoint{
+ VirtualNetwork: network.Id,
+ IPAddress: ipAddress,
+ MacAddress: string(macAddress),
+ }
+}
+
+func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+ operation := "CreateEndpoint"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
+
+ endpoint.VirtualNetwork = network.Id
+ return endpoint.Create()
+}
+
+func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+ operation := "CreateRemoteEndpoint"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+ endpoint.IsRemoteEndpoint = true
+ return network.CreateEndpoint(endpoint)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
new file mode 100644
index 00000000..ecfbf0ed
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
@@ -0,0 +1,95 @@
+package hcsshim
+
+// Type of Request Support in ModifySystem
+type PolicyType string
+
+// RequestType const
+const (
+ Nat PolicyType = "NAT"
+ ACL PolicyType = "ACL"
+ PA PolicyType = "PA"
+ VLAN PolicyType = "VLAN"
+ VSID PolicyType = "VSID"
+ VNet PolicyType = "VNET"
+ L2Driver PolicyType = "L2Driver"
+ Isolation PolicyType = "Isolation"
+ QOS PolicyType = "QOS"
+ OutboundNat PolicyType = "OutBoundNAT"
+ ExternalLoadBalancer PolicyType = "ELB"
+ Route PolicyType = "ROUTE"
+)
+
+type NatPolicy struct {
+ Type PolicyType `json:"Type"`
+ Protocol string
+ InternalPort uint16
+ ExternalPort uint16
+}
+
+type QosPolicy struct {
+ Type PolicyType `json:"Type"`
+ MaximumOutgoingBandwidthInBytes uint64
+}
+
+type IsolationPolicy struct {
+ Type PolicyType `json:"Type"`
+ VLAN uint
+ VSID uint
+ InDefaultIsolation bool
+}
+
+type VlanPolicy struct {
+ Type PolicyType `json:"Type"`
+ VLAN uint
+}
+
+type VsidPolicy struct {
+ Type PolicyType `json:"Type"`
+ VSID uint
+}
+
+type PaPolicy struct {
+ Type PolicyType `json:"Type"`
+ PA string `json:"PA"`
+}
+
+type OutboundNatPolicy struct {
+ Policy
+ VIP string `json:"VIP,omitempty"`
+ Exceptions []string `json:"ExceptionList,omitempty"`
+}
+
+type ActionType string
+type DirectionType string
+type RuleType string
+
+const (
+ Allow ActionType = "Allow"
+ Block ActionType = "Block"
+
+ In DirectionType = "In"
+ Out DirectionType = "Out"
+
+ Host RuleType = "Host"
+ Switch RuleType = "Switch"
+)
+
+type ACLPolicy struct {
+ Type PolicyType `json:"Type"`
+ Protocol uint16
+ InternalPort uint16
+ Action ActionType
+ Direction DirectionType
+ LocalAddress string
+ RemoteAddress string
+ LocalPort uint16
+ RemotePort uint16
+ RuleType RuleType `json:"RuleType,omitempty"`
+
+ Priority uint16
+ ServiceName string
+}
+
+type Policy struct {
+ Type PolicyType `json:"Type"`
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
new file mode 100644
index 00000000..15653b4f
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
@@ -0,0 +1,196 @@
+package hcsshim
+
+import (
+ "encoding/json"
+
+ "github.com/sirupsen/logrus"
+)
+
+// RoutePolicy is a structure defining schema for Route based Policy
+type RoutePolicy struct {
+ Policy
+ DestinationPrefix string `json:"DestinationPrefix,omitempty"`
+ NextHop string `json:"NextHop,omitempty"`
+ EncapEnabled bool `json:"NeedEncap,omitempty"`
+}
+
+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
+type ELBPolicy struct {
+ LBPolicy
+ SourceVIP string `json:"SourceVIP,omitempty"`
+ VIPs []string `json:"VIPs,omitempty"`
+ ILB bool `json:"ILB,omitempty"`
+}
+
+// LBPolicy is a structure defining schema for LoadBalancing based Policy
+type LBPolicy struct {
+ Policy
+ Protocol uint16 `json:"Protocol,omitempty"`
+ InternalPort uint16
+ ExternalPort uint16
+}
+
+// PolicyList is a structure defining schema for Policy list request
+type PolicyList struct {
+ ID string `json:"ID,omitempty"`
+ EndpointReferences []string `json:"References,omitempty"`
+ Policies []json.RawMessage `json:"Policies,omitempty"`
+}
+
+// HNSPolicyListRequest makes a call into HNS to update/query a single network
+func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
+ var policy PolicyList
+ err := hnsCall(method, "/policylists/"+path, request, &policy)
+ if err != nil {
+ return nil, err
+ }
+
+ return &policy, nil
+}
+
+// HNSListPolicyListRequest gets all the policy list
+func HNSListPolicyListRequest() ([]PolicyList, error) {
+ var plist []PolicyList
+ err := hnsCall("GET", "/policylists/", "", &plist)
+ if err != nil {
+ return nil, err
+ }
+
+ return plist, nil
+}
+
+// PolicyListRequest makes a HNS call to modify/query a network policy list
+func PolicyListRequest(method, path, request string) (*PolicyList, error) {
+ policylist := &PolicyList{}
+ err := hnsCall(method, "/policylists/"+path, request, &policylist)
+ if err != nil {
+ return nil, err
+ }
+
+ return policylist, nil
+}
+
+// GetPolicyListByID get the policy list by ID
+func GetPolicyListByID(policyListID string) (*PolicyList, error) {
+ return PolicyListRequest("GET", policyListID, "")
+}
+
+// Create PolicyList by sending PolicyListRequest to HNS.
+func (policylist *PolicyList) Create() (*PolicyList, error) {
+ operation := "Create"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s", policylist.ID)
+ jsonString, err := json.Marshal(policylist)
+ if err != nil {
+ return nil, err
+ }
+ return PolicyListRequest("POST", "", string(jsonString))
+}
+
+// Delete deletes PolicyList
+func (policylist *PolicyList) Delete() (*PolicyList, error) {
+ operation := "Delete"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s", policylist.ID)
+
+ return PolicyListRequest("DELETE", policylist.ID, "")
+}
+
+// AddEndpoint add an endpoint to a Policy List
+func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+ operation := "AddEndpoint"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+ _, err := policylist.Delete()
+ if err != nil {
+ return nil, err
+ }
+
+ // Add Endpoint to the Existing List
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+
+ return policylist.Create()
+}
+
+// RemoveEndpoint removes an endpoint from the Policy List
+func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+ operation := "RemoveEndpoint"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+ _, err := policylist.Delete()
+ if err != nil {
+ return nil, err
+ }
+
+ elementToRemove := "/endpoints/" + endpoint.Id
+
+ var references []string
+
+ for _, endpointReference := range policylist.EndpointReferences {
+ if endpointReference == elementToRemove {
+ continue
+ }
+ references = append(references, endpointReference)
+ }
+ policylist.EndpointReferences = references
+ return policylist.Create()
+}
+
+// AddLoadBalancer policy list for the specified endpoints
+func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
+ operation := "AddLoadBalancer"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" Vip:%s", vip)
+
+ policylist := &PolicyList{}
+
+ elbPolicy := &ELBPolicy{
+ VIPs: []string{vip},
+ ILB: isILB,
+ }
+ elbPolicy.Type = ExternalLoadBalancer
+ elbPolicy.Protocol = protocol
+ elbPolicy.InternalPort = internalPort
+ elbPolicy.ExternalPort = externalPort
+
+ for _, endpoint := range endpoints {
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+ }
+
+ jsonString, err := json.Marshal(elbPolicy)
+ if err != nil {
+ return nil, err
+ }
+ policylist.Policies = append(policylist.Policies, jsonString)
+ return policylist.Create()
+}
+
+// AddRoute adds route policy list for the specified endpoints
+func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
+ operation := "AddRoute"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
+
+ policylist := &PolicyList{}
+
+ rPolicy := &RoutePolicy{
+ DestinationPrefix: destinationPrefix,
+ NextHop: nextHop,
+ EncapEnabled: encapEnabled,
+ }
+ rPolicy.Type = Route
+
+ for _, endpoint := range endpoints {
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+ }
+
+ jsonString, err := json.Marshal(rPolicy)
+ if err != nil {
+ return nil, err
+ }
+
+ policylist.Policies = append(policylist.Policies, jsonString)
+ return policylist.Create()
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/importlayer.go b/vendor/github.com/Microsoft/hcsshim/importlayer.go
index 5f826301..3aed1437 100644
--- a/vendor/github.com/Microsoft/hcsshim/importlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/importlayer.go
@@ -5,10 +5,9 @@ import (
"io/ioutil"
"os"
"path/filepath"
- "runtime"
"github.com/Microsoft/go-winio"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// ImportLayer will take the contents of the folder at importFolderPath and import
@@ -209,6 +208,5 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
if err != nil {
return nil, makeError(err, "ImportLayerStart", "")
}
- runtime.SetFinalizer(w, func(w *FilterLayerWriter) { w.Close() })
return w, nil
}
diff --git a/vendor/github.com/Microsoft/hcsshim/interface.go b/vendor/github.com/Microsoft/hcsshim/interface.go
index 3e330f13..9fc7852e 100644
--- a/vendor/github.com/Microsoft/hcsshim/interface.go
+++ b/vendor/github.com/Microsoft/hcsshim/interface.go
@@ -1,6 +1,7 @@
package hcsshim
import (
+ "encoding/json"
"io"
"time"
)
@@ -8,16 +9,19 @@ import (
// ProcessConfig is used as both the input of Container.CreateProcess
// and to convert the parameters to JSON for passing onto the HCS
type ProcessConfig struct {
- ApplicationName string
- CommandLine string
- User string
- WorkingDirectory string
- Environment map[string]string
- EmulateConsole bool
- CreateStdInPipe bool
- CreateStdOutPipe bool
- CreateStdErrPipe bool
- ConsoleSize [2]uint
+ ApplicationName string `json:",omitempty"`
+ CommandLine string `json:",omitempty"`
+ CommandArgs []string `json:",omitempty"` // Used by Linux Containers on Windows
+ User string `json:",omitempty"`
+ WorkingDirectory string `json:",omitempty"`
+ Environment map[string]string `json:",omitempty"`
+ EmulateConsole bool `json:",omitempty"`
+ CreateStdInPipe bool `json:",omitempty"`
+ CreateStdOutPipe bool `json:",omitempty"`
+ CreateStdErrPipe bool `json:",omitempty"`
+ ConsoleSize [2]uint `json:",omitempty"`
+ CreateInUtilityVm bool `json:",omitempty"` // Used by Linux Containers on Windows
+ OCISpecification *json.RawMessage `json:",omitempty"` // Used by Linux Containers on Windows
}
type Layer struct {
@@ -33,40 +37,61 @@ type MappedDir struct {
IOPSMaximum uint64
}
+type MappedPipe struct {
+ HostPath string
+ ContainerPipeName string
+}
+
type HvRuntime struct {
- ImagePath string `json:",omitempty"`
- SkipTemplate bool `json:",omitempty"`
+ ImagePath string `json:",omitempty"`
+ SkipTemplate bool `json:",omitempty"`
+ LinuxInitrdFile string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
+ LinuxKernelFile string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
+ LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode
+ BootSource string `json:",omitempty"` // "Vhd" for Linux Utility VM booting from VHD
+ WritableBootSource bool `json:",omitempty"` // Linux Utility VM booting from VHD
+}
+
+type MappedVirtualDisk struct {
+ HostPath string `json:",omitempty"` // Path to VHD on the host
+ ContainerPath string // Platform-specific mount point path in the container
+ CreateInUtilityVM bool `json:",omitempty"`
+ ReadOnly bool `json:",omitempty"`
+ Cache string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
+ AttachOnly bool `json:",omitempty:`
}
// ContainerConfig is used as both the input of CreateContainer
// and to convert the parameters to JSON for passing onto the HCS
type ContainerConfig struct {
- SystemType string // HCS requires this to be hard-coded to "Container"
- Name string // Name of the container. We use the docker ID.
- Owner string // The management platform that created this container
- IsDummy bool // Used for development purposes.
- VolumePath string `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
- IgnoreFlushesDuringBoot bool // Optimization hint for container startup in Windows
- LayerFolderPath string `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format %root%\windowsfilter\containerID
- Layers []Layer // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
- Credentials string `json:",omitempty"` // Credentials information
- ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container.
- ProcessorWeight uint64 `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
- ProcessorMaximum int64 `json:",omitempty"` // CPU maximum usage percent 1..100
- StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS
- StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
- StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
- MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes
- HostName string // Hostname
- MappedDirectories []MappedDir // List of mapped directories (volumes/mounts)
- SandboxPath string `json:",omitempty"` // Location of unmounted sandbox. Used by Hyper-V containers only. Format %root%\windowsfilter
- HvPartition bool // True if it a Hyper-V Container
- EndpointList []string // List of networking endpoints to be attached to container
- NetworkSharedContainerName string `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
- HvRuntime *HvRuntime `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
- Servicing bool // True if this container is for servicing
- AllowUnqualifiedDNSQuery bool // True to allow unqualified DNS name resolution
- DNSSearchList string `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
+ SystemType string // HCS requires this to be hard-coded to "Container"
+ Name string // Name of the container. We use the docker ID.
+ Owner string `json:",omitempty"` // The management platform that created this container
+ VolumePath string `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
+ IgnoreFlushesDuringBoot bool `json:",omitempty"` // Optimization hint for container startup in Windows
+ LayerFolderPath string `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format %root%\windowsfilter\containerID
+ Layers []Layer // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
+ Credentials string `json:",omitempty"` // Credentials information
+ ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container.
+ ProcessorWeight uint64 `json:",omitempty"` // CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000. A value of 0 results in default shares.
+ ProcessorMaximum int64 `json:",omitempty"` // Specifies the portion of processor cycles that this container can use as a percentage times 100. Range is from 1 to 10000. A value of 0 results in no limit.
+ StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS
+ StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
+ StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
+ MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes
+ HostName string `json:",omitempty"` // Hostname
+ MappedDirectories []MappedDir `json:",omitempty"` // List of mapped directories (volumes/mounts)
+ MappedPipes []MappedPipe `json:",omitempty"` // List of mapped Windows named pipes
+ HvPartition bool // True if it a Hyper-V Container
+ NetworkSharedContainerName string `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
+ EndpointList []string `json:",omitempty"` // List of networking endpoints to be attached to container
+ HvRuntime *HvRuntime `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
+ Servicing bool `json:",omitempty"` // True if this container is for servicing
+ AllowUnqualifiedDNSQuery bool `json:",omitempty"` // True to allow unqualified DNS name resolution
+ DNSSearchList string `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
+ ContainerType string `json:",omitempty"` // "Linux" for Linux containers on Windows. Omitted otherwise.
+ TerminateOnLastHandleClosed bool `json:",omitempty"` // Should HCS terminate the container once all handles have been closed
+ MappedVirtualDisks []MappedVirtualDisk `json:",omitempty"` // Array of virtual disks to mount at start
}
type ComputeSystemQuery struct {
@@ -109,6 +134,9 @@ type Container interface {
// ProcessList returns details for the processes in a container.
ProcessList() ([]ProcessListItem, error)
+ // MappedVirtualDisks returns virtual disks mapped to a utility VM, indexed by controller
+ MappedVirtualDisks() (map[int]MappedVirtualDiskController, error)
+
// CreateProcess launches a new process within the container.
CreateProcess(c *ProcessConfig) (Process, error)
@@ -117,6 +145,9 @@ type Container interface {
// Close cleans up any state associated with the container but does not terminate or wait for it.
Close() error
+
+ // Modify the System
+ Modify(config *ResourceModificationRequestResponse) error
}
// Process represents a running or exited process.
diff --git a/vendor/github.com/Microsoft/hcsshim/layerexists.go b/vendor/github.com/Microsoft/hcsshim/layerexists.go
index 522d95cc..fe46f404 100644
--- a/vendor/github.com/Microsoft/hcsshim/layerexists.go
+++ b/vendor/github.com/Microsoft/hcsshim/layerexists.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// LayerExists will return true if a layer with the given id exists and is known
// to the system.
diff --git a/vendor/github.com/Microsoft/hcsshim/layerutils.go b/vendor/github.com/Microsoft/hcsshim/layerutils.go
index 47229d22..c0e55037 100644
--- a/vendor/github.com/Microsoft/hcsshim/layerutils.go
+++ b/vendor/github.com/Microsoft/hcsshim/layerutils.go
@@ -7,7 +7,7 @@ import (
"path/filepath"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
/* To pass into syscall, we need a struct matching the following:
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy.go b/vendor/github.com/Microsoft/hcsshim/legacy.go
index 11d90a7b..c7f6073a 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy.go
@@ -23,6 +23,13 @@ var mutatedUtilityVMFiles = map[string]bool{
`EFI\Microsoft\Boot\BCD.LOG2`: true,
}
+const (
+ filesPath = `Files`
+ hivesPath = `Hives`
+ utilityVMPath = `UtilityVM`
+ utilityVMFilesPath = `UtilityVM\Files`
+)
+
func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os.File, err error) {
return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
}
@@ -44,6 +51,10 @@ func makeLongAbsPath(path string) (string, error) {
return `\\?\` + path, nil
}
+func hasPathPrefix(p, prefix string) bool {
+ return strings.HasPrefix(p, prefix) && len(p) > len(prefix) && p[len(prefix)] == '\\'
+}
+
type fileEntry struct {
path string
fi os.FileInfo
@@ -83,7 +94,7 @@ func readTombstones(path string) (map[string]([]string), error) {
ts := make(map[string]([]string))
for s.Scan() {
- t := filepath.Join("Files", s.Text()[1:]) // skip leading `\`
+ t := filepath.Join(filesPath, s.Text()[1:]) // skip leading `\`
dir := filepath.Dir(t)
ts[dir] = append(ts[dir], t)
}
@@ -212,7 +223,7 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
return
}
- if fe.fi.IsDir() && strings.HasPrefix(path, `Files\`) {
+ if fe.fi.IsDir() && hasPathPrefix(path, filesPath) {
fe.path += ".$wcidirs$"
}
@@ -231,14 +242,14 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
return
}
- if !strings.HasPrefix(path, `Files\`) {
+ if !hasPathPrefix(path, filesPath) {
size = fe.fi.Size()
r.backupReader = winio.NewBackupFileReader(f, false)
- if path == "Hives" || path == "Files" {
+ if path == hivesPath || path == filesPath {
// The Hives directory has a non-deterministic file time because of the
// nature of the import process. Use the times from System_Delta.
var g *os.File
- g, err = os.Open(filepath.Join(r.root, `Hives\System_Delta`))
+ g, err = os.Open(filepath.Join(r.root, hivesPath, `System_Delta`))
if err != nil {
return
}
@@ -296,6 +307,16 @@ func (r *legacyLayerReader) Read(b []byte) (int, error) {
return r.backupReader.Read(b)
}
+func (r *legacyLayerReader) Seek(offset int64, whence int) (int64, error) {
+ if r.backupReader == nil {
+ if r.currentFile == nil {
+ return 0, errors.New("no current file")
+ }
+ return r.currentFile.Seek(offset, whence)
+ }
+ return 0, errors.New("seek not supported on this stream")
+}
+
func (r *legacyLayerReader) Close() error {
r.proceed <- false
<-r.result
@@ -357,7 +378,7 @@ func (w *legacyLayerWriter) init() error {
func (w *legacyLayerWriter) initUtilityVM() error {
if !w.HasUtilityVM {
- err := os.Mkdir(filepath.Join(w.destRoot, `UtilityVM`), 0)
+ err := os.Mkdir(filepath.Join(w.destRoot, utilityVMPath), 0)
if err != nil {
return err
}
@@ -365,7 +386,7 @@ func (w *legacyLayerWriter) initUtilityVM() error {
// clone the utility VM from the parent layer into this layer. Use hard
// links to avoid unnecessary copying, since most of the files are
// immutable.
- err = cloneTree(filepath.Join(w.parentRoots[0], `UtilityVM\Files`), filepath.Join(w.destRoot, `UtilityVM\Files`), mutatedUtilityVMFiles)
+ err = cloneTree(filepath.Join(w.parentRoots[0], utilityVMFilesPath), filepath.Join(w.destRoot, utilityVMFilesPath), mutatedUtilityVMFiles)
if err != nil {
return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
}
@@ -490,15 +511,15 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
return err
}
- if name == `UtilityVM` {
+ if name == utilityVMPath {
return w.initUtilityVM()
}
- if strings.HasPrefix(name, `UtilityVM\`) {
+ if hasPathPrefix(name, utilityVMPath) {
if !w.HasUtilityVM {
return errors.New("missing UtilityVM directory")
}
- if !strings.HasPrefix(name, `UtilityVM\Files\`) && name != `UtilityVM\Files` {
+ if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
return errors.New("invalid UtilityVM layer")
}
path := filepath.Join(w.destRoot, name)
@@ -585,7 +606,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
return err
}
- if strings.HasPrefix(name, `Hives\`) {
+ if hasPathPrefix(name, hivesPath) {
w.backupWriter = winio.NewBackupFileWriter(f, false)
} else {
// The file attributes are written before the stream.
@@ -608,22 +629,19 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
return err
}
- var requiredPrefix string
var roots []string
- if prefix := `Files\`; strings.HasPrefix(name, prefix) {
- requiredPrefix = prefix
+ if hasPathPrefix(target, filesPath) {
// Look for cross-layer hard link targets in the parent layers, since
// nothing is in the destination path yet.
roots = w.parentRoots
- } else if prefix := `UtilityVM\Files\`; strings.HasPrefix(name, prefix) {
- requiredPrefix = prefix
+ } else if hasPathPrefix(target, utilityVMFilesPath) {
// Since the utility VM is fully cloned into the destination path
// already, look for cross-layer hard link targets directly in the
// destination path.
roots = []string{w.destRoot}
}
- if requiredPrefix == "" || !strings.HasPrefix(target, requiredPrefix) {
+ if roots == nil || (!hasPathPrefix(name, filesPath) && !hasPathPrefix(name, utilityVMFilesPath)) {
return errors.New("invalid hard link in layer")
}
@@ -657,9 +675,9 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
}
func (w *legacyLayerWriter) Remove(name string) error {
- if strings.HasPrefix(name, `Files\`) {
- w.tombstones = append(w.tombstones, name[len(`Files\`):])
- } else if strings.HasPrefix(name, `UtilityVM\Files\`) {
+ if hasPathPrefix(name, filesPath) {
+ w.tombstones = append(w.tombstones, name[len(filesPath)+1:])
+ } else if hasPathPrefix(name, utilityVMFilesPath) {
err := w.initUtilityVM()
if err != nil {
return err
diff --git a/vendor/github.com/Microsoft/hcsshim/mksyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/mksyscall_windows.go
new file mode 100644
index 00000000..82393ca3
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/mksyscall_windows.go
@@ -0,0 +1,934 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+mksyscall_windows generates windows system call bodies
+
+It parses all files specified on command line containing function
+prototypes (like syscall_windows.go) and prints system call bodies
+to standard output.
+
+The prototypes are marked by lines beginning with "//sys" and read
+like func declarations if //sys is replaced by func, but:
+
+* The parameter lists must give a name for each argument. This
+ includes return parameters.
+
+* The parameter lists must give a type for each argument:
+ the (x, y, z int) shorthand is not allowed.
+
+* If the return parameter is an error number, it must be named err.
+
+* If go func name needs to be different from it's winapi dll name,
+ the winapi name could be specified at the end, after "=" sign, like
+ //sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
+
+* Each function that returns err needs to supply a condition, that
+ return value of winapi will be tested against to detect failure.
+ This would set err to windows "last-error", otherwise it will be nil.
+ The value can be provided at end of //sys declaration, like
+ //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
+ and is [failretval==0] by default.
+
+Usage:
+ mksyscall_windows [flags] [path ...]
+
+The flags are:
+ -output
+ Specify output file name (outputs to console if blank).
+ -trace
+ Generate print statement after every syscall.
+*/
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "flag"
+ "fmt"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "text/template"
+)
+
+var (
+ filename = flag.String("output", "", "output file name (standard output if omitted)")
+ printTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
+ systemDLL = flag.Bool("systemdll", true, "whether all DLLs should be loaded from the Windows system directory")
+)
+
+func trim(s string) string {
+ return strings.Trim(s, " \t")
+}
+
+var packageName string
+
+func packagename() string {
+ return packageName
+}
+
+func syscalldot() string {
+ if packageName == "syscall" {
+ return ""
+ }
+ return "syscall."
+}
+
+// Param is function parameter
+type Param struct {
+ Name string
+ Type string
+ fn *Fn
+ tmpVarIdx int
+}
+
+// tmpVar returns temp variable name that will be used to represent p during syscall.
+func (p *Param) tmpVar() string {
+ if p.tmpVarIdx < 0 {
+ p.tmpVarIdx = p.fn.curTmpVarIdx
+ p.fn.curTmpVarIdx++
+ }
+ return fmt.Sprintf("_p%d", p.tmpVarIdx)
+}
+
+// BoolTmpVarCode returns source code for bool temp variable.
+func (p *Param) BoolTmpVarCode() string {
+ const code = `var %s uint32
+ if %s {
+ %s = 1
+ } else {
+ %s = 0
+ }`
+ tmp := p.tmpVar()
+ return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
+}
+
+// SliceTmpVarCode returns source code for slice temp variable.
+func (p *Param) SliceTmpVarCode() string {
+ const code = `var %s *%s
+ if len(%s) > 0 {
+ %s = &%s[0]
+ }`
+ tmp := p.tmpVar()
+ return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
+}
+
+// StringTmpVarCode returns source code for string temp variable.
+func (p *Param) StringTmpVarCode() string {
+ errvar := p.fn.Rets.ErrorVarName()
+ if errvar == "" {
+ errvar = "_"
+ }
+ tmp := p.tmpVar()
+ const code = `var %s %s
+ %s, %s = %s(%s)`
+ s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
+ if errvar == "-" {
+ return s
+ }
+ const morecode = `
+ if %s != nil {
+ return
+ }`
+ return s + fmt.Sprintf(morecode, errvar)
+}
+
+// TmpVarCode returns source code for temp variable.
+func (p *Param) TmpVarCode() string {
+ switch {
+ case p.Type == "bool":
+ return p.BoolTmpVarCode()
+ case strings.HasPrefix(p.Type, "[]"):
+ return p.SliceTmpVarCode()
+ default:
+ return ""
+ }
+}
+
+// TmpVarHelperCode returns source code for helper's temp variable.
+func (p *Param) TmpVarHelperCode() string {
+ if p.Type != "string" {
+ return ""
+ }
+ return p.StringTmpVarCode()
+}
+
+// SyscallArgList returns source code fragments representing p parameter
+// in syscall. Slices are translated into 2 syscall parameters: pointer to
+// the first element and length.
+func (p *Param) SyscallArgList() []string {
+ t := p.HelperType()
+ var s string
+ switch {
+ case t[0] == '*':
+ s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
+ case t == "bool":
+ s = p.tmpVar()
+ case strings.HasPrefix(t, "[]"):
+ return []string{
+ fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
+ fmt.Sprintf("uintptr(len(%s))", p.Name),
+ }
+ default:
+ s = p.Name
+ }
+ return []string{fmt.Sprintf("uintptr(%s)", s)}
+}
+
+// IsError determines if p parameter is used to return error.
+func (p *Param) IsError() bool {
+ return p.Name == "err" && p.Type == "error"
+}
+
+// HelperType returns type of parameter p used in helper function.
+func (p *Param) HelperType() string {
+ if p.Type == "string" {
+ return p.fn.StrconvType()
+ }
+ return p.Type
+}
+
+// join concatenates parameters ps into a string with sep separator.
+// Each parameter is converted into string by applying fn to it
+// before conversion.
+func join(ps []*Param, fn func(*Param) string, sep string) string {
+ if len(ps) == 0 {
+ return ""
+ }
+ a := make([]string, 0)
+ for _, p := range ps {
+ a = append(a, fn(p))
+ }
+ return strings.Join(a, sep)
+}
+
+// Rets describes function return parameters.
+type Rets struct {
+ Name string
+ Type string
+ ReturnsError bool
+ FailCond string
+}
+
+// ErrorVarName returns error variable name for r.
+func (r *Rets) ErrorVarName() string {
+ if r.ReturnsError {
+ return "err"
+ }
+ if r.Type == "error" {
+ return r.Name
+ }
+ return ""
+}
+
+// ToParams converts r into slice of *Param.
+func (r *Rets) ToParams() []*Param {
+ ps := make([]*Param, 0)
+ if len(r.Name) > 0 {
+ ps = append(ps, &Param{Name: r.Name, Type: r.Type})
+ }
+ if r.ReturnsError {
+ ps = append(ps, &Param{Name: "err", Type: "error"})
+ }
+ return ps
+}
+
+// List returns source code of syscall return parameters.
+func (r *Rets) List() string {
+ s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
+ if len(s) > 0 {
+ s = "(" + s + ")"
+ }
+ return s
+}
+
+// PrintList returns source code of trace printing part correspondent
+// to syscall return values.
+func (r *Rets) PrintList() string {
+ return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
+}
+
+// SetReturnValuesCode returns source code that accepts syscall return values.
+func (r *Rets) SetReturnValuesCode() string {
+ if r.Name == "" && !r.ReturnsError {
+ return ""
+ }
+ retvar := "r0"
+ if r.Name == "" {
+ retvar = "r1"
+ }
+ errvar := "_"
+ if r.ReturnsError {
+ errvar = "e1"
+ }
+ return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
+}
+
+func (r *Rets) useLongHandleErrorCode(retvar string) string {
+ const code = `if %s {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = %sEINVAL
+ }
+ }`
+ cond := retvar + " == 0"
+ if r.FailCond != "" {
+ cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
+ }
+ return fmt.Sprintf(code, cond, syscalldot())
+}
+
+// SetErrorCode returns source code that sets return parameters.
+func (r *Rets) SetErrorCode() string {
+ const code = `if r0 != 0 {
+ %s = %sErrno(r0)
+ }`
+ const hrCode = `if int32(r0) < 0 {
+ %s = %sErrno(win32FromHresult(r0))
+ }`
+ if r.Name == "" && !r.ReturnsError {
+ return ""
+ }
+ if r.Name == "" {
+ return r.useLongHandleErrorCode("r1")
+ }
+ if r.Type == "error" {
+ if r.Name == "hr" {
+ return fmt.Sprintf(hrCode, r.Name, syscalldot())
+ } else {
+ return fmt.Sprintf(code, r.Name, syscalldot())
+ }
+ }
+ s := ""
+ switch {
+ case r.Type[0] == '*':
+ s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
+ case r.Type == "bool":
+ s = fmt.Sprintf("%s = r0 != 0", r.Name)
+ default:
+ s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
+ }
+ if !r.ReturnsError {
+ return s
+ }
+ return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
+}
+
+// Fn describes syscall function.
+type Fn struct {
+ Name string
+ Params []*Param
+ Rets *Rets
+ PrintTrace bool
+ confirmproc bool
+ dllname string
+ dllfuncname string
+ src string
+ // TODO: get rid of this field and just use parameter index instead
+ curTmpVarIdx int // insure tmp variables have uniq names
+}
+
+// extractParams parses s to extract function parameters.
+func extractParams(s string, f *Fn) ([]*Param, error) {
+ s = trim(s)
+ if s == "" {
+ return nil, nil
+ }
+ a := strings.Split(s, ",")
+ ps := make([]*Param, len(a))
+ for i := range ps {
+ s2 := trim(a[i])
+ b := strings.Split(s2, " ")
+ if len(b) != 2 {
+ b = strings.Split(s2, "\t")
+ if len(b) != 2 {
+ return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
+ }
+ }
+ ps[i] = &Param{
+ Name: trim(b[0]),
+ Type: trim(b[1]),
+ fn: f,
+ tmpVarIdx: -1,
+ }
+ }
+ return ps, nil
+}
+
+// extractSection extracts text out of string s starting after start
+// and ending just before end. found return value will indicate success,
+// and prefix, body and suffix will contain correspondent parts of string s.
+func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
+ s = trim(s)
+ if strings.HasPrefix(s, string(start)) {
+ // no prefix
+ body = s[1:]
+ } else {
+ a := strings.SplitN(s, string(start), 2)
+ if len(a) != 2 {
+ return "", "", s, false
+ }
+ prefix = a[0]
+ body = a[1]
+ }
+ a := strings.SplitN(body, string(end), 2)
+ if len(a) != 2 {
+ return "", "", "", false
+ }
+ return prefix, a[0], a[1], true
+}
+
+// newFn parses string s and return created function Fn.
+func newFn(s string) (*Fn, error) {
+ s = trim(s)
+ f := &Fn{
+ Rets: &Rets{},
+ src: s,
+ PrintTrace: *printTraceFlag,
+ }
+ // function name and args
+ prefix, body, s, found := extractSection(s, '(', ')')
+ if !found || prefix == "" {
+ return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
+ }
+ f.Name = prefix
+ var err error
+ f.Params, err = extractParams(body, f)
+ if err != nil {
+ return nil, err
+ }
+ // return values
+ _, body, s, found = extractSection(s, '(', ')')
+ if found {
+ r, err := extractParams(body, f)
+ if err != nil {
+ return nil, err
+ }
+ switch len(r) {
+ case 0:
+ case 1:
+ if r[0].IsError() {
+ f.Rets.ReturnsError = true
+ } else {
+ f.Rets.Name = r[0].Name
+ f.Rets.Type = r[0].Type
+ }
+ case 2:
+ if !r[1].IsError() {
+ return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
+ }
+ f.Rets.ReturnsError = true
+ f.Rets.Name = r[0].Name
+ f.Rets.Type = r[0].Type
+ default:
+ return nil, errors.New("Too many return values in \"" + f.src + "\"")
+ }
+ }
+ // fail condition
+ _, body, s, found = extractSection(s, '[', ']')
+ if found {
+ f.Rets.FailCond = body
+ }
+ // dll and dll function names
+ s = trim(s)
+ if s == "" {
+ return f, nil
+ }
+ if !strings.HasPrefix(s, "=") {
+ return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
+ }
+ s = trim(s[1:])
+ a := strings.Split(s, ".")
+ switch len(a) {
+ case 1:
+ f.dllfuncname = a[0]
+ case 2:
+ f.dllname = a[0]
+ f.dllfuncname = a[1]
+ default:
+ return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
+ }
+ if f.dllfuncname[len(f.dllfuncname)-1] == '?' {
+ f.confirmproc = true
+ f.dllfuncname = f.dllfuncname[0 : len(f.dllfuncname)-1]
+ }
+ return f, nil
+}
+
+// DLLName returns DLL name for function f.
+func (f *Fn) DLLName() string {
+ if f.dllname == "" {
+ return "kernel32"
+ }
+ return f.dllname
+}
+
+// DLLName returns DLL function name for function f.
+func (f *Fn) DLLFuncName() string {
+ if f.dllfuncname == "" {
+ return f.Name
+ }
+ return f.dllfuncname
+}
+
+func (f *Fn) ConfirmProc() bool {
+ return f.confirmproc
+}
+
+// ParamList returns source code for function f parameters.
+func (f *Fn) ParamList() string {
+ return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
+}
+
+// HelperParamList returns source code for helper function f parameters.
+func (f *Fn) HelperParamList() string {
+ return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
+}
+
+// ParamPrintList returns source code of trace printing part correspondent
+// to syscall input parameters.
+func (f *Fn) ParamPrintList() string {
+ return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
+}
+
+// ParamCount return number of syscall parameters for function f.
+func (f *Fn) ParamCount() int {
+ n := 0
+ for _, p := range f.Params {
+ n += len(p.SyscallArgList())
+ }
+ return n
+}
+
+// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
+// to use. It returns parameter count for correspondent SyscallX function.
+func (f *Fn) SyscallParamCount() int {
+ n := f.ParamCount()
+ switch {
+ case n <= 3:
+ return 3
+ case n <= 6:
+ return 6
+ case n <= 9:
+ return 9
+ case n <= 12:
+ return 12
+ case n <= 15:
+ return 15
+ default:
+ panic("too many arguments to system call")
+ }
+}
+
+// Syscall determines which SyscallX function to use for function f.
+func (f *Fn) Syscall() string {
+ c := f.SyscallParamCount()
+ if c == 3 {
+ return syscalldot() + "Syscall"
+ }
+ return syscalldot() + "Syscall" + strconv.Itoa(c)
+}
+
+// SyscallParamList returns source code for SyscallX parameters for function f.
+func (f *Fn) SyscallParamList() string {
+ a := make([]string, 0)
+ for _, p := range f.Params {
+ a = append(a, p.SyscallArgList()...)
+ }
+ for len(a) < f.SyscallParamCount() {
+ a = append(a, "0")
+ }
+ return strings.Join(a, ", ")
+}
+
+// HelperCallParamList returns source code of call into function f helper.
+func (f *Fn) HelperCallParamList() string {
+ a := make([]string, 0, len(f.Params))
+ for _, p := range f.Params {
+ s := p.Name
+ if p.Type == "string" {
+ s = p.tmpVar()
+ }
+ a = append(a, s)
+ }
+ return strings.Join(a, ", ")
+}
+
+// IsUTF16 is true, if f is W (utf16) function. It is false
+// for all A (ascii) functions.
+func (_ *Fn) IsUTF16() bool {
+ return true
+}
+
+// StrconvFunc returns name of Go string to OS string function for f.
+func (f *Fn) StrconvFunc() string {
+ if f.IsUTF16() {
+ return syscalldot() + "UTF16PtrFromString"
+ }
+ return syscalldot() + "BytePtrFromString"
+}
+
+// StrconvType returns Go type name used for OS string for f.
+func (f *Fn) StrconvType() string {
+ if f.IsUTF16() {
+ return "*uint16"
+ }
+ return "*byte"
+}
+
+// HasStringParam is true, if f has at least one string parameter.
+// Otherwise it is false.
+func (f *Fn) HasStringParam() bool {
+ for _, p := range f.Params {
+ if p.Type == "string" {
+ return true
+ }
+ }
+ return false
+}
+
+var uniqDllFuncName = make(map[string]bool)
+
+// IsNotDuplicate is true if f is not a duplicated function
+func (f *Fn) IsNotDuplicate() bool {
+ funcName := f.DLLFuncName()
+ if uniqDllFuncName[funcName] == false {
+ uniqDllFuncName[funcName] = true
+ return true
+ }
+ return false
+}
+
+// HelperName returns name of function f helper.
+func (f *Fn) HelperName() string {
+ if !f.HasStringParam() {
+ return f.Name
+ }
+ return "_" + f.Name
+}
+
+// Source files and functions.
+type Source struct {
+ Funcs []*Fn
+ Files []string
+ StdLibImports []string
+ ExternalImports []string
+}
+
+func (src *Source) Import(pkg string) {
+ src.StdLibImports = append(src.StdLibImports, pkg)
+ sort.Strings(src.StdLibImports)
+}
+
+func (src *Source) ExternalImport(pkg string) {
+ src.ExternalImports = append(src.ExternalImports, pkg)
+ sort.Strings(src.ExternalImports)
+}
+
+// ParseFiles parses files listed in fs and extracts all syscall
+// functions listed in sys comments. It returns source files
+// and functions collection *Source if successful.
+func ParseFiles(fs []string) (*Source, error) {
+ src := &Source{
+ Funcs: make([]*Fn, 0),
+ Files: make([]string, 0),
+ StdLibImports: []string{
+ "unsafe",
+ },
+ ExternalImports: make([]string, 0),
+ }
+ for _, file := range fs {
+ if err := src.ParseFile(file); err != nil {
+ return nil, err
+ }
+ }
+ return src, nil
+}
+
+// DLLs return dll names for a source set src.
+func (src *Source) DLLs() []string {
+ uniq := make(map[string]bool)
+ r := make([]string, 0)
+ for _, f := range src.Funcs {
+ name := f.DLLName()
+ if _, found := uniq[name]; !found {
+ uniq[name] = true
+ r = append(r, name)
+ }
+ }
+ return r
+}
+
+// ParseFile adds additional file path to a source set src.
+func (src *Source) ParseFile(path string) error {
+ file, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+
+ s := bufio.NewScanner(file)
+ for s.Scan() {
+ t := trim(s.Text())
+ if len(t) < 7 {
+ continue
+ }
+ if !strings.HasPrefix(t, "//sys") {
+ continue
+ }
+ t = t[5:]
+ if !(t[0] == ' ' || t[0] == '\t') {
+ continue
+ }
+ f, err := newFn(t[1:])
+ if err != nil {
+ return err
+ }
+ src.Funcs = append(src.Funcs, f)
+ }
+ if err := s.Err(); err != nil {
+ return err
+ }
+ src.Files = append(src.Files, path)
+
+ // get package name
+ fset := token.NewFileSet()
+ _, err = file.Seek(0, 0)
+ if err != nil {
+ return err
+ }
+ pkg, err := parser.ParseFile(fset, "", file, parser.PackageClauseOnly)
+ if err != nil {
+ return err
+ }
+ packageName = pkg.Name.Name
+
+ return nil
+}
+
+// IsStdRepo returns true if src is part of standard library.
+func (src *Source) IsStdRepo() (bool, error) {
+ if len(src.Files) == 0 {
+ return false, errors.New("no input files provided")
+ }
+ abspath, err := filepath.Abs(src.Files[0])
+ if err != nil {
+ return false, err
+ }
+ goroot := runtime.GOROOT()
+ if runtime.GOOS == "windows" {
+ abspath = strings.ToLower(abspath)
+ goroot = strings.ToLower(goroot)
+ }
+ sep := string(os.PathSeparator)
+ if !strings.HasSuffix(goroot, sep) {
+ goroot += sep
+ }
+ return strings.HasPrefix(abspath, goroot), nil
+}
+
+// Generate output source file from a source set src.
+func (src *Source) Generate(w io.Writer) error {
+ const (
+ pkgStd = iota // any package in std library
+ pkgXSysWindows // x/sys/windows package
+ pkgOther
+ )
+ isStdRepo, err := src.IsStdRepo()
+ if err != nil {
+ return err
+ }
+ var pkgtype int
+ switch {
+ case isStdRepo:
+ pkgtype = pkgStd
+ case packageName == "windows":
+ // TODO: this needs better logic than just using package name
+ pkgtype = pkgXSysWindows
+ default:
+ pkgtype = pkgOther
+ }
+ if *systemDLL {
+ switch pkgtype {
+ case pkgStd:
+ src.Import("internal/syscall/windows/sysdll")
+ case pkgXSysWindows:
+ default:
+ src.ExternalImport("golang.org/x/sys/windows")
+ }
+ }
+ src.ExternalImport("github.com/Microsoft/go-winio")
+ if packageName != "syscall" {
+ src.Import("syscall")
+ }
+ funcMap := template.FuncMap{
+ "packagename": packagename,
+ "syscalldot": syscalldot,
+ "newlazydll": func(dll string) string {
+ arg := "\"" + dll + ".dll\""
+ if !*systemDLL {
+ return syscalldot() + "NewLazyDLL(" + arg + ")"
+ }
+ switch pkgtype {
+ case pkgStd:
+ return syscalldot() + "NewLazyDLL(sysdll.Add(" + arg + "))"
+ case pkgXSysWindows:
+ return "NewLazySystemDLL(" + arg + ")"
+ default:
+ return "windows.NewLazySystemDLL(" + arg + ")"
+ }
+ },
+ }
+ t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate))
+ err = t.Execute(w, src)
+ if err != nil {
+ return errors.New("Failed to execute template: " + err.Error())
+ }
+ return nil
+}
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
+ flag.PrintDefaults()
+ os.Exit(1)
+}
+
+func main() {
+ flag.Usage = usage
+ flag.Parse()
+ if len(flag.Args()) <= 0 {
+ fmt.Fprintf(os.Stderr, "no files to parse provided\n")
+ usage()
+ }
+
+ src, err := ParseFiles(flag.Args())
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var buf bytes.Buffer
+ if err := src.Generate(&buf); err != nil {
+ log.Fatal(err)
+ }
+
+ data, err := format.Source(buf.Bytes())
+ if err != nil {
+ log.Fatal(err)
+ }
+ if *filename == "" {
+ _, err = os.Stdout.Write(data)
+ } else {
+ err = ioutil.WriteFile(*filename, data, 0644)
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+// TODO: use println instead to print in the following template
+const srcTemplate = `
+
+{{define "main"}}// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package {{packagename}}
+
+import (
+{{range .StdLibImports}}"{{.}}"
+{{end}}
+
+{{range .ExternalImports}}"{{.}}"
+{{end}}
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = {{syscalldot}}Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e {{syscalldot}}Errno) error {
+ switch e {
+ case 0:
+ return nil
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+{{template "dlls" .}}
+{{template "funcnames" .}})
+{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
+{{end}}
+
+{{/* help functions */}}
+
+{{define "dlls"}}{{range .DLLs}} mod{{.}} = {{newlazydll .}}
+{{end}}{{end}}
+
+{{define "funcnames"}}{{range .Funcs}}{{if .IsNotDuplicate}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}"){{end}}
+{{end}}{{end}}
+
+{{define "helperbody"}}
+func {{.Name}}({{.ParamList}}) {{template "results" .}}{
+{{template "helpertmpvars" .}} return {{.HelperName}}({{.HelperCallParamList}})
+}
+{{end}}
+
+{{define "funcbody"}}
+func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
+{{template "tmpvars" .}} {{template "syscallcheck" .}}{{template "syscall" .}}
+{{template "seterror" .}}{{template "printtrace" .}} return
+}
+{{end}}
+
+{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}}
+{{end}}{{end}}{{end}}
+
+{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}}
+{{end}}{{end}}{{end}}
+
+{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
+
+{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
+
+{{define "syscallcheck"}}{{if .ConfirmProc}}if {{.Rets.ErrorVarName}} = proc{{.DLLFuncName}}.Find(); {{.Rets.ErrorVarName}} != nil {
+ return
+}
+{{end}}{{end}}
+
+
+{{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}}
+{{end}}{{end}}
+
+{{define "printtrace"}}{{if .PrintTrace}} print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
+{{end}}{{end}}
+
+`
diff --git a/vendor/github.com/Microsoft/hcsshim/nametoguid.go b/vendor/github.com/Microsoft/hcsshim/nametoguid.go
index 1a522f95..b7c6d020 100644
--- a/vendor/github.com/Microsoft/hcsshim/nametoguid.go
+++ b/vendor/github.com/Microsoft/hcsshim/nametoguid.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// NameToGuid converts the given string into a GUID using the algorithm in the
// Host Compute Service, ensuring GUIDs generated with the same string are common
diff --git a/vendor/github.com/Microsoft/hcsshim/preparelayer.go b/vendor/github.com/Microsoft/hcsshim/preparelayer.go
index 27916834..5c5b6184 100644
--- a/vendor/github.com/Microsoft/hcsshim/preparelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/preparelayer.go
@@ -3,7 +3,7 @@ package hcsshim
import (
"sync"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var prepareLayerLock sync.Mutex
diff --git a/vendor/github.com/Microsoft/hcsshim/process.go b/vendor/github.com/Microsoft/hcsshim/process.go
index af3fab35..faee2cfe 100644
--- a/vendor/github.com/Microsoft/hcsshim/process.go
+++ b/vendor/github.com/Microsoft/hcsshim/process.go
@@ -3,12 +3,11 @@ package hcsshim
import (
"encoding/json"
"io"
- "runtime"
"sync"
"syscall"
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// ContainerError is an error encountered in HCS
@@ -322,17 +321,11 @@ func (process *process) Close() error {
}
process.handle = 0
- runtime.SetFinalizer(process, nil)
logrus.Debugf(title+" succeeded processid=%d", process.processID)
return nil
}
-// closeProcess wraps process.Close for use by a finalizer
-func closeProcess(process *process) {
- process.Close()
-}
-
func (process *process) registerCallback() error {
context := ¬ifcationWatcherContext{
channels: newChannels(),
diff --git a/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go b/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
index d0ead0bd..e8a3b507 100644
--- a/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
@@ -1,6 +1,6 @@
package hcsshim
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
// UnprepareLayer disables the filesystem filter for the read-write layer with
// the given id.
diff --git a/vendor/github.com/Microsoft/hcsshim/waithelper.go b/vendor/github.com/Microsoft/hcsshim/waithelper.go
index 89c94616..b7be20ea 100644
--- a/vendor/github.com/Microsoft/hcsshim/waithelper.go
+++ b/vendor/github.com/Microsoft/hcsshim/waithelper.go
@@ -3,7 +3,7 @@ package hcsshim
import (
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
@@ -59,4 +59,5 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
case <-c:
return ErrTimeout
}
+ return nil
}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/vendor/github.com/Sirupsen/logrus/terminal_windows.go
deleted file mode 100644
index 05d2f91f..00000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_windows.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build windows,!appengine
-
-package logrus
-
-import (
- "io"
- "os"
- "syscall"
- "unsafe"
-)
-
-var kernel32 = syscall.NewLazyDLL("kernel32.dll")
-
-var (
- procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
-)
-
-// IsTerminal returns true if stderr's file descriptor is a terminal.
-func IsTerminal(f io.Writer) bool {
- switch v := f.(type) {
- case *os.File:
- var st uint32
- r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
- return r != 0 && e == 0
- default:
- return false
- }
-}
diff --git a/vendor/github.com/containers/image/copy/copy.go b/vendor/github.com/containers/image/copy/copy.go
index a8afcc9e..bb52ea76 100644
--- a/vendor/github.com/containers/image/copy/copy.go
+++ b/vendor/github.com/containers/image/copy/copy.go
@@ -3,6 +3,7 @@ package copy
import (
"bytes"
"compress/gzip"
+ "context"
"fmt"
"io"
"io/ioutil"
@@ -13,7 +14,6 @@ import (
pb "gopkg.in/cheggaaa/pb.v1"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/image"
"github.com/containers/image/pkg/compression"
"github.com/containers/image/signature"
@@ -21,6 +21,7 @@ import (
"github.com/containers/image/types"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
type digestingReader struct {
@@ -171,7 +172,7 @@ func Image(policyContext *signature.PolicyContext, destRef, srcRef types.ImageRe
sigs = [][]byte{}
} else {
writeReport("Getting image source signatures\n")
- s, err := src.Signatures()
+ s, err := src.Signatures(context.TODO())
if err != nil {
return errors.Wrap(err, "Error reading signatures")
}
diff --git a/vendor/github.com/containers/image/copy/manifest.go b/vendor/github.com/containers/image/copy/manifest.go
index 6cb7517d..e3b294dd 100644
--- a/vendor/github.com/containers/image/copy/manifest.go
+++ b/vendor/github.com/containers/image/copy/manifest.go
@@ -3,10 +3,10 @@ package copy
import (
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// preferredManifestMIMETypes lists manifest MIME types in order of our preference, if we can't use the original manifest and need to convert.
diff --git a/vendor/github.com/containers/image/directory/directory_src.go b/vendor/github.com/containers/image/directory/directory_src.go
index d432fb72..fddc1c52 100644
--- a/vendor/github.com/containers/image/directory/directory_src.go
+++ b/vendor/github.com/containers/image/directory/directory_src.go
@@ -1,6 +1,7 @@
package directory
import (
+ "context"
"io"
"io/ioutil"
"os"
@@ -59,7 +60,7 @@ func (s *dirImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, err
return r, fi.Size(), nil
}
-func (s *dirImageSource) GetSignatures() ([][]byte, error) {
+func (s *dirImageSource) GetSignatures(ctx context.Context) ([][]byte, error) {
signatures := [][]byte{}
for i := 0; ; i++ {
signature, err := ioutil.ReadFile(s.ref.signaturePath(i))
diff --git a/vendor/github.com/containers/image/docker/archive/src.go b/vendor/github.com/containers/image/docker/archive/src.go
index 5c5267a3..aebcaa82 100644
--- a/vendor/github.com/containers/image/docker/archive/src.go
+++ b/vendor/github.com/containers/image/docker/archive/src.go
@@ -1,9 +1,9 @@
package archive
import (
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/tarfile"
"github.com/containers/image/types"
+ "github.com/sirupsen/logrus"
)
type archiveImageSource struct {
diff --git a/vendor/github.com/containers/image/docker/daemon/daemon_dest.go b/vendor/github.com/containers/image/docker/daemon/daemon_dest.go
index 31cb2eac..559e5c71 100644
--- a/vendor/github.com/containers/image/docker/daemon/daemon_dest.go
+++ b/vendor/github.com/containers/image/docker/daemon/daemon_dest.go
@@ -3,12 +3,12 @@ package daemon
import (
"io"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/docker/tarfile"
"github.com/containers/image/types"
"github.com/docker/docker/client"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"golang.org/x/net/context"
)
diff --git a/vendor/github.com/containers/image/docker/docker_client.go b/vendor/github.com/containers/image/docker/docker_client.go
index 13439462..99102a6c 100644
--- a/vendor/github.com/containers/image/docker/docker_client.go
+++ b/vendor/github.com/containers/image/docker/docker_client.go
@@ -1,6 +1,7 @@
package docker
import (
+ "context"
"crypto/tls"
"encoding/base64"
"encoding/json"
@@ -14,7 +15,6 @@ import (
"strings"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/storage/pkg/homedir"
@@ -23,6 +23,7 @@ import (
"github.com/docker/go-connections/tlsconfig"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
const (
@@ -254,24 +255,25 @@ func newDockerClient(ctx *types.SystemContext, ref dockerReference, write bool,
// makeRequest creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// The host name and schema is taken from the client or autodetected, and the path is relative to it, i.e. the path usually starts with /v2/.
-func (c *dockerClient) makeRequest(method, path string, headers map[string][]string, stream io.Reader) (*http.Response, error) {
- if err := c.detectProperties(); err != nil {
+func (c *dockerClient) makeRequest(ctx context.Context, method, path string, headers map[string][]string, stream io.Reader) (*http.Response, error) {
+ if err := c.detectProperties(ctx); err != nil {
return nil, err
}
url := fmt.Sprintf("%s://%s%s", c.scheme, c.registry, path)
- return c.makeRequestToResolvedURL(method, url, headers, stream, -1, true)
+ return c.makeRequestToResolvedURL(ctx, method, url, headers, stream, -1, true)
}
// makeRequestToResolvedURL creates and executes a http.Request with the specified parameters, adding authentication and TLS options for the Docker client.
// streamLen, if not -1, specifies the length of the data expected on stream.
// makeRequest should generally be preferred.
// TODO(runcom): too many arguments here, use a struct
-func (c *dockerClient) makeRequestToResolvedURL(method, url string, headers map[string][]string, stream io.Reader, streamLen int64, sendAuth bool) (*http.Response, error) {
+func (c *dockerClient) makeRequestToResolvedURL(ctx context.Context, method, url string, headers map[string][]string, stream io.Reader, streamLen int64, sendAuth bool) (*http.Response, error) {
req, err := http.NewRequest(method, url, stream)
if err != nil {
return nil, err
}
+ req = req.WithContext(ctx)
if streamLen != -1 { // Do not blindly overwrite if streamLen == -1, http.NewRequest above can figure out the length of bytes.Reader and similar objects without us having to compute it.
req.ContentLength = streamLen
}
@@ -323,7 +325,7 @@ func (c *dockerClient) setupRequestAuth(req *http.Request) error {
}
service, _ := challenge.Parameters["service"] // Will be "" if not present
scope := fmt.Sprintf("repository:%s:%s", c.scope.remoteName, c.scope.actions)
- token, err := c.getBearerToken(realm, service, scope)
+ token, err := c.getBearerToken(req.Context(), realm, service, scope)
if err != nil {
return err
}
@@ -340,11 +342,12 @@ func (c *dockerClient) setupRequestAuth(req *http.Request) error {
return nil
}
-func (c *dockerClient) getBearerToken(realm, service, scope string) (*bearerToken, error) {
+func (c *dockerClient) getBearerToken(ctx context.Context, realm, service, scope string) (*bearerToken, error) {
authReq, err := http.NewRequest("GET", realm, nil)
if err != nil {
return nil, err
}
+ authReq = authReq.WithContext(ctx)
getParams := authReq.URL.Query()
if service != "" {
getParams.Add("service", service)
@@ -447,14 +450,14 @@ func getAuth(ctx *types.SystemContext, registry string) (string, string, error)
// detectProperties detects various properties of the registry.
// See the dockerClient documentation for members which are affected by this.
-func (c *dockerClient) detectProperties() error {
+func (c *dockerClient) detectProperties(ctx context.Context) error {
if c.scheme != "" {
return nil
}
ping := func(scheme string) error {
url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry)
- resp, err := c.makeRequestToResolvedURL("GET", url, nil, nil, -1, true)
+ resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
logrus.Debugf("Ping %s err %#v", url, err)
if err != nil {
return err
@@ -481,7 +484,7 @@ func (c *dockerClient) detectProperties() error {
// best effort to understand if we're talking to a V1 registry
pingV1 := func(scheme string) bool {
url := fmt.Sprintf(resolvedPingV1URL, scheme, c.registry)
- resp, err := c.makeRequestToResolvedURL("GET", url, nil, nil, -1, true)
+ resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, true)
logrus.Debugf("Ping %s err %#v", url, err)
if err != nil {
return false
@@ -506,9 +509,9 @@ func (c *dockerClient) detectProperties() error {
// getExtensionsSignatures returns signatures from the X-Registry-Supports-Signatures API extension,
// using the original data structures.
-func (c *dockerClient) getExtensionsSignatures(ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) {
+func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerReference, manifestDigest digest.Digest) (*extensionSignatureList, error) {
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(ref.ref), manifestDigest)
- res, err := c.makeRequest("GET", path, nil, nil)
+ res, err := c.makeRequest(ctx, "GET", path, nil, nil)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image.go b/vendor/github.com/containers/image/docker/docker_image.go
index 3bc2beba..992d9203 100644
--- a/vendor/github.com/containers/image/docker/docker_image.go
+++ b/vendor/github.com/containers/image/docker/docker_image.go
@@ -1,6 +1,7 @@
package docker
import (
+ "context"
"encoding/json"
"fmt"
"net/http"
@@ -41,7 +42,8 @@ func (i *Image) SourceRefFullName() string {
// GetRepositoryTags list all tags available in the repository. Note that this has no connection with the tag(s) used for this specific image, if any.
func (i *Image) GetRepositoryTags() ([]string, error) {
path := fmt.Sprintf(tagsPath, reference.Path(i.src.ref.ref))
- res, err := i.src.c.makeRequest("GET", path, nil, nil)
+ // FIXME: Pass the context.Context
+ res, err := i.src.c.makeRequest(context.TODO(), "GET", path, nil, nil)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image_dest.go b/vendor/github.com/containers/image/docker/docker_image_dest.go
index a3a4ca39..68404bda 100644
--- a/vendor/github.com/containers/image/docker/docker_image_dest.go
+++ b/vendor/github.com/containers/image/docker/docker_image_dest.go
@@ -2,6 +2,7 @@ package docker
import (
"bytes"
+ "context"
"crypto/rand"
"encoding/json"
"fmt"
@@ -12,7 +13,6 @@ import (
"os"
"path/filepath"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
@@ -21,6 +21,7 @@ import (
"github.com/docker/distribution/registry/client"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
var manifestMIMETypes = []string{
@@ -75,7 +76,7 @@ func (d *dockerImageDestination) SupportedManifestMIMETypes() []string {
// SupportsSignatures returns an error (to be displayed to the user) if the destination certainly can't store signatures.
// Note: It is still possible for PutSignatures to fail if SupportsSignatures returns nil.
func (d *dockerImageDestination) SupportsSignatures() error {
- if err := d.c.detectProperties(); err != nil {
+ if err := d.c.detectProperties(context.TODO()); err != nil {
return err
}
switch {
@@ -132,7 +133,7 @@ func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobI
// FIXME? Chunked upload, progress reporting, etc.
uploadPath := fmt.Sprintf(blobUploadPath, reference.Path(d.ref.ref))
logrus.Debugf("Uploading %s", uploadPath)
- res, err := d.c.makeRequest("POST", uploadPath, nil, nil)
+ res, err := d.c.makeRequest(context.TODO(), "POST", uploadPath, nil, nil)
if err != nil {
return types.BlobInfo{}, err
}
@@ -149,7 +150,7 @@ func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobI
digester := digest.Canonical.Digester()
sizeCounter := &sizeCounter{}
tee := io.TeeReader(stream, io.MultiWriter(digester.Hash(), sizeCounter))
- res, err = d.c.makeRequestToResolvedURL("PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, tee, inputInfo.Size, true)
+ res, err = d.c.makeRequestToResolvedURL(context.TODO(), "PATCH", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, tee, inputInfo.Size, true)
if err != nil {
logrus.Debugf("Error uploading layer chunked, response %#v", res)
return types.BlobInfo{}, err
@@ -168,7 +169,7 @@ func (d *dockerImageDestination) PutBlob(stream io.Reader, inputInfo types.BlobI
// TODO: check inputInfo.Digest == computedDigest https://github.com/containers/image/pull/70#discussion_r77646717
locationQuery.Set("digest", computedDigest.String())
uploadLocation.RawQuery = locationQuery.Encode()
- res, err = d.c.makeRequestToResolvedURL("PUT", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, nil, -1, true)
+ res, err = d.c.makeRequestToResolvedURL(context.TODO(), "PUT", uploadLocation.String(), map[string][]string{"Content-Type": {"application/octet-stream"}}, nil, -1, true)
if err != nil {
return types.BlobInfo{}, err
}
@@ -193,7 +194,7 @@ func (d *dockerImageDestination) HasBlob(info types.BlobInfo) (bool, int64, erro
checkPath := fmt.Sprintf(blobsPath, reference.Path(d.ref.ref), info.Digest.String())
logrus.Debugf("Checking %s", checkPath)
- res, err := d.c.makeRequest("HEAD", checkPath, nil, nil)
+ res, err := d.c.makeRequest(context.TODO(), "HEAD", checkPath, nil, nil)
if err != nil {
return false, -1, err
}
@@ -239,7 +240,7 @@ func (d *dockerImageDestination) PutManifest(m []byte) error {
if mimeType != "" {
headers["Content-Type"] = []string{mimeType}
}
- res, err := d.c.makeRequest("PUT", path, headers, bytes.NewReader(m))
+ res, err := d.c.makeRequest(context.TODO(), "PUT", path, headers, bytes.NewReader(m))
if err != nil {
return err
}
@@ -275,7 +276,7 @@ func (d *dockerImageDestination) PutSignatures(signatures [][]byte) error {
if len(signatures) == 0 {
return nil
}
- if err := d.c.detectProperties(); err != nil {
+ if err := d.c.detectProperties(context.TODO()); err != nil {
return err
}
switch {
@@ -396,7 +397,7 @@ func (d *dockerImageDestination) putSignaturesToAPIExtension(signatures [][]byte
// always adds signatures. Eventually we should also allow removing signatures,
// but the X-Registry-Supports-Signatures API extension does not support that yet.
- existingSignatures, err := d.c.getExtensionsSignatures(d.ref, d.manifestDigest)
+ existingSignatures, err := d.c.getExtensionsSignatures(context.TODO(), d.ref, d.manifestDigest)
if err != nil {
return err
}
@@ -438,7 +439,7 @@ sigExists:
}
path := fmt.Sprintf(extensionsSignaturePath, reference.Path(d.ref.ref), d.manifestDigest.String())
- res, err := d.c.makeRequest("PUT", path, nil, bytes.NewReader(body))
+ res, err := d.c.makeRequest(context.TODO(), "PUT", path, nil, bytes.NewReader(body))
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/docker/docker_image_src.go b/vendor/github.com/containers/image/docker/docker_image_src.go
index ebc5cfab..88607210 100644
--- a/vendor/github.com/containers/image/docker/docker_image_src.go
+++ b/vendor/github.com/containers/image/docker/docker_image_src.go
@@ -1,6 +1,7 @@
package docker
import (
+ "context"
"fmt"
"io"
"io/ioutil"
@@ -10,13 +11,13 @@ import (
"os"
"strconv"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
"github.com/docker/distribution/registry/client"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
type dockerImageSource struct {
@@ -85,18 +86,18 @@ func simplifyContentType(contentType string) string {
// GetManifest returns the image's manifest along with its MIME type (which may be empty when it can't be determined but the manifest is available).
// It may use a remote (= slow) service.
func (s *dockerImageSource) GetManifest() ([]byte, string, error) {
- err := s.ensureManifestIsLoaded()
+ err := s.ensureManifestIsLoaded(context.TODO())
if err != nil {
return nil, "", err
}
return s.cachedManifest, s.cachedManifestMIMEType, nil
}
-func (s *dockerImageSource) fetchManifest(tagOrDigest string) ([]byte, string, error) {
+func (s *dockerImageSource) fetchManifest(ctx context.Context, tagOrDigest string) ([]byte, string, error) {
path := fmt.Sprintf(manifestPath, reference.Path(s.ref.ref), tagOrDigest)
headers := make(map[string][]string)
headers["Accept"] = s.requestedManifestMIMETypes
- res, err := s.c.makeRequest("GET", path, headers, nil)
+ res, err := s.c.makeRequest(ctx, "GET", path, headers, nil)
if err != nil {
return nil, "", err
}
@@ -114,7 +115,7 @@ func (s *dockerImageSource) fetchManifest(tagOrDigest string) ([]byte, string, e
// GetTargetManifest returns an image's manifest given a digest.
// This is mainly used to retrieve a single image's manifest out of a manifest list.
func (s *dockerImageSource) GetTargetManifest(digest digest.Digest) ([]byte, string, error) {
- return s.fetchManifest(digest.String())
+ return s.fetchManifest(context.TODO(), digest.String())
}
// ensureManifestIsLoaded sets s.cachedManifest and s.cachedManifestMIMEType
@@ -124,7 +125,7 @@ func (s *dockerImageSource) GetTargetManifest(digest digest.Digest) ([]byte, str
// we need to ensure that the digest of the manifest returned by GetManifest
// and used by GetSignatures are consistent, otherwise we would get spurious
// signature verification failures when pulling while a tag is being updated.
-func (s *dockerImageSource) ensureManifestIsLoaded() error {
+func (s *dockerImageSource) ensureManifestIsLoaded(ctx context.Context) error {
if s.cachedManifest != nil {
return nil
}
@@ -134,7 +135,7 @@ func (s *dockerImageSource) ensureManifestIsLoaded() error {
return err
}
- manblob, mt, err := s.fetchManifest(reference)
+ manblob, mt, err := s.fetchManifest(ctx, reference)
if err != nil {
return err
}
@@ -150,7 +151,7 @@ func (s *dockerImageSource) getExternalBlob(urls []string) (io.ReadCloser, int64
err error
)
for _, url := range urls {
- resp, err = s.c.makeRequestToResolvedURL("GET", url, nil, nil, -1, false)
+ resp, err = s.c.makeRequestToResolvedURL(context.TODO(), "GET", url, nil, nil, -1, false)
if err == nil {
if resp.StatusCode != http.StatusOK {
err = errors.Errorf("error fetching external blob from %q: %d", url, resp.StatusCode)
@@ -181,7 +182,7 @@ func (s *dockerImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64,
path := fmt.Sprintf(blobsPath, reference.Path(s.ref.ref), info.Digest.String())
logrus.Debugf("Downloading %s", path)
- res, err := s.c.makeRequest("GET", path, nil, nil)
+ res, err := s.c.makeRequest(context.TODO(), "GET", path, nil, nil)
if err != nil {
return nil, 0, err
}
@@ -192,27 +193,38 @@ func (s *dockerImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64,
return res.Body, getBlobSize(res), nil
}
-func (s *dockerImageSource) GetSignatures() ([][]byte, error) {
- if err := s.c.detectProperties(); err != nil {
+func (s *dockerImageSource) GetSignatures(ctx context.Context) ([][]byte, error) {
+ if err := s.c.detectProperties(ctx); err != nil {
return nil, err
}
switch {
case s.c.signatureBase != nil:
- return s.getSignaturesFromLookaside()
+ return s.getSignaturesFromLookaside(ctx)
case s.c.supportsSignatures:
- return s.getSignaturesFromAPIExtension()
+ return s.getSignaturesFromAPIExtension(ctx)
default:
return [][]byte{}, nil
}
}
+// manifestDigest returns a digest of the manifest, either from the supplied reference or from a fetched manifest.
+func (s *dockerImageSource) manifestDigest(ctx context.Context) (digest.Digest, error) {
+ if digested, ok := s.ref.ref.(reference.Digested); ok {
+ d := digested.Digest()
+ if d.Algorithm() == digest.Canonical {
+ return d, nil
+ }
+ }
+ if err := s.ensureManifestIsLoaded(ctx); err != nil {
+ return "", err
+ }
+ return manifest.Digest(s.cachedManifest)
+}
+
// getSignaturesFromLookaside implements GetSignatures() from the lookaside location configured in s.c.signatureBase,
// which is not nil.
-func (s *dockerImageSource) getSignaturesFromLookaside() ([][]byte, error) {
- if err := s.ensureManifestIsLoaded(); err != nil {
- return nil, err
- }
- manifestDigest, err := manifest.Digest(s.cachedManifest)
+func (s *dockerImageSource) getSignaturesFromLookaside(ctx context.Context) ([][]byte, error) {
+ manifestDigest, err := s.manifestDigest(ctx)
if err != nil {
return nil, err
}
@@ -224,7 +236,7 @@ func (s *dockerImageSource) getSignaturesFromLookaside() ([][]byte, error) {
if url == nil {
return nil, errors.Errorf("Internal error: signatureStorageURL with non-nil base returned nil")
}
- signature, missing, err := s.getOneSignature(url)
+ signature, missing, err := s.getOneSignature(ctx, url)
if err != nil {
return nil, err
}
@@ -239,7 +251,7 @@ func (s *dockerImageSource) getSignaturesFromLookaside() ([][]byte, error) {
// getOneSignature downloads one signature from url.
// If it successfully determines that the signature does not exist, returns with missing set to true and error set to nil.
// NOTE: Keep this in sync with docs/signature-protocols.md!
-func (s *dockerImageSource) getOneSignature(url *url.URL) (signature []byte, missing bool, err error) {
+func (s *dockerImageSource) getOneSignature(ctx context.Context, url *url.URL) (signature []byte, missing bool, err error) {
switch url.Scheme {
case "file":
logrus.Debugf("Reading %s", url.Path)
@@ -254,7 +266,12 @@ func (s *dockerImageSource) getOneSignature(url *url.URL) (signature []byte, mis
case "http", "https":
logrus.Debugf("GET %s", url)
- res, err := s.c.client.Get(url.String())
+ req, err := http.NewRequest("GET", url.String(), nil)
+ if err != nil {
+ return nil, false, err
+ }
+ req = req.WithContext(ctx)
+ res, err := s.c.client.Do(req)
if err != nil {
return nil, false, err
}
@@ -276,16 +293,13 @@ func (s *dockerImageSource) getOneSignature(url *url.URL) (signature []byte, mis
}
// getSignaturesFromAPIExtension implements GetSignatures() using the X-Registry-Supports-Signatures API extension.
-func (s *dockerImageSource) getSignaturesFromAPIExtension() ([][]byte, error) {
- if err := s.ensureManifestIsLoaded(); err != nil {
- return nil, err
- }
- manifestDigest, err := manifest.Digest(s.cachedManifest)
+func (s *dockerImageSource) getSignaturesFromAPIExtension(ctx context.Context) ([][]byte, error) {
+ manifestDigest, err := s.manifestDigest(ctx)
if err != nil {
return nil, err
}
- parsedBody, err := s.c.getExtensionsSignatures(s.ref, manifestDigest)
+ parsedBody, err := s.c.getExtensionsSignatures(ctx, s.ref, manifestDigest)
if err != nil {
return nil, err
}
@@ -316,7 +330,7 @@ func deleteImage(ctx *types.SystemContext, ref dockerReference) error {
return err
}
getPath := fmt.Sprintf(manifestPath, reference.Path(ref.ref), refTail)
- get, err := c.makeRequest("GET", getPath, headers, nil)
+ get, err := c.makeRequest(context.TODO(), "GET", getPath, headers, nil)
if err != nil {
return err
}
@@ -338,7 +352,7 @@ func deleteImage(ctx *types.SystemContext, ref dockerReference) error {
// When retrieving the digest from a registry >= 2.3 use the following header:
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
- delete, err := c.makeRequest("DELETE", deletePath, headers, nil)
+ delete, err := c.makeRequest(context.TODO(), "DELETE", deletePath, headers, nil)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/docker/lookaside.go b/vendor/github.com/containers/image/docker/lookaside.go
index c6dca5e4..18e7733b 100644
--- a/vendor/github.com/containers/image/docker/lookaside.go
+++ b/vendor/github.com/containers/image/docker/lookaside.go
@@ -9,12 +9,12 @@ import (
"path/filepath"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/ghodss/yaml"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// systemRegistriesDirPath is the path to registries.d, used for locating lookaside Docker signature storage.
diff --git a/vendor/github.com/containers/image/docker/tarfile/dest.go b/vendor/github.com/containers/image/docker/tarfile/dest.go
index d0b78d63..72c85c70 100644
--- a/vendor/github.com/containers/image/docker/tarfile/dest.go
+++ b/vendor/github.com/containers/image/docker/tarfile/dest.go
@@ -10,12 +10,12 @@ import (
"os"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
const temporaryDirectoryForBigFiles = "/var/tmp" // Do not use the system default of os.TempDir(), usually /tmp, because with systemd it could be a tmpfs.
diff --git a/vendor/github.com/containers/image/docker/tarfile/src.go b/vendor/github.com/containers/image/docker/tarfile/src.go
index a526f3ef..f77cb713 100644
--- a/vendor/github.com/containers/image/docker/tarfile/src.go
+++ b/vendor/github.com/containers/image/docker/tarfile/src.go
@@ -3,6 +3,7 @@ package tarfile
import (
"archive/tar"
"bytes"
+ "context"
"encoding/json"
"io"
"io/ioutil"
@@ -354,6 +355,6 @@ func (s *Source) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {
}
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
-func (s *Source) GetSignatures() ([][]byte, error) {
+func (s *Source) GetSignatures(ctx context.Context) ([][]byte, error) {
return [][]byte{}, nil
}
diff --git a/vendor/github.com/containers/image/image/docker_schema2.go b/vendor/github.com/containers/image/image/docker_schema2.go
index 9c242cf0..8cc3c495 100644
--- a/vendor/github.com/containers/image/image/docker_schema2.go
+++ b/vendor/github.com/containers/image/image/docker_schema2.go
@@ -8,13 +8,13 @@ import (
"io/ioutil"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
"github.com/opencontainers/go-digest"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// gzippedEmptyLayer is a gzip-compressed version of an empty tar file (1024 NULL bytes)
diff --git a/vendor/github.com/containers/image/image/memory.go b/vendor/github.com/containers/image/image/memory.go
index 304274d1..62995f61 100644
--- a/vendor/github.com/containers/image/image/memory.go
+++ b/vendor/github.com/containers/image/image/memory.go
@@ -1,6 +1,8 @@
package image
import (
+ "context"
+
"github.com/pkg/errors"
"github.com/containers/image/types"
@@ -54,7 +56,7 @@ func (i *memoryImage) Manifest() ([]byte, string, error) {
}
// Signatures is like ImageSource.GetSignatures, but the result is cached; it is OK to call this however often you need.
-func (i *memoryImage) Signatures() ([][]byte, error) {
+func (i *memoryImage) Signatures(ctx context.Context) ([][]byte, error) {
// Modifying an image invalidates signatures; a caller asking the updated image for signatures
// is probably confused.
return nil, errors.New("Internal error: Image.Signatures() is not supported for images modified in memory")
diff --git a/vendor/github.com/containers/image/image/unparsed.go b/vendor/github.com/containers/image/image/unparsed.go
index 446652e7..483cfd04 100644
--- a/vendor/github.com/containers/image/image/unparsed.go
+++ b/vendor/github.com/containers/image/image/unparsed.go
@@ -1,6 +1,8 @@
package image
import (
+ "context"
+
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
@@ -71,9 +73,9 @@ func (i *UnparsedImage) Manifest() ([]byte, string, error) {
}
// Signatures is like ImageSource.GetSignatures, but the result is cached; it is OK to call this however often you need.
-func (i *UnparsedImage) Signatures() ([][]byte, error) {
+func (i *UnparsedImage) Signatures(ctx context.Context) ([][]byte, error) {
if i.cachedSignatures == nil {
- sigs, err := i.src.GetSignatures()
+ sigs, err := i.src.GetSignatures(ctx)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/oci/layout/oci_src.go b/vendor/github.com/containers/image/oci/layout/oci_src.go
index 42556eea..99b9f208 100644
--- a/vendor/github.com/containers/image/oci/layout/oci_src.go
+++ b/vendor/github.com/containers/image/oci/layout/oci_src.go
@@ -1,6 +1,7 @@
package layout
import (
+ "context"
"io"
"io/ioutil"
"os"
@@ -85,6 +86,6 @@ func (s *ociImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, err
return r, fi.Size(), nil
}
-func (s *ociImageSource) GetSignatures() ([][]byte, error) {
+func (s *ociImageSource) GetSignatures(context.Context) ([][]byte, error) {
return [][]byte{}, nil
}
diff --git a/vendor/github.com/containers/image/openshift/openshift.go b/vendor/github.com/containers/image/openshift/openshift.go
index 88659212..19ad2537 100644
--- a/vendor/github.com/containers/image/openshift/openshift.go
+++ b/vendor/github.com/containers/image/openshift/openshift.go
@@ -2,6 +2,7 @@ package openshift
import (
"bytes"
+ "context"
"crypto/rand"
"encoding/json"
"fmt"
@@ -11,7 +12,6 @@ import (
"net/url"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker"
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
@@ -19,6 +19,7 @@ import (
"github.com/containers/image/version"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// openshiftClient is configuration for dealing with a single image stream, for reading or writing.
@@ -70,7 +71,7 @@ func newOpenshiftClient(ref openshiftReference) (*openshiftClient, error) {
}
// doRequest performs a correctly authenticated request to a specified path, and returns response body or an error object.
-func (c *openshiftClient) doRequest(method, path string, requestBody []byte) ([]byte, error) {
+func (c *openshiftClient) doRequest(ctx context.Context, method, path string, requestBody []byte) ([]byte, error) {
url := *c.baseURL
url.Path = path
var requestBodyReader io.Reader
@@ -82,6 +83,7 @@ func (c *openshiftClient) doRequest(method, path string, requestBody []byte) ([]
if err != nil {
return nil, err
}
+ req = req.WithContext(ctx)
if len(c.bearerToken) != 0 {
req.Header.Set("Authorization", "Bearer "+c.bearerToken)
@@ -132,10 +134,10 @@ func (c *openshiftClient) doRequest(method, path string, requestBody []byte) ([]
}
// getImage loads the specified image object.
-func (c *openshiftClient) getImage(imageStreamImageName string) (*image, error) {
+func (c *openshiftClient) getImage(ctx context.Context, imageStreamImageName string) (*image, error) {
// FIXME: validate components per validation.IsValidPathSegmentName?
path := fmt.Sprintf("/oapi/v1/namespaces/%s/imagestreamimages/%s@%s", c.ref.namespace, c.ref.stream, imageStreamImageName)
- body, err := c.doRequest("GET", path, nil)
+ body, err := c.doRequest(ctx, "GET", path, nil)
if err != nil {
return nil, err
}
@@ -203,7 +205,7 @@ func (s *openshiftImageSource) Close() error {
}
func (s *openshiftImageSource) GetTargetManifest(digest digest.Digest) ([]byte, string, error) {
- if err := s.ensureImageIsResolved(); err != nil {
+ if err := s.ensureImageIsResolved(context.TODO()); err != nil {
return nil, "", err
}
return s.docker.GetTargetManifest(digest)
@@ -212,7 +214,7 @@ func (s *openshiftImageSource) GetTargetManifest(digest digest.Digest) ([]byte,
// GetManifest returns the image's manifest along with its MIME type (which may be empty when it can't be determined but the manifest is available).
// It may use a remote (= slow) service.
func (s *openshiftImageSource) GetManifest() ([]byte, string, error) {
- if err := s.ensureImageIsResolved(); err != nil {
+ if err := s.ensureImageIsResolved(context.TODO()); err != nil {
return nil, "", err
}
return s.docker.GetManifest()
@@ -220,18 +222,18 @@ func (s *openshiftImageSource) GetManifest() ([]byte, string, error) {
// GetBlob returns a stream for the specified blob, and the blob’s size (or -1 if unknown).
func (s *openshiftImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {
- if err := s.ensureImageIsResolved(); err != nil {
+ if err := s.ensureImageIsResolved(context.TODO()); err != nil {
return nil, 0, err
}
return s.docker.GetBlob(info)
}
-func (s *openshiftImageSource) GetSignatures() ([][]byte, error) {
- if err := s.ensureImageIsResolved(); err != nil {
+func (s *openshiftImageSource) GetSignatures(ctx context.Context) ([][]byte, error) {
+ if err := s.ensureImageIsResolved(ctx); err != nil {
return nil, err
}
- image, err := s.client.getImage(s.imageStreamImageName)
+ image, err := s.client.getImage(ctx, s.imageStreamImageName)
if err != nil {
return nil, err
}
@@ -245,14 +247,14 @@ func (s *openshiftImageSource) GetSignatures() ([][]byte, error) {
}
// ensureImageIsResolved sets up s.docker and s.imageStreamImageName
-func (s *openshiftImageSource) ensureImageIsResolved() error {
+func (s *openshiftImageSource) ensureImageIsResolved(ctx context.Context) error {
if s.docker != nil {
return nil
}
// FIXME: validate components per validation.IsValidPathSegmentName?
path := fmt.Sprintf("/oapi/v1/namespaces/%s/imagestreams/%s", s.client.ref.namespace, s.client.ref.stream)
- body, err := s.client.doRequest("GET", path, nil)
+ body, err := s.client.doRequest(ctx, "GET", path, nil)
if err != nil {
return err
}
@@ -410,7 +412,7 @@ func (d *openshiftImageDestination) PutSignatures(signatures [][]byte) error {
return nil // No need to even read the old state.
}
- image, err := d.client.getImage(d.imageStreamImageName)
+ image, err := d.client.getImage(context.TODO(), d.imageStreamImageName)
if err != nil {
return err
}
@@ -451,7 +453,7 @@ sigExists:
Content: newSig,
}
body, err := json.Marshal(sig)
- _, err = d.client.doRequest("POST", "/oapi/v1/imagesignatures", body)
+ _, err = d.client.doRequest(context.TODO(), "POST", "/oapi/v1/imagesignatures", body)
if err != nil {
return err
}
diff --git a/vendor/github.com/containers/image/pkg/compression/compression.go b/vendor/github.com/containers/image/pkg/compression/compression.go
index c114ded6..c19d962e 100644
--- a/vendor/github.com/containers/image/pkg/compression/compression.go
+++ b/vendor/github.com/containers/image/pkg/compression/compression.go
@@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// DecompressorFunc returns the decompressed stream, given a compressed stream.
diff --git a/vendor/github.com/containers/image/signature/mechanism_openpgp.go b/vendor/github.com/containers/image/signature/mechanism_openpgp.go
index e383bde3..eccd610c 100644
--- a/vendor/github.com/containers/image/signature/mechanism_openpgp.go
+++ b/vendor/github.com/containers/image/signature/mechanism_openpgp.go
@@ -132,11 +132,17 @@ func (m *openpgpSigningMechanism) Verify(unverifiedSignature []byte) (contents [
if md.SignedBy == nil {
return nil, "", InvalidSignatureError{msg: fmt.Sprintf("Invalid GPG signature: %#v", md.Signature)}
}
- if md.Signature.SigLifetimeSecs != nil {
- expiry := md.Signature.CreationTime.Add(time.Duration(*md.Signature.SigLifetimeSecs) * time.Second)
- if time.Now().After(expiry) {
- return nil, "", InvalidSignatureError{msg: fmt.Sprintf("Signature expired on %s", expiry)}
+ if md.Signature != nil {
+ if md.Signature.SigLifetimeSecs != nil {
+ expiry := md.Signature.CreationTime.Add(time.Duration(*md.Signature.SigLifetimeSecs) * time.Second)
+ if time.Now().After(expiry) {
+ return nil, "", InvalidSignatureError{msg: fmt.Sprintf("Signature expired on %s", expiry)}
+ }
}
+ } else if md.SignatureV3 == nil {
+ // Coverage: If md.SignedBy != nil, the final md.UnverifiedBody.Read() either sets one of md.Signature or md.SignatureV3,
+ // or sets md.SignatureError.
+ return nil, "", InvalidSignatureError{msg: "Unexpected openpgp.MessageDetails: neither Signature nor SignatureV3 is set"}
}
// Uppercase the fingerprint to be compatible with gpgme
diff --git a/vendor/github.com/containers/image/signature/policy_eval.go b/vendor/github.com/containers/image/signature/policy_eval.go
index ba1fcc2a..f818eb09 100644
--- a/vendor/github.com/containers/image/signature/policy_eval.go
+++ b/vendor/github.com/containers/image/signature/policy_eval.go
@@ -6,9 +6,11 @@
package signature
import (
- "github.com/Sirupsen/logrus"
+ "context"
+
"github.com/containers/image/types"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// PolicyRequirementError is an explanatory text for rejecting a signature or an image.
@@ -188,7 +190,8 @@ func (pc *PolicyContext) GetSignaturesWithAcceptedAuthor(image types.UnparsedIma
reqs := pc.requirementsForImageRef(image.Reference())
// FIXME: rename Signatures to UnverifiedSignatures
- unverifiedSignatures, err := image.Signatures()
+ // FIXME: pass context.Context
+ unverifiedSignatures, err := image.Signatures(context.TODO())
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/image/signature/policy_eval_baselayer.go b/vendor/github.com/containers/image/signature/policy_eval_baselayer.go
index dec84c93..89895801 100644
--- a/vendor/github.com/containers/image/signature/policy_eval_baselayer.go
+++ b/vendor/github.com/containers/image/signature/policy_eval_baselayer.go
@@ -3,8 +3,8 @@
package signature
import (
- "github.com/Sirupsen/logrus"
"github.com/containers/image/types"
+ "github.com/sirupsen/logrus"
)
func (pr *prSignedBaseLayer) isSignatureAuthorAccepted(image types.UnparsedImage, sig []byte) (signatureAcceptanceResult, *Signature, error) {
diff --git a/vendor/github.com/containers/image/signature/policy_eval_signedby.go b/vendor/github.com/containers/image/signature/policy_eval_signedby.go
index 285b8630..56665124 100644
--- a/vendor/github.com/containers/image/signature/policy_eval_signedby.go
+++ b/vendor/github.com/containers/image/signature/policy_eval_signedby.go
@@ -3,6 +3,7 @@
package signature
import (
+ "context"
"fmt"
"io/ioutil"
"strings"
@@ -90,7 +91,8 @@ func (pr *prSignedBy) isSignatureAuthorAccepted(image types.UnparsedImage, sig [
}
func (pr *prSignedBy) isRunningImageAllowed(image types.UnparsedImage) (bool, error) {
- sigs, err := image.Signatures()
+ // FIXME: pass context.Context
+ sigs, err := image.Signatures(context.TODO())
if err != nil {
return false, err
}
diff --git a/vendor/github.com/containers/image/storage/storage_image.go b/vendor/github.com/containers/image/storage/storage_image.go
index 8b708bdf..08fa71b5 100644
--- a/vendor/github.com/containers/image/storage/storage_image.go
+++ b/vendor/github.com/containers/image/storage/storage_image.go
@@ -2,6 +2,7 @@ package storage
import (
"bytes"
+ "context"
"encoding/json"
"io"
"io/ioutil"
@@ -9,7 +10,6 @@ import (
"github.com/pkg/errors"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/image"
"github.com/containers/image/manifest"
"github.com/containers/image/types"
@@ -17,6 +17,7 @@ import (
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/ioutils"
ddigest "github.com/opencontainers/go-digest"
+ "github.com/sirupsen/logrus"
)
var (
@@ -537,7 +538,7 @@ func (s *storageImageSource) GetTargetManifest(digest ddigest.Digest) (manifestB
return nil, "", ErrNoManifestLists
}
-func (s *storageImageSource) GetSignatures() (signatures [][]byte, err error) {
+func (s *storageImageSource) GetSignatures(ctx context.Context) (signatures [][]byte, err error) {
var offset int
signature, err := s.imageRef.transport.store.ImageBigData(s.ID, "signatures")
if err != nil {
diff --git a/vendor/github.com/containers/image/storage/storage_reference.go b/vendor/github.com/containers/image/storage/storage_reference.go
index 9aee75be..674330b4 100644
--- a/vendor/github.com/containers/image/storage/storage_reference.go
+++ b/vendor/github.com/containers/image/storage/storage_reference.go
@@ -3,11 +3,11 @@ package storage
import (
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/storage"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// A storageReference holds an arbitrary name and/or an ID, which is a 32-byte
diff --git a/vendor/github.com/containers/image/storage/storage_transport.go b/vendor/github.com/containers/image/storage/storage_transport.go
index 336dd814..1a0ebd04 100644
--- a/vendor/github.com/containers/image/storage/storage_transport.go
+++ b/vendor/github.com/containers/image/storage/storage_transport.go
@@ -6,7 +6,6 @@ import (
"github.com/pkg/errors"
- "github.com/Sirupsen/logrus"
"github.com/containers/image/docker/reference"
"github.com/containers/image/transports"
"github.com/containers/image/types"
@@ -14,6 +13,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/opencontainers/go-digest"
ddigest "github.com/opencontainers/go-digest"
+ "github.com/sirupsen/logrus"
)
func init() {
diff --git a/vendor/github.com/containers/image/transports/transports.go b/vendor/github.com/containers/image/transports/transports.go
index c932806d..687d0a44 100644
--- a/vendor/github.com/containers/image/transports/transports.go
+++ b/vendor/github.com/containers/image/transports/transports.go
@@ -71,13 +71,19 @@ func ImageName(ref types.ImageReference) string {
return ref.Transport().Name() + ":" + ref.StringWithinTransport()
}
-// ListNames returns a list of transport names
+// ListNames returns a list of non deprecated transport names.
+// Deprecated transports can be used, but are not presented to users.
func ListNames() []string {
kt.mu.Lock()
defer kt.mu.Unlock()
+ deprecated := map[string]bool{
+ "atomic": true,
+ }
var names []string
for _, transport := range kt.transports {
- names = append(names, transport.Name())
+ if !deprecated[transport.Name()] {
+ names = append(names, transport.Name())
+ }
}
sort.Strings(names)
return names
diff --git a/vendor/github.com/containers/image/types/types.go b/vendor/github.com/containers/image/types/types.go
index 0788904c..6bcd392f 100644
--- a/vendor/github.com/containers/image/types/types.go
+++ b/vendor/github.com/containers/image/types/types.go
@@ -1,6 +1,7 @@
package types
import (
+ "context"
"io"
"time"
@@ -121,7 +122,7 @@ type ImageSource interface {
// The Digest field in BlobInfo is guaranteed to be provided; Size may be -1.
GetBlob(BlobInfo) (io.ReadCloser, int64, error)
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
- GetSignatures() ([][]byte, error)
+ GetSignatures(context.Context) ([][]byte, error)
}
// ImageDestination is a service, possibly remote (= slow), to store components of a single image.
@@ -204,7 +205,7 @@ type UnparsedImage interface {
// Manifest is like ImageSource.GetManifest, but the result is cached; it is OK to call this however often you need.
Manifest() ([]byte, string, error)
// Signatures is like ImageSource.GetSignatures, but the result is cached; it is OK to call this however often you need.
- Signatures() ([][]byte, error)
+ Signatures(ctx context.Context) ([][]byte, error)
}
// Image is the primary API for inspecting properties of images.
diff --git a/vendor/github.com/containers/image/vendor.conf b/vendor/github.com/containers/image/vendor.conf
index d0fb1aad..d4725e12 100644
--- a/vendor/github.com/containers/image/vendor.conf
+++ b/vendor/github.com/containers/image/vendor.conf
@@ -1,5 +1,5 @@
-github.com/Sirupsen/logrus 7f4b1adc791766938c29457bed0703fb9134421a
-github.com/containers/storage 105f7c77aef0c797429e41552743bf5b03b63263
+github.com/sirupsen/logrus v1.0.0
+github.com/containers/storage 5d8c2f87387fa5be9fa526ae39fbd79b8bdf27be
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
github.com/docker/distribution df5327f76fb6468b84a87771e361762b8be23fdb
github.com/docker/docker 75843d36aa5c3eaade50da005f9e0ff2602f3d5e
diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
index 4742892a..2e7f1e65 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go
@@ -34,7 +34,7 @@ import (
"sync"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/vbatts/tar-split/tar/storage"
"github.com/containers/storage/drivers"
diff --git a/vendor/github.com/containers/storage/drivers/aufs/mount.go b/vendor/github.com/containers/storage/drivers/aufs/mount.go
index da1e892f..8314f142 100644
--- a/vendor/github.com/containers/storage/drivers/aufs/mount.go
+++ b/vendor/github.com/containers/storage/drivers/aufs/mount.go
@@ -6,7 +6,7 @@ import (
"os/exec"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// Unmount the target specified.
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
index 1304f8a7..2608c49f 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
@@ -18,7 +18,7 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/devicemapper"
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/driver.go b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
index 3b584c06..87a427a8 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/driver.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/driver.go
@@ -9,7 +9,7 @@ import (
"path"
"strconv"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/devicemapper"
diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go
index e04772d0..c16fc33e 100644
--- a/vendor/github.com/containers/storage/drivers/driver.go
+++ b/vendor/github.com/containers/storage/drivers/driver.go
@@ -6,8 +6,8 @@ import (
"path/filepath"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/vbatts/tar-split/tar/storage"
"github.com/containers/storage/pkg/archive"
diff --git a/vendor/github.com/containers/storage/drivers/driver_solaris.go b/vendor/github.com/containers/storage/drivers/driver_solaris.go
index d8dc63f4..cfbc26e8 100644
--- a/vendor/github.com/containers/storage/drivers/driver_solaris.go
+++ b/vendor/github.com/containers/storage/drivers/driver_solaris.go
@@ -19,8 +19,8 @@ import (
"path/filepath"
"unsafe"
- log "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
)
const (
diff --git a/vendor/github.com/containers/storage/drivers/fsdiff.go b/vendor/github.com/containers/storage/drivers/fsdiff.go
index 0f5b4fe4..69310729 100644
--- a/vendor/github.com/containers/storage/drivers/fsdiff.go
+++ b/vendor/github.com/containers/storage/drivers/fsdiff.go
@@ -3,7 +3,7 @@ package graphdriver
import (
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index af659b0f..f3cb27e2 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -14,7 +14,7 @@ import (
"strings"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
diff --git a/vendor/github.com/containers/storage/drivers/overlay/randomid.go b/vendor/github.com/containers/storage/drivers/overlay/randomid.go
index 983ed76b..975b3a50 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/randomid.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/randomid.go
@@ -11,7 +11,7 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// generateID creates a new random string identifier with the given length
diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go
index d87fb197..7ab36513 100644
--- a/vendor/github.com/containers/storage/drivers/windows/windows.go
+++ b/vendor/github.com/containers/storage/drivers/windows/windows.go
@@ -22,7 +22,6 @@ import (
"github.com/Microsoft/go-winio/archive/tar"
"github.com/Microsoft/go-winio/backuptar"
"github.com/Microsoft/hcsshim"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
@@ -30,6 +29,7 @@ import (
"github.com/containers/storage/pkg/longpath"
"github.com/containers/storage/pkg/reexec"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
"github.com/vbatts/tar-split/tar/storage"
)
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
index 62cc96b2..c9860ec2 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go
@@ -13,7 +13,6 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
@@ -21,6 +20,7 @@ import (
zfs "github.com/mistifyio/go-zfs"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
type zfsOptions struct {
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
index 3ec1837c..ade71b15 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_freebsd.go
@@ -5,9 +5,9 @@ import (
"strings"
"syscall"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func checkRootdirFs(rootdir string) error {
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
index 392adae2..92b38756 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_linux.go
@@ -4,9 +4,9 @@ import (
"fmt"
"syscall"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func checkRootdirFs(rootdir string) error {
diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go b/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go
index 25e89044..ca595638 100644
--- a/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go
+++ b/vendor/github.com/containers/storage/drivers/zfs/zfs_solaris.go
@@ -20,9 +20,9 @@ import (
"strings"
"unsafe"
- log "github.com/Sirupsen/logrus"
"github.com/containers/storage/drivers"
"github.com/pkg/errors"
+ log "github.com/sirupsen/logrus"
)
func checkRootdirFs(rootdir string) error {
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 1b788301..a4071d71 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -17,13 +17,13 @@ import (
"strings"
"syscall"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/pools"
"github.com/containers/storage/pkg/promise"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
)
type (
diff --git a/vendor/github.com/containers/storage/pkg/archive/changes.go b/vendor/github.com/containers/storage/pkg/archive/changes.go
index 234b0a68..488e1298 100644
--- a/vendor/github.com/containers/storage/pkg/archive/changes.go
+++ b/vendor/github.com/containers/storage/pkg/archive/changes.go
@@ -13,10 +13,10 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/pools"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
)
// ChangeType represents the change type.
diff --git a/vendor/github.com/containers/storage/pkg/archive/copy.go b/vendor/github.com/containers/storage/pkg/archive/copy.go
index 05c243d3..c970f422 100644
--- a/vendor/github.com/containers/storage/pkg/archive/copy.go
+++ b/vendor/github.com/containers/storage/pkg/archive/copy.go
@@ -9,8 +9,8 @@ import (
"path/filepath"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
)
// Errors used or returned by this file.
diff --git a/vendor/github.com/containers/storage/pkg/archive/diff.go b/vendor/github.com/containers/storage/pkg/archive/diff.go
index c8d09d32..c7ad4d94 100644
--- a/vendor/github.com/containers/storage/pkg/archive/diff.go
+++ b/vendor/github.com/containers/storage/pkg/archive/diff.go
@@ -10,10 +10,10 @@ import (
"runtime"
"strings"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/pools"
"github.com/containers/storage/pkg/system"
+ "github.com/sirupsen/logrus"
)
// UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be
diff --git a/vendor/github.com/containers/storage/pkg/archive/example_changes.go b/vendor/github.com/containers/storage/pkg/archive/example_changes.go
new file mode 100644
index 00000000..70f9c556
--- /dev/null
+++ b/vendor/github.com/containers/storage/pkg/archive/example_changes.go
@@ -0,0 +1,97 @@
+// +build ignore
+
+// Simple tool to create an archive stream from an old and new directory
+//
+// By default it will stream the comparison of two temporary directories with junk files
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+
+ "github.com/containers/storage/pkg/archive"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ flDebug = flag.Bool("D", false, "debugging output")
+ flNewDir = flag.String("newdir", "", "")
+ flOldDir = flag.String("olddir", "", "")
+ log = logrus.New()
+)
+
+func main() {
+ flag.Usage = func() {
+ fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)")
+ fmt.Printf("%s [OPTIONS]\n", os.Args[0])
+ flag.PrintDefaults()
+ }
+ flag.Parse()
+ log.Out = os.Stderr
+ if (len(os.Getenv("DEBUG")) > 0) || *flDebug {
+ logrus.SetLevel(logrus.DebugLevel)
+ }
+ var newDir, oldDir string
+
+ if len(*flNewDir) == 0 {
+ var err error
+ newDir, err = ioutil.TempDir("", "storage-test-newDir")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(newDir)
+ if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ newDir = *flNewDir
+ }
+
+ if len(*flOldDir) == 0 {
+ oldDir, err := ioutil.TempDir("", "storage-test-oldDir")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(oldDir)
+ } else {
+ oldDir = *flOldDir
+ }
+
+ changes, err := archive.ChangesDirs(newDir, oldDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ a, err := archive.ExportChanges(newDir, changes)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer a.Close()
+
+ i, err := io.Copy(os.Stdout, a)
+ if err != nil && err != io.EOF {
+ log.Fatal(err)
+ }
+ fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i)
+}
+
+func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) {
+ fileData := []byte("fooo")
+ for n := 0; n < numberOfFiles; n++ {
+ fileName := fmt.Sprintf("file-%d", n)
+ if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil {
+ return 0, err
+ }
+ if makeLinks {
+ if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil {
+ return 0, err
+ }
+ }
+ }
+ totalSize := numberOfFiles * len(fileData)
+ return totalSize, nil
+}
diff --git a/vendor/github.com/containers/storage/pkg/devicemapper/devmapper.go b/vendor/github.com/containers/storage/pkg/devicemapper/devmapper.go
index 838b06af..1ed0e861 100644
--- a/vendor/github.com/containers/storage/pkg/devicemapper/devmapper.go
+++ b/vendor/github.com/containers/storage/pkg/devicemapper/devmapper.go
@@ -10,7 +10,7 @@ import (
"syscall"
"unsafe"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// DevmapperLogger defines methods for logging with devicemapper.
diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
index 763d8d27..6f4a6e61 100644
--- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
+++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go
@@ -10,7 +10,7 @@ import (
"strings"
"text/scanner"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// exclusion returns true if the specified pattern is an exclusion
diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go
index d5c3abf5..9e0e97bd 100644
--- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go
+++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils_unix.go
@@ -7,7 +7,7 @@ import (
"io/ioutil"
"os"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// GetTotalUsedFds Returns the number of used File Descriptors by
diff --git a/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go b/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
index f1ede0c1..34c80548 100644
--- a/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
+++ b/vendor/github.com/containers/storage/pkg/loopback/attach_loopback.go
@@ -8,7 +8,7 @@ import (
"os"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
// Loopback related errors
diff --git a/vendor/github.com/containers/storage/pkg/loopback/loopback.go b/vendor/github.com/containers/storage/pkg/loopback/loopback.go
index bc047928..a8ec3c61 100644
--- a/vendor/github.com/containers/storage/pkg/loopback/loopback.go
+++ b/vendor/github.com/containers/storage/pkg/loopback/loopback.go
@@ -7,7 +7,7 @@ import (
"os"
"syscall"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
func getLoopbackBackingFile(file *os.File) (uint64, uint64, error) {
diff --git a/vendor/github.com/containers/storage/pkg/plugins/client.go b/vendor/github.com/containers/storage/pkg/plugins/client.go
index a8865a07..b4c31c05 100644
--- a/vendor/github.com/containers/storage/pkg/plugins/client.go
+++ b/vendor/github.com/containers/storage/pkg/plugins/client.go
@@ -9,10 +9,10 @@ import (
"net/url"
"time"
- "github.com/Sirupsen/logrus"
"github.com/containers/storage/pkg/plugins/transport"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
+ "github.com/sirupsen/logrus"
)
const (
diff --git a/vendor/github.com/containers/storage/pkg/plugins/plugins.go b/vendor/github.com/containers/storage/pkg/plugins/plugins.go
index f6662c4b..e197c3fd 100644
--- a/vendor/github.com/containers/storage/pkg/plugins/plugins.go
+++ b/vendor/github.com/containers/storage/pkg/plugins/plugins.go
@@ -29,8 +29,8 @@ import (
"sync"
"time"
- "github.com/Sirupsen/logrus"
"github.com/docker/go-connections/tlsconfig"
+ "github.com/sirupsen/logrus"
)
var (
diff --git a/vendor/github.com/containers/storage/pkg/system/syscall_windows.go b/vendor/github.com/containers/storage/pkg/system/syscall_windows.go
index f5f2d569..7aaab7e7 100644
--- a/vendor/github.com/containers/storage/pkg/system/syscall_windows.go
+++ b/vendor/github.com/containers/storage/pkg/system/syscall_windows.go
@@ -4,7 +4,7 @@ import (
"syscall"
"unsafe"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var (
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index 43efa940..4b696203 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -2309,7 +2309,7 @@ type tomlConfig struct {
func init() {
DefaultStoreOptions.RunRoot = "/var/run/containers/storage"
DefaultStoreOptions.GraphRoot = "/var/lib/containers/storage"
- DefaultStoreOptions.GraphDriverName = "overlay"
+ DefaultStoreOptions.GraphDriverName = ""
data, err := ioutil.ReadFile(configFile)
if err != nil {
diff --git a/vendor/github.com/containers/storage/vendor.conf b/vendor/github.com/containers/storage/vendor.conf
index 0f3adb02..81fbbadd 100644
--- a/vendor/github.com/containers/storage/vendor.conf
+++ b/vendor/github.com/containers/storage/vendor.conf
@@ -1,9 +1,9 @@
github.com/BurntSushi/toml master
github.com/Microsoft/go-winio 307e919c663683a9000576fdc855acaf9534c165
-github.com/Microsoft/hcsshim 0f615c198a84e0344b4ed49c464d8833d4648dfc
-github.com/Sirupsen/logrus 61e43dc76f7ee59a82bdf3d71033dc12bea4c77d
+github.com/Microsoft/hcsshim a8d9cc56cbce765a7eebdf4792e6ceceeff3edb8
+github.com/sirupsen/logrus v1.0.0
github.com/docker/engine-api 4290f40c056686fcaa5c9caf02eac1dde9315adf
-github.com/docker/go-connections eb315e36415380e7c2fdee175262560ff42359da
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
github.com/go-check/check 20d25e2804050c1cd24a7eea1e7a6447dd0e74ec
github.com/mattn/go-shellwords 753a2322a99f87c0eff284980e77f53041555bc6
diff --git a/vendor/github.com/docker/distribution/README.md b/vendor/github.com/docker/distribution/README.md
index a6e8db0f..99887885 100644
--- a/vendor/github.com/docker/distribution/README.md
+++ b/vendor/github.com/docker/distribution/README.md
@@ -76,8 +76,7 @@ may be the better choice.
For those who have previously deployed their own registry based on the Registry
1.0 implementation and wish to deploy a Registry 2.0 while retaining images,
data migration is required. A tool to assist with migration efforts has been
-created. For more information see [docker/migrator]
-(https://github.com/docker/migrator).
+created. For more information see [docker/migrator](https://github.com/docker/migrator).
## Contribute
diff --git a/vendor/github.com/docker/distribution/blobs.go b/vendor/github.com/docker/distribution/blobs.go
index 79c5fb33..01d30902 100644
--- a/vendor/github.com/docker/distribution/blobs.go
+++ b/vendor/github.com/docker/distribution/blobs.go
@@ -152,7 +152,7 @@ type BlobProvider interface {
// BlobServer can serve blobs via http.
type BlobServer interface {
- // ServeBlob attempts to serve the blob, identifed by dgst, via http. The
+ // ServeBlob attempts to serve the blob, identified by dgst, via http. The
// service may decide to redirect the client elsewhere or serve the data
// directly.
//
diff --git a/vendor/github.com/docker/distribution/context/doc.go b/vendor/github.com/docker/distribution/context/doc.go
index 3b4ab888..9b623074 100644
--- a/vendor/github.com/docker/distribution/context/doc.go
+++ b/vendor/github.com/docker/distribution/context/doc.go
@@ -64,7 +64,7 @@
// Note that this only affects the new context, the previous context, with the
// version field, can be used independently. Put another way, the new logger,
// added to the request context, is unique to that context and can have
-// request scoped varaibles.
+// request scoped variables.
//
// HTTP Requests
//
diff --git a/vendor/github.com/docker/distribution/context/http.go b/vendor/github.com/docker/distribution/context/http.go
index 7fe9b8ab..7d65c852 100644
--- a/vendor/github.com/docker/distribution/context/http.go
+++ b/vendor/github.com/docker/distribution/context/http.go
@@ -8,9 +8,9 @@ import (
"sync"
"time"
- log "github.com/Sirupsen/logrus"
"github.com/docker/distribution/uuid"
"github.com/gorilla/mux"
+ log "github.com/sirupsen/logrus"
)
// Common errors used with this package.
diff --git a/vendor/github.com/docker/distribution/context/logger.go b/vendor/github.com/docker/distribution/context/logger.go
index fbb6a051..86c5964e 100644
--- a/vendor/github.com/docker/distribution/context/logger.go
+++ b/vendor/github.com/docker/distribution/context/logger.go
@@ -3,7 +3,7 @@ package context
import (
"fmt"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
"runtime"
)
diff --git a/vendor/github.com/docker/distribution/errors.go b/vendor/github.com/docker/distribution/errors.go
index 2062a06f..020d3325 100644
--- a/vendor/github.com/docker/distribution/errors.go
+++ b/vendor/github.com/docker/distribution/errors.go
@@ -77,7 +77,7 @@ func (err ErrManifestUnknownRevision) Error() string {
type ErrManifestUnverified struct{}
func (ErrManifestUnverified) Error() string {
- return fmt.Sprintf("unverified manifest")
+ return "unverified manifest"
}
// ErrManifestVerification provides a type to collect errors encountered
diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go
index fd3510e9..2f66cca8 100644
--- a/vendor/github.com/docker/distribution/reference/reference.go
+++ b/vendor/github.com/docker/distribution/reference/reference.go
@@ -15,7 +15,7 @@
// tag := /[\w][\w.-]{0,127}/
//
// digest := digest-algorithm ":" digest-hex
-// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
+// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
// digest-algorithm-separator := /[+.-_]/
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
diff --git a/vendor/github.com/docker/distribution/reference/regexp.go b/vendor/github.com/docker/distribution/reference/regexp.go
index 405e995d..78603493 100644
--- a/vendor/github.com/docker/distribution/reference/regexp.go
+++ b/vendor/github.com/docker/distribution/reference/regexp.go
@@ -20,15 +20,15 @@ var (
optional(repeated(separatorRegexp, alphaNumericRegexp)))
// domainComponentRegexp restricts the registry domain component of a
- // repository name to start with a component as defined by domainRegexp
+ // repository name to start with a component as defined by DomainRegexp
// and followed by an optional port.
domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
- // domainRegexp defines the structure of potential domain components
+ // DomainRegexp defines the structure of potential domain components
// that may be part of image names. This is purposely a subset of what is
// allowed by DNS to ensure backwards compatibility with Docker image
// names.
- domainRegexp = expression(
+ DomainRegexp = expression(
domainComponentRegexp,
optional(repeated(literal(`.`), domainComponentRegexp)),
optional(literal(`:`), match(`[0-9]+`)))
@@ -51,14 +51,14 @@ var (
// regexp has capturing groups for the domain and name part omitting
// the separating forward slash from either.
NameRegexp = expression(
- optional(domainRegexp, literal(`/`)),
+ optional(DomainRegexp, literal(`/`)),
nameComponentRegexp,
optional(repeated(literal(`/`), nameComponentRegexp)))
// anchoredNameRegexp is used to parse a name value, capturing the
// domain and trailing components.
anchoredNameRegexp = anchored(
- optional(capture(domainRegexp), literal(`/`)),
+ optional(capture(DomainRegexp), literal(`/`)),
capture(nameComponentRegexp,
optional(repeated(literal(`/`), nameComponentRegexp))))
diff --git a/vendor/github.com/docker/distribution/registry/api/v2/urls.go b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
index e2e242ea..1337bdb1 100644
--- a/vendor/github.com/docker/distribution/registry/api/v2/urls.go
+++ b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
@@ -1,10 +1,9 @@
package v2
import (
- "net"
+ "fmt"
"net/http"
"net/url"
- "strconv"
"strings"
"github.com/docker/distribution/reference"
@@ -48,66 +47,42 @@ func NewURLBuilderFromString(root string, relative bool) (*URLBuilder, error) {
// NewURLBuilderFromRequest uses information from an *http.Request to
// construct the root url.
func NewURLBuilderFromRequest(r *http.Request, relative bool) *URLBuilder {
- var scheme string
-
- forwardedProto := r.Header.Get("X-Forwarded-Proto")
- // TODO: log the error
- forwardedHeader, _, _ := parseForwardedHeader(r.Header.Get("Forwarded"))
-
- switch {
- case len(forwardedProto) > 0:
- scheme = forwardedProto
- case len(forwardedHeader["proto"]) > 0:
- scheme = forwardedHeader["proto"]
- case r.TLS != nil:
- scheme = "https"
- case len(r.URL.Scheme) > 0:
- scheme = r.URL.Scheme
- default:
+ var (
scheme = "http"
+ host = r.Host
+ )
+
+ if r.TLS != nil {
+ scheme = "https"
+ } else if len(r.URL.Scheme) > 0 {
+ scheme = r.URL.Scheme
}
- host := r.Host
-
- if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
- // According to the Apache mod_proxy docs, X-Forwarded-Host can be a
- // comma-separated list of hosts, to which each proxy appends the
- // requested host. We want to grab the first from this comma-separated
- // list.
- hosts := strings.SplitN(forwardedHost, ",", 2)
- host = strings.TrimSpace(hosts[0])
- } else if addr, exists := forwardedHeader["for"]; exists {
- host = addr
- } else if h, exists := forwardedHeader["host"]; exists {
- host = h
- }
-
- portLessHost, port := host, ""
- if !isIPv6Address(portLessHost) {
- // with go 1.6, this would treat the last part of IPv6 address as a port
- portLessHost, port, _ = net.SplitHostPort(host)
- }
- if forwardedPort := r.Header.Get("X-Forwarded-Port"); len(port) == 0 && len(forwardedPort) > 0 {
- ports := strings.SplitN(forwardedPort, ",", 2)
- forwardedPort = strings.TrimSpace(ports[0])
- if _, err := strconv.ParseInt(forwardedPort, 10, 32); err == nil {
- port = forwardedPort
+ // Handle fowarded headers
+ // Prefer "Forwarded" header as defined by rfc7239 if given
+ // see https://tools.ietf.org/html/rfc7239
+ if forwarded := r.Header.Get("Forwarded"); len(forwarded) > 0 {
+ forwardedHeader, _, err := parseForwardedHeader(forwarded)
+ if err == nil {
+ if fproto := forwardedHeader["proto"]; len(fproto) > 0 {
+ scheme = fproto
+ }
+ if fhost := forwardedHeader["host"]; len(fhost) > 0 {
+ host = fhost
+ }
}
- }
-
- if len(portLessHost) > 0 {
- host = portLessHost
- }
- if len(port) > 0 {
- // remove enclosing brackets of ipv6 address otherwise they will be duplicated
- if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
- host = host[1 : len(host)-1]
+ } else {
+ if forwardedProto := r.Header.Get("X-Forwarded-Proto"); len(forwardedProto) > 0 {
+ scheme = forwardedProto
+ }
+ if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
+ // According to the Apache mod_proxy docs, X-Forwarded-Host can be a
+ // comma-separated list of hosts, to which each proxy appends the
+ // requested host. We want to grab the first from this comma-separated
+ // list.
+ hosts := strings.SplitN(forwardedHost, ",", 2)
+ host = strings.TrimSpace(hosts[0])
}
- // JoinHostPort properly encloses ipv6 addresses in square brackets
- host = net.JoinHostPort(host, port)
- } else if isIPv6Address(host) && host[0] != '[' {
- // ipv6 needs to be enclosed in square brackets in urls
- host = "[" + host + "]"
}
basePath := routeDescriptorsMap[RouteNameBase].Path
@@ -175,6 +150,8 @@ func (ub *URLBuilder) BuildManifestURL(ref reference.Named) (string, error) {
tagOrDigest = v.Tag()
case reference.Digested:
tagOrDigest = v.Digest().String()
+ default:
+ return "", fmt.Errorf("reference must have a tag or digest")
}
manifestURL, err := route.URL("name", ref.Name(), "reference", tagOrDigest)
@@ -287,28 +264,3 @@ func appendValues(u string, values ...url.Values) string {
return appendValuesURL(up, values...).String()
}
-
-// isIPv6Address returns true if given string is a valid IPv6 address. No port is allowed. The address may be
-// enclosed in square brackets.
-func isIPv6Address(host string) bool {
- if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
- host = host[1 : len(host)-1]
- }
- // The IPv6 scoped addressing zone identifier starts after the last percent sign.
- if i := strings.LastIndexByte(host, '%'); i > 0 {
- host = host[:i]
- }
- ip := net.ParseIP(host)
- if ip == nil {
- return false
- }
- if ip.To16() == nil {
- return false
- }
- if ip.To4() == nil {
- return true
- }
- // dot can be present in ipv4-mapped address, it needs to come after a colon though
- i := strings.IndexAny(host, ":.")
- return i >= 0 && host[i] == ':'
-}
diff --git a/vendor/github.com/docker/distribution/vendor.conf b/vendor/github.com/docker/distribution/vendor.conf
index 443b4bcf..d67edd77 100644
--- a/vendor/github.com/docker/distribution/vendor.conf
+++ b/vendor/github.com/docker/distribution/vendor.conf
@@ -1,19 +1,21 @@
-github.com/Azure/azure-sdk-for-go c6f0533defaaaa26ea4dff3c9774e36033088112
-github.com/Sirupsen/logrus d26492970760ca5d33129d2d799e34be5c4782eb
+github.com/Azure/azure-sdk-for-go 088007b3b08cc02b27f2eadfdcd870958460ce7e
+github.com/Azure/go-autorest ec5f4903f77ed9927ac95b19ab8e44ada64c1356
+github.com/sirupsen/logrus 3d4380f53a34dcdc95f0c1db702615992b38d9a4
github.com/aws/aws-sdk-go c6fc52983ea2375810aa38ddb5370e9cdf611716
-github.com/bshuster-repo/logrus-logstash-hook 5f729f2fb50a301153cae84ff5c58981d51c095a
+github.com/bshuster-repo/logrus-logstash-hook d2c0ecc1836d91814e15e23bb5dc309c3ef51f4a
github.com/bugsnag/bugsnag-go b1d153021fcd90ca3f080db36bec96dc690fb274
github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702
github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782
github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2
+github.com/dgrijalva/jwt-go a601269ab70c205d26370c16f7c81e9017c14e04
github.com/docker/goamz f0a21f5b2e12f83a505ecf79b633bb2035cf6f85
github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21
github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257
github.com/go-ini/ini 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c
-github.com/golang/protobuf/proto 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
+github.com/golang/protobuf 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
github.com/gorilla/context 14f550f51af52180c2eefed15e5fd18d63c0a64a
github.com/gorilla/handlers 60c7bfde3e33c201519a200a4507a158cc03a17b
-github.com/gorilla/mux e444e69cbd2e2e3e0749a2f3c717cec491552bbf
+github.com/gorilla/mux 599cba5e7b6137d46ddf58fb1765f5d928e69604
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
github.com/miekg/dns 271c58e0c14f552178ea321a545ff9af38930f39
@@ -21,15 +23,15 @@ github.com/mitchellh/mapstructure 482a9fd5fa83e8c4e7817413b80f3eb8feec03ef
github.com/ncw/swift b964f2ca856aac39885e258ad25aec08d5f64ee6
github.com/spf13/cobra 312092086bed4968099259622145a0c9ae280064
github.com/spf13/pflag 5644820622454e71517561946e3d94b9f9db6842
-github.com/stevvooe/resumable 51ad44105773cafcbe91927f70ac68e1bf78f8b4
-github.com/xenolf/lego/acme a9d8cec0e6563575e5868a005359ac97911b5985
+github.com/stevvooe/resumable 2aaf90b2ceea5072cb503ef2a620b08ff3119870
+github.com/xenolf/lego a9d8cec0e6563575e5868a005359ac97911b5985
github.com/yvasiyarov/go-metrics 57bccd1ccd43f94bb17fdd8bf3007059b802f85e
github.com/yvasiyarov/gorelic a9bba5b9ab508a086f9a12b8c51fab68478e2128
github.com/yvasiyarov/newrelic_platform_go b21fdbd4370f3717f3bbd2bf41c223bc273068e6
golang.org/x/crypto c10c31b5e94b6f7a0283272dc2bb27163dcea24b
golang.org/x/net 4876518f9e71663000c348837735820161a42df7
golang.org/x/oauth2 045497edb6234273d67dbc25da3f2ddbc4c4cacf
-golang.org/x/time/rate a4bde12657593d5e90d0533a3e4fd95e635124cb
+golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
google.golang.org/api 9bf6e6e569ff057f75d9604a46c52928f17d2b54
google.golang.org/appengine 12d5545dc1cfa6047a286d5e853841b6471f4c19
google.golang.org/cloud 975617b05ea8a58727e6c1a06b6161ff4185a9f2
diff --git a/vendor/github.com/docker/docker/LICENSE b/vendor/github.com/docker/docker/LICENSE
index 8f3fee62..9c8e20ab 100644
--- a/vendor/github.com/docker/docker/LICENSE
+++ b/vendor/github.com/docker/docker/LICENSE
@@ -176,7 +176,7 @@
END OF TERMS AND CONDITIONS
- Copyright 2013-2016 Docker, Inc.
+ Copyright 2013-2017 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/vendor/github.com/docker/docker/NOTICE b/vendor/github.com/docker/docker/NOTICE
index 8a37c1c7..0c74e15b 100644
--- a/vendor/github.com/docker/docker/NOTICE
+++ b/vendor/github.com/docker/docker/NOTICE
@@ -1,5 +1,5 @@
Docker
-Copyright 2012-2016 Docker, Inc.
+Copyright 2012-2017 Docker, Inc.
This product includes software developed at Docker, Inc. (https://www.docker.com).
diff --git a/vendor/github.com/docker/docker/README.md b/vendor/github.com/docker/docker/README.md
index 0b33bdca..533d7717 100644
--- a/vendor/github.com/docker/docker/README.md
+++ b/vendor/github.com/docker/docker/README.md
@@ -1,270 +1,80 @@
-Docker: the container engine [![Release](https://img.shields.io/github/release/docker/docker.svg)](https://github.com/docker/docker/releases/latest)
-============================
+### Docker users, see [Moby and Docker](https://mobyproject.org/#moby-and-docker) to clarify the relationship between the projects
-Docker is an open source project to pack, ship and run any application
-as a lightweight container.
+### Docker maintainers and contributors, see [Transitioning to Moby](#transitioning-to-moby) for more details
-Docker containers are both *hardware-agnostic* and *platform-agnostic*.
-This means they can run anywhere, from your laptop to the largest
-cloud compute instance and everything in between - and they don't require
-you to use a particular language, framework or packaging system. That
-makes them great building blocks for deploying and scaling web apps,
-databases, and backend services without depending on a particular stack
-or provider.
+The Moby Project
+================
-Docker began as an open-source implementation of the deployment engine which
-powered [dotCloud](http://web.archive.org/web/20130530031104/https://www.dotcloud.com/),
-a popular Platform-as-a-Service. It benefits directly from the experience
-accumulated over several years of large-scale operation and support of hundreds
-of thousands of applications and databases.
+![Moby Project logo](docs/static_files/moby-project-logo.png "The Moby Project")
-![Docker logo](docs/static_files/docker-logo-compressed.png "Docker")
+Moby is an open-source project created by Docker to advance the software containerization movement.
+It provides a “Lego set” of dozens of components, the framework for assembling them into custom container-based systems, and a place for all container enthusiasts to experiment and exchange ideas.
-## Security Disclosure
+# Moby
-Security is very important to us. If you have any issue regarding security,
-please disclose the information responsibly by sending an email to
-security@docker.com and not by creating a GitHub issue.
+## Overview
-## Better than VMs
+At the core of Moby is a framework to assemble specialized container systems.
+It provides:
-A common method for distributing applications and sandboxing their
-execution is to use virtual machines, or VMs. Typical VM formats are
-VMware's vmdk, Oracle VirtualBox's vdi, and Amazon EC2's ami. In theory
-these formats should allow every developer to automatically package
-their application into a "machine" for easy distribution and deployment.
-In practice, that almost never happens, for a few reasons:
+- A library of containerized components for all vital aspects of a container system: OS, container runtime, orchestration, infrastructure management, networking, storage, security, build, image distribution, etc.
+- Tools to assemble the components into runnable artifacts for a variety of platforms and architectures: bare metal (both x86 and Arm); executables for Linux, Mac and Windows; VM images for popular cloud and virtualization providers.
+- A set of reference assemblies which can be used as-is, modified, or used as inspiration to create your own.
- * *Size*: VMs are very large which makes them impractical to store
- and transfer.
- * *Performance*: running VMs consumes significant CPU and memory,
- which makes them impractical in many scenarios, for example local
- development of multi-tier applications, and large-scale deployment
- of cpu and memory-intensive applications on large numbers of
- machines.
- * *Portability*: competing VM environments don't play well with each
- other. Although conversion tools do exist, they are limited and
- add even more overhead.
- * *Hardware-centric*: VMs were designed with machine operators in
- mind, not software developers. As a result, they offer very
- limited tooling for what developers need most: building, testing
- and running their software. For example, VMs offer no facilities
- for application versioning, monitoring, configuration, logging or
- service discovery.
+All Moby components are containers, so creating new components is as easy as building a new OCI-compatible container.
-By contrast, Docker relies on a different sandboxing method known as
-*containerization*. Unlike traditional virtualization, containerization
-takes place at the kernel level. Most modern operating system kernels
-now support the primitives necessary for containerization, including
-Linux with [openvz](https://openvz.org),
-[vserver](http://linux-vserver.org) and more recently
-[lxc](https://linuxcontainers.org/), Solaris with
-[zones](https://docs.oracle.com/cd/E26502_01/html/E29024/preface-1.html#scrolltoc),
-and FreeBSD with
-[Jails](https://www.freebsd.org/doc/handbook/jails.html).
+## Principles
-Docker builds on top of these low-level primitives to offer developers a
-portable format and runtime environment that solves all four problems.
-Docker containers are small (and their transfer can be optimized with
-layers), they have basically zero memory and cpu overhead, they are
-completely portable, and are designed from the ground up with an
-application-centric design.
+Moby is an open project guided by strong principles, but modular, flexible and without too strong an opinion on user experience, so it is open to the community to help set its direction.
+The guiding principles are:
-Perhaps best of all, because Docker operates at the OS level, it can still be
-run inside a VM!
+- Batteries included but swappable: Moby includes enough components to build fully featured container system, but its modular architecture ensures that most of the components can be swapped by different implementations.
+- Usable security: Moby will provide secure defaults without compromising usability.
+- Container centric: Moby is built with containers, for running containers.
-## Plays well with others
+With Moby, you should be able to describe all the components of your distributed application, from the high-level configuration files down to the kernel you would like to use and build and deploy it easily.
-Docker does not require you to buy into a particular programming
-language, framework, packaging system, or configuration language.
+Moby uses [containerd](https://github.com/containerd/containerd) as the default container runtime.
-Is your application a Unix process? Does it use files, tcp connections,
-environment variables, standard Unix streams and command-line arguments
-as inputs and outputs? Then Docker can run it.
+## Audience
-Can your application's build be expressed as a sequence of such
-commands? Then Docker can build it.
+Moby is recommended for anyone who wants to assemble a container-based system. This includes:
-## Escape dependency hell
+- Hackers who want to customize or patch their Docker build
+- System engineers or integrators building a container system
+- Infrastructure providers looking to adapt existing container systems to their environment
+- Container enthusiasts who want to experiment with the latest container tech
+- Open-source developers looking to test their project in a variety of different systems
+- Anyone curious about Docker internals and how it’s built
-A common problem for developers is the difficulty of managing all
-their application's dependencies in a simple and automated way.
+Moby is NOT recommended for:
-This is usually difficult for several reasons:
+- Application developers looking for an easy way to run their applications in containers. We recommend Docker CE instead.
+- Enterprise IT and development teams looking for a ready-to-use, commercially supported container platform. We recommend Docker EE instead.
+- Anyone curious about containers and looking for an easy way to learn. We recommend the [docker.com](https://www.docker.com/) website instead.
- * *Cross-platform dependencies*. Modern applications often depend on
- a combination of system libraries and binaries, language-specific
- packages, framework-specific modules, internal components
- developed for another project, etc. These dependencies live in
- different "worlds" and require different tools - these tools
- typically don't work well with each other, requiring awkward
- custom integrations.
+# Transitioning to Moby
- * *Conflicting dependencies*. Different applications may depend on
- different versions of the same dependency. Packaging tools handle
- these situations with various degrees of ease - but they all
- handle them in different and incompatible ways, which again forces
- the developer to do extra work.
+Docker is transitioning all of its open source collaborations to the Moby project going forward.
+During the transition, all open source activity should continue as usual.
- * *Custom dependencies*. A developer may need to prepare a custom
- version of their application's dependency. Some packaging systems
- can handle custom versions of a dependency, others can't - and all
- of them handle it differently.
+We are proposing the following list of changes:
+- splitting up the engine into more open components
+- removing the docker UI, SDK etc to keep them in the Docker org
+- clarifying that the project is not limited to the engine, but to the assembly of all the individual components of the Docker platform
+- open-source new tools & components which we currently use to assemble the Docker product, but could benefit the community
+- defining an open, community-centric governance inspired by the Fedora project (a very successful example of balancing the needs of the community with the constraints of the primary corporate sponsor)
-Docker solves the problem of dependency hell by giving the developer a simple
-way to express *all* their application's dependencies in one place, while
-streamlining the process of assembling them. If this makes you think of
-[XKCD 927](https://xkcd.com/927/), don't worry. Docker doesn't
-*replace* your favorite packaging systems. It simply orchestrates
-their use in a simple and repeatable way. How does it do that? With
-layers.
+-----
-Docker defines a build as running a sequence of Unix commands, one
-after the other, in the same container. Build commands modify the
-contents of the container (usually by installing new files on the
-filesystem), the next command modifies it some more, etc. Since each
-build command inherits the result of the previous commands, the
-*order* in which the commands are executed expresses *dependencies*.
-
-Here's a typical Docker build process:
-
-```bash
-FROM ubuntu:12.04
-RUN apt-get update && apt-get install -y python python-pip curl
-RUN curl -sSL https://github.com/shykes/helloflask/archive/master.tar.gz | tar -xzv
-RUN cd helloflask-master && pip install -r requirements.txt
-```
-
-Note that Docker doesn't care *how* dependencies are built - as long
-as they can be built by running a Unix command in a container.
-
-
-Getting started
-===============
-
-Docker can be installed either on your computer for building applications or
-on servers for running them. To get started, [check out the installation
-instructions in the
-documentation](https://docs.docker.com/engine/installation/).
-
-Usage examples
-==============
-
-Docker can be used to run short-lived commands, long-running daemons
-(app servers, databases, etc.), interactive shell sessions, etc.
-
-You can find a [list of real-world
-examples](https://docs.docker.com/engine/examples/) in the
-documentation.
-
-Under the hood
---------------
-
-Under the hood, Docker is built on the following components:
-
-* The
- [cgroups](https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt)
- and
- [namespaces](http://man7.org/linux/man-pages/man7/namespaces.7.html)
- capabilities of the Linux kernel
-* The [Go](https://golang.org) programming language
-* The [Docker Image Specification](https://github.com/docker/docker/blob/master/image/spec/v1.md)
-* The [Libcontainer Specification](https://github.com/opencontainers/runc/blob/master/libcontainer/SPEC.md)
-
-Contributing to Docker [![GoDoc](https://godoc.org/github.com/docker/docker?status.svg)](https://godoc.org/github.com/docker/docker)
-======================
-
-| **Master** (Linux) | **Experimental** (Linux) | **Windows** | **FreeBSD** |
-|------------------|----------------------|---------|---------|
-| [![Jenkins Build Status](https://jenkins.dockerproject.org/view/Docker/job/Docker%20Master/badge/icon)](https://jenkins.dockerproject.org/view/Docker/job/Docker%20Master/) | [![Jenkins Build Status](https://jenkins.dockerproject.org/view/Docker/job/Docker%20Master%20%28experimental%29/badge/icon)](https://jenkins.dockerproject.org/view/Docker/job/Docker%20Master%20%28experimental%29/) | [![Build Status](http://jenkins.dockerproject.org/job/Docker%20Master%20(windows)/badge/icon)](http://jenkins.dockerproject.org/job/Docker%20Master%20(windows)/) | [![Build Status](http://jenkins.dockerproject.org/job/Docker%20Master%20(freebsd)/badge/icon)](http://jenkins.dockerproject.org/job/Docker%20Master%20(freebsd)/) |
-
-Want to hack on Docker? Awesome! We have [instructions to help you get
-started contributing code or documentation](https://docs.docker.com/opensource/project/who-written-for/).
-
-These instructions are probably not perfect, please let us know if anything
-feels wrong or incomplete. Better yet, submit a PR and improve them yourself.
-
-Getting the development builds
-==============================
-
-Want to run Docker from a master build? You can download
-master builds at [master.dockerproject.org](https://master.dockerproject.org).
-They are updated with each commit merged into the master branch.
-
-Don't know how to use that super cool new feature in the master build? Check
-out the master docs at
-[docs.master.dockerproject.org](http://docs.master.dockerproject.org).
-
-How the project is run
-======================
-
-Docker is a very, very active project. If you want to learn more about how it is run,
-or want to get more involved, the best place to start is [the project directory](https://github.com/docker/docker/tree/master/project).
-
-We are always open to suggestions on process improvements, and are always looking for more maintainers.
-
-### Talking to other Docker users and contributors
-
-
-
-
-
- Internet Relay Chat (IRC) |
-
-
- IRC is a direct line to our most knowledgeable Docker users; we have
- both the #docker and #docker-dev group on
- irc.freenode.net.
- IRC is a rich chat protocol but it can overwhelm new users. You can search
- our chat archives.
-
- Read our IRC quickstart guide for an easy way to get started.
- |
-
-
- Docker Community Forums |
-
- The Docker Engine
- group is for users of the Docker Engine project.
- |
-
-
- Google Groups |
-
- The docker-dev group is for contributors and other people
- contributing to the Docker project. You can join this group without a
- Google account by sending an email to docker-dev+subscribe@googlegroups.com.
- You'll receive a join-request message; simply reply to the message to
- confirm your subscription.
- |
-
-
- Twitter |
-
- You can follow Docker's Twitter feed
- to get updates on our products. You can also tweet us questions or just
- share blogs or stories.
- |
-
-
- Stack Overflow |
-
- Stack Overflow has over 7000 Docker questions listed. We regularly
- monitor Docker questions
- and so do many other knowledgeable Docker users.
- |
-
-
-
-### Legal
+Legal
+=====
*Brought to you courtesy of our legal counsel. For more context,
-please see the [NOTICE](https://github.com/docker/docker/blob/master/NOTICE) document in this repo.*
+please see the [NOTICE](https://github.com/moby/moby/blob/master/NOTICE) document in this repo.*
-Use and transfer of Docker may be subject to certain restrictions by the
+Use and transfer of Moby may be subject to certain restrictions by the
United States and other governments.
It is your responsibility to ensure that your use and/or transfer does not
@@ -275,30 +85,6 @@ For more information, please see https://www.bis.doc.gov
Licensing
=========
-Docker is licensed under the Apache License, Version 2.0. See
-[LICENSE](https://github.com/docker/docker/blob/master/LICENSE) for the full
+Moby is licensed under the Apache License, Version 2.0. See
+[LICENSE](https://github.com/moby/moby/blob/master/LICENSE) for the full
license text.
-
-Other Docker Related Projects
-=============================
-There are a number of projects under development that are based on Docker's
-core technology. These projects expand the tooling built around the
-Docker platform to broaden its application and utility.
-
-* [Docker Registry](https://github.com/docker/distribution): Registry
-server for Docker (hosting/delivery of repositories and images)
-* [Docker Machine](https://github.com/docker/machine): Machine management
-for a container-centric world
-* [Docker Swarm](https://github.com/docker/swarm): A Docker-native clustering
-system
-* [Docker Compose](https://github.com/docker/compose) (formerly Fig):
-Define and run multi-container apps
-* [Kitematic](https://github.com/docker/kitematic): The easiest way to use
-Docker on Mac and Windows
-
-If you know of another project underway that should be listed here, please help
-us keep this list up-to-date by submitting a PR.
-
-Awesome-Docker
-==============
-You can find more projects, tools and articles related to Docker on the [awesome-docker list](https://github.com/veggiemonk/awesome-docker). Add your project there.
diff --git a/vendor/github.com/docker/docker/api/README.md b/vendor/github.com/docker/docker/api/README.md
index 464e0569..bb881325 100644
--- a/vendor/github.com/docker/docker/api/README.md
+++ b/vendor/github.com/docker/docker/api/README.md
@@ -14,8 +14,8 @@ It consists of various components in this repository:
The API is defined by the [Swagger](http://swagger.io/specification/) definition in `api/swagger.yaml`. This definition can be used to:
-1. To automatically generate documentation.
-2. To automatically generate the Go server and client. (A work-in-progress.)
+1. Automatically generate documentation.
+2. Automatically generate the Go server and client. (A work-in-progress.)
3. Provide a machine readable version of the API for introspecting what it can do, automatically generating clients for other languages, etc.
## Updating the API documentation
@@ -37,6 +37,6 @@ There is hopefully enough example material in the file for you to copy a similar
When you make edits to `swagger.yaml`, you may want to check the generated API documentation to ensure it renders correctly.
-All the documentation generation is done in the documentation repository, [docker/docker.github.io](https://github.com/docker/docker.github.io). The Swagger definition is vendored periodically into this repository, but you can manually copy over the Swagger definition to test changes.
+Run `make swagger-docs` and a preview will be running at `http://localhost`. Some of the styling may be incorrect, but you'll be able to ensure that it is generating the correct documentation.
-Copy `api/swagger.yaml` in this repository to `engine/api/[VERSION_NUMBER]/swagger.yaml` in the documentation repository, overwriting what is already there. Then, run `docker-compose up` in the documentation repository and browse to [http://localhost:4000/engine/api/](http://localhost:4000/engine/api/) when it finishes rendering.
+The production documentation is generated by vendoring `swagger.yaml` into [docker/docker.github.io](https://github.com/docker/docker.github.io).
diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go
new file mode 100644
index 00000000..6e462aed
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/common.go
@@ -0,0 +1,65 @@
+package api
+
+import (
+ "encoding/json"
+ "encoding/pem"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/docker/docker/pkg/ioutils"
+ "github.com/docker/docker/pkg/system"
+ "github.com/docker/libtrust"
+)
+
+// Common constants for daemon and client.
+const (
+ // DefaultVersion of Current REST API
+ DefaultVersion string = "1.32"
+
+ // NoBaseImageSpecifier is the symbol used by the FROM
+ // command to specify that no base image is to be used.
+ NoBaseImageSpecifier string = "scratch"
+)
+
+// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
+// otherwise generates a new one
+func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
+ err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700, "")
+ if err != nil {
+ return nil, err
+ }
+ trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
+ if err == libtrust.ErrKeyFileDoesNotExist {
+ trustKey, err = libtrust.GenerateECP256PrivateKey()
+ if err != nil {
+ return nil, fmt.Errorf("Error generating key: %s", err)
+ }
+ encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
+ if err != nil {
+ return nil, fmt.Errorf("Error serializing key: %s", err)
+ }
+ if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
+ return nil, fmt.Errorf("Error saving key file: %s", err)
+ }
+ } else if err != nil {
+ return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
+ }
+ return trustKey, nil
+}
+
+func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
+ if ext == ".json" || ext == ".jwk" {
+ encoded, err = json.Marshal(key)
+ if err != nil {
+ return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
+ }
+ } else {
+ pemBlock, err := key.PEMBlock()
+ if err != nil {
+ return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
+ }
+ encoded = pem.EncodeToMemory(pemBlock)
+ }
+ return
+}
diff --git a/vendor/github.com/docker/docker/api/common_unix.go b/vendor/github.com/docker/docker/api/common_unix.go
new file mode 100644
index 00000000..081e61c4
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/common_unix.go
@@ -0,0 +1,6 @@
+// +build !windows
+
+package api
+
+// MinVersion represents Minimum REST API version supported
+const MinVersion string = "1.12"
diff --git a/vendor/github.com/docker/docker/api/common_windows.go b/vendor/github.com/docker/docker/api/common_windows.go
new file mode 100644
index 00000000..a6268a4f
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/common_windows.go
@@ -0,0 +1,8 @@
+package api
+
+// MinVersion represents Minimum REST API version supported
+// Technically the first daemon API version released on Windows is v1.25 in
+// engine version 1.13. However, some clients are explicitly using downlevel
+// APIs (e.g. docker-compose v2.1 file format) and that is just too restrictive.
+// Hence also allowing 1.24 on Windows.
+const MinVersion string = "1.24"
diff --git a/vendor/github.com/docker/docker/api/names.go b/vendor/github.com/docker/docker/api/names.go
new file mode 100644
index 00000000..f147d1f4
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/names.go
@@ -0,0 +1,9 @@
+package api
+
+import "regexp"
+
+// RestrictedNameChars collects the characters allowed to represent a name, normally used to validate container and volume names.
+const RestrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
+
+// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters.
+var RestrictedNamePattern = regexp.MustCompile(`^` + RestrictedNameChars + `+$`)
diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go
index 7900d64f..18a1263f 100644
--- a/vendor/github.com/docker/docker/api/types/client.go
+++ b/vendor/github.com/docker/docker/api/types/client.go
@@ -4,11 +4,10 @@ import (
"bufio"
"io"
"net"
- "os"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
- "github.com/docker/go-units"
+ units "github.com/docker/go-units"
)
// CheckpointCreateOptions holds parameters to create a checkpoint from a container
@@ -98,6 +97,7 @@ type ContainerStartOptions struct {
// about files to copy into a container
type CopyToContainerOptions struct {
AllowOverwriteDirWithFile bool
+ CopyUIDGID bool
}
// EventsOptions holds parameters to filter events with.
@@ -160,9 +160,10 @@ type ImageBuildOptions struct {
ShmSize int64
Dockerfile string
Ulimits []*units.Ulimit
- // See the parsing of buildArgs in api/server/router/build/build_routes.go
- // for an explaination of why BuildArgs needs to use *string instead of
- // just a string
+ // BuildArgs needs to be a *string instead of just a string so that
+ // we can tell the difference between "" (empty string) and no value
+ // at all (nil). See the parsing of buildArgs in
+ // api/server/router/build/build_routes.go for even more info.
BuildArgs map[string]*string
AuthConfigs map[string]AuthConfig
Context io.Reader
@@ -175,6 +176,13 @@ type ImageBuildOptions struct {
// specified here do not need to have a valid parent chain to match cache.
CacheFrom []string
SecurityOpt []string
+ ExtraHosts []string // List of extra hosts
+ Target string
+ SessionID string
+
+ // TODO @jhowardmsft LCOW Support: This will require extending to include
+ // `Platform string`, but is ommited for now as it's hard-coded temporarily
+ // to avoid API changes.
}
// ImageBuildResponse holds information
@@ -192,8 +200,8 @@ type ImageCreateOptions struct {
// ImageImportSource holds source information for ImageImport
type ImageImportSource struct {
- Source io.Reader // Source is the data to send to the server to create this image from (mutually exclusive with SourceName)
- SourceName string // SourceName is the name of the image to pull (mutually exclusive with Source)
+ Source io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to "-" to leverage this.
+ SourceName string // SourceName is the name of the image to pull. Set to "-" to leverage the Source attribute.
}
// ImageImportOptions holds information to import images from the client host.
@@ -256,18 +264,6 @@ type ResizeOptions struct {
Width uint
}
-// VersionResponse holds version information for the client and the server
-type VersionResponse struct {
- Client *Version
- Server *Version
-}
-
-// ServerOK returns true when the client could connect to the docker server
-// and parse the information received. It returns false otherwise.
-func (v VersionResponse) ServerOK() bool {
- return v.Server != nil
-}
-
// NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct {
Filters filters.Args
@@ -285,6 +281,12 @@ type ServiceCreateOptions struct {
//
// This field follows the format of the X-Registry-Auth header.
EncodedRegistryAuth string
+
+ // QueryRegistry indicates whether the service update requires
+ // contacting a registry. A registry may be contacted to retrieve
+ // the image digest and manifest, which in turn can be used to update
+ // platform or other information about the service.
+ QueryRegistry bool
}
// ServiceCreateResponse contains the information returned to a client
@@ -318,14 +320,32 @@ type ServiceUpdateOptions struct {
// credentials if they are not given in EncodedRegistryAuth. Valid
// values are "spec" and "previous-spec".
RegistryAuthFrom string
+
+ // Rollback indicates whether a server-side rollback should be
+ // performed. When this is set, the provided spec will be ignored.
+ // The valid values are "previous" and "none". An empty value is the
+ // same as "none".
+ Rollback string
+
+ // QueryRegistry indicates whether the service update requires
+ // contacting a registry. A registry may be contacted to retrieve
+ // the image digest and manifest, which in turn can be used to update
+ // platform or other information about the service.
+ QueryRegistry bool
}
-// ServiceListOptions holds parameters to list services with.
+// ServiceListOptions holds parameters to list services with.
type ServiceListOptions struct {
Filters filters.Args
}
-// TaskListOptions holds parameters to list tasks with.
+// ServiceInspectOptions holds parameters related to the "service inspect"
+// operation.
+type ServiceInspectOptions struct {
+ InsertDefaults bool
+}
+
+// TaskListOptions holds parameters to list tasks with.
type TaskListOptions struct {
Filters filters.Args
}
@@ -356,15 +376,6 @@ type PluginInstallOptions struct {
Args []string
}
-// SecretRequestOption is a type for requesting secrets
-type SecretRequestOption struct {
- Source string
- Target string
- UID string
- GID string
- Mode os.FileMode
-}
-
// SwarmUnlockKeyResponse contains the response for Engine API:
// GET /swarm/unlockkey
type SwarmUnlockKeyResponse struct {
diff --git a/vendor/github.com/docker/docker/api/types/configs.go b/vendor/github.com/docker/docker/api/types/configs.go
index 20c19f21..e4d2ce6e 100644
--- a/vendor/github.com/docker/docker/api/types/configs.go
+++ b/vendor/github.com/docker/docker/api/types/configs.go
@@ -16,6 +16,7 @@ type ContainerCreateConfig struct {
HostConfig *container.HostConfig
NetworkingConfig *network.NetworkingConfig
AdjustCPUShares bool
+ Platform string
}
// ContainerRmConfig holds arguments for the container remove
diff --git a/vendor/github.com/docker/docker/api/types/container/config.go b/vendor/github.com/docker/docker/api/types/container/config.go
index fc050e5d..55a03fc9 100644
--- a/vendor/github.com/docker/docker/api/types/container/config.go
+++ b/vendor/github.com/docker/docker/api/types/container/config.go
@@ -7,6 +7,12 @@ import (
"github.com/docker/go-connections/nat"
)
+// MinimumDuration puts a minimum on user configured duration.
+// This is to prevent API error on time unit. For example, API may
+// set 3 as healthcheck interval with intention of 3 seconds, but
+// Docker interprets it as 3 nanoseconds.
+const MinimumDuration = 1 * time.Millisecond
+
// HealthConfig holds configuration settings for the HEALTHCHECK feature.
type HealthConfig struct {
// Test is the test to perform to check that the container is healthy.
@@ -19,8 +25,9 @@ type HealthConfig struct {
Test []string `json:",omitempty"`
// Zero means to inherit. Durations are expressed as integer nanoseconds.
- Interval time.Duration `json:",omitempty"` // Interval is the time to wait between checks.
- Timeout time.Duration `json:",omitempty"` // Timeout is the time to wait before considering the check to have hung.
+ Interval time.Duration `json:",omitempty"` // Interval is the time to wait between checks.
+ Timeout time.Duration `json:",omitempty"` // Timeout is the time to wait before considering the check to have hung.
+ StartPeriod time.Duration `json:",omitempty"` // The start period for the container to initialize before the retries starts to count down.
// Retries is the number of consecutive failures needed to consider a container as unhealthy.
// Zero means inherit.
diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go
new file mode 100644
index 00000000..767945a5
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/container/container_changes.go
@@ -0,0 +1,21 @@
+package container
+
+// ----------------------------------------------------------------------------
+// DO NOT EDIT THIS FILE
+// This file was generated by `swagger generate operation`
+//
+// See hack/generate-swagger-api.sh
+// ----------------------------------------------------------------------------
+
+// ContainerChangeResponseItem container change response item
+// swagger:model ContainerChangeResponseItem
+type ContainerChangeResponseItem struct {
+
+ // Kind of change
+ // Required: true
+ Kind uint8 `json:"Kind"`
+
+ // Path to file that has changed
+ // Required: true
+ Path string `json:"Path"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/container/container_create.go b/vendor/github.com/docker/docker/api/types/container/container_create.go
index d028e3b1..c95023b8 100644
--- a/vendor/github.com/docker/docker/api/types/container/container_create.go
+++ b/vendor/github.com/docker/docker/api/types/container/container_create.go
@@ -4,7 +4,7 @@ package container
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerCreateCreatedBody container create created body
diff --git a/vendor/github.com/docker/docker/api/types/container/container_top.go b/vendor/github.com/docker/docker/api/types/container/container_top.go
new file mode 100644
index 00000000..78bc37ee
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/container/container_top.go
@@ -0,0 +1,21 @@
+package container
+
+// ----------------------------------------------------------------------------
+// DO NOT EDIT THIS FILE
+// This file was generated by `swagger generate operation`
+//
+// See hack/generate-swagger-api.sh
+// ----------------------------------------------------------------------------
+
+// ContainerTopOKBody container top o k body
+// swagger:model ContainerTopOKBody
+type ContainerTopOKBody struct {
+
+ // Each process running in the container, where each is process is an array of values corresponding to the titles
+ // Required: true
+ Processes [][]string `json:"Processes"`
+
+ // The ps column titles
+ // Required: true
+ Titles []string `json:"Titles"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/container/container_update.go b/vendor/github.com/docker/docker/api/types/container/container_update.go
index 81ee12c6..2339366f 100644
--- a/vendor/github.com/docker/docker/api/types/container/container_update.go
+++ b/vendor/github.com/docker/docker/api/types/container/container_update.go
@@ -4,7 +4,7 @@ package container
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerUpdateOKBody container update o k body
diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go
index 16cf3353..77ecdbaf 100644
--- a/vendor/github.com/docker/docker/api/types/container/container_wait.go
+++ b/vendor/github.com/docker/docker/api/types/container/container_wait.go
@@ -4,7 +4,7 @@ package container
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// ContainerWaitOKBody container wait o k body
diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go
index 0c82d625..9fea9eb0 100644
--- a/vendor/github.com/docker/docker/api/types/container/host_config.go
+++ b/vendor/github.com/docker/docker/api/types/container/host_config.go
@@ -10,9 +10,6 @@ import (
"github.com/docker/go-units"
)
-// NetworkMode represents the container network stack.
-type NetworkMode string
-
// Isolation represents the isolation technology of a container. The supported
// values are platform specific
type Isolation string
@@ -66,6 +63,47 @@ func (n IpcMode) Container() string {
return ""
}
+// NetworkMode represents the container network stack.
+type NetworkMode string
+
+// IsNone indicates whether container isn't using a network stack.
+func (n NetworkMode) IsNone() bool {
+ return n == "none"
+}
+
+// IsDefault indicates whether container uses the default network stack.
+func (n NetworkMode) IsDefault() bool {
+ return n == "default"
+}
+
+// IsPrivate indicates whether container uses its private network stack.
+func (n NetworkMode) IsPrivate() bool {
+ return !(n.IsHost() || n.IsContainer())
+}
+
+// IsContainer indicates whether container uses a container network stack.
+func (n NetworkMode) IsContainer() bool {
+ parts := strings.SplitN(string(n), ":", 2)
+ return len(parts) > 1 && parts[0] == "container"
+}
+
+// ConnectedContainer is the id of the container which network this container is connected to.
+func (n NetworkMode) ConnectedContainer() string {
+ parts := strings.SplitN(string(n), ":", 2)
+ if len(parts) > 1 {
+ return parts[1]
+ }
+ return ""
+}
+
+//UserDefined indicates user-created network
+func (n NetworkMode) UserDefined() string {
+ if n.IsUserDefined() {
+ return string(n)
+ }
+ return ""
+}
+
// UsernsMode represents userns mode in the container.
type UsernsMode string
@@ -223,6 +261,17 @@ func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool {
return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount
}
+// LogMode is a type to define the available modes for logging
+// These modes affect how logs are handled when log messages start piling up.
+type LogMode string
+
+// Available logging modes
+const (
+ LogModeUnset = ""
+ LogModeBlocking LogMode = "blocking"
+ LogModeNonBlock LogMode = "non-blocking"
+)
+
// LogConfig represents the logging configuration of the container.
type LogConfig struct {
Type string
@@ -251,6 +300,7 @@ type Resources struct {
CpusetCpus string // CpusetCpus 0-2, 0,1
CpusetMems string // CpusetMems 0-2, 0,1
Devices []DeviceMapping // List of devices to map inside the container
+ DeviceCgroupRules []string // List of rule to be added to the device cgroup
DiskQuota int64 // Disk limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes)
MemoryReservation int64 // Memory soft limit (in bytes)
@@ -317,7 +367,7 @@ type HostConfig struct {
// Applicable to Windows
ConsoleSize [2]uint // Initial console size (height,width)
- Isolation Isolation // Isolation technology of the container (eg default, hyperv)
+ Isolation Isolation // Isolation technology of the container (e.g. default, hyperv)
// Contains container's resources (cgroups, ulimits)
Resources
@@ -327,7 +377,4 @@ type HostConfig struct {
// Run a custom init inside the container, if null, use the daemon's configured settings
Init *bool `json:",omitempty"`
-
- // Custom init path
- InitPath string `json:",omitempty"`
}
diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go b/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go
index 9fb79bed..2d664d1c 100644
--- a/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go
+++ b/vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go
@@ -2,23 +2,11 @@
package container
-import "strings"
-
// IsValid indicates if an isolation technology is valid
func (i Isolation) IsValid() bool {
return i.IsDefault()
}
-// IsPrivate indicates whether container uses its private network stack.
-func (n NetworkMode) IsPrivate() bool {
- return !(n.IsHost() || n.IsContainer())
-}
-
-// IsDefault indicates whether container uses the default network stack.
-func (n NetworkMode) IsDefault() bool {
- return n == "default"
-}
-
// NetworkName returns the name of the network stack.
func (n NetworkMode) NetworkName() string {
if n.IsBridge() {
@@ -47,35 +35,7 @@ func (n NetworkMode) IsHost() bool {
return n == "host"
}
-// IsContainer indicates whether container uses a container network stack.
-func (n NetworkMode) IsContainer() bool {
- parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
-}
-
-// IsNone indicates whether container isn't using a network stack.
-func (n NetworkMode) IsNone() bool {
- return n == "none"
-}
-
-// ConnectedContainer is the id of the container which network this container is connected to.
-func (n NetworkMode) ConnectedContainer() string {
- parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
- return parts[1]
- }
- return ""
-}
-
// IsUserDefined indicates user-created network
func (n NetworkMode) IsUserDefined() bool {
return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()
}
-
-//UserDefined indicates user-created network
-func (n NetworkMode) UserDefined() string {
- if n.IsUserDefined() {
- return string(n)
- }
- return ""
-}
diff --git a/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go b/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go
index 0ee332ba..469923f7 100644
--- a/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go
+++ b/vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go
@@ -4,22 +4,6 @@ import (
"strings"
)
-// IsDefault indicates whether container uses the default network stack.
-func (n NetworkMode) IsDefault() bool {
- return n == "default"
-}
-
-// IsNone indicates whether container isn't using a network stack.
-func (n NetworkMode) IsNone() bool {
- return n == "none"
-}
-
-// IsContainer indicates whether container uses a container network stack.
-// Returns false as windows doesn't support this mode
-func (n NetworkMode) IsContainer() bool {
- return false
-}
-
// IsBridge indicates whether container uses the bridge network stack
// in windows it is given the name NAT
func (n NetworkMode) IsBridge() bool {
@@ -32,20 +16,9 @@ func (n NetworkMode) IsHost() bool {
return false
}
-// IsPrivate indicates whether container uses its private network stack.
-func (n NetworkMode) IsPrivate() bool {
- return !(n.IsHost() || n.IsContainer())
-}
-
-// ConnectedContainer is the id of the container which network this container is connected to.
-// Returns blank string on windows
-func (n NetworkMode) ConnectedContainer() string {
- return ""
-}
-
// IsUserDefined indicates user-created network
func (n NetworkMode) IsUserDefined() bool {
- return !n.IsDefault() && !n.IsNone() && !n.IsBridge()
+ return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
}
// IsHyperV indicates the use of a Hyper-V partition for isolation
@@ -71,17 +44,11 @@ func (n NetworkMode) NetworkName() string {
return "nat"
} else if n.IsNone() {
return "none"
+ } else if n.IsContainer() {
+ return "container"
} else if n.IsUserDefined() {
return n.UserDefined()
}
return ""
}
-
-//UserDefined indicates user-created network
-func (n NetworkMode) UserDefined() string {
- if n.IsUserDefined() {
- return string(n)
- }
- return ""
-}
diff --git a/vendor/github.com/docker/docker/api/types/container/waitcondition.go b/vendor/github.com/docker/docker/api/types/container/waitcondition.go
new file mode 100644
index 00000000..64820fe3
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/container/waitcondition.go
@@ -0,0 +1,22 @@
+package container
+
+// WaitCondition is a type used to specify a container state for which
+// to wait.
+type WaitCondition string
+
+// Possible WaitCondition Values.
+//
+// WaitConditionNotRunning (default) is used to wait for any of the non-running
+// states: "created", "exited", "dead", "removing", or "removed".
+//
+// WaitConditionNextExit is used to wait for the next time the state changes
+// to a non-running state. If the state is currently "created" or "exited",
+// this would cause Wait() to block until either the container runs and exits
+// or is removed.
+//
+// WaitConditionRemoved is used to wait for the container to be removed.
+const (
+ WaitConditionNotRunning WaitCondition = "not-running"
+ WaitConditionNextExit WaitCondition = "next-exit"
+ WaitConditionRemoved WaitCondition = "removed"
+)
diff --git a/vendor/github.com/docker/docker/api/types/events/events.go b/vendor/github.com/docker/docker/api/types/events/events.go
index 7129a65a..e292565b 100644
--- a/vendor/github.com/docker/docker/api/types/events/events.go
+++ b/vendor/github.com/docker/docker/api/types/events/events.go
@@ -13,6 +13,14 @@ const (
PluginEventType = "plugin"
// VolumeEventType is the event type that volumes generate
VolumeEventType = "volume"
+ // ServiceEventType is the event type that services generate
+ ServiceEventType = "service"
+ // NodeEventType is the event type that nodes generate
+ NodeEventType = "node"
+ // SecretEventType is the event type that secrets generate
+ SecretEventType = "secret"
+ // ConfigEventType is the event type that configs generate
+ ConfigEventType = "config"
)
// Actor describes something that generates events,
@@ -36,6 +44,8 @@ type Message struct {
Type string
Action string
Actor Actor
+ // Engine events are local scope. Cluster events are swarm scope.
+ Scope string `json:"scope,omitempty"`
Time int64 `json:"time,omitempty"`
TimeNano int64 `json:"timeNano,omitempty"`
diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go
index e01a41de..beec3d49 100644
--- a/vendor/github.com/docker/docker/api/types/filters/parse.go
+++ b/vendor/github.com/docker/docker/api/types/filters/parse.go
@@ -79,8 +79,8 @@ func ToParamWithVersion(version string, a Args) (string, error) {
}
// for daemons older than v1.10, filter must be of the form map[string][]string
- buf := []byte{}
- err := errors.New("")
+ var buf []byte
+ var err error
if version != "" && versions.LessThan(version, "1.22") {
buf, err = json.Marshal(convertArgsToSlice(a.fields))
} else {
diff --git a/vendor/github.com/docker/docker/api/types/graph_driver_data.go b/vendor/github.com/docker/docker/api/types/graph_driver_data.go
new file mode 100644
index 00000000..4d9bf1c6
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/graph_driver_data.go
@@ -0,0 +1,17 @@
+package types
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+// GraphDriverData Information about a container's graph driver.
+// swagger:model GraphDriverData
+type GraphDriverData struct {
+
+ // data
+ // Required: true
+ Data map[string]string `json:"Data"`
+
+ // name
+ // Required: true
+ Name string `json:"Name"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/image/image_history.go b/vendor/github.com/docker/docker/api/types/image/image_history.go
new file mode 100644
index 00000000..0dd30c72
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/image/image_history.go
@@ -0,0 +1,37 @@
+package image
+
+// ----------------------------------------------------------------------------
+// DO NOT EDIT THIS FILE
+// This file was generated by `swagger generate operation`
+//
+// See hack/generate-swagger-api.sh
+// ----------------------------------------------------------------------------
+
+// HistoryResponseItem history response item
+// swagger:model HistoryResponseItem
+type HistoryResponseItem struct {
+
+ // comment
+ // Required: true
+ Comment string `json:"Comment"`
+
+ // created
+ // Required: true
+ Created int64 `json:"Created"`
+
+ // created by
+ // Required: true
+ CreatedBy string `json:"CreatedBy"`
+
+ // Id
+ // Required: true
+ ID string `json:"Id"`
+
+ // size
+ // Required: true
+ Size int64 `json:"Size"`
+
+ // tags
+ // Required: true
+ Tags []string `json:"Tags"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/image_delete_response_item.go b/vendor/github.com/docker/docker/api/types/image_delete_response_item.go
new file mode 100644
index 00000000..b9a65a0d
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/image_delete_response_item.go
@@ -0,0 +1,15 @@
+package types
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+// ImageDeleteResponseItem image delete response item
+// swagger:model ImageDeleteResponseItem
+type ImageDeleteResponseItem struct {
+
+ // The image ID of an image that was deleted
+ Deleted string `json:"Deleted,omitempty"`
+
+ // The image ID of an image that was untagged
+ Untagged string `json:"Untagged,omitempty"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/mount/mount.go b/vendor/github.com/docker/docker/api/types/mount/mount.go
index 31f2365b..2744f85d 100644
--- a/vendor/github.com/docker/docker/api/types/mount/mount.go
+++ b/vendor/github.com/docker/docker/api/types/mount/mount.go
@@ -23,9 +23,10 @@ type Mount struct {
// Source specifies the name of the mount. Depending on mount type, this
// may be a volume name or a host path, or even ignored.
// Source is not supported for tmpfs (must be an empty value)
- Source string `json:",omitempty"`
- Target string `json:",omitempty"`
- ReadOnly bool `json:",omitempty"`
+ Source string `json:",omitempty"`
+ Target string `json:",omitempty"`
+ ReadOnly bool `json:",omitempty"`
+ Consistency Consistency `json:",omitempty"`
BindOptions *BindOptions `json:",omitempty"`
VolumeOptions *VolumeOptions `json:",omitempty"`
@@ -60,6 +61,20 @@ var Propagations = []Propagation{
PropagationSlave,
}
+// Consistency represents the consistency requirements of a mount.
+type Consistency string
+
+const (
+ // ConsistencyFull guarantees bind-mount-like consistency
+ ConsistencyFull Consistency = "consistent"
+ // ConsistencyCached mounts can cache read data and FS structure
+ ConsistencyCached Consistency = "cached"
+ // ConsistencyDelegated mounts can cache read and written data and structure
+ ConsistencyDelegated Consistency = "delegated"
+ // ConsistencyDefault provides "consistent" behavior unless overridden
+ ConsistencyDefault Consistency = "default"
+)
+
// BindOptions defines options specific to mounts of type "bind".
type BindOptions struct {
Propagation Propagation `json:",omitempty"`
@@ -83,7 +98,7 @@ type TmpfsOptions struct {
// Size sets the size of the tmpfs, in bytes.
//
// This will be converted to an operating system specific value
- // depending on the host. For example, on linux, it will be convered to
+ // depending on the host. For example, on linux, it will be converted to
// use a 'k', 'm' or 'g' syntax. BSD, though not widely supported with
// docker, uses a straight byte value.
//
diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/docker/docker/api/types/network/network.go
index 832b3edb..7c7dbacc 100644
--- a/vendor/github.com/docker/docker/api/types/network/network.go
+++ b/vendor/github.com/docker/docker/api/types/network/network.go
@@ -28,7 +28,15 @@ type EndpointIPAMConfig struct {
LinkLocalIPs []string `json:",omitempty"`
}
-// PeerInfo represents one peer of a overlay network
+// Copy makes a copy of the endpoint ipam config
+func (cfg *EndpointIPAMConfig) Copy() *EndpointIPAMConfig {
+ cfgCopy := *cfg
+ cfgCopy.LinkLocalIPs = make([]string, 0, len(cfg.LinkLocalIPs))
+ cfgCopy.LinkLocalIPs = append(cfgCopy.LinkLocalIPs, cfg.LinkLocalIPs...)
+ return &cfgCopy
+}
+
+// PeerInfo represents one peer of an overlay network
type PeerInfo struct {
Name string
IP string
@@ -50,6 +58,42 @@ type EndpointSettings struct {
GlobalIPv6Address string
GlobalIPv6PrefixLen int
MacAddress string
+ DriverOpts map[string]string
+}
+
+// Task carries the information about one backend task
+type Task struct {
+ Name string
+ EndpointID string
+ EndpointIP string
+ Info map[string]string
+}
+
+// ServiceInfo represents service parameters with the list of service's tasks
+type ServiceInfo struct {
+ VIP string
+ Ports []string
+ LocalLBIndex int
+ Tasks []Task
+}
+
+// Copy makes a deep copy of `EndpointSettings`
+func (es *EndpointSettings) Copy() *EndpointSettings {
+ epCopy := *es
+ if es.IPAMConfig != nil {
+ epCopy.IPAMConfig = es.IPAMConfig.Copy()
+ }
+
+ if es.Links != nil {
+ links := make([]string, 0, len(es.Links))
+ epCopy.Links = append(links, es.Links...)
+ }
+
+ if es.Aliases != nil {
+ aliases := make([]string, 0, len(es.Aliases))
+ epCopy.Aliases = append(aliases, es.Aliases...)
+ }
+ return &epCopy
}
// NetworkingConfig represents the container's networking configuration for each of its interfaces
@@ -57,3 +101,8 @@ type EndpointSettings struct {
type NetworkingConfig struct {
EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network
}
+
+// ConfigReference specifies the source which provides a network's configuration
+type ConfigReference struct {
+ Network string
+}
diff --git a/vendor/github.com/docker/docker/api/types/plugin.go b/vendor/github.com/docker/docker/api/types/plugin.go
index 6cc7a23b..cab333e0 100644
--- a/vendor/github.com/docker/docker/api/types/plugin.go
+++ b/vendor/github.com/docker/docker/api/types/plugin.go
@@ -11,7 +11,7 @@ type Plugin struct {
// Required: true
Config PluginConfig `json:"Config"`
- // True when the plugin is running. False when the plugin is not running, only installed.
+ // True if the plugin is running. False if the plugin is not running, only installed.
// Required: true
Enabled bool `json:"Enabled"`
@@ -42,6 +42,9 @@ type PluginConfig struct {
// Required: true
Description string `json:"Description"`
+ // Docker Version used to create the plugin
+ DockerVersion string `json:"DockerVersion,omitempty"`
+
// documentation
// Required: true
Documentation string `json:"Documentation"`
@@ -58,6 +61,10 @@ type PluginConfig struct {
// Required: true
Interface PluginConfigInterface `json:"Interface"`
+ // ipc host
+ // Required: true
+ IpcHost bool `json:"IpcHost"`
+
// linux
// Required: true
Linux PluginConfigLinux `json:"Linux"`
@@ -70,6 +77,10 @@ type PluginConfig struct {
// Required: true
Network PluginConfigNetwork `json:"Network"`
+ // pid host
+ // Required: true
+ PidHost bool `json:"PidHost"`
+
// propagated mount
// Required: true
PropagatedMount string `json:"PropagatedMount"`
diff --git a/vendor/github.com/docker/docker/api/types/plugin_responses.go b/vendor/github.com/docker/docker/api/types/plugin_responses.go
index d6f75531..18f743fc 100644
--- a/vendor/github.com/docker/docker/api/types/plugin_responses.go
+++ b/vendor/github.com/docker/docker/api/types/plugin_responses.go
@@ -3,19 +3,12 @@ package types
import (
"encoding/json"
"fmt"
+ "sort"
)
// PluginsListResponse contains the response for the Engine API
type PluginsListResponse []*Plugin
-const (
- authzDriver = "AuthzDriver"
- graphDriver = "GraphDriver"
- ipamDriver = "IpamDriver"
- networkDriver = "NetworkDriver"
- volumeDriver = "VolumeDriver"
-)
-
// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType
func (t *PluginInterfaceType) UnmarshalJSON(p []byte) error {
versionIndex := len(p)
@@ -62,3 +55,17 @@ type PluginPrivilege struct {
// PluginPrivileges is a list of PluginPrivilege
type PluginPrivileges []PluginPrivilege
+
+func (s PluginPrivileges) Len() int {
+ return len(s)
+}
+
+func (s PluginPrivileges) Less(i, j int) bool {
+ return s[i].Name < s[j].Name
+}
+
+func (s PluginPrivileges) Swap(i, j int) {
+ sort.Strings(s[i].Value)
+ sort.Strings(s[j].Value)
+ s[i], s[j] = s[j], s[i]
+}
diff --git a/vendor/github.com/docker/docker/api/types/reference/image_reference.go b/vendor/github.com/docker/docker/api/types/reference/image_reference.go
deleted file mode 100644
index be9cf8eb..00000000
--- a/vendor/github.com/docker/docker/api/types/reference/image_reference.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package reference
-
-import (
- distreference "github.com/docker/distribution/reference"
-)
-
-// Parse parses the given references and returns the repository and
-// tag (if present) from it. If there is an error during parsing, it will
-// return an error.
-func Parse(ref string) (string, string, error) {
- distributionRef, err := distreference.ParseNamed(ref)
- if err != nil {
- return "", "", err
- }
-
- tag := GetTagFromNamedRef(distributionRef)
- return distributionRef.Name(), tag, nil
-}
-
-// GetTagFromNamedRef returns a tag from the specified reference.
-// This function is necessary as long as the docker "server" api makes the distinction between repository
-// and tags.
-func GetTagFromNamedRef(ref distreference.Named) string {
- var tag string
- switch x := ref.(type) {
- case distreference.Digested:
- tag = x.Digest().String()
- case distreference.NamedTagged:
- tag = x.Tag()
- default:
- tag = "latest"
- }
- return tag
-}
diff --git a/vendor/github.com/docker/docker/api/types/registry/authenticate.go b/vendor/github.com/docker/docker/api/types/registry/authenticate.go
index 5e37d19b..42cac443 100644
--- a/vendor/github.com/docker/docker/api/types/registry/authenticate.go
+++ b/vendor/github.com/docker/docker/api/types/registry/authenticate.go
@@ -4,7 +4,7 @@ package registry
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// AuthenticateOKBody authenticate o k body
diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go
index 28fafab9..b98a943a 100644
--- a/vendor/github.com/docker/docker/api/types/registry/registry.go
+++ b/vendor/github.com/docker/docker/api/types/registry/registry.go
@@ -3,13 +3,17 @@ package registry
import (
"encoding/json"
"net"
+
+ "github.com/opencontainers/image-spec/specs-go/v1"
)
// ServiceConfig stores daemon registry services configuration.
type ServiceConfig struct {
- InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
- IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
- Mirrors []string
+ AllowNondistributableArtifactsCIDRs []*NetIPNet
+ AllowNondistributableArtifactsHostnames []string
+ InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"`
+ IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"`
+ Mirrors []string
}
// NetIPNet is the net.IPNet type, which can be marshalled and
@@ -102,3 +106,14 @@ type SearchResults struct {
// Results is a slice containing the actual results for the search
Results []SearchResult `json:"results"`
}
+
+// DistributionInspect describes the result obtained from contacting the
+// registry to retrieve image metadata
+type DistributionInspect struct {
+ // Descriptor contains information about the manifest, including
+ // the content addressable digest
+ Descriptor v1.Descriptor
+ // Platforms contains the list of platforms supported by the image,
+ // obtained by parsing the manifest
+ Platforms []v1.Platform
+}
diff --git a/vendor/github.com/docker/docker/api/types/seccomp.go b/vendor/github.com/docker/docker/api/types/seccomp.go
index 4f02ef36..7d62c9a4 100644
--- a/vendor/github.com/docker/docker/api/types/seccomp.go
+++ b/vendor/github.com/docker/docker/api/types/seccomp.go
@@ -10,7 +10,7 @@ type Seccomp struct {
Syscalls []*Syscall `json:"syscalls"`
}
-// Architecture is used to represent an specific architecture
+// Architecture is used to represent a specific architecture
// and its sub-architectures
type Architecture struct {
Arch Arch `json:"architecture"`
diff --git a/vendor/github.com/docker/docker/api/types/stats.go b/vendor/github.com/docker/docker/api/types/stats.go
index 9bf1928b..7ca76a5b 100644
--- a/vendor/github.com/docker/docker/api/types/stats.go
+++ b/vendor/github.com/docker/docker/api/types/stats.go
@@ -47,6 +47,9 @@ type CPUStats struct {
// System Usage. Linux only.
SystemUsage uint64 `json:"system_cpu_usage,omitempty"`
+ // Online CPUs. Linux only.
+ OnlineCPUs uint32 `json:"online_cpus,omitempty"`
+
// Throttling Data. Linux only.
ThrottlingData ThrottlingData `json:"throttling_data,omitempty"`
}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/common.go b/vendor/github.com/docker/docker/api/types/swarm/common.go
index 64a648ba..2834cf20 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/common.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/common.go
@@ -17,11 +17,24 @@ type Meta struct {
// Annotations represents how to describe an object.
type Annotations struct {
Name string `json:",omitempty"`
- Labels map[string]string `json:",omitempty"`
+ Labels map[string]string `json:"Labels"`
}
-// Driver represents a driver (network, logging).
+// Driver represents a driver (network, logging, secrets backend).
type Driver struct {
Name string `json:",omitempty"`
Options map[string]string `json:",omitempty"`
}
+
+// TLSInfo represents the TLS information about what CA certificate is trusted,
+// and who the issuer for a TLS certificate is
+type TLSInfo struct {
+ // TrustRoot is the trusted CA root certificate in PEM format
+ TrustRoot string `json:",omitempty"`
+
+ // CertIssuer is the raw subject bytes of the issuer
+ CertIssuerSubject []byte `json:",omitempty"`
+
+ // CertIssuerPublicKey is the raw public key bytes of the issuer
+ CertIssuerPublicKey []byte `json:",omitempty"`
+}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/config.go b/vendor/github.com/docker/docker/api/types/swarm/config.go
new file mode 100644
index 00000000..0fb021ce
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/swarm/config.go
@@ -0,0 +1,31 @@
+package swarm
+
+import "os"
+
+// Config represents a config.
+type Config struct {
+ ID string
+ Meta
+ Spec ConfigSpec
+}
+
+// ConfigSpec represents a config specification from a config in swarm
+type ConfigSpec struct {
+ Annotations
+ Data []byte `json:",omitempty"`
+}
+
+// ConfigReferenceFileTarget is a file target in a config reference
+type ConfigReferenceFileTarget struct {
+ Name string
+ UID string
+ GID string
+ Mode os.FileMode
+}
+
+// ConfigReference is a reference to a config in swarm
+type ConfigReference struct {
+ File *ConfigReferenceFileTarget
+ ConfigID string
+ ConfigName string
+}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/container.go b/vendor/github.com/docker/docker/api/types/swarm/container.go
index 4ab476cc..6f8b45f6 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/container.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/container.go
@@ -21,6 +21,28 @@ type DNSConfig struct {
Options []string `json:",omitempty"`
}
+// SELinuxContext contains the SELinux labels of the container.
+type SELinuxContext struct {
+ Disable bool
+
+ User string
+ Role string
+ Type string
+ Level string
+}
+
+// CredentialSpec for managed service account (Windows only)
+type CredentialSpec struct {
+ File string
+ Registry string
+}
+
+// Privileges defines the security options for the container.
+type Privileges struct {
+ CredentialSpec *CredentialSpec
+ SELinuxContext *SELinuxContext
+}
+
// ContainerSpec represents the spec of a container.
type ContainerSpec struct {
Image string `json:",omitempty"`
@@ -32,8 +54,11 @@ type ContainerSpec struct {
Dir string `json:",omitempty"`
User string `json:",omitempty"`
Groups []string `json:",omitempty"`
+ Privileges *Privileges `json:",omitempty"`
+ StopSignal string `json:",omitempty"`
TTY bool `json:",omitempty"`
OpenStdin bool `json:",omitempty"`
+ ReadOnly bool `json:",omitempty"`
Mounts []mount.Mount `json:",omitempty"`
StopGracePeriod *time.Duration `json:",omitempty"`
Healthcheck *container.HealthConfig `json:",omitempty"`
@@ -43,4 +68,5 @@ type ContainerSpec struct {
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
+ Configs []*ConfigReference `json:",omitempty"`
}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/network.go b/vendor/github.com/docker/docker/api/types/swarm/network.go
index 5a5e11bd..97c484e1 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/network.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/network.go
@@ -1,5 +1,9 @@
package swarm
+import (
+ "github.com/docker/docker/api/types/network"
+)
+
// Endpoint represents an endpoint.
type Endpoint struct {
Spec EndpointSpec `json:",omitempty"`
@@ -78,17 +82,21 @@ type Network struct {
// NetworkSpec represents the spec of a network.
type NetworkSpec struct {
Annotations
- DriverConfiguration *Driver `json:",omitempty"`
- IPv6Enabled bool `json:",omitempty"`
- Internal bool `json:",omitempty"`
- Attachable bool `json:",omitempty"`
- IPAMOptions *IPAMOptions `json:",omitempty"`
+ DriverConfiguration *Driver `json:",omitempty"`
+ IPv6Enabled bool `json:",omitempty"`
+ Internal bool `json:",omitempty"`
+ Attachable bool `json:",omitempty"`
+ Ingress bool `json:",omitempty"`
+ IPAMOptions *IPAMOptions `json:",omitempty"`
+ ConfigFrom *network.ConfigReference `json:",omitempty"`
+ Scope string `json:",omitempty"`
}
// NetworkAttachmentConfig represents the configuration of a network attachment.
type NetworkAttachmentConfig struct {
- Target string `json:",omitempty"`
- Aliases []string `json:",omitempty"`
+ Target string `json:",omitempty"`
+ Aliases []string `json:",omitempty"`
+ DriverOpts map[string]string `json:",omitempty"`
}
// NetworkAttachment represents a network attachment.
diff --git a/vendor/github.com/docker/docker/api/types/swarm/node.go b/vendor/github.com/docker/docker/api/types/swarm/node.go
index 379e17a7..28c6851e 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/node.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/node.go
@@ -52,6 +52,7 @@ type NodeDescription struct {
Platform Platform `json:",omitempty"`
Resources Resources `json:",omitempty"`
Engine EngineDescription `json:",omitempty"`
+ TLSInfo TLSInfo `json:",omitempty"`
}
// Platform represents the platform (Arch/OS).
diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime.go b/vendor/github.com/docker/docker/api/types/swarm/runtime.go
new file mode 100644
index 00000000..c4c731dc
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/swarm/runtime.go
@@ -0,0 +1,19 @@
+package swarm
+
+// RuntimeType is the type of runtime used for the TaskSpec
+type RuntimeType string
+
+// RuntimeURL is the proto type url
+type RuntimeURL string
+
+const (
+ // RuntimeContainer is the container based runtime
+ RuntimeContainer RuntimeType = "container"
+ // RuntimePlugin is the plugin based runtime
+ RuntimePlugin RuntimeType = "plugin"
+
+ // RuntimeURLContainer is the proto url for the container type
+ RuntimeURLContainer RuntimeURL = "types.docker.com/RuntimeContainer"
+ // RuntimeURLPlugin is the proto url for the plugin type
+ RuntimeURLPlugin RuntimeURL = "types.docker.com/RuntimePlugin"
+)
diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go
new file mode 100644
index 00000000..47ae234e
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go
@@ -0,0 +1,3 @@
+//go:generate protoc -I . --gogofast_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto
+
+package runtime
diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go
new file mode 100644
index 00000000..1fdc9b04
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go
@@ -0,0 +1,712 @@
+// Code generated by protoc-gen-gogo.
+// source: plugin.proto
+// DO NOT EDIT!
+
+/*
+ Package runtime is a generated protocol buffer package.
+
+ It is generated from these files:
+ plugin.proto
+
+ It has these top-level messages:
+ PluginSpec
+ PluginPrivilege
+*/
+package runtime
+
+import proto "github.com/gogo/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+// PluginSpec defines the base payload which clients can specify for creating
+// a service with the plugin runtime.
+type PluginSpec struct {
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
+ Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
+ Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
+}
+
+func (m *PluginSpec) Reset() { *m = PluginSpec{} }
+func (m *PluginSpec) String() string { return proto.CompactTextString(m) }
+func (*PluginSpec) ProtoMessage() {}
+func (*PluginSpec) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{0} }
+
+func (m *PluginSpec) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *PluginSpec) GetRemote() string {
+ if m != nil {
+ return m.Remote
+ }
+ return ""
+}
+
+func (m *PluginSpec) GetPrivileges() []*PluginPrivilege {
+ if m != nil {
+ return m.Privileges
+ }
+ return nil
+}
+
+func (m *PluginSpec) GetDisabled() bool {
+ if m != nil {
+ return m.Disabled
+ }
+ return false
+}
+
+// PluginPrivilege describes a permission the user has to accept
+// upon installing a plugin.
+type PluginPrivilege struct {
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ Value []string `protobuf:"bytes,3,rep,name=value" json:"value,omitempty"`
+}
+
+func (m *PluginPrivilege) Reset() { *m = PluginPrivilege{} }
+func (m *PluginPrivilege) String() string { return proto.CompactTextString(m) }
+func (*PluginPrivilege) ProtoMessage() {}
+func (*PluginPrivilege) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{1} }
+
+func (m *PluginPrivilege) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *PluginPrivilege) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *PluginPrivilege) GetValue() []string {
+ if m != nil {
+ return m.Value
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*PluginSpec)(nil), "PluginSpec")
+ proto.RegisterType((*PluginPrivilege)(nil), "PluginPrivilege")
+}
+func (m *PluginSpec) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalTo(dAtA)
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
+ var i int
+ _ = i
+ var l int
+ _ = l
+ if len(m.Name) > 0 {
+ dAtA[i] = 0xa
+ i++
+ i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
+ i += copy(dAtA[i:], m.Name)
+ }
+ if len(m.Remote) > 0 {
+ dAtA[i] = 0x12
+ i++
+ i = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote)))
+ i += copy(dAtA[i:], m.Remote)
+ }
+ if len(m.Privileges) > 0 {
+ for _, msg := range m.Privileges {
+ dAtA[i] = 0x1a
+ i++
+ i = encodeVarintPlugin(dAtA, i, uint64(msg.Size()))
+ n, err := msg.MarshalTo(dAtA[i:])
+ if err != nil {
+ return 0, err
+ }
+ i += n
+ }
+ }
+ if m.Disabled {
+ dAtA[i] = 0x20
+ i++
+ if m.Disabled {
+ dAtA[i] = 1
+ } else {
+ dAtA[i] = 0
+ }
+ i++
+ }
+ return i, nil
+}
+
+func (m *PluginPrivilege) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalTo(dAtA)
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
+ var i int
+ _ = i
+ var l int
+ _ = l
+ if len(m.Name) > 0 {
+ dAtA[i] = 0xa
+ i++
+ i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
+ i += copy(dAtA[i:], m.Name)
+ }
+ if len(m.Description) > 0 {
+ dAtA[i] = 0x12
+ i++
+ i = encodeVarintPlugin(dAtA, i, uint64(len(m.Description)))
+ i += copy(dAtA[i:], m.Description)
+ }
+ if len(m.Value) > 0 {
+ for _, s := range m.Value {
+ dAtA[i] = 0x1a
+ i++
+ l = len(s)
+ for l >= 1<<7 {
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+ l >>= 7
+ i++
+ }
+ dAtA[i] = uint8(l)
+ i++
+ i += copy(dAtA[i:], s)
+ }
+ }
+ return i, nil
+}
+
+func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int {
+ dAtA[offset] = uint8(v)
+ dAtA[offset+1] = uint8(v >> 8)
+ dAtA[offset+2] = uint8(v >> 16)
+ dAtA[offset+3] = uint8(v >> 24)
+ dAtA[offset+4] = uint8(v >> 32)
+ dAtA[offset+5] = uint8(v >> 40)
+ dAtA[offset+6] = uint8(v >> 48)
+ dAtA[offset+7] = uint8(v >> 56)
+ return offset + 8
+}
+func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int {
+ dAtA[offset] = uint8(v)
+ dAtA[offset+1] = uint8(v >> 8)
+ dAtA[offset+2] = uint8(v >> 16)
+ dAtA[offset+3] = uint8(v >> 24)
+ return offset + 4
+}
+func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return offset + 1
+}
+func (m *PluginSpec) Size() (n int) {
+ var l int
+ _ = l
+ l = len(m.Name)
+ if l > 0 {
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ l = len(m.Remote)
+ if l > 0 {
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ if len(m.Privileges) > 0 {
+ for _, e := range m.Privileges {
+ l = e.Size()
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ }
+ if m.Disabled {
+ n += 2
+ }
+ return n
+}
+
+func (m *PluginPrivilege) Size() (n int) {
+ var l int
+ _ = l
+ l = len(m.Name)
+ if l > 0 {
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ l = len(m.Description)
+ if l > 0 {
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ if len(m.Value) > 0 {
+ for _, s := range m.Value {
+ l = len(s)
+ n += 1 + l + sovPlugin(uint64(l))
+ }
+ }
+ return n
+}
+
+func sovPlugin(x uint64) (n int) {
+ for {
+ n++
+ x >>= 7
+ if x == 0 {
+ break
+ }
+ }
+ return n
+}
+func sozPlugin(x uint64) (n int) {
+ return sovPlugin(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (m *PluginSpec) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: PluginSpec: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: PluginSpec: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Name = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Remote", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Remote = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Privileges", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + msglen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Privileges = append(m.Privileges, &PluginPrivilege{})
+ if err := m.Privileges[len(m.Privileges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Disabled", wireType)
+ }
+ var v int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ v |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ m.Disabled = bool(v != 0)
+ default:
+ iNdEx = preIndex
+ skippy, err := skipPlugin(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: PluginPrivilege: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: PluginPrivilege: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Name = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Description = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Value = append(m.Value, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipPlugin(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthPlugin
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipPlugin(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ return iNdEx, nil
+ case 1:
+ iNdEx += 8
+ return iNdEx, nil
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ iNdEx += length
+ if length < 0 {
+ return 0, ErrInvalidLengthPlugin
+ }
+ return iNdEx, nil
+ case 3:
+ for {
+ var innerWire uint64
+ var start int = iNdEx
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowPlugin
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ innerWire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ innerWireType := int(innerWire & 0x7)
+ if innerWireType == 4 {
+ break
+ }
+ next, err := skipPlugin(dAtA[start:])
+ if err != nil {
+ return 0, err
+ }
+ iNdEx = start + next
+ }
+ return iNdEx, nil
+ case 4:
+ return iNdEx, nil
+ case 5:
+ iNdEx += 4
+ return iNdEx, nil
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ }
+ panic("unreachable")
+}
+
+var (
+ ErrInvalidLengthPlugin = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowPlugin = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
+
+var fileDescriptorPlugin = []byte{
+ // 196 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
+ 0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b,
+ 0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30,
+ 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12,
+ 0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35,
+ 0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c,
+ 0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a,
+ 0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab,
+ 0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
+ 0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33,
+ 0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
+ 0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79,
+ 0x0c, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto
new file mode 100644
index 00000000..06eb7ba6
--- /dev/null
+++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto
@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+// PluginSpec defines the base payload which clients can specify for creating
+// a service with the plugin runtime.
+message PluginSpec {
+ string name = 1;
+ string remote = 2;
+ repeated PluginPrivilege privileges = 3;
+ bool disabled = 4;
+}
+
+// PluginPrivilege describes a permission the user has to accept
+// upon installing a plugin.
+message PluginPrivilege {
+ string name = 1;
+ string description = 2;
+ repeated string value = 3;
+}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/secret.go b/vendor/github.com/docker/docker/api/types/swarm/secret.go
index fdb23888..f9b1e926 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/secret.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/secret.go
@@ -12,7 +12,8 @@ type Secret struct {
// SecretSpec represents a secret specification from a secret in swarm
type SecretSpec struct {
Annotations
- Data []byte `json:",omitempty"`
+ Data []byte `json:",omitempty"`
+ Driver *Driver `json:",omitempty"` // name of the secrets driver used to fetch the secret's value from an external secret store
}
// SecretReferenceFileTarget is a file target in a secret reference
diff --git a/vendor/github.com/docker/docker/api/types/swarm/service.go b/vendor/github.com/docker/docker/api/types/swarm/service.go
index 2cf2642c..fa31a7ec 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/service.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/service.go
@@ -6,10 +6,10 @@ import "time"
type Service struct {
ID string
Meta
- Spec ServiceSpec `json:",omitempty"`
- PreviousSpec *ServiceSpec `json:",omitempty"`
- Endpoint Endpoint `json:",omitempty"`
- UpdateStatus UpdateStatus `json:",omitempty"`
+ Spec ServiceSpec `json:",omitempty"`
+ PreviousSpec *ServiceSpec `json:",omitempty"`
+ Endpoint Endpoint `json:",omitempty"`
+ UpdateStatus *UpdateStatus `json:",omitempty"`
}
// ServiceSpec represents the spec of a service.
@@ -18,9 +18,10 @@ type ServiceSpec struct {
// TaskTemplate defines how the service should construct new tasks when
// orchestrating this service.
- TaskTemplate TaskSpec `json:",omitempty"`
- Mode ServiceMode `json:",omitempty"`
- UpdateConfig *UpdateConfig `json:",omitempty"`
+ TaskTemplate TaskSpec `json:",omitempty"`
+ Mode ServiceMode `json:",omitempty"`
+ UpdateConfig *UpdateConfig `json:",omitempty"`
+ RollbackConfig *UpdateConfig `json:",omitempty"`
// Networks field in ServiceSpec is deprecated. The
// same field in TaskSpec should be used instead.
@@ -45,13 +46,19 @@ const (
UpdateStatePaused UpdateState = "paused"
// UpdateStateCompleted is the completed state.
UpdateStateCompleted UpdateState = "completed"
+ // UpdateStateRollbackStarted is the state with a rollback in progress.
+ UpdateStateRollbackStarted UpdateState = "rollback_started"
+ // UpdateStateRollbackPaused is the state with a rollback in progress.
+ UpdateStateRollbackPaused UpdateState = "rollback_paused"
+ // UpdateStateRollbackCompleted is the state with a rollback in progress.
+ UpdateStateRollbackCompleted UpdateState = "rollback_completed"
)
// UpdateStatus reports the status of a service update.
type UpdateStatus struct {
State UpdateState `json:",omitempty"`
- StartedAt time.Time `json:",omitempty"`
- CompletedAt time.Time `json:",omitempty"`
+ StartedAt *time.Time `json:",omitempty"`
+ CompletedAt *time.Time `json:",omitempty"`
Message string `json:",omitempty"`
}
@@ -68,6 +75,13 @@ const (
UpdateFailureActionPause = "pause"
// UpdateFailureActionContinue CONTINUE
UpdateFailureActionContinue = "continue"
+ // UpdateFailureActionRollback ROLLBACK
+ UpdateFailureActionRollback = "rollback"
+
+ // UpdateOrderStopFirst STOP_FIRST
+ UpdateOrderStopFirst = "stop-first"
+ // UpdateOrderStartFirst START_FIRST
+ UpdateOrderStartFirst = "start-first"
)
// UpdateConfig represents the update configuration.
@@ -102,4 +116,9 @@ type UpdateConfig struct {
// If the failure action is PAUSE, no more tasks will be updated until
// another update is started.
MaxFailureRatio float32
+
+ // Order indicates the order of operations when rolling out an updated
+ // task. Either the old task is shut down before the new task is
+ // started, or the new task is started before the old task is shut down.
+ Order string
}
diff --git a/vendor/github.com/docker/docker/api/types/swarm/swarm.go b/vendor/github.com/docker/docker/api/types/swarm/swarm.go
index 0b422196..b65fa86d 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/swarm.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/swarm.go
@@ -2,12 +2,14 @@ package swarm
import "time"
-// ClusterInfo represents info about the cluster for outputing in "info"
+// ClusterInfo represents info about the cluster for outputting in "info"
// it contains the same information as "Swarm", but without the JoinTokens
type ClusterInfo struct {
ID string
Meta
- Spec Spec
+ Spec Spec
+ TLSInfo TLSInfo
+ RootRotationInProgress bool
}
// Swarm represents a swarm.
@@ -107,6 +109,16 @@ type CAConfig struct {
// ExternalCAs is a list of CAs to which a manager node will make
// certificate signing requests for node certificates.
ExternalCAs []*ExternalCA `json:",omitempty"`
+
+ // SigningCACert and SigningCAKey specify the desired signing root CA and
+ // root CA key for the swarm. When inspecting the cluster, the key will
+ // be redacted.
+ SigningCACert string `json:",omitempty"`
+ SigningCAKey string `json:",omitempty"`
+
+ // If this value changes, and there is no specified signing cert and key,
+ // then the swarm is forced to generate a new root certificate ane key.
+ ForceRotate uint64 `json:",omitempty"`
}
// ExternalCAProtocol represents type of external CA.
@@ -126,23 +138,31 @@ type ExternalCA struct {
// Options is a set of additional key/value pairs whose interpretation
// depends on the specified CA type.
Options map[string]string `json:",omitempty"`
+
+ // CACert specifies which root CA is used by this external CA. This certificate must
+ // be in PEM format.
+ CACert string
}
// InitRequest is the request used to init a swarm.
type InitRequest struct {
ListenAddr string
AdvertiseAddr string
+ DataPathAddr string
ForceNewCluster bool
Spec Spec
AutoLockManagers bool
+ Availability NodeAvailability
}
// JoinRequest is the request used to join a swarm.
type JoinRequest struct {
ListenAddr string
AdvertiseAddr string
+ DataPathAddr string
RemoteAddrs []string
JoinToken string // accept by secret
+ Availability NodeAvailability
}
// UnlockRequest is the request used to unlock a swarm.
@@ -177,10 +197,10 @@ type Info struct {
Error string
RemoteManagers []Peer
- Nodes int
- Managers int
+ Nodes int `json:",omitempty"`
+ Managers int `json:",omitempty"`
- Cluster ClusterInfo
+ Cluster *ClusterInfo `json:",omitempty"`
}
// Peer represents a peer.
diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/docker/docker/api/types/swarm/task.go
index ace12cc8..ff11b07e 100644
--- a/vendor/github.com/docker/docker/api/types/swarm/task.go
+++ b/vendor/github.com/docker/docker/api/types/swarm/task.go
@@ -1,6 +1,10 @@
package swarm
-import "time"
+import (
+ "time"
+
+ "github.com/docker/docker/api/types/swarm/runtime"
+)
// TaskState represents the state of a task.
type TaskState string
@@ -47,11 +51,16 @@ type Task struct {
Status TaskStatus `json:",omitempty"`
DesiredState TaskState `json:",omitempty"`
NetworksAttachments []NetworkAttachment `json:",omitempty"`
+ GenericResources []GenericResource `json:",omitempty"`
}
// TaskSpec represents the spec of a task.
type TaskSpec struct {
- ContainerSpec ContainerSpec `json:",omitempty"`
+ // ContainerSpec and PluginSpec are mutually exclusive.
+ // PluginSpec will only be used when the `Runtime` field is set to `plugin`
+ ContainerSpec *ContainerSpec `json:",omitempty"`
+ PluginSpec *runtime.PluginSpec `json:",omitempty"`
+
Resources *ResourceRequirements `json:",omitempty"`
RestartPolicy *RestartPolicy `json:",omitempty"`
Placement *Placement `json:",omitempty"`
@@ -65,12 +74,40 @@ type TaskSpec struct {
// ForceUpdate is a counter that triggers an update even if no relevant
// parameters have been changed.
ForceUpdate uint64
+
+ Runtime RuntimeType `json:",omitempty"`
}
// Resources represents resources (CPU/Memory).
type Resources struct {
- NanoCPUs int64 `json:",omitempty"`
- MemoryBytes int64 `json:",omitempty"`
+ NanoCPUs int64 `json:",omitempty"`
+ MemoryBytes int64 `json:",omitempty"`
+ GenericResources []GenericResource `json:",omitempty"`
+}
+
+// GenericResource represents a "user defined" resource which can
+// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)
+type GenericResource struct {
+ NamedResourceSpec *NamedGenericResource `json:",omitempty"`
+ DiscreteResourceSpec *DiscreteGenericResource `json:",omitempty"`
+}
+
+// NamedGenericResource represents a "user defined" resource which is defined
+// as a string.
+// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
+// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...)
+type NamedGenericResource struct {
+ Kind string `json:",omitempty"`
+ Value string `json:",omitempty"`
+}
+
+// DiscreteGenericResource represents a "user defined" resource which is defined
+// as an integer
+// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
+// Value is used to count the resource (SSD=5, HDD=3, ...)
+type DiscreteGenericResource struct {
+ Kind string `json:",omitempty"`
+ Value int64 `json:",omitempty"`
}
// ResourceRequirements represents resources requirements.
@@ -81,7 +118,26 @@ type ResourceRequirements struct {
// Placement represents orchestration parameters.
type Placement struct {
- Constraints []string `json:",omitempty"`
+ Constraints []string `json:",omitempty"`
+ Preferences []PlacementPreference `json:",omitempty"`
+
+ // Platforms stores all the platforms that the image can run on.
+ // This field is used in the platform filter for scheduling. If empty,
+ // then the platform filter is off, meaning there are no scheduling restrictions.
+ Platforms []Platform `json:",omitempty"`
+}
+
+// PlacementPreference provides a way to make the scheduler aware of factors
+// such as topology.
+type PlacementPreference struct {
+ Spread *SpreadOver
+}
+
+// SpreadOver is a scheduling preference that instructs the scheduler to spread
+// tasks evenly over groups of nodes identified by labels.
+type SpreadOver struct {
+ // label descriptor, such as engine.labels.az
+ SpreadDescriptor string
}
// RestartPolicy represents the restart policy.
diff --git a/vendor/github.com/docker/docker/api/types/time/timestamp.go b/vendor/github.com/docker/docker/api/types/time/timestamp.go
index d3695ba7..9aa9702d 100644
--- a/vendor/github.com/docker/docker/api/types/time/timestamp.go
+++ b/vendor/github.com/docker/docker/api/types/time/timestamp.go
@@ -84,7 +84,7 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
}
if err != nil {
- // if there is a `-` then its an RFC3339 like timestamp otherwise assume unixtimestamp
+ // if there is a `-` then it's an RFC3339 like timestamp otherwise assume unixtimestamp
if strings.Contains(value, "-") {
return "", err // was probably an RFC3339 like timestamp but the parser failed with an error
}
@@ -118,7 +118,7 @@ func ParseTimestamps(value string, def int64) (int64, int64, error) {
if err != nil {
return s, n, err
}
- // should already be in nanoseconds but just in case convert n to nanoseonds
+ // should already be in nanoseconds but just in case convert n to nanoseconds
n = int64(float64(n) * math.Pow(float64(10), float64(9-len(sa[1]))))
return s, n, nil
}
diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go
index a82c3e88..f7ac7729 100644
--- a/vendor/github.com/docker/docker/api/types/types.go
+++ b/vendor/github.com/docker/docker/api/types/types.go
@@ -17,38 +17,6 @@ import (
"github.com/docker/go-connections/nat"
)
-// ContainerChange contains response of Engine API:
-// GET "/containers/{name:.*}/changes"
-type ContainerChange struct {
- Kind int
- Path string
-}
-
-// ImageHistory contains response of Engine API:
-// GET "/images/{name:.*}/history"
-type ImageHistory struct {
- ID string `json:"Id"`
- Created int64
- CreatedBy string
- Tags []string
- Size int64
- Comment string
-}
-
-// ImageDelete contains response of Engine API:
-// DELETE "/images/{name:.*}"
-type ImageDelete struct {
- Untagged string `json:",omitempty"`
- Deleted string `json:",omitempty"`
-}
-
-// GraphDriverData returns Image's graph driver config info
-// when calling inspect command
-type GraphDriverData struct {
- Name string
- Data map[string]string
-}
-
// RootFS returns Image's RootFS description including the layer IDs.
type RootFS struct {
Type string
@@ -77,6 +45,12 @@ type ImageInspect struct {
VirtualSize int64
GraphDriver GraphDriverData
RootFS RootFS
+ Metadata ImageMetadata
+}
+
+// ImageMetadata contains engine-local data about the image
+type ImageMetadata struct {
+ LastTagTime time.Time `json:",omitempty"`
}
// Container contains response of Engine API:
@@ -125,17 +99,11 @@ type ContainerStats struct {
OSType string `json:"ostype"`
}
-// ContainerProcessList contains response of Engine API:
-// GET "/containers/{name:.*}/top"
-type ContainerProcessList struct {
- Processes [][]string
- Titles []string
-}
-
// Ping contains response of Engine API:
// GET "/_ping"
type Ping struct {
APIVersion string
+ OSType string
Experimental bool
}
@@ -154,11 +122,11 @@ type Version struct {
BuildTime string `json:",omitempty"`
}
-// Commit records a external tool actual commit id version along the
-// one expect by dockerd as set at build time
+// Commit holds the Git-commit (SHA1) that a binary was built from, as reported
+// in the version-string of external tools, such as containerd, or runC.
type Commit struct {
- ID string
- Expected string
+ ID string // ID is the actual commit ID of external tool.
+ Expected string // Expected is the commit ID of external tool expected by dockerd as set at build time.
}
// Info contains response of Engine API:
@@ -200,6 +168,7 @@ type Info struct {
RegistryConfig *registry.ServiceConfig
NCPU int
MemTotal int64
+ GenericResources []swarm.GenericResource
DockerRootDir string
HTTPProxy string `json:"HttpProxy"`
HTTPSProxy string `json:"HttpsProxy"`
@@ -276,6 +245,8 @@ type PluginsInfo struct {
Network []string
// List of Authorization plugins registered
Authorization []string
+ // List of Log plugins registered
+ Log []string
}
// ExecStartCheck is a temp struct used by execStart
@@ -313,7 +284,7 @@ type Health struct {
// ContainerState stores container's running state
// it's part of ContainerJSONBase and will return by "inspect" command
type ContainerState struct {
- Status string
+ Status string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead"
Running bool
Paused bool
Restarting bool
@@ -356,6 +327,7 @@ type ContainerJSONBase struct {
Name string
RestartCount int
Driver string
+ Platform string
MountLabel string
ProcessLabel string
AppArmorProfile string
@@ -429,19 +401,23 @@ type MountPoint struct {
// NetworkResource is the body of the "get network" http response message
type NetworkResource struct {
- Name string // Name is the requested name of the network
- ID string `json:"Id"` // ID uniquely identifies a network on a single machine
- Created time.Time // Created is the time the network created
- Scope string // Scope describes the level at which the network exists (e.g. `global` for cluster-wide or `local` for machine level)
- Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
- EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6
- IPAM network.IPAM // IPAM is the network's IP Address Management
- Internal bool // Internal represents if the network is used internal only
- Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
- Containers map[string]EndpointResource // Containers contains endpoints belonging to the network
- Options map[string]string // Options holds the network specific options to use for when creating the network
- Labels map[string]string // Labels holds metadata specific to the network being created
- Peers []network.PeerInfo `json:",omitempty"` // List of peer nodes for an overlay network
+ Name string // Name is the requested name of the network
+ ID string `json:"Id"` // ID uniquely identifies a network on a single machine
+ Created time.Time // Created is the time the network created
+ Scope string // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)
+ Driver string // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)
+ EnableIPv6 bool // EnableIPv6 represents whether to enable IPv6
+ IPAM network.IPAM // IPAM is the network's IP Address Management
+ Internal bool // Internal represents if the network is used internal only
+ Attachable bool // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.
+ Ingress bool // Ingress indicates the network is providing the routing-mesh for the swarm cluster.
+ ConfigFrom network.ConfigReference // ConfigFrom specifies the source which will provide the configuration for this network.
+ ConfigOnly bool // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.
+ Containers map[string]EndpointResource // Containers contains endpoints belonging to the network
+ Options map[string]string // Options holds the network specific options to use for when creating the network
+ Labels map[string]string // Labels holds metadata specific to the network being created
+ Peers []network.PeerInfo `json:",omitempty"` // List of peer nodes for an overlay network
+ Services map[string]network.ServiceInfo `json:",omitempty"`
}
// EndpointResource contains network resources allocated and used for a container in a network
@@ -455,12 +431,23 @@ type EndpointResource struct {
// NetworkCreate is the expected body of the "create network" http request message
type NetworkCreate struct {
+ // Check for networks with duplicate names.
+ // Network is primarily keyed based on a random ID and not on the name.
+ // Network name is strictly a user-friendly alias to the network
+ // which is uniquely identified using ID.
+ // And there is no guaranteed way to check for duplicates.
+ // Option CheckDuplicate is there to provide a best effort checking of any networks
+ // which has the same name but it is not guaranteed to catch all name collisions.
CheckDuplicate bool
Driver string
+ Scope string
EnableIPv6 bool
IPAM *network.IPAM
Internal bool
Attachable bool
+ Ingress bool
+ ConfigOnly bool
+ ConfigFrom *network.ConfigReference
Options map[string]string
Labels map[string]string
}
@@ -489,6 +476,12 @@ type NetworkDisconnect struct {
Force bool
}
+// NetworkInspectOptions holds parameters to inspect network
+type NetworkInspectOptions struct {
+ Scope string
+ Verbose bool
+}
+
// Checkpoint represents the details of a checkpoint
type Checkpoint struct {
Name string // Name is the name of the checkpoint
@@ -503,10 +496,11 @@ type Runtime struct {
// DiskUsage contains response of Engine API:
// GET "/system/df"
type DiskUsage struct {
- LayersSize int64
- Images []*ImageSummary
- Containers []*Container
- Volumes []*Volume
+ LayersSize int64
+ Images []*ImageSummary
+ Containers []*Container
+ Volumes []*Volume
+ BuilderSize int64
}
// ContainersPruneReport contains the response for Engine API:
@@ -526,7 +520,13 @@ type VolumesPruneReport struct {
// ImagesPruneReport contains the response for Engine API:
// POST "/images/prune"
type ImagesPruneReport struct {
- ImagesDeleted []ImageDelete
+ ImagesDeleted []ImageDeleteResponseItem
+ SpaceReclaimed uint64
+}
+
+// BuildCachePruneReport contains the response for Engine API:
+// POST "/build/prune"
+type BuildCachePruneReport struct {
SpaceReclaimed uint64
}
@@ -547,3 +547,29 @@ type SecretCreateResponse struct {
type SecretListOptions struct {
Filters filters.Args
}
+
+// ConfigCreateResponse contains the information returned to a client
+// on the creation of a new config.
+type ConfigCreateResponse struct {
+ // ID is the id of the created config.
+ ID string
+}
+
+// ConfigListOptions holds parameters to list configs
+type ConfigListOptions struct {
+ Filters filters.Args
+}
+
+// PushResult contains the tag, manifest digest, and manifest size from the
+// push. It's used to signal this information to the trust code in the client
+// so it can sign the manifest if necessary.
+type PushResult struct {
+ Tag string
+ Digest string
+ Size int
+}
+
+// BuildResult contains the image id of a successful build
+type BuildResult struct {
+ ID string
+}
diff --git a/vendor/github.com/docker/docker/api/types/versions/README.md b/vendor/github.com/docker/docker/api/types/versions/README.md
index cdac50a5..1ef911ed 100644
--- a/vendor/github.com/docker/docker/api/types/versions/README.md
+++ b/vendor/github.com/docker/docker/api/types/versions/README.md
@@ -1,10 +1,10 @@
-## Legacy API type versions
+# Legacy API type versions
This package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`.
Consider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`.
-### Package name conventions
+## Package name conventions
The package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention:
diff --git a/vendor/github.com/docker/docker/api/types/volume.go b/vendor/github.com/docker/docker/api/types/volume.go
index da4f8ebd..b5ee96a5 100644
--- a/vendor/github.com/docker/docker/api/types/volume.go
+++ b/vendor/github.com/docker/docker/api/types/volume.go
@@ -7,6 +7,9 @@ package types
// swagger:model Volume
type Volume struct {
+ // Date/Time the volume was created.
+ CreatedAt string `json:"CreatedAt,omitempty"`
+
// Name of the volume driver used by the volume.
// Required: true
Driver string `json:"Driver"`
@@ -44,15 +47,23 @@ type Volume struct {
UsageData *VolumeUsageData `json:"UsageData,omitempty"`
}
-// VolumeUsageData volume usage data
+// VolumeUsageData Usage details about the volume. This information is used by the
+// `GET /system/df` endpoint, and omitted in other endpoints.
+//
// swagger:model VolumeUsageData
type VolumeUsageData struct {
- // The number of containers referencing this volume.
+ // The number of containers referencing this volume. This field
+ // is set to `-1` if the reference-count is not available.
+ //
// Required: true
RefCount int64 `json:"RefCount"`
- // The disk space used by the volume (local driver only)
+ // Amount of disk space used by the volume (in bytes). This information
+ // is only available for volumes created with the `"local"` volume
+ // driver. For volumes created with other volume drivers, this field
+ // is set to `-1` ("not available")
+ //
// Required: true
Size int64 `json:"Size"`
}
diff --git a/vendor/github.com/docker/docker/api/types/volume/volumes_create.go b/vendor/github.com/docker/docker/api/types/volume/volumes_create.go
index 679c1600..9f70e43c 100644
--- a/vendor/github.com/docker/docker/api/types/volume/volumes_create.go
+++ b/vendor/github.com/docker/docker/api/types/volume/volumes_create.go
@@ -4,7 +4,7 @@ package volume
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
// VolumesCreateBody volumes create body
diff --git a/vendor/github.com/docker/docker/api/types/volume/volumes_list.go b/vendor/github.com/docker/docker/api/types/volume/volumes_list.go
index 7770bcb8..833dad93 100644
--- a/vendor/github.com/docker/docker/api/types/volume/volumes_list.go
+++ b/vendor/github.com/docker/docker/api/types/volume/volumes_list.go
@@ -4,7 +4,7 @@ package volume
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
-// See hack/swagger-gen.sh
+// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------
import "github.com/docker/docker/api/types"
diff --git a/vendor/github.com/docker/docker/client/build_prune.go b/vendor/github.com/docker/docker/client/build_prune.go
new file mode 100644
index 00000000..ccab115d
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/build_prune.go
@@ -0,0 +1,30 @@
+package client
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/docker/docker/api/types"
+ "golang.org/x/net/context"
+)
+
+// BuildCachePrune requests the daemon to delete unused cache data
+func (cli *Client) BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error) {
+ if err := cli.NewVersionError("1.31", "build prune"); err != nil {
+ return nil, err
+ }
+
+ report := types.BuildCachePruneReport{}
+
+ serverResp, err := cli.post(ctx, "/build/prune", nil, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer ensureReaderClosed(serverResp)
+
+ if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {
+ return nil, fmt.Errorf("Error retrieving disk usage: %v", err)
+ }
+
+ return &report, nil
+}
diff --git a/vendor/github.com/docker/docker/client/checkpoint_list.go b/vendor/github.com/docker/docker/client/checkpoint_list.go
index 8eb720a6..ffe44bc9 100644
--- a/vendor/github.com/docker/docker/client/checkpoint_list.go
+++ b/vendor/github.com/docker/docker/client/checkpoint_list.go
@@ -2,13 +2,14 @@ package client
import (
"encoding/json"
+ "net/http"
"net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
-// CheckpointList returns the volumes configured in the docker host.
+// CheckpointList returns the checkpoints of the given container in the docker host
func (cli *Client) CheckpointList(ctx context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) {
var checkpoints []types.Checkpoint
@@ -19,6 +20,9 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
if err != nil {
+ if resp.statusCode == http.StatusNotFound {
+ return checkpoints, containerNotFoundError{container}
+ }
return checkpoints, err
}
diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go
index a9bdab6b..c4e3914b 100644
--- a/vendor/github.com/docker/docker/client/client.go
+++ b/vendor/github.com/docker/docker/client/client.go
@@ -3,7 +3,7 @@ Package client is a Go client for the Docker Engine API.
The "docker" command uses this package to communicate with the daemon. It can also
be used by your own Go applications to do anything the command-line interface does
-– running containers, pulling images, managing swarms, etc.
+- running containers, pulling images, managing swarms, etc.
For more information about the Engine API, see the documentation:
https://docs.docker.com/engine/reference/api/
@@ -46,6 +46,7 @@ For example, to list running containers (the equivalent of "docker ps"):
package client
import (
+ "errors"
"fmt"
"net/http"
"net/url"
@@ -53,12 +54,16 @@ import (
"path/filepath"
"strings"
+ "github.com/docker/docker/api"
+ "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/versions"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
+ "golang.org/x/net/context"
)
-// DefaultVersion is the version of the current stable API
-const DefaultVersion string = "1.25"
+// ErrRedirect is the error returned by checkRedirect when the request is non-GET.
+var ErrRedirect = errors.New("unexpected redirect in response")
// Client is the API client that performs all operations
// against a docker server.
@@ -83,10 +88,27 @@ type Client struct {
manualOverride bool
}
+// CheckRedirect specifies the policy for dealing with redirect responses:
+// If the request is non-GET return `ErrRedirect`. Otherwise use the last response.
+//
+// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client .
+// The Docker client (and by extension docker API client) can be made to to send a request
+// like POST /containers//start where what would normally be in the name section of the URL is empty.
+// This triggers an HTTP 301 from the daemon.
+// In go 1.8 this 301 will be converted to a GET request, and ends up getting a 404 from the daemon.
+// This behavior change manifests in the client in that before the 301 was not followed and
+// the client did not generate an error, but now results in a message like Error response from daemon: page not found.
+func CheckRedirect(req *http.Request, via []*http.Request) error {
+ if via[0].Method == http.MethodGet {
+ return http.ErrUseLastResponse
+ }
+ return ErrRedirect
+}
+
// NewEnvClient initializes a new API client based on environment variables.
// Use DOCKER_HOST to set the url to the docker server.
// Use DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
-// Use DOCKER_CERT_PATH to load the tls certificates from.
+// Use DOCKER_CERT_PATH to load the TLS certificates from.
// Use DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
func NewEnvClient() (*Client, error) {
var client *http.Client
@@ -106,6 +128,7 @@ func NewEnvClient() (*Client, error) {
Transport: &http.Transport{
TLSClientConfig: tlsc,
},
+ CheckRedirect: CheckRedirect,
}
}
@@ -115,7 +138,7 @@ func NewEnvClient() (*Client, error) {
}
version := os.Getenv("DOCKER_API_VERSION")
if version == "" {
- version = DefaultVersion
+ version = api.DefaultVersion
}
cli, err := NewClient(host, version, client, nil)
@@ -142,14 +165,15 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
}
if client != nil {
- if _, ok := client.Transport.(*http.Transport); !ok {
+ if _, ok := client.Transport.(http.RoundTripper); !ok {
return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
}
} else {
transport := new(http.Transport)
sockets.ConfigureTransport(transport, proto, addr)
client = &http.Client{
- Transport: transport,
+ Transport: transport,
+ CheckRedirect: CheckRedirect,
}
}
@@ -195,9 +219,9 @@ func (cli *Client) getAPIPath(p string, query url.Values) string {
var apiPath string
if cli.version != "" {
v := strings.TrimPrefix(cli.version, "v")
- apiPath = fmt.Sprintf("%s/v%s%s", cli.basePath, v, p)
+ apiPath = cli.basePath + "/v" + v + p
} else {
- apiPath = fmt.Sprintf("%s%s", cli.basePath, p)
+ apiPath = cli.basePath + p
}
u := &url.URL{
@@ -212,17 +236,45 @@ func (cli *Client) getAPIPath(p string, query url.Values) string {
// ClientVersion returns the version string associated with this
// instance of the Client. Note that this value can be changed
// via the DOCKER_API_VERSION env var.
+// This operation doesn't acquire a mutex.
func (cli *Client) ClientVersion() string {
return cli.version
}
-// UpdateClientVersion updates the version string associated with this
-// instance of the Client.
-func (cli *Client) UpdateClientVersion(v string) {
- if !cli.manualOverride {
- cli.version = v
+// NegotiateAPIVersion updates the version string associated with this
+// instance of the Client to match the latest version the server supports
+func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
+ ping, _ := cli.Ping(ctx)
+ cli.NegotiateAPIVersionPing(ping)
+}
+
+// NegotiateAPIVersionPing updates the version string associated with this
+// instance of the Client to match the latest version the server supports
+func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
+ if cli.manualOverride {
+ return
}
+ // try the latest version before versioning headers existed
+ if p.APIVersion == "" {
+ p.APIVersion = "1.24"
+ }
+
+ // if the client is not initialized with a version, start with the latest supported version
+ if cli.version == "" {
+ cli.version = api.DefaultVersion
+ }
+
+ // if server version is lower than the maximum version supported by the Client, downgrade
+ if versions.LessThan(p.APIVersion, api.DefaultVersion) {
+ cli.version = p.APIVersion
+ }
+}
+
+// DaemonHost returns the host associated with this instance of the Client.
+// This operation doesn't acquire a mutex.
+func (cli *Client) DaemonHost() string {
+ return cli.host
}
// ParseHost verifies that the given host strings is valid.
@@ -244,3 +296,19 @@ func ParseHost(host string) (string, string, string, error) {
}
return proto, addr, basePath, nil
}
+
+// CustomHTTPHeaders returns the custom http headers associated with this
+// instance of the Client. This operation doesn't acquire a mutex.
+func (cli *Client) CustomHTTPHeaders() map[string]string {
+ m := make(map[string]string)
+ for k, v := range cli.customHTTPHeaders {
+ m[k] = v
+ }
+ return m
+}
+
+// SetCustomHTTPHeaders updates the custom http headers associated with this
+// instance of the Client. This operation doesn't acquire a mutex.
+func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) {
+ cli.customHTTPHeaders = headers
+}
diff --git a/vendor/github.com/docker/docker/client/config_create.go b/vendor/github.com/docker/docker/client/config_create.go
new file mode 100644
index 00000000..bc4a952b
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/config_create.go
@@ -0,0 +1,25 @@
+package client
+
+import (
+ "encoding/json"
+
+ "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/swarm"
+ "golang.org/x/net/context"
+)
+
+// ConfigCreate creates a new Config.
+func (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
+ var response types.ConfigCreateResponse
+ if err := cli.NewVersionError("1.30", "config create"); err != nil {
+ return response, err
+ }
+ resp, err := cli.post(ctx, "/configs/create", nil, config, nil)
+ if err != nil {
+ return response, err
+ }
+
+ err = json.NewDecoder(resp.body).Decode(&response)
+ ensureReaderClosed(resp)
+ return response, err
+}
diff --git a/vendor/github.com/docker/docker/client/config_inspect.go b/vendor/github.com/docker/docker/client/config_inspect.go
new file mode 100644
index 00000000..ebb6d636
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/config_inspect.go
@@ -0,0 +1,37 @@
+package client
+
+import (
+ "bytes"
+ "encoding/json"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/docker/docker/api/types/swarm"
+ "golang.org/x/net/context"
+)
+
+// ConfigInspectWithRaw returns the config information with raw data
+func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {
+ if err := cli.NewVersionError("1.30", "config inspect"); err != nil {
+ return swarm.Config{}, nil, err
+ }
+ resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
+ if err != nil {
+ if resp.statusCode == http.StatusNotFound {
+ return swarm.Config{}, nil, configNotFoundError{id}
+ }
+ return swarm.Config{}, nil, err
+ }
+ defer ensureReaderClosed(resp)
+
+ body, err := ioutil.ReadAll(resp.body)
+ if err != nil {
+ return swarm.Config{}, nil, err
+ }
+
+ var config swarm.Config
+ rdr := bytes.NewReader(body)
+ err = json.NewDecoder(rdr).Decode(&config)
+
+ return config, body, err
+}
diff --git a/vendor/github.com/docker/docker/client/config_list.go b/vendor/github.com/docker/docker/client/config_list.go
new file mode 100644
index 00000000..8483ca14
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/config_list.go
@@ -0,0 +1,38 @@
+package client
+
+import (
+ "encoding/json"
+ "net/url"
+
+ "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/filters"
+ "github.com/docker/docker/api/types/swarm"
+ "golang.org/x/net/context"
+)
+
+// ConfigList returns the list of configs.
+func (cli *Client) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
+ if err := cli.NewVersionError("1.30", "config list"); err != nil {
+ return nil, err
+ }
+ query := url.Values{}
+
+ if options.Filters.Len() > 0 {
+ filterJSON, err := filters.ToParam(options.Filters)
+ if err != nil {
+ return nil, err
+ }
+
+ query.Set("filters", filterJSON)
+ }
+
+ resp, err := cli.get(ctx, "/configs", query, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ var configs []swarm.Config
+ err = json.NewDecoder(resp.body).Decode(&configs)
+ ensureReaderClosed(resp)
+ return configs, err
+}
diff --git a/vendor/github.com/docker/docker/client/config_remove.go b/vendor/github.com/docker/docker/client/config_remove.go
new file mode 100644
index 00000000..726b5c85
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/config_remove.go
@@ -0,0 +1,13 @@
+package client
+
+import "golang.org/x/net/context"
+
+// ConfigRemove removes a Config.
+func (cli *Client) ConfigRemove(ctx context.Context, id string) error {
+ if err := cli.NewVersionError("1.30", "config remove"); err != nil {
+ return err
+ }
+ resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
+ ensureReaderClosed(resp)
+ return err
+}
diff --git a/vendor/github.com/docker/docker/client/config_update.go b/vendor/github.com/docker/docker/client/config_update.go
new file mode 100644
index 00000000..823751bb
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/config_update.go
@@ -0,0 +1,21 @@
+package client
+
+import (
+ "net/url"
+ "strconv"
+
+ "github.com/docker/docker/api/types/swarm"
+ "golang.org/x/net/context"
+)
+
+// ConfigUpdate attempts to update a Config
+func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {
+ if err := cli.NewVersionError("1.30", "config update"); err != nil {
+ return err
+ }
+ query := url.Values{}
+ query.Set("version", strconv.FormatUint(version.Index, 10))
+ resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)
+ ensureReaderClosed(resp)
+ return err
+}
diff --git a/vendor/github.com/docker/docker/client/container_attach.go b/vendor/github.com/docker/docker/client/container_attach.go
index eea46821..0fdf3ed0 100644
--- a/vendor/github.com/docker/docker/client/container_attach.go
+++ b/vendor/github.com/docker/docker/client/container_attach.go
@@ -11,6 +11,26 @@ import (
// It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close.
+//
+// The stream format on the response will be in one of two formats:
+//
+// If the container is using a TTY, there is only a single stream (stdout), and
+// data is copied directly from the container output stream, no extra
+// multiplexing or headers.
+//
+// If the container is *not* using a TTY, streams for stdout and stderr are
+// multiplexed.
+// The format of the multiplexed stream is as follows:
+//
+// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
+//
+// STREAM_TYPE can be 1 for stdout and 2 for stderr
+//
+// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
+// This is the size of OUTPUT.
+//
+// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this
+// stream.
func (cli *Client) ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) {
query := url.Values{}
if options.Stream {
diff --git a/vendor/github.com/docker/docker/client/container_commit.go b/vendor/github.com/docker/docker/client/container_commit.go
index c766d62e..531d796e 100644
--- a/vendor/github.com/docker/docker/client/container_commit.go
+++ b/vendor/github.com/docker/docker/client/container_commit.go
@@ -5,9 +5,8 @@ import (
"errors"
"net/url"
- distreference "github.com/docker/distribution/reference"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/reference"
"golang.org/x/net/context"
)
@@ -15,17 +14,20 @@ import (
func (cli *Client) ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error) {
var repository, tag string
if options.Reference != "" {
- distributionRef, err := distreference.ParseNamed(options.Reference)
+ ref, err := reference.ParseNormalizedNamed(options.Reference)
if err != nil {
return types.IDResponse{}, err
}
- if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical {
+ if _, isCanonical := ref.(reference.Canonical); isCanonical {
return types.IDResponse{}, errors.New("refusing to create a tag with a digest reference")
}
+ ref = reference.TagNameOnly(ref)
- tag = reference.GetTagFromNamedRef(distributionRef)
- repository = distributionRef.Name()
+ if tagged, ok := ref.(reference.Tagged); ok {
+ tag = tagged.Tag()
+ }
+ repository = reference.FamiliarName(ref)
}
query := url.Values{}
diff --git a/vendor/github.com/docker/docker/client/container_copy.go b/vendor/github.com/docker/docker/client/container_copy.go
index 8380eeab..30ba6803 100644
--- a/vendor/github.com/docker/docker/client/container_copy.go
+++ b/vendor/github.com/docker/docker/client/container_copy.go
@@ -20,7 +20,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
- urlStr := fmt.Sprintf("/containers/%s/archive", containerID)
+ urlStr := "/containers/" + containerID + "/archive"
response, err := cli.head(ctx, urlStr, query, nil)
if err != nil {
return types.ContainerPathStat{}, err
@@ -30,6 +30,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri
}
// CopyToContainer copies content into the container filesystem.
+// Note that `content` must be a Reader for a TAR
func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error {
query := url.Values{}
query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API.
@@ -38,7 +39,11 @@ func (cli *Client) CopyToContainer(ctx context.Context, container, path string,
query.Set("noOverwriteDirNonDir", "true")
}
- apiPath := fmt.Sprintf("/containers/%s/archive", container)
+ if options.CopyUIDGID {
+ query.Set("copyUIDGID", "true")
+ }
+
+ apiPath := "/containers/" + container + "/archive"
response, err := cli.putRaw(ctx, apiPath, query, content, nil)
if err != nil {
@@ -59,7 +64,7 @@ func (cli *Client) CopyFromContainer(ctx context.Context, container, srcPath str
query := make(url.Values, 1)
query.Set("path", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.
- apiPath := fmt.Sprintf("/containers/%s/archive", container)
+ apiPath := "/containers/" + container + "/archive"
response, err := cli.get(ctx, apiPath, query, nil)
if err != nil {
return nil, types.ContainerPathStat{}, err
diff --git a/vendor/github.com/docker/docker/client/container_create.go b/vendor/github.com/docker/docker/client/container_create.go
index 9f627aaf..6841b0b2 100644
--- a/vendor/github.com/docker/docker/client/container_create.go
+++ b/vendor/github.com/docker/docker/client/container_create.go
@@ -7,6 +7,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
+ "github.com/docker/docker/api/types/versions"
"golang.org/x/net/context"
)
@@ -25,6 +26,11 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
return response, err
}
+ // When using API 1.24 and under, the client is responsible for removing the container
+ if hostConfig != nil && versions.LessThan(cli.ClientVersion(), "1.25") {
+ hostConfig.AutoRemove = false
+ }
+
query := url.Values{}
if containerName != "" {
query.Set("name", containerName)
diff --git a/vendor/github.com/docker/docker/client/container_diff.go b/vendor/github.com/docker/docker/client/container_diff.go
index 1e3e554f..884dc9fe 100644
--- a/vendor/github.com/docker/docker/client/container_diff.go
+++ b/vendor/github.com/docker/docker/client/container_diff.go
@@ -4,13 +4,13 @@ import (
"encoding/json"
"net/url"
- "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
)
// ContainerDiff shows differences in a container filesystem since it was started.
-func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]types.ContainerChange, error) {
- var changes []types.ContainerChange
+func (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.ContainerChangeResponseItem, error) {
+ var changes []container.ContainerChangeResponseItem
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/changes", url.Values{}, nil)
if err != nil {
diff --git a/vendor/github.com/docker/docker/client/container_logs.go b/vendor/github.com/docker/docker/client/container_logs.go
index 69056b63..0f32e9f1 100644
--- a/vendor/github.com/docker/docker/client/container_logs.go
+++ b/vendor/github.com/docker/docker/client/container_logs.go
@@ -13,6 +13,26 @@ import (
// ContainerLogs returns the logs generated by a container in an io.ReadCloser.
// It's up to the caller to close the stream.
+//
+// The stream format on the response will be in one of two formats:
+//
+// If the container is using a TTY, there is only a single stream (stdout), and
+// data is copied directly from the container output stream, no extra
+// multiplexing or headers.
+//
+// If the container is *not* using a TTY, streams for stdout and stderr are
+// multiplexed.
+// The format of the multiplexed stream is as follows:
+//
+// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
+//
+// STREAM_TYPE can be 1 for stdout and 2 for stderr
+//
+// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.
+// This is the size of OUTPUT.
+//
+// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this
+// stream.
func (cli *Client) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
query := url.Values{}
if options.ShowStdout {
diff --git a/vendor/github.com/docker/docker/client/container_top.go b/vendor/github.com/docker/docker/client/container_top.go
index 4e7270ea..9689123a 100644
--- a/vendor/github.com/docker/docker/client/container_top.go
+++ b/vendor/github.com/docker/docker/client/container_top.go
@@ -5,13 +5,13 @@ import (
"net/url"
"strings"
- "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
)
// ContainerTop shows process information from within a container.
-func (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (types.ContainerProcessList, error) {
- var response types.ContainerProcessList
+func (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (container.ContainerTopOKBody, error) {
+ var response container.ContainerTopOKBody
query := url.Values{}
if len(arguments) > 0 {
query.Set("ps_args", strings.Join(arguments, " "))
diff --git a/vendor/github.com/docker/docker/client/container_wait.go b/vendor/github.com/docker/docker/client/container_wait.go
index 93212c70..854c6c05 100644
--- a/vendor/github.com/docker/docker/client/container_wait.go
+++ b/vendor/github.com/docker/docker/client/container_wait.go
@@ -2,25 +2,83 @@ package client
import (
"encoding/json"
+ "net/url"
"golang.org/x/net/context"
"github.com/docker/docker/api/types/container"
+ "github.com/docker/docker/api/types/versions"
)
-// ContainerWait pauses execution until a container exits.
-// It returns the API status code as response of its readiness.
-func (cli *Client) ContainerWait(ctx context.Context, containerID string) (int64, error) {
- resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", nil, nil, nil)
+// ContainerWait waits until the specified container is in a certain state
+// indicated by the given condition, either "not-running" (default),
+// "next-exit", or "removed".
+//
+// If this client's API version is before 1.30, condition is ignored and
+// ContainerWait will return immediately with the two channels, as the server
+// will wait as if the condition were "not-running".
+//
+// If this client's API version is at least 1.30, ContainerWait blocks until
+// the request has been acknowledged by the server (with a response header),
+// then returns two channels on which the caller can wait for the exit status
+// of the container or an error if there was a problem either beginning the
+// wait request or in getting the response. This allows the caller to
+// synchronize ContainerWait with other calls, such as specifying a
+// "next-exit" condition before issuing a ContainerStart request.
+func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
+ if versions.LessThan(cli.ClientVersion(), "1.30") {
+ return cli.legacyContainerWait(ctx, containerID)
+ }
+
+ resultC := make(chan container.ContainerWaitOKBody)
+ errC := make(chan error, 1)
+
+ query := url.Values{}
+ query.Set("condition", string(condition))
+
+ resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", query, nil, nil)
if err != nil {
- return -1, err
- }
- defer ensureReaderClosed(resp)
-
- var res container.ContainerWaitOKBody
- if err := json.NewDecoder(resp.body).Decode(&res); err != nil {
- return -1, err
+ defer ensureReaderClosed(resp)
+ errC <- err
+ return resultC, errC
}
- return res.StatusCode, nil
+ go func() {
+ defer ensureReaderClosed(resp)
+ var res container.ContainerWaitOKBody
+ if err := json.NewDecoder(resp.body).Decode(&res); err != nil {
+ errC <- err
+ return
+ }
+
+ resultC <- res
+ }()
+
+ return resultC, errC
+}
+
+// legacyContainerWait returns immediately and doesn't have an option to wait
+// until the container is removed.
+func (cli *Client) legacyContainerWait(ctx context.Context, containerID string) (<-chan container.ContainerWaitOKBody, <-chan error) {
+ resultC := make(chan container.ContainerWaitOKBody)
+ errC := make(chan error)
+
+ go func() {
+ resp, err := cli.post(ctx, "/containers/"+containerID+"/wait", nil, nil, nil)
+ if err != nil {
+ errC <- err
+ return
+ }
+ defer ensureReaderClosed(resp)
+
+ var res container.ContainerWaitOKBody
+ if err := json.NewDecoder(resp.body).Decode(&res); err != nil {
+ errC <- err
+ return
+ }
+
+ resultC <- res
+ }()
+
+ return resultC, errC
}
diff --git a/vendor/github.com/docker/docker/client/distribution_inspect.go b/vendor/github.com/docker/docker/client/distribution_inspect.go
new file mode 100644
index 00000000..aa5bc6a6
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/distribution_inspect.go
@@ -0,0 +1,35 @@
+package client
+
+import (
+ "encoding/json"
+ "net/url"
+
+ registrytypes "github.com/docker/docker/api/types/registry"
+ "golang.org/x/net/context"
+)
+
+// DistributionInspect returns the image digest with full Manifest
+func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registrytypes.DistributionInspect, error) {
+ // Contact the registry to retrieve digest and platform information
+ var distributionInspect registrytypes.DistributionInspect
+
+ if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil {
+ return distributionInspect, err
+ }
+ var headers map[string][]string
+
+ if encodedRegistryAuth != "" {
+ headers = map[string][]string{
+ "X-Registry-Auth": {encodedRegistryAuth},
+ }
+ }
+
+ resp, err := cli.get(ctx, "/distribution/"+image+"/json", url.Values{}, headers)
+ if err != nil {
+ return distributionInspect, err
+ }
+
+ err = json.NewDecoder(resp.body).Decode(&distributionInspect)
+ ensureReaderClosed(resp)
+ return distributionInspect, err
+}
diff --git a/vendor/github.com/docker/docker/client/errors.go b/vendor/github.com/docker/docker/client/errors.go
index bf6923f1..fc7df9f1 100644
--- a/vendor/github.com/docker/docker/client/errors.go
+++ b/vendor/github.com/docker/docker/client/errors.go
@@ -228,8 +228,8 @@ func IsErrPluginPermissionDenied(err error) bool {
// NewVersionError returns an error if the APIVersion required
// if less than the current supported version
func (cli *Client) NewVersionError(APIrequired, feature string) error {
- if versions.LessThan(cli.version, APIrequired) {
- return fmt.Errorf("%q requires API version %s, but the Docker server is version %s", feature, APIrequired, cli.version)
+ if cli.version != "" && versions.LessThan(cli.version, APIrequired) {
+ return fmt.Errorf("%q requires API version %s, but the Docker daemon API version is %s", feature, APIrequired, cli.version)
}
return nil
}
@@ -244,7 +244,7 @@ func (e secretNotFoundError) Error() string {
return fmt.Sprintf("Error: no such secret: %s", e.name)
}
-// NoFound indicates that this error type is of NotFound
+// NotFound indicates that this error type is of NotFound
func (e secretNotFoundError) NotFound() bool {
return true
}
@@ -256,6 +256,28 @@ func IsErrSecretNotFound(err error) bool {
return ok
}
+// configNotFoundError implements an error returned when a config is not found.
+type configNotFoundError struct {
+ name string
+}
+
+// Error returns a string representation of a configNotFoundError
+func (e configNotFoundError) Error() string {
+ return fmt.Sprintf("Error: no such config: %s", e.name)
+}
+
+// NotFound indicates that this error type is of NotFound
+func (e configNotFoundError) NotFound() bool {
+ return true
+}
+
+// IsErrConfigNotFound returns true if the error is caused
+// when a config is not found.
+func IsErrConfigNotFound(err error) bool {
+ _, ok := err.(configNotFoundError)
+ return ok
+}
+
// pluginNotFoundError implements an error returned when a plugin is not in the docker host.
type pluginNotFoundError struct {
name string
diff --git a/vendor/github.com/docker/docker/client/hijack.go b/vendor/github.com/docker/docker/client/hijack.go
index 74c53f52..8cf0119f 100644
--- a/vendor/github.com/docker/docker/client/hijack.go
+++ b/vendor/github.com/docker/docker/client/hijack.go
@@ -1,8 +1,8 @@
package client
import (
+ "bufio"
"crypto/tls"
- "errors"
"fmt"
"net"
"net/http"
@@ -14,6 +14,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/tlsconfig"
"github.com/docker/go-connections/sockets"
+ "github.com/pkg/errors"
"golang.org/x/net/context"
)
@@ -46,37 +47,12 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
}
req = cli.addHeaders(req, headers)
- req.Host = cli.addr
- req.Header.Set("Connection", "Upgrade")
- req.Header.Set("Upgrade", "tcp")
-
- conn, err := dial(cli.proto, cli.addr, resolveTLSConfig(cli.client.Transport))
+ conn, err := cli.setupHijackConn(req, "tcp")
if err != nil {
- if strings.Contains(err.Error(), "connection refused") {
- return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
- }
return types.HijackedResponse{}, err
}
- // When we set up a TCP connection for hijack, there could be long periods
- // of inactivity (a long running command with no output) that in certain
- // network setups may cause ECONNTIMEOUT, leaving the client in an unknown
- // state. Setting TCP KeepAlive on the socket connection will prohibit
- // ECONNTIMEOUT unless the socket connection truly is broken
- if tcpConn, ok := conn.(*net.TCPConn); ok {
- tcpConn.SetKeepAlive(true)
- tcpConn.SetKeepAlivePeriod(30 * time.Second)
- }
-
- clientconn := httputil.NewClientConn(conn, nil)
- defer clientconn.Close()
-
- // Server hijacks the connection, error 'connection closed' expected
- _, err = clientconn.Do(req)
-
- rwc, br := clientconn.Hijack()
-
- return types.HijackedResponse{Conn: rwc, Reader: br}, err
+ return types.HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn)}, err
}
func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {
@@ -175,3 +151,58 @@ func dial(proto, addr string, tlsConfig *tls.Config) (net.Conn, error) {
}
return net.Dial(proto, addr)
}
+
+func (cli *Client) setupHijackConn(req *http.Request, proto string) (net.Conn, error) {
+ req.Host = cli.addr
+ req.Header.Set("Connection", "Upgrade")
+ req.Header.Set("Upgrade", proto)
+
+ conn, err := dial(cli.proto, cli.addr, resolveTLSConfig(cli.client.Transport))
+ if err != nil {
+ return nil, errors.Wrap(err, "cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
+ }
+
+ // When we set up a TCP connection for hijack, there could be long periods
+ // of inactivity (a long running command with no output) that in certain
+ // network setups may cause ECONNTIMEOUT, leaving the client in an unknown
+ // state. Setting TCP KeepAlive on the socket connection will prohibit
+ // ECONNTIMEOUT unless the socket connection truly is broken
+ if tcpConn, ok := conn.(*net.TCPConn); ok {
+ tcpConn.SetKeepAlive(true)
+ tcpConn.SetKeepAlivePeriod(30 * time.Second)
+ }
+
+ clientconn := httputil.NewClientConn(conn, nil)
+ defer clientconn.Close()
+
+ // Server hijacks the connection, error 'connection closed' expected
+ resp, err := clientconn.Do(req)
+ if err != httputil.ErrPersistEOF {
+ if err != nil {
+ return nil, err
+ }
+ if resp.StatusCode != http.StatusSwitchingProtocols {
+ resp.Body.Close()
+ return nil, fmt.Errorf("unable to upgrade to %s, received %d", proto, resp.StatusCode)
+ }
+ }
+
+ c, br := clientconn.Hijack()
+ if br.Buffered() > 0 {
+ // If there is buffered content, wrap the connection
+ c = &hijackedConn{c, br}
+ } else {
+ br.Reset(nil)
+ }
+
+ return c, nil
+}
+
+type hijackedConn struct {
+ net.Conn
+ r *bufio.Reader
+}
+
+func (c *hijackedConn) Read(b []byte) (int, error) {
+ return c.r.Read(b)
+}
diff --git a/vendor/github.com/docker/docker/client/image_build.go b/vendor/github.com/docker/docker/client/image_build.go
index 6fde75dc..44a215f9 100644
--- a/vendor/github.com/docker/docker/client/image_build.go
+++ b/vendor/github.com/docker/docker/client/image_build.go
@@ -29,7 +29,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio
return types.ImageBuildResponse{}, err
}
headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))
- headers.Set("Content-Type", "application/tar")
+ headers.Set("Content-Type", "application/x-tar")
serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers)
if err != nil {
@@ -48,6 +48,7 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
query := url.Values{
"t": options.Tags,
"securityopt": options.SecurityOpt,
+ "extrahosts": options.ExtraHosts,
}
if options.SuppressOutput {
query.Set("q", "1")
@@ -94,6 +95,7 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
query.Set("cgroupparent", options.CgroupParent)
query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10))
query.Set("dockerfile", options.Dockerfile)
+ query.Set("target", options.Target)
ulimitsJSON, err := json.Marshal(options.Ulimits)
if err != nil {
@@ -118,6 +120,9 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur
return query, err
}
query.Set("cachefrom", string(cacheFromJSON))
+ if options.SessionID != "" {
+ query.Set("session", options.SessionID)
+ }
return query, nil
}
diff --git a/vendor/github.com/docker/docker/client/image_create.go b/vendor/github.com/docker/docker/client/image_create.go
index cf023a71..4436abb0 100644
--- a/vendor/github.com/docker/docker/client/image_create.go
+++ b/vendor/github.com/docker/docker/client/image_create.go
@@ -6,21 +6,21 @@ import (
"golang.org/x/net/context"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/reference"
)
// ImageCreate creates a new image based in the parent options.
// It returns the JSON content in the response body.
func (cli *Client) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {
- repository, tag, err := reference.Parse(parentReference)
+ ref, err := reference.ParseNormalizedNamed(parentReference)
if err != nil {
return nil, err
}
query := url.Values{}
- query.Set("fromImage", repository)
- query.Set("tag", tag)
+ query.Set("fromImage", reference.FamiliarName(ref))
+ query.Set("tag", getAPITagFromNamedRef(ref))
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
if err != nil {
return nil, err
diff --git a/vendor/github.com/docker/docker/client/image_history.go b/vendor/github.com/docker/docker/client/image_history.go
index acb1ee92..7b4babcb 100644
--- a/vendor/github.com/docker/docker/client/image_history.go
+++ b/vendor/github.com/docker/docker/client/image_history.go
@@ -4,13 +4,13 @@ import (
"encoding/json"
"net/url"
- "github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/image"
"golang.org/x/net/context"
)
// ImageHistory returns the changes in an image in history format.
-func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]types.ImageHistory, error) {
- var history []types.ImageHistory
+func (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) {
+ var history []image.HistoryResponseItem
serverResp, err := cli.get(ctx, "/images/"+imageID+"/history", url.Values{}, nil)
if err != nil {
return history, err
diff --git a/vendor/github.com/docker/docker/client/image_import.go b/vendor/github.com/docker/docker/client/image_import.go
index c6f154b2..d7dedd82 100644
--- a/vendor/github.com/docker/docker/client/image_import.go
+++ b/vendor/github.com/docker/docker/client/image_import.go
@@ -15,7 +15,7 @@ import (
func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
if ref != "" {
//Check if the given image name can be resolved
- if _, err := reference.ParseNamed(ref); err != nil {
+ if _, err := reference.ParseNormalizedNamed(ref); err != nil {
return nil, err
}
}
diff --git a/vendor/github.com/docker/docker/client/image_pull.go b/vendor/github.com/docker/docker/client/image_pull.go
index 3bffdb70..a72b9bf7 100644
--- a/vendor/github.com/docker/docker/client/image_pull.go
+++ b/vendor/github.com/docker/docker/client/image_pull.go
@@ -7,8 +7,8 @@ import (
"golang.org/x/net/context"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/reference"
)
// ImagePull requests the docker host to pull an image from a remote registry.
@@ -19,16 +19,16 @@ import (
// FIXME(vdemeester): there is currently used in a few way in docker/docker
// - if not in trusted content, ref is used to pass the whole reference, and tag is empty
// - if in trusted content, ref is used to pass the reference name, and tag for the digest
-func (cli *Client) ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
- repository, tag, err := reference.Parse(ref)
+func (cli *Client) ImagePull(ctx context.Context, refStr string, options types.ImagePullOptions) (io.ReadCloser, error) {
+ ref, err := reference.ParseNormalizedNamed(refStr)
if err != nil {
return nil, err
}
query := url.Values{}
- query.Set("fromImage", repository)
- if tag != "" && !options.All {
- query.Set("tag", tag)
+ query.Set("fromImage", reference.FamiliarName(ref))
+ if !options.All {
+ query.Set("tag", getAPITagFromNamedRef(ref))
}
resp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)
@@ -44,3 +44,18 @@ func (cli *Client) ImagePull(ctx context.Context, ref string, options types.Imag
}
return resp.body, nil
}
+
+// getAPITagFromNamedRef returns a tag from the specified reference.
+// This function is necessary as long as the docker "server" api expects
+// digests to be sent as tags and makes a distinction between the name
+// and tag/digest part of a reference.
+func getAPITagFromNamedRef(ref reference.Named) string {
+ if digested, ok := ref.(reference.Digested); ok {
+ return digested.Digest().String()
+ }
+ ref = reference.TagNameOnly(ref)
+ if tagged, ok := ref.(reference.Tagged); ok {
+ return tagged.Tag()
+ }
+ return ""
+}
diff --git a/vendor/github.com/docker/docker/client/image_push.go b/vendor/github.com/docker/docker/client/image_push.go
index 8e73d28f..410d2fb9 100644
--- a/vendor/github.com/docker/docker/client/image_push.go
+++ b/vendor/github.com/docker/docker/client/image_push.go
@@ -8,7 +8,7 @@ import (
"golang.org/x/net/context"
- distreference "github.com/docker/distribution/reference"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
)
@@ -16,31 +16,33 @@ import (
// It executes the privileged function if the operation is unauthorized
// and it tries one more time.
// It's up to the caller to handle the io.ReadCloser and close it properly.
-func (cli *Client) ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) {
- distributionRef, err := distreference.ParseNamed(ref)
+func (cli *Client) ImagePush(ctx context.Context, image string, options types.ImagePushOptions) (io.ReadCloser, error) {
+ ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return nil, err
}
- if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical {
+ if _, isCanonical := ref.(reference.Canonical); isCanonical {
return nil, errors.New("cannot push a digest reference")
}
- var tag = ""
- if nameTaggedRef, isNamedTagged := distributionRef.(distreference.NamedTagged); isNamedTagged {
+ tag := ""
+ name := reference.FamiliarName(ref)
+
+ if nameTaggedRef, isNamedTagged := ref.(reference.NamedTagged); isNamedTagged {
tag = nameTaggedRef.Tag()
}
query := url.Values{}
query.Set("tag", tag)
- resp, err := cli.tryImagePush(ctx, distributionRef.Name(), query, options.RegistryAuth)
+ resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth)
if resp.statusCode == http.StatusUnauthorized && options.PrivilegeFunc != nil {
newAuthHeader, privilegeErr := options.PrivilegeFunc()
if privilegeErr != nil {
return nil, privilegeErr
}
- resp, err = cli.tryImagePush(ctx, distributionRef.Name(), query, newAuthHeader)
+ resp, err = cli.tryImagePush(ctx, name, query, newAuthHeader)
}
if err != nil {
return nil, err
diff --git a/vendor/github.com/docker/docker/client/image_remove.go b/vendor/github.com/docker/docker/client/image_remove.go
index 839e5311..6921209e 100644
--- a/vendor/github.com/docker/docker/client/image_remove.go
+++ b/vendor/github.com/docker/docker/client/image_remove.go
@@ -9,7 +9,7 @@ import (
)
// ImageRemove removes an image from the docker host.
-func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDelete, error) {
+func (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
query := url.Values{}
if options.Force {
@@ -24,7 +24,7 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options type
return nil, err
}
- var dels []types.ImageDelete
+ var dels []types.ImageDeleteResponseItem
err = json.NewDecoder(resp.body).Decode(&dels)
ensureReaderClosed(resp)
return dels, err
diff --git a/vendor/github.com/docker/docker/client/image_tag.go b/vendor/github.com/docker/docker/client/image_tag.go
index bdbf94ad..8924f71e 100644
--- a/vendor/github.com/docker/docker/client/image_tag.go
+++ b/vendor/github.com/docker/docker/client/image_tag.go
@@ -1,34 +1,37 @@
package client
import (
- "errors"
- "fmt"
"net/url"
+ "github.com/docker/distribution/reference"
+ "github.com/pkg/errors"
"golang.org/x/net/context"
-
- distreference "github.com/docker/distribution/reference"
- "github.com/docker/docker/api/types/reference"
)
// ImageTag tags an image in the docker host
-func (cli *Client) ImageTag(ctx context.Context, imageID, ref string) error {
- distributionRef, err := distreference.ParseNamed(ref)
- if err != nil {
- return fmt.Errorf("Error parsing reference: %q is not a valid repository/tag", ref)
+func (cli *Client) ImageTag(ctx context.Context, source, target string) error {
+ if _, err := reference.ParseAnyReference(source); err != nil {
+ return errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", source)
}
- if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical {
+ ref, err := reference.ParseNormalizedNamed(target)
+ if err != nil {
+ return errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", target)
+ }
+
+ if _, isCanonical := ref.(reference.Canonical); isCanonical {
return errors.New("refusing to create a tag with a digest reference")
}
- tag := reference.GetTagFromNamedRef(distributionRef)
+ ref = reference.TagNameOnly(ref)
query := url.Values{}
- query.Set("repo", distributionRef.Name())
- query.Set("tag", tag)
+ query.Set("repo", reference.FamiliarName(ref))
+ if tagged, ok := ref.(reference.Tagged); ok {
+ query.Set("tag", tagged.Tag())
+ }
- resp, err := cli.post(ctx, "/images/"+imageID+"/tag", query, nil, nil)
+ resp, err := cli.post(ctx, "/images/"+source+"/tag", query, nil, nil)
ensureReaderClosed(resp)
return err
}
diff --git a/vendor/github.com/docker/docker/client/interface.go b/vendor/github.com/docker/docker/client/interface.go
index 05978039..acd4de1d 100644
--- a/vendor/github.com/docker/docker/client/interface.go
+++ b/vendor/github.com/docker/docker/client/interface.go
@@ -2,12 +2,14 @@ package client
import (
"io"
+ "net"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
+ "github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
@@ -17,7 +19,9 @@ import (
// CommonAPIClient is the common methods between stable and experimental versions of APIClient.
type CommonAPIClient interface {
+ ConfigAPIClient
ContainerAPIClient
+ DistributionAPIClient
ImageAPIClient
NodeAPIClient
NetworkAPIClient
@@ -28,8 +32,11 @@ type CommonAPIClient interface {
SystemAPIClient
VolumeAPIClient
ClientVersion() string
+ DaemonHost() string
ServerVersion(ctx context.Context) (types.Version, error)
- UpdateClientVersion(v string)
+ NegotiateAPIVersion(ctx context.Context)
+ NegotiateAPIVersionPing(types.Ping)
+ DialSession(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error)
}
// ContainerAPIClient defines API client methods for the containers
@@ -37,7 +44,7 @@ type ContainerAPIClient interface {
ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error)
ContainerCommit(ctx context.Context, container string, options types.ContainerCommitOptions) (types.IDResponse, error)
ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
- ContainerDiff(ctx context.Context, container string) ([]types.ContainerChange, error)
+ ContainerDiff(ctx context.Context, container string) ([]container.ContainerChangeResponseItem, error)
ContainerExecAttach(ctx context.Context, execID string, config types.ExecConfig) (types.HijackedResponse, error)
ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)
ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error)
@@ -58,27 +65,33 @@ type ContainerAPIClient interface {
ContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error)
ContainerStart(ctx context.Context, container string, options types.ContainerStartOptions) error
ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
- ContainerTop(ctx context.Context, container string, arguments []string) (types.ContainerProcessList, error)
+ ContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error)
ContainerUnpause(ctx context.Context, container string) error
ContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error)
- ContainerWait(ctx context.Context, container string) (int64, error)
+ ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error)
}
+// DistributionAPIClient defines API client methods for the registry
+type DistributionAPIClient interface {
+ DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error)
+}
+
// ImageAPIClient defines API client methods for the images
type ImageAPIClient interface {
ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
+ BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error)
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
- ImageHistory(ctx context.Context, image string) ([]types.ImageHistory, error)
+ ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)
ImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error)
ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)
ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)
ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error)
- ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDelete, error)
+ ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error)
ImageSave(ctx context.Context, images []string) (io.ReadCloser, error)
ImageTag(ctx context.Context, image, ref string) error
@@ -90,8 +103,8 @@ type NetworkAPIClient interface {
NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error
NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error)
NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error
- NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error)
- NetworkInspectWithRaw(ctx context.Context, networkID string) (types.NetworkResource, []byte, error)
+ NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error)
+ NetworkInspectWithRaw(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error)
NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
NetworkRemove(ctx context.Context, networkID string) error
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error)
@@ -107,7 +120,7 @@ type NodeAPIClient interface {
// PluginAPIClient defines API client methods for the plugins
type PluginAPIClient interface {
- PluginList(ctx context.Context) (types.PluginsListResponse, error)
+ PluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error)
PluginRemove(ctx context.Context, name string, options types.PluginRemoveOptions) error
PluginEnable(ctx context.Context, name string, options types.PluginEnableOptions) error
PluginDisable(ctx context.Context, name string, options types.PluginDisableOptions) error
@@ -122,11 +135,12 @@ type PluginAPIClient interface {
// ServiceAPIClient defines API client methods for the services
type ServiceAPIClient interface {
ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error)
- ServiceInspectWithRaw(ctx context.Context, serviceID string) (swarm.Service, []byte, error)
+ ServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)
ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error)
ServiceRemove(ctx context.Context, serviceID string) error
ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error)
ServiceLogs(ctx context.Context, serviceID string, options types.ContainerLogsOptions) (io.ReadCloser, error)
+ TaskLogs(ctx context.Context, taskID string, options types.ContainerLogsOptions) (io.ReadCloser, error)
TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error)
TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error)
}
@@ -169,3 +183,12 @@ type SecretAPIClient interface {
SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error)
SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error
}
+
+// ConfigAPIClient defines API client methods for configs
+type ConfigAPIClient interface {
+ ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error)
+ ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (types.ConfigCreateResponse, error)
+ ConfigRemove(ctx context.Context, id string) error
+ ConfigInspectWithRaw(ctx context.Context, name string) (swarm.Config, []byte, error)
+ ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error
+}
diff --git a/vendor/github.com/docker/docker/client/login.go b/vendor/github.com/docker/docker/client/login.go
index 600dc719..79219ff5 100644
--- a/vendor/github.com/docker/docker/client/login.go
+++ b/vendor/github.com/docker/docker/client/login.go
@@ -11,7 +11,7 @@ import (
)
// RegistryLogin authenticates the docker server with a given docker registry.
-// It returns UnauthorizerError when the authentication fails.
+// It returns unauthorizedError when the authentication fails.
func (cli *Client) RegistryLogin(ctx context.Context, auth types.AuthConfig) (registry.AuthenticateOKBody, error) {
resp, err := cli.post(ctx, "/auth", url.Values{}, auth, nil)
diff --git a/vendor/github.com/docker/docker/client/network_inspect.go b/vendor/github.com/docker/docker/client/network_inspect.go
index 5ad4ea5b..848c9799 100644
--- a/vendor/github.com/docker/docker/client/network_inspect.go
+++ b/vendor/github.com/docker/docker/client/network_inspect.go
@@ -5,21 +5,33 @@ import (
"encoding/json"
"io/ioutil"
"net/http"
+ "net/url"
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
// NetworkInspect returns the information for a specific network configured in the docker host.
-func (cli *Client) NetworkInspect(ctx context.Context, networkID string) (types.NetworkResource, error) {
- networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID)
+func (cli *Client) NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) {
+ networkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID, options)
return networkResource, err
}
// NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation.
-func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string) (types.NetworkResource, []byte, error) {
- var networkResource types.NetworkResource
- resp, err := cli.get(ctx, "/networks/"+networkID, nil, nil)
+func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) {
+ var (
+ networkResource types.NetworkResource
+ resp serverResponse
+ err error
+ )
+ query := url.Values{}
+ if options.Verbose {
+ query.Set("verbose", "true")
+ }
+ if options.Scope != "" {
+ query.Set("scope", options.Scope)
+ }
+ resp, err = cli.get(ctx, "/networks/"+networkID, query, nil)
if err != nil {
if resp.statusCode == http.StatusNotFound {
return networkResource, nil, networkNotFoundError{networkID}
diff --git a/vendor/github.com/docker/docker/client/parse_logs.go b/vendor/github.com/docker/docker/client/parse_logs.go
new file mode 100644
index 00000000..e427f80a
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/parse_logs.go
@@ -0,0 +1,41 @@
+package client
+
+// parse_logs.go contains utility helpers for getting information out of docker
+// log lines. really, it only contains ParseDetails right now. maybe in the
+// future there will be some desire to parse log messages back into a struct?
+// that would go here if we did
+
+import (
+ "net/url"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+// ParseLogDetails takes a details string of key value pairs in the form
+// "k=v,l=w", where the keys and values are url query escaped, and each pair
+// is separated by a comma, returns a map. returns an error if the details
+// string is not in a valid format
+// the exact form of details encoding is implemented in
+// api/server/httputils/write_log_stream.go
+func ParseLogDetails(details string) (map[string]string, error) {
+ pairs := strings.Split(details, ",")
+ detailsMap := make(map[string]string, len(pairs))
+ for _, pair := range pairs {
+ p := strings.SplitN(pair, "=", 2)
+ // if there is no equals sign, we will only get 1 part back
+ if len(p) != 2 {
+ return nil, errors.New("invalid details format")
+ }
+ k, err := url.QueryUnescape(p[0])
+ if err != nil {
+ return nil, err
+ }
+ v, err := url.QueryUnescape(p[1])
+ if err != nil {
+ return nil, err
+ }
+ detailsMap[k] = v
+ }
+ return detailsMap, nil
+}
diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go
index 22dcda24..a4c2e2c4 100644
--- a/vendor/github.com/docker/docker/client/ping.go
+++ b/vendor/github.com/docker/docker/client/ping.go
@@ -1,16 +1,14 @@
package client
import (
- "fmt"
-
"github.com/docker/docker/api/types"
"golang.org/x/net/context"
)
-// Ping pings the server and return the value of the "Docker-Experimental" & "API-Version" headers
+// Ping pings the server and returns the value of the "Docker-Experimental", "OS-Type" & "API-Version" headers
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
var ping types.Ping
- req, err := cli.buildRequest("GET", fmt.Sprintf("%s/_ping", cli.basePath), nil, nil)
+ req, err := cli.buildRequest("GET", cli.basePath+"/_ping", nil, nil)
if err != nil {
return ping, err
}
@@ -20,11 +18,15 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
}
defer ensureReaderClosed(serverResp)
- ping.APIVersion = serverResp.header.Get("API-Version")
+ if serverResp.header != nil {
+ ping.APIVersion = serverResp.header.Get("API-Version")
- if serverResp.header.Get("Docker-Experimental") == "true" {
- ping.Experimental = true
+ if serverResp.header.Get("Docker-Experimental") == "true" {
+ ping.Experimental = true
+ }
+ ping.OSType = serverResp.header.Get("OSType")
}
- return ping, nil
+ err = cli.checkResponseErr(serverResp)
+ return ping, err
}
diff --git a/vendor/github.com/docker/docker/client/plugin_create.go b/vendor/github.com/docker/docker/client/plugin_create.go
index a660ba57..27954aa5 100644
--- a/vendor/github.com/docker/docker/client/plugin_create.go
+++ b/vendor/github.com/docker/docker/client/plugin_create.go
@@ -12,7 +12,7 @@ import (
// PluginCreate creates a plugin
func (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {
headers := http.Header(make(map[string][]string))
- headers.Set("Content-Type", "application/tar")
+ headers.Set("Content-Type", "application/x-tar")
query := url.Values{}
query.Set("name", createOptions.RepoName)
diff --git a/vendor/github.com/docker/docker/client/plugin_install.go b/vendor/github.com/docker/docker/client/plugin_install.go
index 3217c4cf..ce3e0506 100644
--- a/vendor/github.com/docker/docker/client/plugin_install.go
+++ b/vendor/github.com/docker/docker/client/plugin_install.go
@@ -15,7 +15,7 @@ import (
// PluginInstall installs a plugin
func (cli *Client) PluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) {
query := url.Values{}
- if _, err := reference.ParseNamed(options.RemoteRef); err != nil {
+ if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
return nil, errors.Wrap(err, "invalid remote reference")
}
query.Set("remote", options.RemoteRef)
@@ -60,8 +60,8 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types
return
}
- err = cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
- pw.CloseWithError(err)
+ enableErr := cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
+ pw.CloseWithError(enableErr)
}()
return pr, nil
}
diff --git a/vendor/github.com/docker/docker/client/plugin_list.go b/vendor/github.com/docker/docker/client/plugin_list.go
index 88c480a3..3acde3b9 100644
--- a/vendor/github.com/docker/docker/client/plugin_list.go
+++ b/vendor/github.com/docker/docker/client/plugin_list.go
@@ -2,15 +2,26 @@ package client
import (
"encoding/json"
+ "net/url"
"github.com/docker/docker/api/types"
+ "github.com/docker/docker/api/types/filters"
"golang.org/x/net/context"
)
// PluginList returns the installed plugins
-func (cli *Client) PluginList(ctx context.Context) (types.PluginsListResponse, error) {
+func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error) {
var plugins types.PluginsListResponse
- resp, err := cli.get(ctx, "/plugins", nil, nil)
+ query := url.Values{}
+
+ if filter.Len() > 0 {
+ filterJSON, err := filters.ToParamWithVersion(cli.version, filter)
+ if err != nil {
+ return plugins, err
+ }
+ query.Set("filters", filterJSON)
+ }
+ resp, err := cli.get(ctx, "/plugins", query, nil)
if err != nil {
return plugins, err
}
diff --git a/vendor/github.com/docker/docker/client/plugin_upgrade.go b/vendor/github.com/docker/docker/client/plugin_upgrade.go
index 95a4356b..049ebfa2 100644
--- a/vendor/github.com/docker/docker/client/plugin_upgrade.go
+++ b/vendor/github.com/docker/docker/client/plugin_upgrade.go
@@ -1,7 +1,6 @@
package client
import (
- "fmt"
"io"
"net/url"
@@ -13,8 +12,11 @@ import (
// PluginUpgrade upgrades a plugin
func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) {
+ if err := cli.NewVersionError("1.26", "plugin upgrade"); err != nil {
+ return nil, err
+ }
query := url.Values{}
- if _, err := reference.ParseNamed(options.RemoteRef); err != nil {
+ if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
return nil, errors.Wrap(err, "invalid remote reference")
}
query.Set("remote", options.RemoteRef)
@@ -33,5 +35,5 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types
func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {
headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
- return cli.post(ctx, fmt.Sprintf("/plugins/%s/upgrade", name), query, privileges, headers)
+ return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers)
}
diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go
index ac053636..3e7d43fe 100644
--- a/vendor/github.com/docker/docker/client/request.go
+++ b/vendor/github.com/docker/docker/client/request.go
@@ -24,6 +24,7 @@ type serverResponse struct {
body io.ReadCloser
header http.Header
statusCode int
+ reqURL *url.URL
}
// head sends an http request to the docker API using the method HEAD.
@@ -31,12 +32,12 @@ func (cli *Client) head(ctx context.Context, path string, query url.Values, head
return cli.sendRequest(ctx, "HEAD", path, query, nil, headers)
}
-// getWithContext sends an http request to the docker API using the method GET with a specific go context.
+// get sends an http request to the docker API using the method GET with a specific Go context.
func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) {
return cli.sendRequest(ctx, "GET", path, query, nil, headers)
}
-// postWithContext sends an http request to the docker API using the method POST with a specific go context.
+// post sends an http request to the docker API using the method POST with a specific Go context.
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
body, headers, err := encodeBody(obj, headers)
if err != nil {
@@ -58,7 +59,7 @@ func (cli *Client) put(ctx context.Context, path string, query url.Values, obj i
return cli.sendRequest(ctx, "PUT", path, query, body, headers)
}
-// put sends an http request to the docker API using the method PUT.
+// putRaw sends an http request to the docker API using the method PUT.
func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) {
return cli.sendRequest(ctx, "PUT", path, query, body, headers)
}
@@ -118,11 +119,18 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
if err != nil {
return serverResponse{}, err
}
- return cli.doRequest(ctx, req)
+ resp, err := cli.doRequest(ctx, req)
+ if err != nil {
+ return resp, err
+ }
+ if err := cli.checkResponseErr(resp); err != nil {
+ return resp, err
+ }
+ return resp, nil
}
func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResponse, error) {
- serverResp := serverResponse{statusCode: -1}
+ serverResp := serverResponse{statusCode: -1, reqURL: req.URL}
resp, err := ctxhttp.Do(ctx, cli.client, req)
if err != nil {
@@ -165,7 +173,7 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
// daemon on Windows where the daemon is listening on a named pipe
// `//./pipe/docker_engine, and the client must be running elevated.
// Give users a clue rather than the not-overly useful message
- // such as `error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.25/info:
+ // such as `error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.26/info:
// open //./pipe/docker_engine: The system cannot find the file specified.`.
// Note we can't string compare "The system cannot find the file specified" as
// this is localised - for example in French the error would be
@@ -179,37 +187,44 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
if resp != nil {
serverResp.statusCode = resp.StatusCode
+ serverResp.body = resp.Body
+ serverResp.header = resp.Header
}
-
- if serverResp.statusCode < 200 || serverResp.statusCode >= 400 {
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return serverResp, err
- }
- if len(body) == 0 {
- return serverResp, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), req.URL)
- }
-
- var errorMessage string
- if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) &&
- resp.Header.Get("Content-Type") == "application/json" {
- var errorResponse types.ErrorResponse
- if err := json.Unmarshal(body, &errorResponse); err != nil {
- return serverResp, fmt.Errorf("Error reading JSON: %v", err)
- }
- errorMessage = errorResponse.Message
- } else {
- errorMessage = string(body)
- }
-
- return serverResp, fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage))
- }
-
- serverResp.body = resp.Body
- serverResp.header = resp.Header
return serverResp, nil
}
+func (cli *Client) checkResponseErr(serverResp serverResponse) error {
+ if serverResp.statusCode >= 200 && serverResp.statusCode < 400 {
+ return nil
+ }
+
+ body, err := ioutil.ReadAll(serverResp.body)
+ if err != nil {
+ return err
+ }
+ if len(body) == 0 {
+ return fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
+ }
+
+ var ct string
+ if serverResp.header != nil {
+ ct = serverResp.header.Get("Content-Type")
+ }
+
+ var errorMessage string
+ if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) && ct == "application/json" {
+ var errorResponse types.ErrorResponse
+ if err := json.Unmarshal(body, &errorResponse); err != nil {
+ return fmt.Errorf("Error reading JSON: %v", err)
+ }
+ errorMessage = errorResponse.Message
+ } else {
+ errorMessage = string(body)
+ }
+
+ return fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage))
+}
+
func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request {
// Add CLI Config's HTTP Headers BEFORE we set the Docker headers
// then the user can't change OUR headers
@@ -239,9 +254,9 @@ func encodeData(data interface{}) (*bytes.Buffer, error) {
}
func ensureReaderClosed(response serverResponse) {
- if body := response.body; body != nil {
+ if response.body != nil {
// Drain up to 512 bytes and close the body to let the Transport reuse the connection
- io.CopyN(ioutil.Discard, body, 512)
+ io.CopyN(ioutil.Discard, response.body, 512)
response.body.Close()
}
}
diff --git a/vendor/github.com/docker/docker/client/secret_create.go b/vendor/github.com/docker/docker/client/secret_create.go
index de8b0415..4354afea 100644
--- a/vendor/github.com/docker/docker/client/secret_create.go
+++ b/vendor/github.com/docker/docker/client/secret_create.go
@@ -10,10 +10,11 @@ import (
// SecretCreate creates a new Secret.
func (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) {
- var headers map[string][]string
-
var response types.SecretCreateResponse
- resp, err := cli.post(ctx, "/secrets/create", nil, secret, headers)
+ if err := cli.NewVersionError("1.25", "secret create"); err != nil {
+ return response, err
+ }
+ resp, err := cli.post(ctx, "/secrets/create", nil, secret, nil)
if err != nil {
return response, err
}
diff --git a/vendor/github.com/docker/docker/client/secret_inspect.go b/vendor/github.com/docker/docker/client/secret_inspect.go
index f7745761..9b602972 100644
--- a/vendor/github.com/docker/docker/client/secret_inspect.go
+++ b/vendor/github.com/docker/docker/client/secret_inspect.go
@@ -12,6 +12,9 @@ import (
// SecretInspectWithRaw returns the secret information with raw data
func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {
+ if err := cli.NewVersionError("1.25", "secret inspect"); err != nil {
+ return swarm.Secret{}, nil, err
+ }
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
if err != nil {
if resp.statusCode == http.StatusNotFound {
diff --git a/vendor/github.com/docker/docker/client/secret_list.go b/vendor/github.com/docker/docker/client/secret_list.go
index 7e9d5ec1..0d33ecfb 100644
--- a/vendor/github.com/docker/docker/client/secret_list.go
+++ b/vendor/github.com/docker/docker/client/secret_list.go
@@ -12,6 +12,9 @@ import (
// SecretList returns the list of secrets.
func (cli *Client) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
+ if err := cli.NewVersionError("1.25", "secret list"); err != nil {
+ return nil, err
+ }
query := url.Values{}
if options.Filters.Len() > 0 {
diff --git a/vendor/github.com/docker/docker/client/secret_remove.go b/vendor/github.com/docker/docker/client/secret_remove.go
index 1955b988..c5e37af1 100644
--- a/vendor/github.com/docker/docker/client/secret_remove.go
+++ b/vendor/github.com/docker/docker/client/secret_remove.go
@@ -4,6 +4,9 @@ import "golang.org/x/net/context"
// SecretRemove removes a Secret.
func (cli *Client) SecretRemove(ctx context.Context, id string) error {
+ if err := cli.NewVersionError("1.25", "secret remove"); err != nil {
+ return err
+ }
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
ensureReaderClosed(resp)
return err
diff --git a/vendor/github.com/docker/docker/client/secret_update.go b/vendor/github.com/docker/docker/client/secret_update.go
index b94e24aa..875a4c90 100644
--- a/vendor/github.com/docker/docker/client/secret_update.go
+++ b/vendor/github.com/docker/docker/client/secret_update.go
@@ -8,9 +8,11 @@ import (
"golang.org/x/net/context"
)
-// SecretUpdate updates a Secret. Currently, the only part of a secret spec
-// which can be updated is Labels.
+// SecretUpdate attempts to update a Secret
func (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
+ if err := cli.NewVersionError("1.25", "secret update"); err != nil {
+ return err
+ }
query := url.Values{}
query.Set("version", strconv.FormatUint(version.Index, 10))
resp, err := cli.post(ctx, "/secrets/"+id+"/update", query, secret, nil)
diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go
index 3d1be225..a3683944 100644
--- a/vendor/github.com/docker/docker/client/service_create.go
+++ b/vendor/github.com/docker/docker/client/service_create.go
@@ -2,20 +2,71 @@ package client
import (
"encoding/json"
+ "fmt"
+ "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
+ "github.com/opencontainers/go-digest"
+ "github.com/pkg/errors"
"golang.org/x/net/context"
)
// ServiceCreate creates a new Service.
func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (types.ServiceCreateResponse, error) {
- var headers map[string][]string
+ var distErr error
+
+ headers := map[string][]string{
+ "version": {cli.version},
+ }
if options.EncodedRegistryAuth != "" {
- headers = map[string][]string{
- "X-Registry-Auth": {options.EncodedRegistryAuth},
+ headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
+ }
+
+ // Make sure containerSpec is not nil when no runtime is set or the runtime is set to container
+ if service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == "" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {
+ service.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{}
+ }
+
+ if err := validateServiceSpec(service); err != nil {
+ return types.ServiceCreateResponse{}, err
+ }
+
+ // ensure that the image is tagged
+ var imgPlatforms []swarm.Platform
+ if service.TaskTemplate.ContainerSpec != nil {
+ if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
+ service.TaskTemplate.ContainerSpec.Image = taggedImg
}
+ if options.QueryRegistry {
+ var img string
+ img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
+ if img != "" {
+ service.TaskTemplate.ContainerSpec.Image = img
+ }
+ }
+ }
+
+ // ensure that the image is tagged
+ if service.TaskTemplate.PluginSpec != nil {
+ if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
+ service.TaskTemplate.PluginSpec.Remote = taggedImg
+ }
+ if options.QueryRegistry {
+ var img string
+ img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth)
+ if img != "" {
+ service.TaskTemplate.PluginSpec.Remote = img
+ }
+ }
+ }
+
+ if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 {
+ service.TaskTemplate.Placement = &swarm.Placement{}
+ }
+ if len(imgPlatforms) > 0 {
+ service.TaskTemplate.Placement.Platforms = imgPlatforms
}
var response types.ServiceCreateResponse
@@ -25,6 +76,81 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec,
}
err = json.NewDecoder(resp.body).Decode(&response)
+
+ if distErr != nil {
+ response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
+ }
+
ensureReaderClosed(resp)
return response, err
}
+
+func imageDigestAndPlatforms(ctx context.Context, cli *Client, image, encodedAuth string) (string, []swarm.Platform, error) {
+ distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth)
+ imageWithDigest := image
+ var platforms []swarm.Platform
+ if err != nil {
+ return "", nil, err
+ }
+
+ imageWithDigest = imageWithDigestString(image, distributionInspect.Descriptor.Digest)
+
+ if len(distributionInspect.Platforms) > 0 {
+ platforms = make([]swarm.Platform, 0, len(distributionInspect.Platforms))
+ for _, p := range distributionInspect.Platforms {
+ platforms = append(platforms, swarm.Platform{
+ Architecture: p.Architecture,
+ OS: p.OS,
+ })
+ }
+ }
+ return imageWithDigest, platforms, err
+}
+
+// imageWithDigestString takes an image string and a digest, and updates
+// the image string if it didn't originally contain a digest. It returns
+// an empty string if there are no updates.
+func imageWithDigestString(image string, dgst digest.Digest) string {
+ namedRef, err := reference.ParseNormalizedNamed(image)
+ if err == nil {
+ if _, isCanonical := namedRef.(reference.Canonical); !isCanonical {
+ // ensure that image gets a default tag if none is provided
+ img, err := reference.WithDigest(namedRef, dgst)
+ if err == nil {
+ return reference.FamiliarString(img)
+ }
+ }
+ }
+ return ""
+}
+
+// imageWithTagString takes an image string, and returns a tagged image
+// string, adding a 'latest' tag if one was not provided. It returns an
+// emptry string if a canonical reference was provided
+func imageWithTagString(image string) string {
+ namedRef, err := reference.ParseNormalizedNamed(image)
+ if err == nil {
+ return reference.FamiliarString(reference.TagNameOnly(namedRef))
+ }
+ return ""
+}
+
+// digestWarning constructs a formatted warning string using the
+// image name that could not be pinned by digest. The formatting
+// is hardcoded, but could me made smarter in the future
+func digestWarning(image string) string {
+ return fmt.Sprintf("image %s could not be accessed on a registry to record\nits digest. Each node will access %s independently,\npossibly leading to different nodes running different\nversions of the image.\n", image, image)
+}
+
+func validateServiceSpec(s swarm.ServiceSpec) error {
+ if s.TaskTemplate.ContainerSpec != nil && s.TaskTemplate.PluginSpec != nil {
+ return errors.New("must not specify both a container spec and a plugin spec in the task template")
+ }
+ if s.TaskTemplate.PluginSpec != nil && s.TaskTemplate.Runtime != swarm.RuntimePlugin {
+ return errors.New("mismatched runtime with plugin spec")
+ }
+ if s.TaskTemplate.ContainerSpec != nil && (s.TaskTemplate.Runtime != "" && s.TaskTemplate.Runtime != swarm.RuntimeContainer) {
+ return errors.New("mismatched runtime with container spec")
+ }
+ return nil
+}
diff --git a/vendor/github.com/docker/docker/client/service_inspect.go b/vendor/github.com/docker/docker/client/service_inspect.go
index ca71cbde..d7e051e3 100644
--- a/vendor/github.com/docker/docker/client/service_inspect.go
+++ b/vendor/github.com/docker/docker/client/service_inspect.go
@@ -3,16 +3,21 @@ package client
import (
"bytes"
"encoding/json"
+ "fmt"
"io/ioutil"
"net/http"
+ "net/url"
+ "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context"
)
// ServiceInspectWithRaw returns the service information and the raw data.
-func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string) (swarm.Service, []byte, error) {
- serverResp, err := cli.get(ctx, "/services/"+serviceID, nil, nil)
+func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
+ query := url.Values{}
+ query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults))
+ serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil)
if err != nil {
if serverResp.statusCode == http.StatusNotFound {
return swarm.Service{}, nil, serviceNotFoundError{serviceID}
diff --git a/vendor/github.com/docker/docker/client/service_update.go b/vendor/github.com/docker/docker/client/service_update.go
index afa94d47..8764f299 100644
--- a/vendor/github.com/docker/docker/client/service_update.go
+++ b/vendor/github.com/docker/docker/client/service_update.go
@@ -13,22 +13,68 @@ import (
// ServiceUpdate updates a Service.
func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) {
var (
- headers map[string][]string
query = url.Values{}
+ distErr error
)
+ headers := map[string][]string{
+ "version": {cli.version},
+ }
+
if options.EncodedRegistryAuth != "" {
- headers = map[string][]string{
- "X-Registry-Auth": {options.EncodedRegistryAuth},
- }
+ headers["X-Registry-Auth"] = []string{options.EncodedRegistryAuth}
}
if options.RegistryAuthFrom != "" {
query.Set("registryAuthFrom", options.RegistryAuthFrom)
}
+ if options.Rollback != "" {
+ query.Set("rollback", options.Rollback)
+ }
+
query.Set("version", strconv.FormatUint(version.Index, 10))
+ if err := validateServiceSpec(service); err != nil {
+ return types.ServiceUpdateResponse{}, err
+ }
+
+ var imgPlatforms []swarm.Platform
+ // ensure that the image is tagged
+ if service.TaskTemplate.ContainerSpec != nil {
+ if taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != "" {
+ service.TaskTemplate.ContainerSpec.Image = taggedImg
+ }
+ if options.QueryRegistry {
+ var img string
+ img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.ContainerSpec.Image, options.EncodedRegistryAuth)
+ if img != "" {
+ service.TaskTemplate.ContainerSpec.Image = img
+ }
+ }
+ }
+
+ // ensure that the image is tagged
+ if service.TaskTemplate.PluginSpec != nil {
+ if taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != "" {
+ service.TaskTemplate.PluginSpec.Remote = taggedImg
+ }
+ if options.QueryRegistry {
+ var img string
+ img, imgPlatforms, distErr = imageDigestAndPlatforms(ctx, cli, service.TaskTemplate.PluginSpec.Remote, options.EncodedRegistryAuth)
+ if img != "" {
+ service.TaskTemplate.PluginSpec.Remote = img
+ }
+ }
+ }
+
+ if service.TaskTemplate.Placement == nil && len(imgPlatforms) > 0 {
+ service.TaskTemplate.Placement = &swarm.Placement{}
+ }
+ if len(imgPlatforms) > 0 {
+ service.TaskTemplate.Placement.Platforms = imgPlatforms
+ }
+
var response types.ServiceUpdateResponse
resp, err := cli.post(ctx, "/services/"+serviceID+"/update", query, service, headers)
if err != nil {
@@ -36,6 +82,11 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version
}
err = json.NewDecoder(resp.body).Decode(&response)
+
+ if distErr != nil {
+ response.Warnings = append(response.Warnings, digestWarning(service.TaskTemplate.ContainerSpec.Image))
+ }
+
ensureReaderClosed(resp)
return response, err
}
diff --git a/vendor/github.com/docker/docker/client/session.go b/vendor/github.com/docker/docker/client/session.go
new file mode 100644
index 00000000..8ee91621
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/session.go
@@ -0,0 +1,19 @@
+package client
+
+import (
+ "net"
+ "net/http"
+
+ "golang.org/x/net/context"
+)
+
+// DialSession returns a connection that can be used communication with daemon
+func (cli *Client) DialSession(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
+ req, err := http.NewRequest("POST", "/session", nil)
+ if err != nil {
+ return nil, err
+ }
+ req = cli.addHeaders(req, meta)
+
+ return cli.setupHijackConn(req, proto)
+}
diff --git a/vendor/github.com/docker/docker/client/swarm_init.go b/vendor/github.com/docker/docker/client/swarm_init.go
index fd45d066..9e65e1cc 100644
--- a/vendor/github.com/docker/docker/client/swarm_init.go
+++ b/vendor/github.com/docker/docker/client/swarm_init.go
@@ -7,7 +7,7 @@ import (
"golang.org/x/net/context"
)
-// SwarmInit initializes the Swarm.
+// SwarmInit initializes the swarm.
func (cli *Client) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {
serverResp, err := cli.post(ctx, "/swarm/init", nil, req, nil)
if err != nil {
diff --git a/vendor/github.com/docker/docker/client/swarm_inspect.go b/vendor/github.com/docker/docker/client/swarm_inspect.go
index 6d95cfc0..77e72f84 100644
--- a/vendor/github.com/docker/docker/client/swarm_inspect.go
+++ b/vendor/github.com/docker/docker/client/swarm_inspect.go
@@ -7,7 +7,7 @@ import (
"golang.org/x/net/context"
)
-// SwarmInspect inspects the Swarm.
+// SwarmInspect inspects the swarm.
func (cli *Client) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {
serverResp, err := cli.get(ctx, "/swarm", nil, nil)
if err != nil {
diff --git a/vendor/github.com/docker/docker/client/swarm_join.go b/vendor/github.com/docker/docker/client/swarm_join.go
index cda99930..19e5192b 100644
--- a/vendor/github.com/docker/docker/client/swarm_join.go
+++ b/vendor/github.com/docker/docker/client/swarm_join.go
@@ -5,7 +5,7 @@ import (
"golang.org/x/net/context"
)
-// SwarmJoin joins the Swarm.
+// SwarmJoin joins the swarm.
func (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
resp, err := cli.post(ctx, "/swarm/join", nil, req, nil)
ensureReaderClosed(resp)
diff --git a/vendor/github.com/docker/docker/client/swarm_leave.go b/vendor/github.com/docker/docker/client/swarm_leave.go
index a4df7321..3a205cf3 100644
--- a/vendor/github.com/docker/docker/client/swarm_leave.go
+++ b/vendor/github.com/docker/docker/client/swarm_leave.go
@@ -6,7 +6,7 @@ import (
"golang.org/x/net/context"
)
-// SwarmLeave leaves the Swarm.
+// SwarmLeave leaves the swarm.
func (cli *Client) SwarmLeave(ctx context.Context, force bool) error {
query := url.Values{}
if force {
diff --git a/vendor/github.com/docker/docker/client/swarm_unlock.go b/vendor/github.com/docker/docker/client/swarm_unlock.go
index addfb59f..9ee441fe 100644
--- a/vendor/github.com/docker/docker/client/swarm_unlock.go
+++ b/vendor/github.com/docker/docker/client/swarm_unlock.go
@@ -5,13 +5,9 @@ import (
"golang.org/x/net/context"
)
-// SwarmUnlock unlockes locked swarm.
+// SwarmUnlock unlocks locked swarm.
func (cli *Client) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
serverResp, err := cli.post(ctx, "/swarm/unlock", nil, req, nil)
- if err != nil {
- return err
- }
-
ensureReaderClosed(serverResp)
return err
}
diff --git a/vendor/github.com/docker/docker/client/swarm_update.go b/vendor/github.com/docker/docker/client/swarm_update.go
index cc8eeb65..7245fd4e 100644
--- a/vendor/github.com/docker/docker/client/swarm_update.go
+++ b/vendor/github.com/docker/docker/client/swarm_update.go
@@ -9,7 +9,7 @@ import (
"golang.org/x/net/context"
)
-// SwarmUpdate updates the Swarm.
+// SwarmUpdate updates the swarm.
func (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error {
query := url.Values{}
query.Set("version", strconv.FormatUint(version.Index, 10))
diff --git a/vendor/github.com/docker/docker/client/task_logs.go b/vendor/github.com/docker/docker/client/task_logs.go
new file mode 100644
index 00000000..2ed19543
--- /dev/null
+++ b/vendor/github.com/docker/docker/client/task_logs.go
@@ -0,0 +1,52 @@
+package client
+
+import (
+ "io"
+ "net/url"
+ "time"
+
+ "golang.org/x/net/context"
+
+ "github.com/docker/docker/api/types"
+ timetypes "github.com/docker/docker/api/types/time"
+)
+
+// TaskLogs returns the logs generated by a task in an io.ReadCloser.
+// It's up to the caller to close the stream.
+func (cli *Client) TaskLogs(ctx context.Context, taskID string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
+ query := url.Values{}
+ if options.ShowStdout {
+ query.Set("stdout", "1")
+ }
+
+ if options.ShowStderr {
+ query.Set("stderr", "1")
+ }
+
+ if options.Since != "" {
+ ts, err := timetypes.GetTimestamp(options.Since, time.Now())
+ if err != nil {
+ return nil, err
+ }
+ query.Set("since", ts)
+ }
+
+ if options.Timestamps {
+ query.Set("timestamps", "1")
+ }
+
+ if options.Details {
+ query.Set("details", "1")
+ }
+
+ if options.Follow {
+ query.Set("follow", "1")
+ }
+ query.Set("tail", options.Tail)
+
+ resp, err := cli.get(ctx, "/tasks/"+taskID+"/logs", query, nil)
+ if err != nil {
+ return nil, err
+ }
+ return resp.body, nil
+}
diff --git a/vendor/github.com/docker/docker/client/transport.go b/vendor/github.com/docker/docker/client/transport.go
index f04e6016..401ab15d 100644
--- a/vendor/github.com/docker/docker/client/transport.go
+++ b/vendor/github.com/docker/docker/client/transport.go
@@ -2,12 +2,9 @@ package client
import (
"crypto/tls"
- "errors"
"net/http"
)
-var errTLSConfigUnavailable = errors.New("TLSConfig unavailable")
-
// transportFunc allows us to inject a mock transport for testing. We define it
// here so we can detect the tlsconfig and return nil for only this type.
type transportFunc func(*http.Request) (*http.Response, error)
@@ -16,7 +13,7 @@ func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return tf(req)
}
-// resolveTLSConfig attempts to resolve the tls configuration from the
+// resolveTLSConfig attempts to resolve the TLS configuration from the
// RoundTripper.
func resolveTLSConfig(transport http.RoundTripper) *tls.Config {
switch tr := transport.(type) {
diff --git a/vendor/github.com/docker/docker/client/utils.go b/vendor/github.com/docker/docker/client/utils.go
index 23d520ec..f3d8877d 100644
--- a/vendor/github.com/docker/docker/client/utils.go
+++ b/vendor/github.com/docker/docker/client/utils.go
@@ -1,9 +1,10 @@
package client
import (
- "github.com/docker/docker/api/types/filters"
"net/url"
"regexp"
+
+ "github.com/docker/docker/api/types/filters"
)
var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`)
diff --git a/vendor/github.com/docker/docker/client/volume_prune.go b/vendor/github.com/docker/docker/client/volume_prune.go
index a07e4ce6..2e7fea77 100644
--- a/vendor/github.com/docker/docker/client/volume_prune.go
+++ b/vendor/github.com/docker/docker/client/volume_prune.go
@@ -29,7 +29,7 @@ func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args)
defer ensureReaderClosed(serverResp)
if err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {
- return report, fmt.Errorf("Error retrieving disk usage: %v", err)
+ return report, fmt.Errorf("Error retrieving volume prune report: %v", err)
}
return report, nil
diff --git a/vendor/github.com/docker/docker/hack/README.md b/vendor/github.com/docker/docker/hack/README.md
new file mode 100644
index 00000000..802395d5
--- /dev/null
+++ b/vendor/github.com/docker/docker/hack/README.md
@@ -0,0 +1,60 @@
+## About
+
+This directory contains a collection of scripts used to build and manage this
+repository. If there are any issues regarding the intention of a particular
+script (or even part of a certain script), please reach out to us.
+It may help us either refine our current scripts, or add on new ones
+that are appropriate for a given use case.
+
+## DinD (dind.sh)
+
+DinD is a wrapper script which allows Docker to be run inside a Docker
+container. DinD requires the container to
+be run with privileged mode enabled.
+
+## Generate Authors (generate-authors.sh)
+
+Generates AUTHORS; a file with all the names and corresponding emails of
+individual contributors. AUTHORS can be found in the home directory of
+this repository.
+
+## Make
+
+There are two make files, each with different extensions. Neither are supposed
+to be called directly; only invoke `make`. Both scripts run inside a Docker
+container.
+
+### make.ps1
+
+- The Windows native build script that uses PowerShell semantics; it is limited
+unlike `hack\make.sh` since it does not provide support for the full set of
+operations provided by the Linux counterpart, `make.sh`. However, `make.ps1`
+does provide support for local Windows development and Windows to Windows CI.
+More information is found within `make.ps1` by the author, @jhowardmsft
+
+### make.sh
+
+- Referenced via `make test` when running tests on a local machine,
+or directly referenced when running tests inside a Docker development container.
+- When running on a local machine, `make test` to run all tests found in
+`test`, `test-unit`, `test-integration-cli`, and `test-docker-py` on
+your local machine. The default timeout is set in `make.sh` to 60 minutes
+(`${TIMEOUT:=60m}`), since it currently takes up to an hour to run
+all of the tests.
+- When running inside a Docker development container, `hack/make.sh` does
+not have a single target that runs all the tests. You need to provide a
+single command line with multiple targets that performs the same thing.
+An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration-cli test-docker-py`
+- For more information related to testing outside the scope of this README,
+refer to
+[Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/)
+
+## Release (release.sh)
+
+Releases any bundles built by `make` on a public AWS S3 bucket.
+For information regarding configuration, please view `release.sh`.
+
+## Vendor (vendor.sh)
+
+A shell script that is a wrapper around Vndr. For information on how to use
+this, please refer to [vndr's README](https://github.com/LK4D4/vndr/blob/master/README.md)
diff --git a/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/README.md b/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/README.md
new file mode 100644
index 00000000..1cea5252
--- /dev/null
+++ b/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/README.md
@@ -0,0 +1,69 @@
+# Integration Testing on Swarm
+
+IT on Swarm allows you to execute integration test in parallel across a Docker Swarm cluster
+
+## Architecture
+
+### Master service
+
+ - Works as a funker caller
+ - Calls a worker funker (`-worker-service`) with a chunk of `-check.f` filter strings (passed as a file via `-input` flag, typically `/mnt/input`)
+
+### Worker service
+
+ - Works as a funker callee
+ - Executes an equivalent of `TESTFLAGS=-check.f TestFoo|TestBar|TestBaz ... make test-integration-cli` using the bind-mounted API socket (`docker.sock`)
+
+### Client
+
+ - Controls master and workers via `docker stack`
+ - No need to have a local daemon
+
+Typically, the master and workers are supposed to be running on a cloud environment,
+while the client is supposed to be running on a laptop, e.g. Docker for Mac/Windows.
+
+## Requirement
+
+ - Docker daemon 1.13 or later
+ - Private registry for distributed execution with multiple nodes
+
+## Usage
+
+### Step 1: Prepare images
+
+ $ make build-integration-cli-on-swarm
+
+Following environment variables are known to work in this step:
+
+ - `BUILDFLAGS`
+ - `DOCKER_INCREMENTAL_BINARY`
+
+Note: during the transition into Moby Project, you might need to create a symbolic link `$GOPATH/src/github.com/docker/docker` to `$GOPATH/src/github.com/moby/moby`.
+
+### Step 2: Execute tests
+
+ $ ./hack/integration-cli-on-swarm/integration-cli-on-swarm -replicas 40 -push-worker-image YOUR_REGISTRY.EXAMPLE.COM/integration-cli-worker:latest
+
+Following environment variables are known to work in this step:
+
+ - `DOCKER_GRAPHDRIVER`
+ - `DOCKER_EXPERIMENTAL`
+
+#### Flags
+
+Basic flags:
+
+ - `-replicas N`: the number of worker service replicas. i.e. degree of parallelism.
+ - `-chunks N`: the number of chunks. By default, `chunks` == `replicas`.
+ - `-push-worker-image REGISTRY/IMAGE:TAG`: push the worker image to the registry. Note that if you have only single node and hence you do not need a private registry, you do not need to specify `-push-worker-image`.
+
+Experimental flags for mitigating makespan nonuniformity:
+
+ - `-shuffle`: Shuffle the test filter strings
+
+Flags for debugging IT on Swarm itself:
+
+ - `-rand-seed N`: the random seed. This flag is useful for deterministic replaying. By default(0), the timestamp is used.
+ - `-filters-file FILE`: the file contains `-check.f` strings. By default, the file is automatically generated.
+ - `-dry-run`: skip the actual workload
+ - `keep-executor`: do not auto-remove executor containers, which is used for running privileged programs on Swarm
diff --git a/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/agent/vendor.conf b/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/agent/vendor.conf
new file mode 100644
index 00000000..efd6d6d0
--- /dev/null
+++ b/vendor/github.com/docker/docker/hack/integration-cli-on-swarm/agent/vendor.conf
@@ -0,0 +1,2 @@
+# dependencies specific to worker (i.e. github.com/docker/docker/...) are not vendored here
+github.com/bfirsh/funker-go eaa0a2e06f30e72c9a0b7f858951e581e26ef773
diff --git a/vendor/github.com/docker/docker/pkg/ioutils/fmt.go b/vendor/github.com/docker/docker/pkg/ioutils/fmt.go
deleted file mode 100644
index 0b04b0ba..00000000
--- a/vendor/github.com/docker/docker/pkg/ioutils/fmt.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package ioutils
-
-import (
- "fmt"
- "io"
-)
-
-// FprintfIfNotEmpty prints the string value if it's not empty
-func FprintfIfNotEmpty(w io.Writer, format, value string) (int, error) {
- if value != "" {
- return fmt.Fprintf(w, format, value)
- }
- return 0, nil
-}
-
-// FprintfIfTrue prints the boolean value if it's true
-func FprintfIfTrue(w io.Writer, format string, ok bool) (int, error) {
- if ok {
- return fmt.Fprintf(w, format, ok)
- }
- return 0, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/ioutils/multireader.go b/vendor/github.com/docker/docker/pkg/ioutils/multireader.go
deleted file mode 100644
index d7b97486..00000000
--- a/vendor/github.com/docker/docker/pkg/ioutils/multireader.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package ioutils
-
-import (
- "bytes"
- "fmt"
- "io"
- "os"
-)
-
-type pos struct {
- idx int
- offset int64
-}
-
-type multiReadSeeker struct {
- readers []io.ReadSeeker
- pos *pos
- posIdx map[io.ReadSeeker]int
-}
-
-func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) {
- var tmpOffset int64
- switch whence {
- case os.SEEK_SET:
- for i, rdr := range r.readers {
- // get size of the current reader
- s, err := rdr.Seek(0, os.SEEK_END)
- if err != nil {
- return -1, err
- }
-
- if offset > tmpOffset+s {
- if i == len(r.readers)-1 {
- rdrOffset := s + (offset - tmpOffset)
- if _, err := rdr.Seek(rdrOffset, os.SEEK_SET); err != nil {
- return -1, err
- }
- r.pos = &pos{i, rdrOffset}
- return offset, nil
- }
-
- tmpOffset += s
- continue
- }
-
- rdrOffset := offset - tmpOffset
- idx := i
-
- rdr.Seek(rdrOffset, os.SEEK_SET)
- // make sure all following readers are at 0
- for _, rdr := range r.readers[i+1:] {
- rdr.Seek(0, os.SEEK_SET)
- }
-
- if rdrOffset == s && i != len(r.readers)-1 {
- idx++
- rdrOffset = 0
- }
- r.pos = &pos{idx, rdrOffset}
- return offset, nil
- }
- case os.SEEK_END:
- for _, rdr := range r.readers {
- s, err := rdr.Seek(0, os.SEEK_END)
- if err != nil {
- return -1, err
- }
- tmpOffset += s
- }
- r.Seek(tmpOffset+offset, os.SEEK_SET)
- return tmpOffset + offset, nil
- case os.SEEK_CUR:
- if r.pos == nil {
- return r.Seek(offset, os.SEEK_SET)
- }
- // Just return the current offset
- if offset == 0 {
- return r.getCurOffset()
- }
-
- curOffset, err := r.getCurOffset()
- if err != nil {
- return -1, err
- }
- rdr, rdrOffset, err := r.getReaderForOffset(curOffset + offset)
- if err != nil {
- return -1, err
- }
-
- r.pos = &pos{r.posIdx[rdr], rdrOffset}
- return curOffset + offset, nil
- default:
- return -1, fmt.Errorf("Invalid whence: %d", whence)
- }
-
- return -1, fmt.Errorf("Error seeking for whence: %d, offset: %d", whence, offset)
-}
-
-func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, int64, error) {
-
- var offsetTo int64
-
- for _, rdr := range r.readers {
- size, err := getReadSeekerSize(rdr)
- if err != nil {
- return nil, -1, err
- }
- if offsetTo+size > offset {
- return rdr, offset - offsetTo, nil
- }
- if rdr == r.readers[len(r.readers)-1] {
- return rdr, offsetTo + offset, nil
- }
- offsetTo += size
- }
-
- return nil, 0, nil
-}
-
-func (r *multiReadSeeker) getCurOffset() (int64, error) {
- var totalSize int64
- for _, rdr := range r.readers[:r.pos.idx+1] {
- if r.posIdx[rdr] == r.pos.idx {
- totalSize += r.pos.offset
- break
- }
-
- size, err := getReadSeekerSize(rdr)
- if err != nil {
- return -1, fmt.Errorf("error getting seeker size: %v", err)
- }
- totalSize += size
- }
- return totalSize, nil
-}
-
-func (r *multiReadSeeker) getOffsetToReader(rdr io.ReadSeeker) (int64, error) {
- var offset int64
- for _, r := range r.readers {
- if r == rdr {
- break
- }
-
- size, err := getReadSeekerSize(rdr)
- if err != nil {
- return -1, err
- }
- offset += size
- }
- return offset, nil
-}
-
-func (r *multiReadSeeker) Read(b []byte) (int, error) {
- if r.pos == nil {
- r.pos = &pos{0, 0}
- }
-
- bLen := int64(len(b))
- buf := bytes.NewBuffer(nil)
- var rdr io.ReadSeeker
-
- for _, rdr = range r.readers[r.pos.idx:] {
- readBytes, err := io.CopyN(buf, rdr, bLen)
- if err != nil && err != io.EOF {
- return -1, err
- }
- bLen -= readBytes
-
- if bLen == 0 {
- break
- }
- }
-
- rdrPos, err := rdr.Seek(0, os.SEEK_CUR)
- if err != nil {
- return -1, err
- }
- r.pos = &pos{r.posIdx[rdr], rdrPos}
- return buf.Read(b)
-}
-
-func getReadSeekerSize(rdr io.ReadSeeker) (int64, error) {
- // save the current position
- pos, err := rdr.Seek(0, os.SEEK_CUR)
- if err != nil {
- return -1, err
- }
-
- // get the size
- size, err := rdr.Seek(0, os.SEEK_END)
- if err != nil {
- return -1, err
- }
-
- // reset the position
- if _, err := rdr.Seek(pos, os.SEEK_SET); err != nil {
- return -1, err
- }
- return size, nil
-}
-
-// MultiReadSeeker returns a ReadSeeker that's the logical concatenation of the provided
-// input readseekers. After calling this method the initial position is set to the
-// beginning of the first ReadSeeker. At the end of a ReadSeeker, Read always advances
-// to the beginning of the next ReadSeeker and returns EOF at the end of the last ReadSeeker.
-// Seek can be used over the sum of lengths of all readseekers.
-//
-// When a MultiReadSeeker is used, no Read and Seek operations should be made on
-// its ReadSeeker components. Also, users should make no assumption on the state
-// of individual readseekers while the MultiReadSeeker is used.
-func MultiReadSeeker(readers ...io.ReadSeeker) io.ReadSeeker {
- if len(readers) == 1 {
- return readers[0]
- }
- idx := make(map[io.ReadSeeker]int)
- for i, rdr := range readers {
- idx[rdr] = i
- }
- return &multiReadSeeker{
- readers: readers,
- posIdx: idx,
- }
-}
diff --git a/vendor/github.com/docker/docker/pkg/mount/flags_freebsd.go b/vendor/github.com/docker/docker/pkg/mount/flags_freebsd.go
index f166cb2f..5f76f331 100644
--- a/vendor/github.com/docker/docker/pkg/mount/flags_freebsd.go
+++ b/vendor/github.com/docker/docker/pkg/mount/flags_freebsd.go
@@ -45,4 +45,5 @@ const (
RELATIME = 0
REMOUNT = 0
STRICTATIME = 0
+ mntDetach = 0
)
diff --git a/vendor/github.com/docker/docker/pkg/mount/flags_linux.go b/vendor/github.com/docker/docker/pkg/mount/flags_linux.go
index dc696dce..0425d0dd 100644
--- a/vendor/github.com/docker/docker/pkg/mount/flags_linux.go
+++ b/vendor/github.com/docker/docker/pkg/mount/flags_linux.go
@@ -1,85 +1,87 @@
package mount
import (
- "syscall"
+ "golang.org/x/sys/unix"
)
const (
// RDONLY will mount the file system read-only.
- RDONLY = syscall.MS_RDONLY
+ RDONLY = unix.MS_RDONLY
// NOSUID will not allow set-user-identifier or set-group-identifier bits to
// take effect.
- NOSUID = syscall.MS_NOSUID
+ NOSUID = unix.MS_NOSUID
// NODEV will not interpret character or block special devices on the file
// system.
- NODEV = syscall.MS_NODEV
+ NODEV = unix.MS_NODEV
// NOEXEC will not allow execution of any binaries on the mounted file system.
- NOEXEC = syscall.MS_NOEXEC
+ NOEXEC = unix.MS_NOEXEC
// SYNCHRONOUS will allow I/O to the file system to be done synchronously.
- SYNCHRONOUS = syscall.MS_SYNCHRONOUS
+ SYNCHRONOUS = unix.MS_SYNCHRONOUS
// DIRSYNC will force all directory updates within the file system to be done
// synchronously. This affects the following system calls: create, link,
// unlink, symlink, mkdir, rmdir, mknod and rename.
- DIRSYNC = syscall.MS_DIRSYNC
+ DIRSYNC = unix.MS_DIRSYNC
// REMOUNT will attempt to remount an already-mounted file system. This is
// commonly used to change the mount flags for a file system, especially to
// make a readonly file system writeable. It does not change device or mount
// point.
- REMOUNT = syscall.MS_REMOUNT
+ REMOUNT = unix.MS_REMOUNT
// MANDLOCK will force mandatory locks on a filesystem.
- MANDLOCK = syscall.MS_MANDLOCK
+ MANDLOCK = unix.MS_MANDLOCK
// NOATIME will not update the file access time when reading from a file.
- NOATIME = syscall.MS_NOATIME
+ NOATIME = unix.MS_NOATIME
// NODIRATIME will not update the directory access time.
- NODIRATIME = syscall.MS_NODIRATIME
+ NODIRATIME = unix.MS_NODIRATIME
// BIND remounts a subtree somewhere else.
- BIND = syscall.MS_BIND
+ BIND = unix.MS_BIND
// RBIND remounts a subtree and all possible submounts somewhere else.
- RBIND = syscall.MS_BIND | syscall.MS_REC
+ RBIND = unix.MS_BIND | unix.MS_REC
// UNBINDABLE creates a mount which cannot be cloned through a bind operation.
- UNBINDABLE = syscall.MS_UNBINDABLE
+ UNBINDABLE = unix.MS_UNBINDABLE
// RUNBINDABLE marks the entire mount tree as UNBINDABLE.
- RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC
+ RUNBINDABLE = unix.MS_UNBINDABLE | unix.MS_REC
// PRIVATE creates a mount which carries no propagation abilities.
- PRIVATE = syscall.MS_PRIVATE
+ PRIVATE = unix.MS_PRIVATE
// RPRIVATE marks the entire mount tree as PRIVATE.
- RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC
+ RPRIVATE = unix.MS_PRIVATE | unix.MS_REC
// SLAVE creates a mount which receives propagation from its master, but not
// vice versa.
- SLAVE = syscall.MS_SLAVE
+ SLAVE = unix.MS_SLAVE
// RSLAVE marks the entire mount tree as SLAVE.
- RSLAVE = syscall.MS_SLAVE | syscall.MS_REC
+ RSLAVE = unix.MS_SLAVE | unix.MS_REC
// SHARED creates a mount which provides the ability to create mirrors of
// that mount such that mounts and unmounts within any of the mirrors
// propagate to the other mirrors.
- SHARED = syscall.MS_SHARED
+ SHARED = unix.MS_SHARED
// RSHARED marks the entire mount tree as SHARED.
- RSHARED = syscall.MS_SHARED | syscall.MS_REC
+ RSHARED = unix.MS_SHARED | unix.MS_REC
// RELATIME updates inode access times relative to modify or change time.
- RELATIME = syscall.MS_RELATIME
+ RELATIME = unix.MS_RELATIME
// STRICTATIME allows to explicitly request full atime updates. This makes
// it possible for the kernel to default to relatime or noatime but still
// allow userspace to override it.
- STRICTATIME = syscall.MS_STRICTATIME
+ STRICTATIME = unix.MS_STRICTATIME
+
+ mntDetach = unix.MNT_DETACH
)
diff --git a/vendor/github.com/docker/docker/pkg/mount/flags_unsupported.go b/vendor/github.com/docker/docker/pkg/mount/flags_unsupported.go
index 5564f7b3..9ed741e3 100644
--- a/vendor/github.com/docker/docker/pkg/mount/flags_unsupported.go
+++ b/vendor/github.com/docker/docker/pkg/mount/flags_unsupported.go
@@ -27,4 +27,5 @@ const (
STRICTATIME = 0
SYNCHRONOUS = 0
RDONLY = 0
+ mntDetach = 0
)
diff --git a/vendor/github.com/docker/docker/pkg/mount/mount.go b/vendor/github.com/docker/docker/pkg/mount/mount.go
index 66ac4bf4..c9fdfd69 100644
--- a/vendor/github.com/docker/docker/pkg/mount/mount.go
+++ b/vendor/github.com/docker/docker/pkg/mount/mount.go
@@ -1,7 +1,8 @@
package mount
import (
- "time"
+ "sort"
+ "strings"
)
// GetMounts retrieves a list of mounts for the current running process.
@@ -46,29 +47,40 @@ func Mount(device, target, mType, options string) error {
// flags.go for supported option flags.
func ForceMount(device, target, mType, options string) error {
flag, data := parseOptions(options)
- if err := mount(device, target, mType, uintptr(flag), data); err != nil {
- return err
- }
- return nil
+ return mount(device, target, mType, uintptr(flag), data)
}
-// Unmount will unmount the target filesystem, so long as it is mounted.
+// Unmount lazily unmounts a filesystem on supported platforms, otherwise
+// does a normal unmount.
func Unmount(target string) error {
if mounted, err := Mounted(target); err != nil || !mounted {
return err
}
- return ForceUnmount(target)
+ return unmount(target, mntDetach)
}
-// ForceUnmount will force an unmount of the target filesystem, regardless if
-// it is mounted or not.
-func ForceUnmount(target string) (err error) {
- // Simple retry logic for unmount
- for i := 0; i < 10; i++ {
- if err = unmount(target, 0); err == nil {
- return nil
- }
- time.Sleep(100 * time.Millisecond)
+// RecursiveUnmount unmounts the target and all mounts underneath, starting with
+// the deepsest mount first.
+func RecursiveUnmount(target string) error {
+ mounts, err := GetMounts()
+ if err != nil {
+ return err
}
- return
+
+ // Make the deepest mount be first
+ sort.Sort(sort.Reverse(byMountpoint(mounts)))
+
+ for i, m := range mounts {
+ if !strings.HasPrefix(m.Mountpoint, target) {
+ continue
+ }
+ if err := Unmount(m.Mountpoint); err != nil && i == len(mounts)-1 {
+ if mounted, err := Mounted(m.Mountpoint); err != nil || mounted {
+ return err
+ }
+ // Ignore errors for submounts and continue trying to unmount others
+ // The final unmount should fail if there ane any submounts remaining
+ }
+ }
+ return nil
}
diff --git a/vendor/github.com/docker/docker/pkg/mount/mounter_freebsd.go b/vendor/github.com/docker/docker/pkg/mount/mounter_freebsd.go
index bb870e6f..814896cc 100644
--- a/vendor/github.com/docker/docker/pkg/mount/mounter_freebsd.go
+++ b/vendor/github.com/docker/docker/pkg/mount/mounter_freebsd.go
@@ -13,8 +13,9 @@ import "C"
import (
"fmt"
"strings"
- "syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
func allocateIOVecs(options []string) []C.struct_iovec {
@@ -55,5 +56,5 @@ func mount(device, target, mType string, flag uintptr, data string) error {
}
func unmount(target string, flag int) error {
- return syscall.Unmount(target, flag)
+ return unix.Unmount(target, flag)
}
diff --git a/vendor/github.com/docker/docker/pkg/mount/mounter_linux.go b/vendor/github.com/docker/docker/pkg/mount/mounter_linux.go
index dd4280c7..39c36d47 100644
--- a/vendor/github.com/docker/docker/pkg/mount/mounter_linux.go
+++ b/vendor/github.com/docker/docker/pkg/mount/mounter_linux.go
@@ -1,21 +1,57 @@
package mount
import (
- "syscall"
+ "golang.org/x/sys/unix"
)
-func mount(device, target, mType string, flag uintptr, data string) error {
- if err := syscall.Mount(device, target, mType, flag, data); err != nil {
- return err
+const (
+ // ptypes is the set propagation types.
+ ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE
+
+ // pflags is the full set valid flags for a change propagation call.
+ pflags = ptypes | unix.MS_REC | unix.MS_SILENT
+
+ // broflags is the combination of bind and read only
+ broflags = unix.MS_BIND | unix.MS_RDONLY
+)
+
+// isremount returns true if either device name or flags identify a remount request, false otherwise.
+func isremount(device string, flags uintptr) bool {
+ switch {
+ // We treat device "" and "none" as a remount request to provide compatibility with
+ // requests that don't explicitly set MS_REMOUNT such as those manipulating bind mounts.
+ case flags&unix.MS_REMOUNT != 0, device == "", device == "none":
+ return true
+ default:
+ return false
+ }
+}
+
+func mount(device, target, mType string, flags uintptr, data string) error {
+ oflags := flags &^ ptypes
+ if !isremount(device, flags) || data != "" {
+ // Initial call applying all non-propagation flags for mount
+ // or remount with changed data
+ if err := unix.Mount(device, target, mType, oflags, data); err != nil {
+ return err
+ }
}
- // If we have a bind mount or remount, remount...
- if flag&syscall.MS_BIND == syscall.MS_BIND && flag&syscall.MS_RDONLY == syscall.MS_RDONLY {
- return syscall.Mount(device, target, mType, flag|syscall.MS_REMOUNT, data)
+ if flags&ptypes != 0 {
+ // Change the propagation type.
+ if err := unix.Mount("", target, "", flags&pflags, ""); err != nil {
+ return err
+ }
}
+
+ if oflags&broflags == broflags {
+ // Remount the bind to apply read only.
+ return unix.Mount("", target, "", oflags|unix.MS_REMOUNT, "")
+ }
+
return nil
}
func unmount(target string, flag int) error {
- return syscall.Unmount(target, flag)
+ return unix.Unmount(target, flag)
}
diff --git a/vendor/github.com/docker/docker/pkg/mount/mountinfo.go b/vendor/github.com/docker/docker/pkg/mount/mountinfo.go
index e3fc3535..ff4cc1d8 100644
--- a/vendor/github.com/docker/docker/pkg/mount/mountinfo.go
+++ b/vendor/github.com/docker/docker/pkg/mount/mountinfo.go
@@ -38,3 +38,17 @@ type Info struct {
// VfsOpts represents per super block options.
VfsOpts string
}
+
+type byMountpoint []*Info
+
+func (by byMountpoint) Len() int {
+ return len(by)
+}
+
+func (by byMountpoint) Less(i, j int) bool {
+ return by[i].Mountpoint < by[j].Mountpoint
+}
+
+func (by byMountpoint) Swap(i, j int) {
+ by[i], by[j] = by[j], by[i]
+}
diff --git a/vendor/github.com/docker/docker/pkg/pools/pools.go b/vendor/github.com/docker/docker/pkg/pools/pools.go
index 5c5aead6..6a111a3b 100644
--- a/vendor/github.com/docker/docker/pkg/pools/pools.go
+++ b/vendor/github.com/docker/docker/pkg/pools/pools.go
@@ -17,15 +17,16 @@ import (
"github.com/docker/docker/pkg/ioutils"
)
+const buffer32K = 32 * 1024
+
var (
// BufioReader32KPool is a pool which returns bufio.Reader with a 32K buffer.
BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K)
// BufioWriter32KPool is a pool which returns bufio.Writer with a 32K buffer.
BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K)
+ buffer32KPool = newBufferPoolWithSize(buffer32K)
)
-const buffer32K = 32 * 1024
-
// BufioReaderPool is a bufio reader that uses sync.Pool.
type BufioReaderPool struct {
pool sync.Pool
@@ -54,11 +55,31 @@ func (bufPool *BufioReaderPool) Put(b *bufio.Reader) {
bufPool.pool.Put(b)
}
+type bufferPool struct {
+ pool sync.Pool
+}
+
+func newBufferPoolWithSize(size int) *bufferPool {
+ return &bufferPool{
+ pool: sync.Pool{
+ New: func() interface{} { return make([]byte, size) },
+ },
+ }
+}
+
+func (bp *bufferPool) Get() []byte {
+ return bp.pool.Get().([]byte)
+}
+
+func (bp *bufferPool) Put(b []byte) {
+ bp.pool.Put(b)
+}
+
// Copy is a convenience wrapper which uses a buffer to avoid allocation in io.Copy.
func Copy(dst io.Writer, src io.Reader) (written int64, err error) {
- buf := BufioReader32KPool.Get(src)
- written, err = io.Copy(dst, buf)
- BufioReader32KPool.Put(buf)
+ buf := buffer32KPool.Get()
+ written, err = io.CopyBuffer(dst, src, buf)
+ buffer32KPool.Put(buf)
return
}
diff --git a/vendor/github.com/docker/docker/pkg/random/random.go b/vendor/github.com/docker/docker/pkg/random/random.go
deleted file mode 100644
index 70de4d13..00000000
--- a/vendor/github.com/docker/docker/pkg/random/random.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package random
-
-import (
- cryptorand "crypto/rand"
- "io"
- "math"
- "math/big"
- "math/rand"
- "sync"
- "time"
-)
-
-// Rand is a global *rand.Rand instance, which initialized with NewSource() source.
-var Rand = rand.New(NewSource())
-
-// Reader is a global, shared instance of a pseudorandom bytes generator.
-// It doesn't consume entropy.
-var Reader io.Reader = &reader{rnd: Rand}
-
-// copypaste from standard math/rand
-type lockedSource struct {
- lk sync.Mutex
- src rand.Source
-}
-
-func (r *lockedSource) Int63() (n int64) {
- r.lk.Lock()
- n = r.src.Int63()
- r.lk.Unlock()
- return
-}
-
-func (r *lockedSource) Seed(seed int64) {
- r.lk.Lock()
- r.src.Seed(seed)
- r.lk.Unlock()
-}
-
-// NewSource returns math/rand.Source safe for concurrent use and initialized
-// with current unix-nano timestamp
-func NewSource() rand.Source {
- var seed int64
- if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
- // This should not happen, but worst-case fallback to time-based seed.
- seed = time.Now().UnixNano()
- } else {
- seed = cryptoseed.Int64()
- }
- return &lockedSource{
- src: rand.NewSource(seed),
- }
-}
-
-type reader struct {
- rnd *rand.Rand
-}
-
-func (r *reader) Read(b []byte) (int, error) {
- i := 0
- for {
- val := r.rnd.Int63()
- for val > 0 {
- b[i] = byte(val)
- i++
- if i == len(b) {
- return i, nil
- }
- val >>= 8
- }
- }
-}
diff --git a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go b/vendor/github.com/docker/docker/pkg/signal/signal_linux.go
index d418cbe9..3594796c 100644
--- a/vendor/github.com/docker/docker/pkg/signal/signal_linux.go
+++ b/vendor/github.com/docker/docker/pkg/signal/signal_linux.go
@@ -2,6 +2,8 @@ package signal
import (
"syscall"
+
+ "golang.org/x/sys/unix"
)
const (
@@ -11,41 +13,41 @@ const (
// SignalMap is a map of Linux signals.
var SignalMap = map[string]syscall.Signal{
- "ABRT": syscall.SIGABRT,
- "ALRM": syscall.SIGALRM,
- "BUS": syscall.SIGBUS,
- "CHLD": syscall.SIGCHLD,
- "CLD": syscall.SIGCLD,
- "CONT": syscall.SIGCONT,
- "FPE": syscall.SIGFPE,
- "HUP": syscall.SIGHUP,
- "ILL": syscall.SIGILL,
- "INT": syscall.SIGINT,
- "IO": syscall.SIGIO,
- "IOT": syscall.SIGIOT,
- "KILL": syscall.SIGKILL,
- "PIPE": syscall.SIGPIPE,
- "POLL": syscall.SIGPOLL,
- "PROF": syscall.SIGPROF,
- "PWR": syscall.SIGPWR,
- "QUIT": syscall.SIGQUIT,
- "SEGV": syscall.SIGSEGV,
- "STKFLT": syscall.SIGSTKFLT,
- "STOP": syscall.SIGSTOP,
- "SYS": syscall.SIGSYS,
- "TERM": syscall.SIGTERM,
- "TRAP": syscall.SIGTRAP,
- "TSTP": syscall.SIGTSTP,
- "TTIN": syscall.SIGTTIN,
- "TTOU": syscall.SIGTTOU,
- "UNUSED": syscall.SIGUNUSED,
- "URG": syscall.SIGURG,
- "USR1": syscall.SIGUSR1,
- "USR2": syscall.SIGUSR2,
- "VTALRM": syscall.SIGVTALRM,
- "WINCH": syscall.SIGWINCH,
- "XCPU": syscall.SIGXCPU,
- "XFSZ": syscall.SIGXFSZ,
+ "ABRT": unix.SIGABRT,
+ "ALRM": unix.SIGALRM,
+ "BUS": unix.SIGBUS,
+ "CHLD": unix.SIGCHLD,
+ "CLD": unix.SIGCLD,
+ "CONT": unix.SIGCONT,
+ "FPE": unix.SIGFPE,
+ "HUP": unix.SIGHUP,
+ "ILL": unix.SIGILL,
+ "INT": unix.SIGINT,
+ "IO": unix.SIGIO,
+ "IOT": unix.SIGIOT,
+ "KILL": unix.SIGKILL,
+ "PIPE": unix.SIGPIPE,
+ "POLL": unix.SIGPOLL,
+ "PROF": unix.SIGPROF,
+ "PWR": unix.SIGPWR,
+ "QUIT": unix.SIGQUIT,
+ "SEGV": unix.SIGSEGV,
+ "STKFLT": unix.SIGSTKFLT,
+ "STOP": unix.SIGSTOP,
+ "SYS": unix.SIGSYS,
+ "TERM": unix.SIGTERM,
+ "TRAP": unix.SIGTRAP,
+ "TSTP": unix.SIGTSTP,
+ "TTIN": unix.SIGTTIN,
+ "TTOU": unix.SIGTTOU,
+ "UNUSED": unix.SIGUNUSED,
+ "URG": unix.SIGURG,
+ "USR1": unix.SIGUSR1,
+ "USR2": unix.SIGUSR2,
+ "VTALRM": unix.SIGVTALRM,
+ "WINCH": unix.SIGWINCH,
+ "XCPU": unix.SIGXCPU,
+ "XFSZ": unix.SIGXFSZ,
"RTMIN": sigrtmin,
"RTMIN+1": sigrtmin + 1,
"RTMIN+2": sigrtmin + 2,
diff --git a/vendor/github.com/docker/docker/pkg/signal/trap.go b/vendor/github.com/docker/docker/pkg/signal/trap.go
index 638a1ab6..2884dfee 100644
--- a/vendor/github.com/docker/docker/pkg/signal/trap.go
+++ b/vendor/github.com/docker/docker/pkg/signal/trap.go
@@ -11,7 +11,6 @@ import (
"syscall"
"time"
- "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
)
@@ -27,7 +26,9 @@ import (
// the docker daemon is not restarted and also running under systemd.
// Fixes https://github.com/docker/docker/issues/19728
//
-func Trap(cleanup func()) {
+func Trap(cleanup func(), logger interface {
+ Info(args ...interface{})
+}) {
c := make(chan os.Signal, 1)
// we will handle INT, TERM, QUIT, SIGPIPE here
signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
@@ -40,7 +41,7 @@ func Trap(cleanup func()) {
}
go func(sig os.Signal) {
- logrus.Infof("Processing signal '%v'", sig)
+ logger.Info(fmt.Sprintf("Processing signal '%v'", sig))
switch sig {
case os.Interrupt, syscall.SIGTERM:
if atomic.LoadUint32(&interruptCount) < 3 {
@@ -54,11 +55,11 @@ func Trap(cleanup func()) {
}
} else {
// 3 SIGTERM/INT signals received; force exit without cleanup
- logrus.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
+ logger.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
}
case syscall.SIGQUIT:
DumpStacks("")
- logrus.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
+ logger.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
}
//for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
os.Exit(128 + int(sig.(syscall.Signal)))
diff --git a/vendor/github.com/docker/docker/pkg/stringid/stringid.go b/vendor/github.com/docker/docker/pkg/stringid/stringid.go
index fa35d8ba..a0c7c42a 100644
--- a/vendor/github.com/docker/docker/pkg/stringid/stringid.go
+++ b/vendor/github.com/docker/docker/pkg/stringid/stringid.go
@@ -2,19 +2,25 @@
package stringid
import (
- "crypto/rand"
+ cryptorand "crypto/rand"
"encoding/hex"
+ "fmt"
"io"
+ "math"
+ "math/big"
+ "math/rand"
"regexp"
"strconv"
"strings"
-
- "github.com/docker/docker/pkg/random"
+ "time"
)
const shortLen = 12
-var validShortID = regexp.MustCompile("^[a-z0-9]{12}$")
+var (
+ validShortID = regexp.MustCompile("^[a-f0-9]{12}$")
+ validHex = regexp.MustCompile(`^[a-f0-9]{64}$`)
+)
// IsShortID determines if an arbitrary string *looks like* a short ID.
func IsShortID(id string) bool {
@@ -35,12 +41,8 @@ func TruncateID(id string) string {
return id
}
-func generateID(crypto bool) string {
+func generateID(r io.Reader) string {
b := make([]byte, 32)
- r := random.Reader
- if crypto {
- r = rand.Reader
- }
for {
if _, err := io.ReadFull(r, b); err != nil {
panic(err) // This shouldn't happen
@@ -58,12 +60,40 @@ func generateID(crypto bool) string {
// GenerateRandomID returns a unique id.
func GenerateRandomID() string {
- return generateID(true)
+ return generateID(cryptorand.Reader)
}
// GenerateNonCryptoID generates unique id without using cryptographically
// secure sources of random.
// It helps you to save entropy.
func GenerateNonCryptoID() string {
- return generateID(false)
+ return generateID(readerFunc(rand.Read))
+}
+
+// ValidateID checks whether an ID string is a valid image ID.
+func ValidateID(id string) error {
+ if ok := validHex.MatchString(id); !ok {
+ return fmt.Errorf("image ID %q is invalid", id)
+ }
+ return nil
+}
+
+func init() {
+ // safely set the seed globally so we generate random ids. Tries to use a
+ // crypto seed before falling back to time.
+ var seed int64
+ if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
+ // This should not happen, but worst-case fallback to time-based seed.
+ seed = time.Now().UnixNano()
+ } else {
+ seed = cryptoseed.Int64()
+ }
+
+ rand.Seed(seed)
+}
+
+type readerFunc func(p []byte) (int, error)
+
+func (fn readerFunc) Read(p []byte) (int, error) {
+ return fn(p)
}
diff --git a/vendor/github.com/docker/docker/pkg/stringutils/stringutils.go b/vendor/github.com/docker/docker/pkg/stringutils/stringutils.go
index 8e1c812d..8c4c3987 100644
--- a/vendor/github.com/docker/docker/pkg/stringutils/stringutils.go
+++ b/vendor/github.com/docker/docker/pkg/stringutils/stringutils.go
@@ -5,8 +5,6 @@ import (
"bytes"
"math/rand"
"strings"
-
- "github.com/docker/docker/pkg/random"
)
// GenerateRandomAlphaOnlyString generates an alphabetical random string with length n.
@@ -15,7 +13,7 @@ func GenerateRandomAlphaOnlyString(n int) string {
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]byte, n)
for i := range b {
- b[i] = letters[random.Rand.Intn(len(letters))]
+ b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
@@ -77,7 +75,7 @@ func quote(word string, buf *bytes.Buffer) {
for i := 0; i < len(word); i++ {
b := word[i]
if b == '\'' {
- // Replace literal ' with a close ', a \', and a open '
+ // Replace literal ' with a close ', a \', and an open '
buf.WriteString("'\\''")
} else {
buf.WriteByte(b)
diff --git a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE
index 34c4ea7c..b9fbf3c9 100644
--- a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE
+++ b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.APACHE
@@ -176,7 +176,7 @@
END OF TERMS AND CONDITIONS
- Copyright 2014-2016 Docker, Inc.
+ Copyright 2014-2017 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD
index 9b4f4a29..4c056c5e 100644
--- a/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD
+++ b/vendor/github.com/docker/docker/pkg/symlink/LICENSE.BSD
@@ -1,4 +1,4 @@
-Copyright (c) 2014-2016 The Docker & Go Authors. All rights reserved.
+Copyright (c) 2014-2017 The Docker & Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
diff --git a/vendor/github.com/docker/docker/pkg/symlink/fs.go b/vendor/github.com/docker/docker/pkg/symlink/fs.go
index f6bc2231..52fb9a69 100644
--- a/vendor/github.com/docker/docker/pkg/symlink/fs.go
+++ b/vendor/github.com/docker/docker/pkg/symlink/fs.go
@@ -40,7 +40,7 @@ func FollowSymlinkInScope(path, root string) (string, error) {
//
// Example:
// If /foo/bar -> /outside,
-// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide"
+// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/outside"
//
// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks
// are created and not to create subsequently, additional symlinks that could potentially make a
diff --git a/vendor/github.com/docker/docker/pkg/symlink/fs_windows.go b/vendor/github.com/docker/docker/pkg/symlink/fs_windows.go
index 241e531f..31523ade 100644
--- a/vendor/github.com/docker/docker/pkg/symlink/fs_windows.go
+++ b/vendor/github.com/docker/docker/pkg/symlink/fs_windows.go
@@ -6,49 +6,49 @@ import (
"os"
"path/filepath"
"strings"
- "syscall"
"github.com/docker/docker/pkg/longpath"
+ "golang.org/x/sys/windows"
)
func toShort(path string) (string, error) {
- p, err := syscall.UTF16FromString(path)
+ p, err := windows.UTF16FromString(path)
if err != nil {
return "", err
}
b := p // GetShortPathName says we can reuse buffer
- n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
+ n, err := windows.GetShortPathName(&p[0], &b[0], uint32(len(b)))
if err != nil {
return "", err
}
if n > uint32(len(b)) {
b = make([]uint16, n)
- if _, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b))); err != nil {
+ if _, err = windows.GetShortPathName(&p[0], &b[0], uint32(len(b))); err != nil {
return "", err
}
}
- return syscall.UTF16ToString(b), nil
+ return windows.UTF16ToString(b), nil
}
func toLong(path string) (string, error) {
- p, err := syscall.UTF16FromString(path)
+ p, err := windows.UTF16FromString(path)
if err != nil {
return "", err
}
b := p // GetLongPathName says we can reuse buffer
- n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+ n, err := windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
if err != nil {
return "", err
}
if n > uint32(len(b)) {
b = make([]uint16, n)
- n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+ n, err = windows.GetLongPathName(&p[0], &b[0], uint32(len(b)))
if err != nil {
return "", err
}
}
b = b[:n]
- return syscall.UTF16ToString(b), nil
+ return windows.UTF16ToString(b), nil
}
func evalSymlinks(path string) (string, error) {
@@ -65,7 +65,7 @@ func evalSymlinks(path string) (string, error) {
if err != nil {
return "", err
}
- // syscall.GetLongPathName does not change the case of the drive letter,
+ // windows.GetLongPathName does not change the case of the drive letter,
// but the result of EvalSymlinks must be unique, so we have
// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
// Make drive letter upper case.
diff --git a/vendor/github.com/docker/docker/pkg/system/chtimes.go b/vendor/github.com/docker/docker/pkg/system/chtimes.go
index 7637f12e..056d1995 100644
--- a/vendor/github.com/docker/docker/pkg/system/chtimes.go
+++ b/vendor/github.com/docker/docker/pkg/system/chtimes.go
@@ -2,26 +2,9 @@ package system
import (
"os"
- "syscall"
"time"
- "unsafe"
)
-var (
- maxTime time.Time
-)
-
-func init() {
- if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
- // This is a 64 bit timespec
- // os.Chtimes limits time to the following
- maxTime = time.Unix(0, 1<<63-1)
- } else {
- // This is a 32 bit timespec
- maxTime = time.Unix(1<<31-1, 0)
- }
-}
-
// Chtimes changes the access time and modified time of a file at the given path
func Chtimes(name string, atime time.Time, mtime time.Time) error {
unixMinTime := time.Unix(0, 0)
diff --git a/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go b/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go
index 29458684..45428c14 100644
--- a/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go
@@ -3,25 +3,26 @@
package system
import (
- "syscall"
"time"
+
+ "golang.org/x/sys/windows"
)
//setCTime will set the create time on a file. On Windows, this requires
//calling SetFileTime and explicitly including the create time.
func setCTime(path string, ctime time.Time) error {
- ctimespec := syscall.NsecToTimespec(ctime.UnixNano())
- pathp, e := syscall.UTF16PtrFromString(path)
+ ctimespec := windows.NsecToTimespec(ctime.UnixNano())
+ pathp, e := windows.UTF16PtrFromString(path)
if e != nil {
return e
}
- h, e := syscall.CreateFile(pathp,
- syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil,
- syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
+ h, e := windows.CreateFile(pathp,
+ windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil,
+ windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
if e != nil {
return e
}
- defer syscall.Close(h)
- c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec))
- return syscall.SetFileTime(h, &c, nil, nil)
+ defer windows.Close(h)
+ c := windows.NsecToFiletime(windows.TimespecToNsec(ctimespec))
+ return windows.SetFileTime(h, &c, nil, nil)
}
diff --git a/vendor/github.com/docker/docker/pkg/system/events_windows.go b/vendor/github.com/docker/docker/pkg/system/events_windows.go
index 3ec6d221..192e3678 100644
--- a/vendor/github.com/docker/docker/pkg/system/events_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/events_windows.go
@@ -19,8 +19,8 @@ var (
)
// CreateEvent implements win32 CreateEventW func in golang. It will create an event object.
-func CreateEvent(eventAttributes *syscall.SecurityAttributes, manualReset bool, initialState bool, name string) (handle syscall.Handle, err error) {
- namep, _ := syscall.UTF16PtrFromString(name)
+func CreateEvent(eventAttributes *windows.SecurityAttributes, manualReset bool, initialState bool, name string) (handle windows.Handle, err error) {
+ namep, _ := windows.UTF16PtrFromString(name)
var _p1 uint32
if manualReset {
_p1 = 1
@@ -31,45 +31,45 @@ func CreateEvent(eventAttributes *syscall.SecurityAttributes, manualReset bool,
}
r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
use(unsafe.Pointer(namep))
- handle = syscall.Handle(r0)
- if handle == syscall.InvalidHandle {
+ handle = windows.Handle(r0)
+ if handle == windows.InvalidHandle {
err = e1
}
return
}
// OpenEvent implements win32 OpenEventW func in golang. It opens an event object.
-func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle syscall.Handle, err error) {
- namep, _ := syscall.UTF16PtrFromString(name)
+func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle windows.Handle, err error) {
+ namep, _ := windows.UTF16PtrFromString(name)
var _p1 uint32
if inheritHandle {
_p1 = 1
}
r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep)))
use(unsafe.Pointer(namep))
- handle = syscall.Handle(r0)
- if handle == syscall.InvalidHandle {
+ handle = windows.Handle(r0)
+ if handle == windows.InvalidHandle {
err = e1
}
return
}
// SetEvent implements win32 SetEvent func in golang.
-func SetEvent(handle syscall.Handle) (err error) {
+func SetEvent(handle windows.Handle) (err error) {
return setResetPulse(handle, procSetEvent)
}
// ResetEvent implements win32 ResetEvent func in golang.
-func ResetEvent(handle syscall.Handle) (err error) {
+func ResetEvent(handle windows.Handle) (err error) {
return setResetPulse(handle, procResetEvent)
}
// PulseEvent implements win32 PulseEvent func in golang.
-func PulseEvent(handle syscall.Handle) (err error) {
+func PulseEvent(handle windows.Handle) (err error) {
return setResetPulse(handle, procPulseEvent)
}
-func setResetPulse(handle syscall.Handle, proc *windows.LazyProc) (err error) {
+func setResetPulse(handle windows.Handle, proc *windows.LazyProc) (err error) {
r0, _, _ := proc.Call(uintptr(handle))
if r0 != 0 {
err = syscall.Errno(r0)
diff --git a/vendor/github.com/docker/docker/pkg/system/filesys.go b/vendor/github.com/docker/docker/pkg/system/filesys.go
index 810c7947..102565f7 100644
--- a/vendor/github.com/docker/docker/pkg/system/filesys.go
+++ b/vendor/github.com/docker/docker/pkg/system/filesys.go
@@ -3,19 +3,19 @@
package system
import (
+ "io/ioutil"
"os"
"path/filepath"
)
-// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
-// ACL'd for Builtin Administrators and Local System.
-func MkdirAllWithACL(path string, perm os.FileMode) error {
- return MkdirAll(path, perm)
+// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
+func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
+ return MkdirAll(path, perm, sddl)
}
// MkdirAll creates a directory named path along with any necessary parents,
// with permission specified by attribute perm for all dir created.
-func MkdirAll(path string, perm os.FileMode) error {
+func MkdirAll(path string, perm os.FileMode, sddl string) error {
return os.MkdirAll(path, perm)
}
@@ -24,7 +24,7 @@ func IsAbs(path string) bool {
return filepath.IsAbs(path)
}
-// The functions below here are wrappers for the equivalents in the os package.
+// The functions below here are wrappers for the equivalents in the os and ioutils packages.
// They are passthrough on Unix platforms, and only relevant on Windows.
// CreateSequential creates the named file with mode 0666 (before umask), truncating
@@ -52,3 +52,16 @@ func OpenSequential(name string) (*os.File, error) {
func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, error) {
return os.OpenFile(name, flag, perm)
}
+
+// TempFileSequential creates a new temporary file in the directory dir
+// with a name beginning with prefix, opens the file for reading
+// and writing, and returns the resulting *os.File.
+// If dir is the empty string, TempFile uses the default directory
+// for temporary files (see os.TempDir).
+// Multiple programs calling TempFile simultaneously
+// will not choose the same file. The caller can use f.Name()
+// to find the pathname of the file. It is the caller's responsibility
+// to remove the file when no longer needed.
+func TempFileSequential(dir, prefix string) (f *os.File, err error) {
+ return ioutil.TempFile(dir, prefix)
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/filesys_windows.go b/vendor/github.com/docker/docker/pkg/system/filesys_windows.go
index 6094f01f..a61b53d0 100644
--- a/vendor/github.com/docker/docker/pkg/system/filesys_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/filesys_windows.go
@@ -6,28 +6,39 @@ import (
"os"
"path/filepath"
"regexp"
+ "strconv"
"strings"
+ "sync"
"syscall"
+ "time"
"unsafe"
winio "github.com/Microsoft/go-winio"
+ "golang.org/x/sys/windows"
+)
+
+const (
+ // SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
+ SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
+ // SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
+ SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
)
// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
-// ACL'd for Builtin Administrators and Local System.
-func MkdirAllWithACL(path string, perm os.FileMode) error {
- return mkdirall(path, true)
+// with an appropriate SDDL defined ACL.
+func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
+ return mkdirall(path, true, sddl)
}
// MkdirAll implementation that is volume path aware for Windows.
-func MkdirAll(path string, _ os.FileMode) error {
- return mkdirall(path, false)
+func MkdirAll(path string, _ os.FileMode, sddl string) error {
+ return mkdirall(path, false, sddl)
}
// mkdirall is a custom version of os.MkdirAll modified for use on Windows
// so that it is both volume path aware, and can create a directory with
// a DACL.
-func mkdirall(path string, adminAndLocalSystem bool) error {
+func mkdirall(path string, applyACL bool, sddl string) error {
if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
return nil
}
@@ -61,15 +72,15 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
if j > 1 {
// Create parent
- err = mkdirall(path[0:j-1], false)
+ err = mkdirall(path[0:j-1], false, sddl)
if err != nil {
return err
}
}
// Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
- if adminAndLocalSystem {
- err = mkdirWithACL(path)
+ if applyACL {
+ err = mkdirWithACL(path, sddl)
} else {
err = os.Mkdir(path, 0)
}
@@ -89,13 +100,12 @@ func mkdirall(path string, adminAndLocalSystem bool) error {
// mkdirWithACL creates a new directory. If there is an error, it will be of
// type *PathError. .
//
-// This is a modified and combined version of os.Mkdir and syscall.Mkdir
+// This is a modified and combined version of os.Mkdir and windows.Mkdir
// in golang to cater for creating a directory am ACL permitting full
// access, with inheritance, to any subfolder/file for Built-in Administrators
// and Local System.
-func mkdirWithACL(name string) error {
- sa := syscall.SecurityAttributes{Length: 0}
- sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
+func mkdirWithACL(name string, sddl string) error {
+ sa := windows.SecurityAttributes{Length: 0}
sd, err := winio.SddlToSecurityDescriptor(sddl)
if err != nil {
return &os.PathError{Op: "mkdir", Path: name, Err: err}
@@ -104,12 +114,12 @@ func mkdirWithACL(name string) error {
sa.InheritHandle = 1
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
- namep, err := syscall.UTF16PtrFromString(name)
+ namep, err := windows.UTF16PtrFromString(name)
if err != nil {
return &os.PathError{Op: "mkdir", Path: name, Err: err}
}
- e := syscall.CreateDirectory(namep, &sa)
+ e := windows.CreateDirectory(namep, &sa)
if e != nil {
return &os.PathError{Op: "mkdir", Path: name, Err: e}
}
@@ -132,7 +142,7 @@ func IsAbs(path string) bool {
return true
}
-// The origin of the functions below here are the golang OS and syscall packages,
+// The origin of the functions below here are the golang OS and windows packages,
// slightly modified to only cope with files, not directories due to the
// specific use case.
//
@@ -164,73 +174,125 @@ func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error)
if name == "" {
return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
}
- r, errf := syscallOpenFileSequential(name, flag, 0)
+ r, errf := windowsOpenFileSequential(name, flag, 0)
if errf == nil {
return r, nil
}
return nil, &os.PathError{Op: "open", Path: name, Err: errf}
}
-func syscallOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
- r, e := syscallOpenSequential(name, flag|syscall.O_CLOEXEC, 0)
+func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
+ r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
if e != nil {
return nil, e
}
return os.NewFile(uintptr(r), name), nil
}
-func makeInheritSa() *syscall.SecurityAttributes {
- var sa syscall.SecurityAttributes
+func makeInheritSa() *windows.SecurityAttributes {
+ var sa windows.SecurityAttributes
sa.Length = uint32(unsafe.Sizeof(sa))
sa.InheritHandle = 1
return &sa
}
-func syscallOpenSequential(path string, mode int, _ uint32) (fd syscall.Handle, err error) {
+func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
if len(path) == 0 {
- return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND
+ return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
}
- pathp, err := syscall.UTF16PtrFromString(path)
+ pathp, err := windows.UTF16PtrFromString(path)
if err != nil {
- return syscall.InvalidHandle, err
+ return windows.InvalidHandle, err
}
var access uint32
- switch mode & (syscall.O_RDONLY | syscall.O_WRONLY | syscall.O_RDWR) {
- case syscall.O_RDONLY:
- access = syscall.GENERIC_READ
- case syscall.O_WRONLY:
- access = syscall.GENERIC_WRITE
- case syscall.O_RDWR:
- access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
+ switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
+ case windows.O_RDONLY:
+ access = windows.GENERIC_READ
+ case windows.O_WRONLY:
+ access = windows.GENERIC_WRITE
+ case windows.O_RDWR:
+ access = windows.GENERIC_READ | windows.GENERIC_WRITE
}
- if mode&syscall.O_CREAT != 0 {
- access |= syscall.GENERIC_WRITE
+ if mode&windows.O_CREAT != 0 {
+ access |= windows.GENERIC_WRITE
}
- if mode&syscall.O_APPEND != 0 {
- access &^= syscall.GENERIC_WRITE
- access |= syscall.FILE_APPEND_DATA
+ if mode&windows.O_APPEND != 0 {
+ access &^= windows.GENERIC_WRITE
+ access |= windows.FILE_APPEND_DATA
}
- sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
- var sa *syscall.SecurityAttributes
- if mode&syscall.O_CLOEXEC == 0 {
+ sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
+ var sa *windows.SecurityAttributes
+ if mode&windows.O_CLOEXEC == 0 {
sa = makeInheritSa()
}
var createmode uint32
switch {
- case mode&(syscall.O_CREAT|syscall.O_EXCL) == (syscall.O_CREAT | syscall.O_EXCL):
- createmode = syscall.CREATE_NEW
- case mode&(syscall.O_CREAT|syscall.O_TRUNC) == (syscall.O_CREAT | syscall.O_TRUNC):
- createmode = syscall.CREATE_ALWAYS
- case mode&syscall.O_CREAT == syscall.O_CREAT:
- createmode = syscall.OPEN_ALWAYS
- case mode&syscall.O_TRUNC == syscall.O_TRUNC:
- createmode = syscall.TRUNCATE_EXISTING
+ case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
+ createmode = windows.CREATE_NEW
+ case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
+ createmode = windows.CREATE_ALWAYS
+ case mode&windows.O_CREAT == windows.O_CREAT:
+ createmode = windows.OPEN_ALWAYS
+ case mode&windows.O_TRUNC == windows.O_TRUNC:
+ createmode = windows.TRUNCATE_EXISTING
default:
- createmode = syscall.OPEN_EXISTING
+ createmode = windows.OPEN_EXISTING
}
// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
- h, e := syscall.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
+ h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
return h, e
}
+
+// Helpers for TempFileSequential
+var rand uint32
+var randmu sync.Mutex
+
+func reseed() uint32 {
+ return uint32(time.Now().UnixNano() + int64(os.Getpid()))
+}
+func nextSuffix() string {
+ randmu.Lock()
+ r := rand
+ if r == 0 {
+ r = reseed()
+ }
+ r = r*1664525 + 1013904223 // constants from Numerical Recipes
+ rand = r
+ randmu.Unlock()
+ return strconv.Itoa(int(1e9 + r%1e9))[1:]
+}
+
+// TempFileSequential is a copy of ioutil.TempFile, modified to use sequential
+// file access. Below is the original comment from golang:
+// TempFile creates a new temporary file in the directory dir
+// with a name beginning with prefix, opens the file for reading
+// and writing, and returns the resulting *os.File.
+// If dir is the empty string, TempFile uses the default directory
+// for temporary files (see os.TempDir).
+// Multiple programs calling TempFile simultaneously
+// will not choose the same file. The caller can use f.Name()
+// to find the pathname of the file. It is the caller's responsibility
+// to remove the file when no longer needed.
+func TempFileSequential(dir, prefix string) (f *os.File, err error) {
+ if dir == "" {
+ dir = os.TempDir()
+ }
+
+ nconflict := 0
+ for i := 0; i < 10000; i++ {
+ name := filepath.Join(dir, prefix+nextSuffix())
+ f, err = OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
+ if os.IsExist(err) {
+ if nconflict++; nconflict > 10 {
+ randmu.Lock()
+ rand = reseed()
+ randmu.Unlock()
+ }
+ continue
+ }
+ break
+ }
+ return
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/init.go b/vendor/github.com/docker/docker/pkg/system/init.go
new file mode 100644
index 00000000..17935088
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/init.go
@@ -0,0 +1,22 @@
+package system
+
+import (
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+// Used by chtimes
+var maxTime time.Time
+
+func init() {
+ // chtimes initialization
+ if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
+ // This is a 64 bit timespec
+ // os.Chtimes limits time to the following
+ maxTime = time.Unix(0, 1<<63-1)
+ } else {
+ // This is a 32 bit timespec
+ maxTime = time.Unix(1<<31-1, 0)
+ }
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/init_windows.go b/vendor/github.com/docker/docker/pkg/system/init_windows.go
new file mode 100644
index 00000000..019c6644
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/init_windows.go
@@ -0,0 +1,17 @@
+package system
+
+import "os"
+
+// LCOWSupported determines if Linux Containers on Windows are supported.
+// Note: This feature is in development (06/17) and enabled through an
+// environment variable. At a future time, it will be enabled based
+// on build number. @jhowardmsft
+var lcowSupported = false
+
+func init() {
+ // LCOW initialization
+ if os.Getenv("LCOW_SUPPORTED") != "" {
+ lcowSupported = true
+ }
+
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/lcow_unix.go b/vendor/github.com/docker/docker/pkg/system/lcow_unix.go
new file mode 100644
index 00000000..cff33bb4
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/lcow_unix.go
@@ -0,0 +1,8 @@
+// +build !windows
+
+package system
+
+// LCOWSupported returns true if Linux containers on Windows are supported.
+func LCOWSupported() bool {
+ return false
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/lcow_windows.go b/vendor/github.com/docker/docker/pkg/system/lcow_windows.go
new file mode 100644
index 00000000..e54d01e6
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/lcow_windows.go
@@ -0,0 +1,6 @@
+package system
+
+// LCOWSupported returns true if Linux containers on Windows are supported.
+func LCOWSupported() bool {
+ return lcowSupported
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/lstat.go b/vendor/github.com/docker/docker/pkg/system/lstat_unix.go
similarity index 100%
rename from vendor/github.com/docker/docker/pkg/system/lstat.go
rename to vendor/github.com/docker/docker/pkg/system/lstat_unix.go
diff --git a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go b/vendor/github.com/docker/docker/pkg/system/lstat_windows.go
index 49e87eb4..e51df0da 100644
--- a/vendor/github.com/docker/docker/pkg/system/lstat_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/lstat_windows.go
@@ -1,25 +1,14 @@
-// +build windows
-
package system
-import (
- "os"
-)
+import "os"
// Lstat calls os.Lstat to get a fileinfo interface back.
// This is then copied into our own locally defined structure.
-// Note the Linux version uses fromStatT to do the copy back,
-// but that not strictly necessary when already in an OS specific module.
func Lstat(path string) (*StatT, error) {
fi, err := os.Lstat(path)
if err != nil {
return nil, err
}
- return &StatT{
- name: fi.Name(),
- size: fi.Size(),
- mode: fi.Mode(),
- modTime: fi.ModTime(),
- isDir: fi.IsDir()}, nil
+ return fromStatT(&fi)
}
diff --git a/vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go b/vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go
index 7f4f84f7..925776e7 100644
--- a/vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go
+++ b/vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go
@@ -7,6 +7,7 @@ import (
"unsafe"
)
+// #cgo CFLAGS: -std=c99
// #cgo LDFLAGS: -lkstat
// #include
// #include
diff --git a/vendor/github.com/docker/docker/pkg/system/mknod.go b/vendor/github.com/docker/docker/pkg/system/mknod.go
index 73958182..af79a653 100644
--- a/vendor/github.com/docker/docker/pkg/system/mknod.go
+++ b/vendor/github.com/docker/docker/pkg/system/mknod.go
@@ -3,13 +3,13 @@
package system
import (
- "syscall"
+ "golang.org/x/sys/unix"
)
// Mknod creates a filesystem node (file, device special file or named pipe) named path
// with attributes specified by mode and dev.
func Mknod(path string, mode uint32, dev int) error {
- return syscall.Mknod(path, mode, dev)
+ return unix.Mknod(path, mode, dev)
}
// Mkdev is used to build the value of linux devices (in /dev/) which specifies major
diff --git a/vendor/github.com/docker/docker/pkg/system/path.go b/vendor/github.com/docker/docker/pkg/system/path.go
new file mode 100644
index 00000000..f634a6be
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/path.go
@@ -0,0 +1,21 @@
+package system
+
+import "runtime"
+
+const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+
+// DefaultPathEnv is unix style list of directories to search for
+// executables. Each directory is separated from the next by a colon
+// ':' character .
+func DefaultPathEnv(platform string) string {
+ if runtime.GOOS == "windows" {
+ if platform != runtime.GOOS && LCOWSupported() {
+ return defaultUnixPathEnv
+ }
+ // Deliberately empty on Windows containers on Windows as the default path will be set by
+ // the container. Docker has no context of what the default path should be.
+ return ""
+ }
+ return defaultUnixPathEnv
+
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/path_unix.go b/vendor/github.com/docker/docker/pkg/system/path_unix.go
index c607c4db..f3762e69 100644
--- a/vendor/github.com/docker/docker/pkg/system/path_unix.go
+++ b/vendor/github.com/docker/docker/pkg/system/path_unix.go
@@ -2,11 +2,6 @@
package system
-// DefaultPathEnv is unix style list of directories to search for
-// executables. Each directory is separated from the next by a colon
-// ':' character .
-const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
// is the system drive. This is a no-op on Linux.
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
diff --git a/vendor/github.com/docker/docker/pkg/system/path_windows.go b/vendor/github.com/docker/docker/pkg/system/path_windows.go
index cbfe2c15..aab89152 100644
--- a/vendor/github.com/docker/docker/pkg/system/path_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/path_windows.go
@@ -8,15 +8,11 @@ import (
"strings"
)
-// DefaultPathEnv is deliberately empty on Windows as the default path will be set by
-// the container. Docker has no context of what the default path should be.
-const DefaultPathEnv = ""
-
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
// This is used, for example, when validating a user provided path in docker cp.
// If a drive letter is supplied, it must be the system drive. The drive letter
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
-// need the path in this syntax so that it can ultimately be contatenated with
+// need the path in this syntax so that it can ultimately be concatenated with
// a Windows long-path which doesn't support drive-letters. Examples:
// C: --> Fail
// C:\ --> \
diff --git a/vendor/github.com/docker/docker/pkg/system/process_unix.go b/vendor/github.com/docker/docker/pkg/system/process_unix.go
new file mode 100644
index 00000000..26c8b42c
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/process_unix.go
@@ -0,0 +1,24 @@
+// +build linux freebsd solaris darwin
+
+package system
+
+import (
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+// IsProcessAlive returns true if process with a given pid is running.
+func IsProcessAlive(pid int) bool {
+ err := unix.Kill(pid, syscall.Signal(0))
+ if err == nil || err == unix.EPERM {
+ return true
+ }
+
+ return false
+}
+
+// KillProcess force-stops a process.
+func KillProcess(pid int) {
+ unix.Kill(pid, unix.SIGKILL)
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/rm.go b/vendor/github.com/docker/docker/pkg/system/rm.go
new file mode 100644
index 00000000..101b569a
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/system/rm.go
@@ -0,0 +1,80 @@
+package system
+
+import (
+ "os"
+ "syscall"
+ "time"
+
+ "github.com/docker/docker/pkg/mount"
+ "github.com/pkg/errors"
+)
+
+// EnsureRemoveAll wraps `os.RemoveAll` to check for specific errors that can
+// often be remedied.
+// Only use `EnsureRemoveAll` if you really want to make every effort to remove
+// a directory.
+//
+// Because of the way `os.Remove` (and by extension `os.RemoveAll`) works, there
+// can be a race between reading directory entries and then actually attempting
+// to remove everything in the directory.
+// These types of errors do not need to be returned since it's ok for the dir to
+// be gone we can just retry the remove operation.
+//
+// This should not return a `os.ErrNotExist` kind of error under any circumstances
+func EnsureRemoveAll(dir string) error {
+ notExistErr := make(map[string]bool)
+
+ // track retries
+ exitOnErr := make(map[string]int)
+ maxRetry := 5
+
+ // Attempt to unmount anything beneath this dir first
+ mount.RecursiveUnmount(dir)
+
+ for {
+ err := os.RemoveAll(dir)
+ if err == nil {
+ return err
+ }
+
+ pe, ok := err.(*os.PathError)
+ if !ok {
+ return err
+ }
+
+ if os.IsNotExist(err) {
+ if notExistErr[pe.Path] {
+ return err
+ }
+ notExistErr[pe.Path] = true
+
+ // There is a race where some subdir can be removed but after the parent
+ // dir entries have been read.
+ // So the path could be from `os.Remove(subdir)`
+ // If the reported non-existent path is not the passed in `dir` we
+ // should just retry, but otherwise return with no error.
+ if pe.Path == dir {
+ return nil
+ }
+ continue
+ }
+
+ if pe.Err != syscall.EBUSY {
+ return err
+ }
+
+ if mounted, _ := mount.Mounted(pe.Path); mounted {
+ if e := mount.Unmount(pe.Path); e != nil {
+ if mounted, _ := mount.Mounted(pe.Path); mounted {
+ return errors.Wrapf(e, "error while removing %s", dir)
+ }
+ }
+ }
+
+ if exitOnErr[pe.Path] == maxRetry {
+ return err
+ }
+ exitOnErr[pe.Path]++
+ time.Sleep(100 * time.Millisecond)
+ }
+}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_darwin.go b/vendor/github.com/docker/docker/pkg/system/stat_darwin.go
index f0742f59..715f05b9 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_darwin.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_darwin.go
@@ -1,10 +1,8 @@
package system
-import (
- "syscall"
-)
+import "syscall"
-// fromStatT creates a system.StatT type from a syscall.Stat_t type
+// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
return &StatT{size: s.Size,
mode: uint32(s.Mode),
@@ -13,20 +11,3 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
rdev: uint64(s.Rdev),
mtim: s.Mtimespec}, nil
}
-
-// FromStatT loads a system.StatT from a syscall.Stat_t.
-func FromStatT(s *syscall.Stat_t) (*StatT, error) {
- return fromStatT(s)
-}
-
-// Stat takes a path to a file and returns
-// a system.StatT type pertaining to that file.
-//
-// Throws an error if the file does not exist
-func Stat(path string) (*StatT, error) {
- s := &syscall.Stat_t{}
- if err := syscall.Stat(path, s); err != nil {
- return nil, err
- }
- return fromStatT(s)
-}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_freebsd.go b/vendor/github.com/docker/docker/pkg/system/stat_freebsd.go
index d0fb6f15..715f05b9 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_freebsd.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_freebsd.go
@@ -1,8 +1,6 @@
package system
-import (
- "syscall"
-)
+import "syscall"
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
@@ -13,15 +11,3 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
rdev: uint64(s.Rdev),
mtim: s.Mtimespec}, nil
}
-
-// Stat takes a path to a file and returns
-// a system.Stat_t type pertaining to that file.
-//
-// Throws an error if the file does not exist
-func Stat(path string) (*StatT, error) {
- s := &syscall.Stat_t{}
- if err := syscall.Stat(path, s); err != nil {
- return nil, err
- }
- return fromStatT(s)
-}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_linux.go b/vendor/github.com/docker/docker/pkg/system/stat_linux.go
index 8b1eded1..66bf6e28 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_linux.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_linux.go
@@ -1,33 +1,19 @@
package system
-import (
- "syscall"
-)
+import "syscall"
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
return &StatT{size: s.Size,
- mode: s.Mode,
+ mode: uint32(s.Mode),
uid: s.Uid,
gid: s.Gid,
- rdev: s.Rdev,
+ rdev: uint64(s.Rdev),
mtim: s.Mtim}, nil
}
-// FromStatT exists only on linux, and loads a system.StatT from a
-// syscal.Stat_t.
+// FromStatT converts a syscall.Stat_t type to a system.Stat_t type
+// This is exposed on Linux as pkg/archive/changes uses it.
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
return fromStatT(s)
}
-
-// Stat takes a path to a file and returns
-// a system.StatT type pertaining to that file.
-//
-// Throws an error if the file does not exist
-func Stat(path string) (*StatT, error) {
- s := &syscall.Stat_t{}
- if err := syscall.Stat(path, s); err != nil {
- return nil, err
- }
- return fromStatT(s)
-}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go b/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go
index 3c3b71fb..b607dea9 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_openbsd.go
@@ -1,10 +1,8 @@
package system
-import (
- "syscall"
-)
+import "syscall"
-// fromStatT creates a system.StatT type from a syscall.Stat_t type
+// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
return &StatT{size: s.Size,
mode: uint32(s.Mode),
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_solaris.go b/vendor/github.com/docker/docker/pkg/system/stat_solaris.go
index 0216985a..b607dea9 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_solaris.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_solaris.go
@@ -1,12 +1,8 @@
-// +build solaris
-
package system
-import (
- "syscall"
-)
+import "syscall"
-// fromStatT creates a system.StatT type from a syscall.Stat_t type
+// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
return &StatT{size: s.Size,
mode: uint32(s.Mode),
@@ -15,20 +11,3 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
rdev: uint64(s.Rdev),
mtim: s.Mtim}, nil
}
-
-// FromStatT loads a system.StatT from a syscal.Stat_t.
-func FromStatT(s *syscall.Stat_t) (*StatT, error) {
- return fromStatT(s)
-}
-
-// Stat takes a path to a file and returns
-// a system.StatT type pertaining to that file.
-//
-// Throws an error if the file does not exist
-func Stat(path string) (*StatT, error) {
- s := &syscall.Stat_t{}
- if err := syscall.Stat(path, s); err != nil {
- return nil, err
- }
- return fromStatT(s)
-}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat.go b/vendor/github.com/docker/docker/pkg/system/stat_unix.go
similarity index 74%
rename from vendor/github.com/docker/docker/pkg/system/stat.go
rename to vendor/github.com/docker/docker/pkg/system/stat_unix.go
index 087034c5..91c7d121 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_unix.go
@@ -47,7 +47,14 @@ func (s StatT) Mtim() syscall.Timespec {
return s.mtim
}
-// GetLastModification returns file's last modification time.
-func (s StatT) GetLastModification() syscall.Timespec {
- return s.Mtim()
+// Stat takes a path to a file and returns
+// a system.StatT type pertaining to that file.
+//
+// Throws an error if the file does not exist
+func Stat(path string) (*StatT, error) {
+ s := &syscall.Stat_t{}
+ if err := syscall.Stat(path, s); err != nil {
+ return nil, err
+ }
+ return fromStatT(s)
}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_unsupported.go b/vendor/github.com/docker/docker/pkg/system/stat_unsupported.go
deleted file mode 100644
index 5d85f523..00000000
--- a/vendor/github.com/docker/docker/pkg/system/stat_unsupported.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// +build !linux,!windows,!freebsd,!solaris,!openbsd,!darwin
-
-package system
-
-import (
- "syscall"
-)
-
-// fromStatT creates a system.StatT type from a syscall.Stat_t type
-func fromStatT(s *syscall.Stat_t) (*StatT, error) {
- return &StatT{size: s.Size,
- mode: uint32(s.Mode),
- uid: s.Uid,
- gid: s.Gid,
- rdev: uint64(s.Rdev),
- mtim: s.Mtimespec}, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/system/stat_windows.go b/vendor/github.com/docker/docker/pkg/system/stat_windows.go
index 39490c62..6c639726 100644
--- a/vendor/github.com/docker/docker/pkg/system/stat_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/stat_windows.go
@@ -1,5 +1,3 @@
-// +build windows
-
package system
import (
@@ -8,18 +6,11 @@ import (
)
// StatT type contains status of a file. It contains metadata
-// like name, permission, size, etc about a file.
+// like permission, size, etc about a file.
type StatT struct {
- name string
- size int64
- mode os.FileMode
- modTime time.Time
- isDir bool
-}
-
-// Name returns file's name.
-func (s StatT) Name() string {
- return s.name
+ mode os.FileMode
+ size int64
+ mtim time.Time
}
// Size returns file's size.
@@ -29,15 +20,30 @@ func (s StatT) Size() int64 {
// Mode returns file's permission mode.
func (s StatT) Mode() os.FileMode {
- return s.mode
+ return os.FileMode(s.mode)
}
-// ModTime returns file's last modification time.
-func (s StatT) ModTime() time.Time {
- return s.modTime
+// Mtim returns file's last modification time.
+func (s StatT) Mtim() time.Time {
+ return time.Time(s.mtim)
}
-// IsDir returns whether file is actually a directory.
-func (s StatT) IsDir() bool {
- return s.isDir
+// Stat takes a path to a file and returns
+// a system.StatT type pertaining to that file.
+//
+// Throws an error if the file does not exist
+func Stat(path string) (*StatT, error) {
+ fi, err := os.Stat(path)
+ if err != nil {
+ return nil, err
+ }
+ return fromStatT(&fi)
+}
+
+// fromStatT converts a os.FileInfo type to a system.StatT type
+func fromStatT(fi *os.FileInfo) (*StatT, error) {
+ return &StatT{
+ size: (*fi).Size(),
+ mode: (*fi).Mode(),
+ mtim: (*fi).ModTime()}, nil
}
diff --git a/vendor/github.com/docker/docker/pkg/system/syscall_unix.go b/vendor/github.com/docker/docker/pkg/system/syscall_unix.go
index 3ae91284..49dbdd37 100644
--- a/vendor/github.com/docker/docker/pkg/system/syscall_unix.go
+++ b/vendor/github.com/docker/docker/pkg/system/syscall_unix.go
@@ -2,12 +2,12 @@
package system
-import "syscall"
+import "golang.org/x/sys/unix"
// Unmount is a platform-specific helper function to call
// the unmount syscall.
func Unmount(dest string) error {
- return syscall.Unmount(dest, 0)
+ return unix.Unmount(dest, 0)
}
// CommandLineToArgv should not be used on Unix.
diff --git a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go b/vendor/github.com/docker/docker/pkg/system/syscall_windows.go
index 1f311874..23e9b207 100644
--- a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go
+++ b/vendor/github.com/docker/docker/pkg/system/syscall_windows.go
@@ -1,15 +1,16 @@
package system
import (
- "syscall"
"unsafe"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/sys/windows"
)
var (
- ntuserApiset = syscall.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
- procGetVersionExW = modkernel32.NewProc("GetVersionExW")
+ ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
+ procGetVersionExW = modkernel32.NewProc("GetVersionExW")
+ procGetProductInfo = modkernel32.NewProc("GetProductInfo")
)
// OSVersion is a wrapper for Windows version information
@@ -41,7 +42,7 @@ type osVersionInfoEx struct {
func GetOSVersion() OSVersion {
var err error
osv := OSVersion{}
- osv.Version, err = syscall.GetVersion()
+ osv.Version, err = windows.GetVersion()
if err != nil {
// GetVersion never fails.
panic(err)
@@ -66,6 +67,22 @@ func IsWindowsClient() bool {
return osviex.ProductType == verNTWorkstation
}
+// IsIoTCore returns true if the currently running image is based off of
+// Windows 10 IoT Core.
+// @engine maintainers - this function should not be removed or modified as it
+// is used to enforce licensing restrictions on Windows.
+func IsIoTCore() bool {
+ var returnedProductType uint32
+ r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType)))
+ if r1 == 0 {
+ logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err)
+ return false
+ }
+ const productIoTUAP = 0x0000007B
+ const productIoTUAPCommercial = 0x00000083
+ return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial
+}
+
// Unmount is a platform-specific helper function to call
// the unmount syscall. Not supported on Windows
func Unmount(dest string) error {
@@ -76,20 +93,20 @@ func Unmount(dest string) error {
func CommandLineToArgv(commandLine string) ([]string, error) {
var argc int32
- argsPtr, err := syscall.UTF16PtrFromString(commandLine)
+ argsPtr, err := windows.UTF16PtrFromString(commandLine)
if err != nil {
return nil, err
}
- argv, err := syscall.CommandLineToArgv(argsPtr, &argc)
+ argv, err := windows.CommandLineToArgv(argsPtr, &argc)
if err != nil {
return nil, err
}
- defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
+ defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv))))
newArgs := make([]string, argc)
for i, v := range (*argv)[:argc] {
- newArgs[i] = string(syscall.UTF16ToString((*v)[:]))
+ newArgs[i] = string(windows.UTF16ToString((*v)[:]))
}
return newArgs, nil
diff --git a/vendor/github.com/docker/docker/pkg/system/umask.go b/vendor/github.com/docker/docker/pkg/system/umask.go
index 3d0146b0..5a10eda5 100644
--- a/vendor/github.com/docker/docker/pkg/system/umask.go
+++ b/vendor/github.com/docker/docker/pkg/system/umask.go
@@ -3,11 +3,11 @@
package system
import (
- "syscall"
+ "golang.org/x/sys/unix"
)
// Umask sets current process's file mode creation mask to newmask
// and returns oldmask.
func Umask(newmask int) (oldmask int, err error) {
- return syscall.Umask(newmask), nil
+ return unix.Umask(newmask), nil
}
diff --git a/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go b/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go
index e2eac3b5..6a775243 100644
--- a/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go
+++ b/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go
@@ -3,18 +3,20 @@ package system
import (
"syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
// LUtimesNano is used to change access and modification time of the specified path.
-// It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm.
+// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
func LUtimesNano(path string, ts []syscall.Timespec) error {
var _path *byte
- _path, err := syscall.BytePtrFromString(path)
+ _path, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
- if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS {
+ if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS {
return err
}
diff --git a/vendor/github.com/docker/docker/pkg/system/utimes_linux.go b/vendor/github.com/docker/docker/pkg/system/utimes_linux.go
index fc8a1aba..edc588a6 100644
--- a/vendor/github.com/docker/docker/pkg/system/utimes_linux.go
+++ b/vendor/github.com/docker/docker/pkg/system/utimes_linux.go
@@ -3,22 +3,21 @@ package system
import (
"syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
// LUtimesNano is used to change access and modification time of the specified path.
-// It's used for symbol link file because syscall.UtimesNano doesn't support a NOFOLLOW flag atm.
+// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
func LUtimesNano(path string, ts []syscall.Timespec) error {
- // These are not currently available in syscall
- atFdCwd := -100
- atSymLinkNoFollow := 0x100
+ atFdCwd := unix.AT_FDCWD
var _path *byte
- _path, err := syscall.BytePtrFromString(path)
+ _path, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
-
- if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(atSymLinkNoFollow), 0, 0); err != 0 && err != syscall.ENOSYS {
+ if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS {
return err
}
diff --git a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go
index d2e2c057..98b111be 100644
--- a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go
+++ b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go
@@ -1,63 +1,29 @@
package system
-import (
- "syscall"
- "unsafe"
-)
+import "golang.org/x/sys/unix"
// Lgetxattr retrieves the value of the extended attribute identified by attr
// and associated with the given path in the file system.
// It will returns a nil slice and nil error if the xattr is not set.
func Lgetxattr(path string, attr string) ([]byte, error) {
- pathBytes, err := syscall.BytePtrFromString(path)
- if err != nil {
- return nil, err
- }
- attrBytes, err := syscall.BytePtrFromString(attr)
- if err != nil {
- return nil, err
- }
-
dest := make([]byte, 128)
- destBytes := unsafe.Pointer(&dest[0])
- sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
- if errno == syscall.ENODATA {
+ sz, errno := unix.Lgetxattr(path, attr, dest)
+ if errno == unix.ENODATA {
return nil, nil
}
- if errno == syscall.ERANGE {
+ if errno == unix.ERANGE {
dest = make([]byte, sz)
- destBytes := unsafe.Pointer(&dest[0])
- sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
+ sz, errno = unix.Lgetxattr(path, attr, dest)
}
- if errno != 0 {
+ if errno != nil {
return nil, errno
}
return dest[:sz], nil
}
-var _zero uintptr
-
// Lsetxattr sets the value of the extended attribute identified by attr
// and associated with the given path in the file system.
func Lsetxattr(path string, attr string, data []byte, flags int) error {
- pathBytes, err := syscall.BytePtrFromString(path)
- if err != nil {
- return err
- }
- attrBytes, err := syscall.BytePtrFromString(attr)
- if err != nil {
- return err
- }
- var dataBytes unsafe.Pointer
- if len(data) > 0 {
- dataBytes = unsafe.Pointer(&data[0])
- } else {
- dataBytes = unsafe.Pointer(&_zero)
- }
- _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
- if errno != 0 {
- return errno
- }
- return nil
+ return unix.Lsetxattr(path, attr, data, flags)
}
diff --git a/vendor/github.com/docker/docker/pkg/term/proxy.go b/vendor/github.com/docker/docker/pkg/term/proxy.go
new file mode 100644
index 00000000..e648eb81
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/term/proxy.go
@@ -0,0 +1,74 @@
+package term
+
+import (
+ "io"
+)
+
+// EscapeError is special error which returned by a TTY proxy reader's Read()
+// method in case its detach escape sequence is read.
+type EscapeError struct{}
+
+func (EscapeError) Error() string {
+ return "read escape sequence"
+}
+
+// escapeProxy is used only for attaches with a TTY. It is used to proxy
+// stdin keypresses from the underlying reader and look for the passed in
+// escape key sequence to signal a detach.
+type escapeProxy struct {
+ escapeKeys []byte
+ escapeKeyPos int
+ r io.Reader
+}
+
+// NewEscapeProxy returns a new TTY proxy reader which wraps the given reader
+// and detects when the specified escape keys are read, in which case the Read
+// method will return an error of type EscapeError.
+func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader {
+ return &escapeProxy{
+ escapeKeys: escapeKeys,
+ r: r,
+ }
+}
+
+func (r *escapeProxy) Read(buf []byte) (int, error) {
+ nr, err := r.r.Read(buf)
+
+ preserve := func() {
+ // this preserves the original key presses in the passed in buffer
+ nr += r.escapeKeyPos
+ preserve := make([]byte, 0, r.escapeKeyPos+len(buf))
+ preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...)
+ preserve = append(preserve, buf...)
+ r.escapeKeyPos = 0
+ copy(buf[0:nr], preserve)
+ }
+
+ if nr != 1 || err != nil {
+ if r.escapeKeyPos > 0 {
+ preserve()
+ }
+ return nr, err
+ }
+
+ if buf[0] != r.escapeKeys[r.escapeKeyPos] {
+ if r.escapeKeyPos > 0 {
+ preserve()
+ }
+ return nr, nil
+ }
+
+ if r.escapeKeyPos == len(r.escapeKeys)-1 {
+ return 0, EscapeError{}
+ }
+
+ // Looks like we've got an escape key, but we need to match again on the next
+ // read.
+ // Store the current escape key we found so we can look for the next one on
+ // the next read.
+ // Since this is an escape key, make sure we don't let the caller read it
+ // If later on we find that this is not the escape sequence, we'll add the
+ // keys back
+ r.escapeKeyPos++
+ return nr - r.escapeKeyPos, nil
+}
diff --git a/vendor/github.com/docker/docker/pkg/term/tc_other.go b/vendor/github.com/docker/docker/pkg/term/tc.go
similarity index 50%
rename from vendor/github.com/docker/docker/pkg/term/tc_other.go
rename to vendor/github.com/docker/docker/pkg/term/tc.go
index 750d7c3f..6d2dfd3a 100644
--- a/vendor/github.com/docker/docker/pkg/term/tc_other.go
+++ b/vendor/github.com/docker/docker/pkg/term/tc.go
@@ -1,5 +1,4 @@
// +build !windows
-// +build !linux !cgo
// +build !solaris !cgo
package term
@@ -7,14 +6,16 @@ package term
import (
"syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
func tcget(fd uintptr, p *Termios) syscall.Errno {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
+ _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
return err
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
+ _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
return err
}
diff --git a/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go b/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go
deleted file mode 100644
index 59dac5ba..00000000
--- a/vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// +build linux,cgo
-
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-// #include
-import "C"
-
-// Termios is the Unix API for terminal I/O.
-// It is passthrough for syscall.Termios in order to make it portable with
-// other platforms where it is not available or handled differently.
-type Termios syscall.Termios
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if err := tcget(fd, &oldState.termios); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
-
- C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
- if err := tcset(fd, &newState); err != 0 {
- return nil, err
- }
- return &oldState, nil
-}
-
-func tcget(fd uintptr, p *Termios) syscall.Errno {
- ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
- if ret != 0 {
- return err.(syscall.Errno)
- }
- return 0
-}
-
-func tcset(fd uintptr, p *Termios) syscall.Errno {
- ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
- if ret != 0 {
- return err.(syscall.Errno)
- }
- return 0
-}
diff --git a/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go b/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go
index c9139d0c..50234aff 100644
--- a/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go
+++ b/vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go
@@ -5,15 +5,17 @@ package term
import (
"syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
// #include
import "C"
// Termios is the Unix API for terminal I/O.
-// It is passthrough for syscall.Termios in order to make it portable with
+// It is passthrough for unix.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
-type Termios syscall.Termios
+type Termios unix.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
@@ -26,11 +28,11 @@ func MakeRaw(fd uintptr) (*State, error) {
newState := oldState.termios
- newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON | syscall.IXANY)
- newState.Oflag &^= syscall.OPOST
- newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
- newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
- newState.Cflag |= syscall.CS8
+ newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON | unix.IXANY)
+ newState.Oflag &^= unix.OPOST
+ newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
+ newState.Cflag &^= (unix.CSIZE | unix.PARENB)
+ newState.Cflag |= unix.CS8
/*
VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
diff --git a/vendor/github.com/docker/docker/pkg/term/term.go b/vendor/github.com/docker/docker/pkg/term/term.go
index fe59faa9..4f59d8d9 100644
--- a/vendor/github.com/docker/docker/pkg/term/term.go
+++ b/vendor/github.com/docker/docker/pkg/term/term.go
@@ -10,7 +10,8 @@ import (
"io"
"os"
"os/signal"
- "syscall"
+
+ "golang.org/x/sys/unix"
)
var (
@@ -31,7 +32,7 @@ type Winsize struct {
y uint16
}
-// StdStreams returns the standard streams (stdin, stdout, stedrr).
+// StdStreams returns the standard streams (stdin, stdout, stderr).
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
return os.Stdin, os.Stdout, os.Stderr
}
@@ -79,7 +80,7 @@ func SaveState(fd uintptr) (*State, error) {
// descriptor, with echo disabled.
func DisableEcho(fd uintptr, state *State) error {
newState := state.termios
- newState.Lflag &^= syscall.ECHO
+ newState.Lflag &^= unix.ECHO
if err := tcset(fd, &newState); err != 0 {
return err
diff --git a/vendor/github.com/docker/docker/pkg/term/term_windows.go b/vendor/github.com/docker/docker/pkg/term/term_windows.go
index a91f07e4..c0332c3c 100644
--- a/vendor/github.com/docker/docker/pkg/term/term_windows.go
+++ b/vendor/github.com/docker/docker/pkg/term/term_windows.go
@@ -6,7 +6,7 @@ import (
"io"
"os"
"os/signal"
- "syscall"
+ "syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE
"github.com/Azure/go-ansiterm/winterm"
"github.com/docker/docker/pkg/term/windows"
@@ -33,7 +33,7 @@ const (
// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
var vtInputSupported bool
-// StdStreams returns the standard streams (stdin, stdout, stedrr).
+// StdStreams returns the standard streams (stdin, stdout, stderr).
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
// Turn on VT handling on all std handles, if possible. This might
// fail, in which case we will fall back to terminal emulation.
@@ -78,20 +78,24 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
emulateStderr = false
}
+ // Temporarily use STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and
+ // STD_ERROR_HANDLE from syscall rather than x/sys/windows as long as
+ // go-ansiterm hasn't switch to x/sys/windows.
+ // TODO: switch back to x/sys/windows once go-ansiterm has switched
if emulateStdin {
- stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
+ stdIn = windowsconsole.NewAnsiReader(syscall.STD_INPUT_HANDLE)
} else {
stdIn = os.Stdin
}
if emulateStdout {
- stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
+ stdOut = windowsconsole.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
} else {
stdOut = os.Stdout
}
if emulateStderr {
- stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
+ stdErr = windowsconsole.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
} else {
stdErr = os.Stderr
}
@@ -101,7 +105,7 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
func GetFdInfo(in interface{}) (uintptr, bool) {
- return windows.GetHandleInfo(in)
+ return windowsconsole.GetHandleInfo(in)
}
// GetWinsize returns the window size based on the specified file descriptor.
@@ -121,7 +125,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd uintptr) bool {
- return windows.IsConsole(fd)
+ return windowsconsole.IsConsole(fd)
}
// RestoreTerminal restores the terminal connected to the given file descriptor
diff --git a/vendor/github.com/docker/docker/pkg/term/termios_bsd.go b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go
new file mode 100644
index 00000000..c47341e8
--- /dev/null
+++ b/vendor/github.com/docker/docker/pkg/term/termios_bsd.go
@@ -0,0 +1,42 @@
+// +build darwin freebsd openbsd
+
+package term
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/unix"
+)
+
+const (
+ getTermios = unix.TIOCGETA
+ setTermios = unix.TIOCSETA
+)
+
+// Termios is the Unix API for terminal I/O.
+type Termios unix.Termios
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd uintptr) (*State, error) {
+ var oldState State
+ if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
+ return nil, err
+ }
+
+ newState := oldState.termios
+ newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
+ newState.Oflag &^= unix.OPOST
+ newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
+ newState.Cflag &^= (unix.CSIZE | unix.PARENB)
+ newState.Cflag |= unix.CS8
+ newState.Cc[unix.VMIN] = 1
+ newState.Cc[unix.VTIME] = 0
+
+ if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
+ return nil, err
+ }
+
+ return &oldState, nil
+}
diff --git a/vendor/github.com/docker/docker/pkg/term/termios_darwin.go b/vendor/github.com/docker/docker/pkg/term/termios_darwin.go
deleted file mode 100644
index 480db900..00000000
--- a/vendor/github.com/docker/docker/pkg/term/termios_darwin.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TIOCGETA
- setTermios = syscall.TIOCSETA
-)
-
-// Termios magic numbers, passthrough to the ones defined in syscall.
-const (
- IGNBRK = syscall.IGNBRK
- PARMRK = syscall.PARMRK
- INLCR = syscall.INLCR
- IGNCR = syscall.IGNCR
- ECHONL = syscall.ECHONL
- CSIZE = syscall.CSIZE
- ICRNL = syscall.ICRNL
- ISTRIP = syscall.ISTRIP
- PARENB = syscall.PARENB
- ECHO = syscall.ECHO
- ICANON = syscall.ICANON
- ISIG = syscall.ISIG
- IXON = syscall.IXON
- BRKINT = syscall.BRKINT
- INPCK = syscall.INPCK
- OPOST = syscall.OPOST
- CS8 = syscall.CS8
- IEXTEN = syscall.IEXTEN
-)
-
-// Termios is the Unix API for terminal I/O.
-type Termios struct {
- Iflag uint64
- Oflag uint64
- Cflag uint64
- Lflag uint64
- Cc [20]byte
- Ispeed uint64
- Ospeed uint64
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
- newState.Oflag &^= OPOST
- newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
- newState.Cflag &^= (CSIZE | PARENB)
- newState.Cflag |= CS8
- newState.Cc[syscall.VMIN] = 1
- newState.Cc[syscall.VTIME] = 0
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go b/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go
deleted file mode 100644
index ed843ad6..00000000
--- a/vendor/github.com/docker/docker/pkg/term/termios_freebsd.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TIOCGETA
- setTermios = syscall.TIOCSETA
-)
-
-// Termios magic numbers, passthrough to the ones defined in syscall.
-const (
- IGNBRK = syscall.IGNBRK
- PARMRK = syscall.PARMRK
- INLCR = syscall.INLCR
- IGNCR = syscall.IGNCR
- ECHONL = syscall.ECHONL
- CSIZE = syscall.CSIZE
- ICRNL = syscall.ICRNL
- ISTRIP = syscall.ISTRIP
- PARENB = syscall.PARENB
- ECHO = syscall.ECHO
- ICANON = syscall.ICANON
- ISIG = syscall.ISIG
- IXON = syscall.IXON
- BRKINT = syscall.BRKINT
- INPCK = syscall.INPCK
- OPOST = syscall.OPOST
- CS8 = syscall.CS8
- IEXTEN = syscall.IEXTEN
-)
-
-// Termios is the Unix API for terminal I/O.
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]byte
- Ispeed uint32
- Ospeed uint32
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
- newState.Oflag &^= OPOST
- newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
- newState.Cflag &^= (CSIZE | PARENB)
- newState.Cflag |= CS8
- newState.Cc[syscall.VMIN] = 1
- newState.Cc[syscall.VTIME] = 0
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/term/termios_linux.go b/vendor/github.com/docker/docker/pkg/term/termios_linux.go
index 22921b6a..3e25eb7a 100644
--- a/vendor/github.com/docker/docker/pkg/term/termios_linux.go
+++ b/vendor/github.com/docker/docker/pkg/term/termios_linux.go
@@ -1,46 +1,36 @@
-// +build !cgo
-
package term
import (
- "syscall"
- "unsafe"
+ "golang.org/x/sys/unix"
)
const (
- getTermios = syscall.TCGETS
- setTermios = syscall.TCSETS
+ getTermios = unix.TCGETS
+ setTermios = unix.TCSETS
)
// Termios is the Unix API for terminal I/O.
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]byte
- Ispeed uint32
- Ospeed uint32
-}
+type Termios unix.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
+ termios, err := unix.IoctlGetTermios(int(fd), getTermios)
+ if err != nil {
return nil, err
}
- newState := oldState.termios
+ var oldState State
+ oldState.termios = Termios(*termios)
- newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
- newState.Oflag &^= syscall.OPOST
- newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
- newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
- newState.Cflag |= syscall.CS8
+ termios.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
+ termios.Oflag &^= unix.OPOST
+ termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
+ termios.Cflag &^= (unix.CSIZE | unix.PARENB)
+ termios.Cflag |= unix.CS8
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
+ if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil {
return nil, err
}
return &oldState, nil
diff --git a/vendor/github.com/docker/docker/pkg/term/termios_openbsd.go b/vendor/github.com/docker/docker/pkg/term/termios_openbsd.go
deleted file mode 100644
index ed843ad6..00000000
--- a/vendor/github.com/docker/docker/pkg/term/termios_openbsd.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package term
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- getTermios = syscall.TIOCGETA
- setTermios = syscall.TIOCSETA
-)
-
-// Termios magic numbers, passthrough to the ones defined in syscall.
-const (
- IGNBRK = syscall.IGNBRK
- PARMRK = syscall.PARMRK
- INLCR = syscall.INLCR
- IGNCR = syscall.IGNCR
- ECHONL = syscall.ECHONL
- CSIZE = syscall.CSIZE
- ICRNL = syscall.ICRNL
- ISTRIP = syscall.ISTRIP
- PARENB = syscall.PARENB
- ECHO = syscall.ECHO
- ICANON = syscall.ICANON
- ISIG = syscall.ISIG
- IXON = syscall.IXON
- BRKINT = syscall.BRKINT
- INPCK = syscall.INPCK
- OPOST = syscall.OPOST
- CS8 = syscall.CS8
- IEXTEN = syscall.IEXTEN
-)
-
-// Termios is the Unix API for terminal I/O.
-type Termios struct {
- Iflag uint32
- Oflag uint32
- Cflag uint32
- Lflag uint32
- Cc [20]byte
- Ispeed uint32
- Ospeed uint32
-}
-
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd uintptr) (*State, error) {
- var oldState State
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
- return nil, err
- }
-
- newState := oldState.termios
- newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
- newState.Oflag &^= OPOST
- newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
- newState.Cflag &^= (CSIZE | PARENB)
- newState.Cflag |= CS8
- newState.Cc[syscall.VMIN] = 1
- newState.Cc[syscall.VTIME] = 0
-
- if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
- return nil, err
- }
-
- return &oldState, nil
-}
diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go
index cb0b8835..29d39631 100644
--- a/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go
+++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go
@@ -1,6 +1,6 @@
// +build windows
-package windows
+package windowsconsole
import (
"bytes"
diff --git a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go
index a3ce5697..256577e1 100644
--- a/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go
+++ b/vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go
@@ -1,6 +1,6 @@
// +build windows
-package windows
+package windowsconsole
import (
"io"
diff --git a/vendor/github.com/docker/docker/pkg/term/windows/console.go b/vendor/github.com/docker/docker/pkg/term/windows/console.go
index ca5c3b2e..4bad32ea 100644
--- a/vendor/github.com/docker/docker/pkg/term/windows/console.go
+++ b/vendor/github.com/docker/docker/pkg/term/windows/console.go
@@ -1,6 +1,6 @@
// +build windows
-package windows
+package windowsconsole
import (
"os"
diff --git a/vendor/github.com/docker/docker/pkg/term/windows/windows.go b/vendor/github.com/docker/docker/pkg/term/windows/windows.go
index ce4cb599..c02a93a0 100644
--- a/vendor/github.com/docker/docker/pkg/term/windows/windows.go
+++ b/vendor/github.com/docker/docker/pkg/term/windows/windows.go
@@ -2,7 +2,7 @@
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
-package windows
+package windowsconsole
import (
"io/ioutil"
@@ -10,7 +10,7 @@ import (
"sync"
ansiterm "github.com/Azure/go-ansiterm"
- "github.com/Sirupsen/logrus"
+ "github.com/sirupsen/logrus"
)
var logger *logrus.Logger
diff --git a/vendor/github.com/docker/docker/pkg/term/term_unix.go b/vendor/github.com/docker/docker/pkg/term/winsize.go
similarity index 67%
rename from vendor/github.com/docker/docker/pkg/term/term_unix.go
rename to vendor/github.com/docker/docker/pkg/term/winsize.go
index ddf87a0e..f58367fe 100644
--- a/vendor/github.com/docker/docker/pkg/term/term_unix.go
+++ b/vendor/github.com/docker/docker/pkg/term/winsize.go
@@ -3,14 +3,15 @@
package term
import (
- "syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
+ _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return ws, nil
@@ -20,7 +21,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
- _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
+ _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return nil
diff --git a/vendor/github.com/docker/docker/pkg/term/term_solaris.go b/vendor/github.com/docker/docker/pkg/term/winsize_solaris_cgo.go
similarity index 73%
rename from vendor/github.com/docker/docker/pkg/term/term_solaris.go
rename to vendor/github.com/docker/docker/pkg/term/winsize_solaris_cgo.go
index 112debbe..39c1d320 100644
--- a/vendor/github.com/docker/docker/pkg/term/term_solaris.go
+++ b/vendor/github.com/docker/docker/pkg/term/winsize_solaris_cgo.go
@@ -1,10 +1,11 @@
-// +build solaris
+// +build solaris,cgo
package term
import (
- "syscall"
"unsafe"
+
+ "golang.org/x/sys/unix"
)
/*
@@ -22,7 +23,7 @@ import "C"
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
- ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
+ ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return ws, nil
@@ -32,7 +33,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
- ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
+ ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return nil
diff --git a/vendor/github.com/docker/docker/pkg/tlsconfig/tlsconfig_clone_go16.go b/vendor/github.com/docker/docker/pkg/tlsconfig/tlsconfig_clone_go16.go
deleted file mode 100644
index 0b816650..00000000
--- a/vendor/github.com/docker/docker/pkg/tlsconfig/tlsconfig_clone_go16.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// +build go1.6,!go1.7
-
-package tlsconfig
-
-import "crypto/tls"
-
-// Clone returns a clone of tls.Config. This function is provided for
-// compatibility for go1.6 that doesn't include this method in stdlib.
-func Clone(c *tls.Config) *tls.Config {
- return &tls.Config{
- Rand: c.Rand,
- Time: c.Time,
- Certificates: c.Certificates,
- NameToCertificate: c.NameToCertificate,
- GetCertificate: c.GetCertificate,
- RootCAs: c.RootCAs,
- NextProtos: c.NextProtos,
- ServerName: c.ServerName,
- ClientAuth: c.ClientAuth,
- ClientCAs: c.ClientCAs,
- InsecureSkipVerify: c.InsecureSkipVerify,
- CipherSuites: c.CipherSuites,
- PreferServerCipherSuites: c.PreferServerCipherSuites,
- SessionTicketsDisabled: c.SessionTicketsDisabled,
- SessionTicketKey: c.SessionTicketKey,
- ClientSessionCache: c.ClientSessionCache,
- MinVersion: c.MinVersion,
- MaxVersion: c.MaxVersion,
- CurvePreferences: c.CurvePreferences,
- }
-}
diff --git a/vendor/github.com/docker/docker/pkg/truncindex/truncindex.go b/vendor/github.com/docker/docker/pkg/truncindex/truncindex.go
index 02610b8b..74776e65 100644
--- a/vendor/github.com/docker/docker/pkg/truncindex/truncindex.go
+++ b/vendor/github.com/docker/docker/pkg/truncindex/truncindex.go
@@ -77,10 +77,7 @@ func (idx *TruncIndex) addID(id string) error {
func (idx *TruncIndex) Add(id string) error {
idx.Lock()
defer idx.Unlock()
- if err := idx.addID(id); err != nil {
- return err
- }
- return nil
+ return idx.addID(id)
}
// Delete removes an ID from the TruncIndex. If there are multiple IDs
@@ -128,8 +125,13 @@ func (idx *TruncIndex) Get(s string) (string, error) {
return "", ErrNotExist
}
-// Iterate iterates over all stored IDs, and passes each of them to the given handler.
+// Iterate iterates over all stored IDs and passes each of them to the given
+// handler. Take care that the handler method does not call any public
+// method on truncindex as the internal locking is not reentrant/recursive
+// and will result in deadlock.
func (idx *TruncIndex) Iterate(handler func(id string)) {
+ idx.Lock()
+ defer idx.Unlock()
idx.trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error {
handler(string(prefix))
return nil
diff --git a/vendor/github.com/docker/docker/utils/templates/templates.go b/vendor/github.com/docker/docker/utils/templates/templates.go
deleted file mode 100644
index 91c376f3..00000000
--- a/vendor/github.com/docker/docker/utils/templates/templates.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package templates
-
-import (
- "encoding/json"
- "strings"
- "text/template"
-)
-
-// basicFunctions are the set of initial
-// functions provided to every template.
-var basicFunctions = template.FuncMap{
- "json": func(v interface{}) string {
- a, _ := json.Marshal(v)
- return string(a)
- },
- "split": strings.Split,
- "join": strings.Join,
- "title": strings.Title,
- "lower": strings.ToLower,
- "upper": strings.ToUpper,
- "pad": padWithSpace,
-}
-
-// Parse creates a new annonymous template with the basic functions
-// and parses the given format.
-func Parse(format string) (*template.Template, error) {
- return NewParse("", format)
-}
-
-// NewParse creates a new tagged template with the basic functions
-// and parses the given format.
-func NewParse(tag, format string) (*template.Template, error) {
- return template.New(tag).Funcs(basicFunctions).Parse(format)
-}
-
-// padWithSpace adds whitespace to the input if the input is non-empty
-func padWithSpace(source string, prefix, suffix int) string {
- if source == "" {
- return source
- }
- return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix)
-}
diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf
index bb7718bc..7608b0e3 100644
--- a/vendor/github.com/docker/docker/vendor.conf
+++ b/vendor/github.com/docker/docker/vendor.conf
@@ -1,84 +1,89 @@
# the following lines are in sorted order, FYI
-github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
-github.com/Microsoft/hcsshim v0.5.9
-github.com/Microsoft/go-winio v0.3.8
-github.com/Sirupsen/logrus v0.11.0
-github.com/davecgh/go-spew 6d212800a42e8ab5c146b8ace3490ee17e5225f9
+github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
+github.com/Microsoft/hcsshim v0.6.2
+github.com/Microsoft/go-winio v0.4.4
+github.com/moby/buildkit da2b9dc7dab99e824b2b1067ad7d0523e32dd2d9 https://github.com/dmcgowan/buildkit.git
+github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
github.com/gorilla/context v1.1
github.com/gorilla/mux v1.1
+github.com/jhowardmsft/opengcs v0.0.12
github.com/kr/pty 5cf931ef8f
-github.com/mattn/go-shellwords v1.0.0
-github.com/mattn/go-sqlite3 v1.1.0
+github.com/mattn/go-shellwords v1.0.3
+github.com/sirupsen/logrus v1.0.1
github.com/tchap/go-patricia v2.2.6
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
-# forked golang.org/x/net package includes a patch for lazy loading trace templates
-golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://github.com/tonistiigi/net.git
-golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
-github.com/docker/go-units 8a7beacffa3009a9ac66bad506b18ffdd110cf97
-github.com/docker/go-connections ecb4cb2dd420ada7df7f2593d6c25441f65f69f2
+golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
+golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
+github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
+github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987
+github.com/pmezard/go-difflib v1.0.0
github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5
github.com/imdario/mergo 0.2.1
+golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0
#get libnetwork packages
-github.com/docker/libnetwork 45b40861e677e37cf27bc184eca5af92f8cdd32d
-github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
+github.com/docker/libnetwork 248fd5ea6a67f8810da322e6e7441e8de96a9045 https://github.com/dmcgowan/libnetwork.git
+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 88ac4de0d1a0ca6def284b571342db3b777a4c37
+github.com/hashicorp/memberlist v0.1.0
+github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
+github.com/hashicorp/go-sockaddr acd314c5781ea706c710d9ea70069fd2e110d61d
github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
-github.com/vishvananda/netlink 482f7a52b758233521878cb6c5904b6bd63f3457
+github.com/vishvananda/netlink bd6d5de5ccef2d66b0a26177928d0d8895d7f969
github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060
github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d
-github.com/coreos/etcd 3a49cbb769ebd8d1dd25abb1e83386e9883a5707
+github.com/coreos/etcd v3.2.1
+github.com/coreos/go-semver v0.2.0
github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
github.com/hashicorp/consul v0.5.2
github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904
github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
# get graph and distribution packages
-github.com/docker/distribution 28602af35aceda2f8d571bad7ca37a54cf0250bc
+github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c
github.com/vbatts/tar-split v0.10.1
+github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
# get go-zfs packages
github.com/mistifyio/go-zfs 22c9b32c84eb0d0c6f4043b6e90fc94073de92fa
github.com/pborman/uuid v1.0
-# get desired notary commit, might also need to be updated in Dockerfile
-github.com/docker/notary v0.4.2
-
-google.golang.org/grpc v1.0.2
-github.com/miekg/pkcs11 df8ae6ca730422dba20c768ff38ef7d79077a59f
-github.com/docker/go v1.5.1-1-1-gbaf439e
-github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
+google.golang.org/grpc v1.3.0
# When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly
-github.com/opencontainers/runc 9df8b306d01f59d3a8029be411de015b7304dd8f https://github.com/docker/runc.git # libcontainer
-github.com/opencontainers/runtime-spec 1c7c27d043c2a5e513a44084d2b10d77d1402b8c # specs
+github.com/opencontainers/runc e9325d442f5979c4f79bfa9e09bdf7abb74ba03b https://github.com/dmcgowan/runc.git
+github.com/opencontainers/image-spec 372ad780f63454fbbbbcc7cf80e5b90245c13e13
+github.com/opencontainers/runtime-spec d42f1eb741e6361e858d83fc75aa6893b66292c4 # specs
+
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
+
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
github.com/coreos/go-systemd v4
github.com/godbus/dbus v4.0.0
github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
-github.com/golang/protobuf 1f49d83d9aa00e6ce4fc8258c71cc7786aec968a
+github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
# gelf logging driver deps
-github.com/Graylog2/go-gelf aab2f594e4585d43468ac57287b0dece9d806883
+github.com/Graylog2/go-gelf 7029da823dad4ef3a876df61065156acb703b2ea
github.com/fluent/fluent-logger-golang v1.2.1
# fluent-logger-golang deps
-github.com/philhofer/fwd 899e4efba8eaa1fea74175308f3fae18ff3319fa
+github.com/philhofer/fwd 98c11a7a6ec829d672b03833c3d69a7fae1ca972
github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
# fsnotify
-github.com/fsnotify/fsnotify v1.2.11
+github.com/fsnotify/fsnotify v1.4.2
# awslogs deps
github.com/aws/aws-sdk-go v1.4.22
@@ -86,30 +91,29 @@ github.com/go-ini/ini 060d7da055ba6ec5ea7a31f116332fe5efa04ce0
github.com/jmespath/go-jmespath 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74
# logentries
-github.com/bsphere/le_go d3308aafe090956bc89a65f0769f58251a1b4f03
+github.com/bsphere/le_go 7a984a84b5492ae539b79b62fb4a10afc63c7bcf
# gcplogs deps
-golang.org/x/oauth2 2baa8a1b9338cf13d9eeb27696d761155fa480be
-google.golang.org/api dc6d2353af16e2a2b0ff6986af051d473a4ed468
-google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0
-
-# native credentials
-github.com/docker/docker-credential-helpers f72c04f1d8e71959a6d103f808c50ccbad79b9fd
+golang.org/x/oauth2 96382aa079b72d8c014eb0c50f6c223d1e6a2de0
+google.golang.org/api 3cc2e591b550923a2c5f0ab5a803feda924d5823
+cloud.google.com/go 9d965e63e8cceb1b5d7977a202f0fcb8866d6525
+github.com/googleapis/gax-go da06d194a00e19ce00d9011a13931c3f6f6887c7
+google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
# containerd
-github.com/docker/containerd aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1
+github.com/containerd/containerd fc10004571bb9b26695ccbf2dd4a83213f60b93e https://github.com/dmcgowan/containerd.git
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
+github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d
+github.com/tonistiigi/fsutil 0ac4c11b053b9c5c7c47558f81f96c7100ce50fb
# cluster
-github.com/docker/swarmkit 1c7f003d75f091d5f7051ed982594420e4515f77
-github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
-github.com/gogo/protobuf v0.3
+github.com/docker/swarmkit 8bdecc57887ffc598b63d6433f58e0d2852112c3 https://github.com/dmcgowan/swarmkit.git
+github.com/gogo/protobuf v0.4
github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2
golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
-github.com/mreiferson/go-httpclient 63fe23f7434723dc904c901043af07931f293c47
-github.com/hashicorp/go-memdb 608dda3b1410a73eaf3ac8b517c9ae7ebab6aa87
+github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
github.com/hashicorp/go-immutable-radix 8e8ed81f8f0bf1bdd829593fdd5c29922c1ea990
github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
github.com/coreos/pkg fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
@@ -119,22 +123,25 @@ github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8
github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5
-bitbucket.org/ww/goautoneg 75cd24fc2f2c2a2088577d12123ddee5f54e0675
-github.com/matttproud/golang_protobuf_extensions fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a
+github.com/matttproud/golang_protobuf_extensions v1.0.0
github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
+github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
# cli
-github.com/spf13/cobra v1.5 https://github.com/dnephin/cobra.git
-github.com/spf13/pflag dabebe21bf790f782ea4c7bbd2efc430de182afd
+github.com/spf13/cobra v1.5.1 https://github.com/dnephin/cobra.git
+github.com/spf13/pflag 9ff6c6923cfffbcd502984b8e0c80539a94968b7
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
-github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff
+github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty
# metrics
-github.com/docker/go-metrics 86138d05f285fd9737a99bee2d9be30866b59d72
+github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
-# composefile
-github.com/mitchellh/mapstructure f3009df150dadf309fdee4a54ed65c124afad715
-github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
-github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
-github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
-gopkg.in/yaml.v2 a83829b6f1293c91addabc89d0571c246397bbf4
+github.com/opencontainers/selinux v1.0.0-rc1
+
+# archive/tar
+# mkdir -p ./vendor/archive
+# git clone git://github.com/tonistiigi/go-1.git ./go
+# git --git-dir ./go/.git --work-tree ./go checkout revert-prefix-ignore
+# cp -a go/src/archive/tar ./vendor/archive/tar
+# rm -rf ./go
+# vndr
diff --git a/vendor/github.com/docker/go-connections/tlsconfig/certpool_go17.go b/vendor/github.com/docker/go-connections/tlsconfig/certpool_go17.go
index 1d5fa4c7..1ca0965e 100644
--- a/vendor/github.com/docker/go-connections/tlsconfig/certpool_go17.go
+++ b/vendor/github.com/docker/go-connections/tlsconfig/certpool_go17.go
@@ -5,8 +5,6 @@ package tlsconfig
import (
"crypto/x509"
"runtime"
-
- "github.com/Sirupsen/logrus"
)
// SystemCertPool returns a copy of the system cert pool,
@@ -14,7 +12,6 @@ import (
func SystemCertPool() (*x509.CertPool, error) {
certpool, err := x509.SystemCertPool()
if err != nil && runtime.GOOS == "windows" {
- logrus.Infof("Unable to use system certificate pool: %v", err)
return x509.NewCertPool(), nil
}
return certpool, err
diff --git a/vendor/github.com/docker/go-connections/tlsconfig/certpool_other.go b/vendor/github.com/docker/go-connections/tlsconfig/certpool_other.go
index 262c95e8..9ca97453 100644
--- a/vendor/github.com/docker/go-connections/tlsconfig/certpool_other.go
+++ b/vendor/github.com/docker/go-connections/tlsconfig/certpool_other.go
@@ -5,12 +5,10 @@ package tlsconfig
import (
"crypto/x509"
- "github.com/Sirupsen/logrus"
)
// SystemCertPool returns an new empty cert pool,
// accessing system cert pool is supported in go 1.7
func SystemCertPool() (*x509.CertPool, error) {
- logrus.Warn("Unable to use system certificate pool: requires building with go 1.7 or later")
return x509.NewCertPool(), nil
}
diff --git a/vendor/github.com/docker/go-connections/tlsconfig/config.go b/vendor/github.com/docker/go-connections/tlsconfig/config.go
index ad4b112a..1b31bbb8 100644
--- a/vendor/github.com/docker/go-connections/tlsconfig/config.go
+++ b/vendor/github.com/docker/go-connections/tlsconfig/config.go
@@ -13,7 +13,6 @@ import (
"io/ioutil"
"os"
- "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
)
@@ -106,7 +105,6 @@ func certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) {
if !certPool.AppendCertsFromPEM(pem) {
return nil, fmt.Errorf("failed to append certificates from PEM file: %q", caFile)
}
- logrus.Debugf("Trusting %d certs", len(certPool.Subjects()))
return certPool, nil
}
diff --git a/vendor/github.com/opencontainers/runc/README.md b/vendor/github.com/opencontainers/runc/README.md
index a951f0db..eabfb982 100644
--- a/vendor/github.com/opencontainers/runc/README.md
+++ b/vendor/github.com/opencontainers/runc/README.md
@@ -145,11 +145,33 @@ Your process field in the `config.json` should look like this below with `"termi
"TERM=xterm"
],
"cwd": "/",
- "capabilities": [
- "CAP_AUDIT_WRITE",
- "CAP_KILL",
- "CAP_NET_BIND_SERVICE"
- ],
+ "capabilities": {
+ "bounding": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ],
+ "effective": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ],
+ "inheritable": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ],
+ "permitted": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ],
+ "ambient": [
+ "CAP_AUDIT_WRITE",
+ "CAP_KILL",
+ "CAP_NET_BIND_SERVICE"
+ ]
+ },
"rlimits": [
{
"type": "RLIMIT_NOFILE",
@@ -161,7 +183,7 @@ Your process field in the `config.json` should look like this below with `"termi
},
```
-Now we can go though the lifecycle operations in your shell.
+Now we can go through the lifecycle operations in your shell.
```bash
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
index 456c57d9..b010b4b3 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go
@@ -353,7 +353,6 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
switch name {
case "name=systemd":
// let systemd handle this
- break
case "cpuset":
path, err := getSubsystemPath(c, name)
if err != nil && !cgroups.IsNotFound(err) {
@@ -363,7 +362,6 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
if err := s.ApplyDir(path, c, pid); err != nil {
return err
}
- break
default:
_, err := join(c, name, pid)
if err != nil {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
index 98f4b858..269fffff 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
@@ -7,8 +7,9 @@ import (
"os/exec"
"time"
- "github.com/Sirupsen/logrus"
"github.com/opencontainers/runtime-spec/specs-go"
+
+ "github.com/sirupsen/logrus"
)
type Rlimit struct {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
index 52eebf55..5fc171a5 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
@@ -79,9 +79,6 @@ type Namespace struct {
}
func (n *Namespace) GetPath(pid int) string {
- if n.Path != "" {
- return n.Path
- }
return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
index 4fd35da8..461dc097 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
@@ -2,11 +2,9 @@ package devices
import (
"errors"
- "fmt"
"io/ioutil"
"os"
"path/filepath"
- "syscall" //only for Stat_t
"github.com/opencontainers/runc/libcontainer/configs"
@@ -19,45 +17,41 @@ var (
// Testing dependencies
var (
- osLstat = os.Lstat
+ unixLstat = unix.Lstat
ioutilReadDir = ioutil.ReadDir
)
// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
func DeviceFromPath(path, permissions string) (*configs.Device, error) {
- fileInfo, err := osLstat(path)
+ var stat unix.Stat_t
+ err := unixLstat(path, &stat)
if err != nil {
return nil, err
}
var (
- devType rune
- mode = fileInfo.Mode()
- fileModePermissionBits = os.FileMode.Perm(mode)
+ devType rune
+ mode = stat.Mode
)
switch {
- case mode&os.ModeDevice == 0:
- return nil, ErrNotADevice
- case mode&os.ModeCharDevice != 0:
- fileModePermissionBits |= unix.S_IFCHR
+ case mode&unix.S_IFBLK == unix.S_IFBLK:
+ devType = 'b'
+ case mode&unix.S_IFCHR == unix.S_IFCHR:
devType = 'c'
default:
- fileModePermissionBits |= unix.S_IFBLK
- devType = 'b'
+ return nil, ErrNotADevice
}
- stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
- if !ok {
- return nil, fmt.Errorf("cannot determine the device number for device %s", path)
- }
- devNumber := int(stat_t.Rdev)
+ devNumber := int(stat.Rdev)
+ uid := stat.Uid
+ gid := stat.Gid
return &configs.Device{
Type: devType,
Path: path,
Major: Major(devNumber),
Minor: Minor(devNumber),
Permissions: permissions,
- FileMode: fileModePermissionBits,
- Uid: stat_t.Uid,
- Gid: stat_t.Gid,
+ FileMode: os.FileMode(mode),
+ Uid: uid,
+ Gid: gid,
}, nil
}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
index 0ad68834..197e6d08 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
@@ -143,8 +143,7 @@ static int write_file(char *data, size_t data_len, char *pathfmt, ...)
fd = open(path, O_RDWR);
if (fd < 0) {
- ret = -1;
- goto out;
+ return -1;
}
len = write(fd, data, data_len);
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
index bf491c89..95e9eebc 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
@@ -2,8 +2,6 @@ package user
import (
"errors"
-
- "golang.org/x/sys/unix"
)
var (
@@ -37,13 +35,6 @@ func lookupUser(filter func(u User) bool) (User, error) {
return users[0], nil
}
-// CurrentUser looks up the current user by their user id in /etc/passwd. If the
-// user cannot be found (or there is no /etc/passwd file on the filesystem),
-// then CurrentUser returns an error.
-func CurrentUser() (User, error) {
- return LookupUid(unix.Getuid())
-}
-
// LookupUser looks up a user by their username in /etc/passwd. If the user
// cannot be found (or there is no /etc/passwd file on the filesystem), then
// LookupUser returns an error.
@@ -85,13 +76,6 @@ func lookupGroup(filter func(g Group) bool) (Group, error) {
return groups[0], nil
}
-// CurrentGroup looks up the current user's group by their primary group id's
-// entry in /etc/passwd. If the group cannot be found (or there is no
-// /etc/group file on the filesystem), then CurrentGroup returns an error.
-func CurrentGroup() (Group, error) {
- return LookupGid(unix.Getgid())
-}
-
// LookupGroup looks up a group by its name in /etc/group. If the group cannot
// be found (or there is no /etc/group file on the filesystem), then LookupGroup
// returns an error.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
index 758b734c..c2bb9ec9 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
@@ -5,6 +5,8 @@ package user
import (
"io"
"os"
+
+ "golang.org/x/sys/unix"
)
// Unix-specific path to the passwd and group formatted files.
@@ -28,3 +30,17 @@ func GetGroupPath() (string, error) {
func GetGroup() (io.ReadCloser, error) {
return os.Open(unixGroupPath)
}
+
+// CurrentUser looks up the current user by their user id in /etc/passwd. If the
+// user cannot be found (or there is no /etc/passwd file on the filesystem),
+// then CurrentUser returns an error.
+func CurrentUser() (User, error) {
+ return LookupUid(unix.Getuid())
+}
+
+// CurrentGroup looks up the current user's group by their primary group id's
+// entry in /etc/passwd. If the group cannot be found (or there is no
+// /etc/group file on the filesystem), then CurrentGroup returns an error.
+func CurrentGroup() (Group, error) {
+ return LookupGid(unix.Getgid())
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
index 72179488..4a8d00ac 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
@@ -2,7 +2,10 @@
package user
-import "io"
+import (
+ "io"
+ "syscall"
+)
func GetPasswdPath() (string, error) {
return "", ErrUnsupported
@@ -19,3 +22,17 @@ func GetGroupPath() (string, error) {
func GetGroup() (io.ReadCloser, error) {
return nil, ErrUnsupported
}
+
+// CurrentUser looks up the current user by their user id in /etc/passwd. If the
+// user cannot be found (or there is no /etc/passwd file on the filesystem),
+// then CurrentUser returns an error.
+func CurrentUser() (User, error) {
+ return LookupUid(syscall.Getuid())
+}
+
+// CurrentGroup looks up the current user's group by their primary group id's
+// entry in /etc/passwd. If the group cannot be found (or there is no
+// /etc/group file on the filesystem), then CurrentGroup returns an error.
+func CurrentGroup() (Group, error) {
+ return LookupGid(syscall.Getgid())
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
index 2471535a..8962cab3 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go
@@ -358,8 +358,8 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
// Okay, so it's numeric. We can just roll with this.
}
- } else if len(groups) > 0 && uidErr != nil {
- // Supplementary group ids only make sense if in the implicit form for non-numeric users.
+ } else if len(groups) > 0 {
+ // Supplementary group ids only make sense if in the implicit form.
user.Sgids = make([]int, len(groups))
for i, group := range groups {
user.Sgids[i] = group.Gid
diff --git a/vendor/github.com/opencontainers/runc/vendor.conf b/vendor/github.com/opencontainers/runc/vendor.conf
index 509e2b7b..9506b5c6 100644
--- a/vendor/github.com/opencontainers/runc/vendor.conf
+++ b/vendor/github.com/opencontainers/runc/vendor.conf
@@ -6,7 +6,7 @@ github.com/opencontainers/runtime-spec v1.0.0
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
github.com/opencontainers/selinux v1.0.0-rc1
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
-github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
+github.com/sirupsen/logrus a3f95b5c423586578a4e099b11a46c2479628cac
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
# systemd integration.
diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
index ed80742b..2cf4a363 100644
--- a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
+++ b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
@@ -341,6 +341,13 @@ func (g *Generator) RemoveAnnotation(key string) {
delete(g.spec.Annotations, key)
}
+// SetProcessConsoleSize sets g.spec.Process.ConsoleSize.
+func (g *Generator) SetProcessConsoleSize(width, height uint) {
+ g.initSpecProcessConsoleSize()
+ g.spec.Process.ConsoleSize.Width = width
+ g.spec.Process.ConsoleSize.Height = height
+}
+
// SetProcessUID sets g.spec.Process.User.UID.
func (g *Generator) SetProcessUID(uid uint32) {
g.initSpecProcess()
diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/spec.go b/vendor/github.com/opencontainers/runtime-tools/generate/spec.go
index 523066c0..519d2544 100644
--- a/vendor/github.com/opencontainers/runtime-tools/generate/spec.go
+++ b/vendor/github.com/opencontainers/runtime-tools/generate/spec.go
@@ -17,6 +17,13 @@ func (g *Generator) initSpecProcess() {
}
}
+func (g *Generator) initSpecProcessConsoleSize() {
+ g.initSpecProcess()
+ if g.spec.Process.ConsoleSize == nil {
+ g.spec.Process.ConsoleSize = &rspec.Box{}
+ }
+}
+
func (g *Generator) initSpecProcessCapabilities() {
g.initSpecProcess()
if g.spec.Process.Capabilities == nil {
diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/error.go b/vendor/github.com/opencontainers/runtime-tools/validate/error.go
new file mode 100644
index 00000000..754d032b
--- /dev/null
+++ b/vendor/github.com/opencontainers/runtime-tools/validate/error.go
@@ -0,0 +1,110 @@
+package validate
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ rspec "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// ComplianceLevel represents the OCI compliance levels
+type ComplianceLevel int
+
+const (
+ // MAY-level
+
+ // ComplianceMay represents 'MAY' in RFC2119
+ ComplianceMay ComplianceLevel = iota
+ // ComplianceOptional represents 'OPTIONAL' in RFC2119
+ ComplianceOptional
+
+ // SHOULD-level
+
+ // ComplianceShould represents 'SHOULD' in RFC2119
+ ComplianceShould
+ // ComplianceShouldNot represents 'SHOULD NOT' in RFC2119
+ ComplianceShouldNot
+ // ComplianceRecommended represents 'RECOMMENDED' in RFC2119
+ ComplianceRecommended
+ // ComplianceNotRecommended represents 'NOT RECOMMENDED' in RFC2119
+ ComplianceNotRecommended
+
+ // MUST-level
+
+ // ComplianceMust represents 'MUST' in RFC2119
+ ComplianceMust
+ // ComplianceMustNot represents 'MUST NOT' in RFC2119
+ ComplianceMustNot
+ // ComplianceShall represents 'SHALL' in RFC2119
+ ComplianceShall
+ // ComplianceShallNot represents 'SHALL NOT' in RFC2119
+ ComplianceShallNot
+ // ComplianceRequired represents 'REQUIRED' in RFC2119
+ ComplianceRequired
+)
+
+// ErrorCode represents the compliance content
+type ErrorCode int
+
+const (
+ // DefaultFilesystems represents the error code of default filesystems test
+ DefaultFilesystems ErrorCode = iota
+)
+
+// Error represents an error with compliance level and OCI reference
+type Error struct {
+ Level ComplianceLevel
+ Reference string
+ Err error
+}
+
+const referencePrefix = "https://github.com/opencontainers/runtime-spec/blob"
+
+var ociErrors = map[ErrorCode]Error{
+ DefaultFilesystems: Error{Level: ComplianceShould, Reference: "config-linux.md#default-filesystems"},
+}
+
+// ParseLevel takes a string level and returns the OCI compliance level constant
+func ParseLevel(level string) (ComplianceLevel, error) {
+ switch strings.ToUpper(level) {
+ case "MAY":
+ fallthrough
+ case "OPTIONAL":
+ return ComplianceMay, nil
+ case "SHOULD":
+ fallthrough
+ case "SHOULDNOT":
+ fallthrough
+ case "RECOMMENDED":
+ fallthrough
+ case "NOTRECOMMENDED":
+ return ComplianceShould, nil
+ case "MUST":
+ fallthrough
+ case "MUSTNOT":
+ fallthrough
+ case "SHALL":
+ fallthrough
+ case "SHALLNOT":
+ fallthrough
+ case "REQUIRED":
+ return ComplianceMust, nil
+ }
+
+ var l ComplianceLevel
+ return l, fmt.Errorf("%q is not a valid compliance level", level)
+}
+
+// NewError creates an Error by ErrorCode and message
+func NewError(code ErrorCode, msg string) error {
+ err := ociErrors[code]
+ err.Err = errors.New(msg)
+
+ return &err
+}
+
+// Error returns the error message with OCI reference
+func (oci *Error) Error() string {
+ return fmt.Sprintf("%s\nRefer to: %s/v%s/%s", oci.Err.Error(), referencePrefix, rspec.Version, oci.Reference)
+}
diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go b/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
index 2fcd21b4..d97865d4 100644
--- a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
+++ b/vendor/github.com/opencontainers/runtime-tools/validate/validate.go
@@ -14,9 +14,9 @@ import (
"unicode"
"unicode/utf8"
- "github.com/Sirupsen/logrus"
"github.com/blang/semver"
rspec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/sirupsen/logrus"
"github.com/syndtr/gocapability/capability"
)
@@ -96,22 +96,31 @@ func NewValidatorFromPath(bundlePath string, hostSpecific bool, platform string)
// CheckAll checks all parts of runtime bundle
func (v *Validator) CheckAll() (msgs []string) {
msgs = append(msgs, v.CheckPlatform()...)
- msgs = append(msgs, v.CheckRootfsPath()...)
+ msgs = append(msgs, v.CheckRoot()...)
msgs = append(msgs, v.CheckMandatoryFields()...)
msgs = append(msgs, v.CheckSemVer()...)
msgs = append(msgs, v.CheckMounts()...)
msgs = append(msgs, v.CheckProcess()...)
msgs = append(msgs, v.CheckHooks()...)
- if v.spec.Linux != nil {
- msgs = append(msgs, v.CheckLinux()...)
- }
+ msgs = append(msgs, v.CheckLinux()...)
return
}
-// CheckRootfsPath checks status of v.spec.Root.Path
-func (v *Validator) CheckRootfsPath() (msgs []string) {
- logrus.Debugf("check rootfs path")
+// CheckRoot checks status of v.spec.Root
+func (v *Validator) CheckRoot() (msgs []string) {
+ logrus.Debugf("check root")
+
+ if v.platform == "windows" && v.spec.Windows.HyperV != nil {
+ if v.spec.Root != nil {
+ msgs = append(msgs, fmt.Sprintf("for Hyper-V containers, Root must not be set"))
+ return
+ }
+ return
+ } else if v.spec.Root == nil {
+ msgs = append(msgs, fmt.Sprintf("for non-Hyper-V containers, Root must be set"))
+ return
+ }
absBundlePath, err := filepath.Abs(v.bundlePath)
if err != nil {
@@ -211,6 +220,10 @@ func checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (ms
func (v *Validator) CheckProcess() (msgs []string) {
logrus.Debugf("check process")
+ if v.spec.Process == nil {
+ return
+ }
+
process := v.spec.Process
if !filepath.IsAbs(process.Cwd) {
msgs = append(msgs, fmt.Sprintf("cwd %q is not an absolute path", process.Cwd))
@@ -425,6 +438,10 @@ func (v *Validator) CheckPlatform() (msgs []string) {
func (v *Validator) CheckLinux() (msgs []string) {
logrus.Debugf("check linux")
+ if v.spec.Linux == nil {
+ return
+ }
+
var typeList = map[rspec.LinuxNamespaceType]struct {
num int
newExist bool
diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/LICENSE
rename to vendor/github.com/sirupsen/logrus/LICENSE
diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
similarity index 86%
rename from vendor/github.com/Sirupsen/logrus/README.md
rename to vendor/github.com/sirupsen/logrus/README.md
index 640cf61f..cbe8b696 100644
--- a/vendor/github.com/Sirupsen/logrus/README.md
+++ b/vendor/github.com/sirupsen/logrus/README.md
@@ -1,10 +1,4 @@
-# Logrus [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/Sirupsen/logrus?status.svg)](https://godoc.org/github.com/Sirupsen/logrus)
-
-**Seeing weird case-sensitive problems?** See [this
-issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021).
-This change has been reverted. I apologize for causing this. I greatly
-underestimated the impact this would have. Logrus strives for stability and
-backwards compatibility and failed to provide that.
+# Logrus [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus)
Logrus is a structured logger for Go (golang), completely API compatible with
the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
@@ -13,6 +7,17 @@ many large deployments. The core API is unlikely to change much but please
version control your Logrus to make sure you aren't fetching latest `master` on
every build.**
+**Seeing weird case-sensitive problems?** Unfortunately, the author failed to
+realize the consequences of renaming to lower-case. Due to the Go package
+environment, this caused issues. Regretfully, there's no turning back now.
+Everything using `logrus` will need to use the lower-case:
+`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
+
+I am terribly sorry for this inconvenience. Logrus strives hard for backwards
+compatibility, and the author failed to realize the cascading consequences of
+such a name-change. To fix Glide, see [these
+comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
+
Nicely color-coded in development (when a TTY is attached, otherwise just
plain text):
@@ -52,6 +57,12 @@ time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x20822
exit status 1
```
+#### Case-sensitivity
+
+The organization's name was changed to lower-case--and this will not be changed
+back. If you are getting import conflicts due to case sensitivity, please use
+the lower-case import: `github.com/sirupsen/logrus`.
+
#### Example
The simplest way to use Logrus is simply the package-level exported logger:
@@ -60,7 +71,7 @@ The simplest way to use Logrus is simply the package-level exported logger:
package main
import (
- log "github.com/Sirupsen/logrus"
+ log "github.com/sirupsen/logrus"
)
func main() {
@@ -71,7 +82,7 @@ func main() {
```
Note that it's completely api-compatible with the stdlib logger, so you can
-replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"`
+replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
and you'll now have the flexibility of Logrus. You can customize it all you
want:
@@ -80,7 +91,7 @@ package main
import (
"os"
- log "github.com/Sirupsen/logrus"
+ log "github.com/sirupsen/logrus"
)
func init() {
@@ -130,7 +141,8 @@ application, you can also create an instance of the `logrus` Logger:
package main
import (
- "github.com/Sirupsen/logrus"
+ "os"
+ "github.com/sirupsen/logrus"
)
// Create a new instance of the logger. You can have any number of instances.
@@ -158,7 +170,7 @@ func main() {
#### Fields
-Logrus encourages careful, structured logging though logging fields instead of
+Logrus encourages careful, structured logging through logging fields instead of
long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
to send event %s to topic %s with key %d")`, you should log the much more
discoverable:
@@ -189,7 +201,7 @@ application or parts of one. For example, you may want to always log the
every line, you can create a `logrus.Entry` to pass around instead:
```go
-requestLogger := log.WithFields(log.Fields{"request_id": request_id, user_ip: user_ip})
+requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request") # will log request_id and user_ip
requestLogger.Warn("something not great happened")
```
@@ -205,9 +217,9 @@ Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
```go
import (
- log "github.com/Sirupsen/logrus"
+ log "github.com/sirupsen/logrus"
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
- logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
"log/syslog"
)
@@ -235,14 +247,16 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
+| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) |
| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
+| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/)
| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
-| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) |
+| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) |
| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
@@ -267,9 +281,11 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
+| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
+| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) |
#### Level logging
@@ -318,7 +334,7 @@ could do:
```go
import (
- log "github.com/Sirupsen/logrus"
+ log "github.com/sirupsen/logrus"
)
init() {
@@ -421,7 +437,7 @@ entries. It should not be a feature of the application-level logger.
| Tool | Description |
| ---- | ----------- |
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
-|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper arround Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
+|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
#### Testing
@@ -431,15 +447,24 @@ Logrus has a built in facility for asserting the presence of log messages. This
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
```go
-logger, hook := NewNullLogger()
-logger.Error("Hello error")
+import(
+ "github.com/sirupsen/logrus"
+ "github.com/sirupsen/logrus/hooks/null"
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
-assert.Equal(1, len(hook.Entries))
-assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
-assert.Equal("Hello error", hook.LastEntry().Message)
+func TestSomething(t*testing.T){
+ logger, hook := null.NewNullLogger()
+ logger.Error("Helloerror")
-hook.Reset()
-assert.Nil(hook.LastEntry())
+ assert.Equal(t, 1, len(hook.Entries))
+ assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal(t, "Helloerror", hook.LastEntry().Message)
+
+ hook.Reset()
+ assert.Nil(t, hook.LastEntry())
+}
```
#### Fatal handlers
diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go
similarity index 96%
rename from vendor/github.com/Sirupsen/logrus/alt_exit.go
rename to vendor/github.com/sirupsen/logrus/alt_exit.go
index b4c9e847..8af90637 100644
--- a/vendor/github.com/Sirupsen/logrus/alt_exit.go
+++ b/vendor/github.com/sirupsen/logrus/alt_exit.go
@@ -1,7 +1,7 @@
package logrus
// The following code was sourced and modified from the
-// https://bitbucket.org/tebeka/atexit package governed by the following license:
+// https://github.com/tebeka/atexit package governed by the following license:
//
// Copyright (c) 2012 Miki Tebeka .
//
diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go
similarity index 83%
rename from vendor/github.com/Sirupsen/logrus/doc.go
rename to vendor/github.com/sirupsen/logrus/doc.go
index dddd5f87..da67aba0 100644
--- a/vendor/github.com/Sirupsen/logrus/doc.go
+++ b/vendor/github.com/sirupsen/logrus/doc.go
@@ -7,7 +7,7 @@ The simplest way to use Logrus is simply the package-level exported logger:
package main
import (
- log "github.com/Sirupsen/logrus"
+ log "github.com/sirupsen/logrus"
)
func main() {
@@ -21,6 +21,6 @@ The simplest way to use Logrus is simply the package-level exported logger:
Output:
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
-For a full guide visit https://github.com/Sirupsen/logrus
+For a full guide visit https://github.com/sirupsen/logrus
*/
package logrus
diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
similarity index 89%
rename from vendor/github.com/Sirupsen/logrus/entry.go
rename to vendor/github.com/sirupsen/logrus/entry.go
index 4edbe7a2..320e5d5b 100644
--- a/vendor/github.com/Sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -126,7 +126,7 @@ func (entry Entry) log(level Level, msg string) {
}
func (entry *Entry) Debug(args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
+ if entry.Logger.level() >= DebugLevel {
entry.log(DebugLevel, fmt.Sprint(args...))
}
}
@@ -136,13 +136,13 @@ func (entry *Entry) Print(args ...interface{}) {
}
func (entry *Entry) Info(args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
+ if entry.Logger.level() >= InfoLevel {
entry.log(InfoLevel, fmt.Sprint(args...))
}
}
func (entry *Entry) Warn(args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
+ if entry.Logger.level() >= WarnLevel {
entry.log(WarnLevel, fmt.Sprint(args...))
}
}
@@ -152,20 +152,20 @@ func (entry *Entry) Warning(args ...interface{}) {
}
func (entry *Entry) Error(args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
+ if entry.Logger.level() >= ErrorLevel {
entry.log(ErrorLevel, fmt.Sprint(args...))
}
}
func (entry *Entry) Fatal(args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
+ if entry.Logger.level() >= FatalLevel {
entry.log(FatalLevel, fmt.Sprint(args...))
}
Exit(1)
}
func (entry *Entry) Panic(args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
+ if entry.Logger.level() >= PanicLevel {
entry.log(PanicLevel, fmt.Sprint(args...))
}
panic(fmt.Sprint(args...))
@@ -174,13 +174,13 @@ func (entry *Entry) Panic(args ...interface{}) {
// Entry Printf family functions
func (entry *Entry) Debugf(format string, args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
+ if entry.Logger.level() >= DebugLevel {
entry.Debug(fmt.Sprintf(format, args...))
}
}
func (entry *Entry) Infof(format string, args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
+ if entry.Logger.level() >= InfoLevel {
entry.Info(fmt.Sprintf(format, args...))
}
}
@@ -190,7 +190,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
}
func (entry *Entry) Warnf(format string, args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
+ if entry.Logger.level() >= WarnLevel {
entry.Warn(fmt.Sprintf(format, args...))
}
}
@@ -200,20 +200,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
}
func (entry *Entry) Errorf(format string, args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
+ if entry.Logger.level() >= ErrorLevel {
entry.Error(fmt.Sprintf(format, args...))
}
}
func (entry *Entry) Fatalf(format string, args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
+ if entry.Logger.level() >= FatalLevel {
entry.Fatal(fmt.Sprintf(format, args...))
}
Exit(1)
}
func (entry *Entry) Panicf(format string, args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
+ if entry.Logger.level() >= PanicLevel {
entry.Panic(fmt.Sprintf(format, args...))
}
}
@@ -221,13 +221,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) {
// Entry Println family functions
func (entry *Entry) Debugln(args ...interface{}) {
- if entry.Logger.Level >= DebugLevel {
+ if entry.Logger.level() >= DebugLevel {
entry.Debug(entry.sprintlnn(args...))
}
}
func (entry *Entry) Infoln(args ...interface{}) {
- if entry.Logger.Level >= InfoLevel {
+ if entry.Logger.level() >= InfoLevel {
entry.Info(entry.sprintlnn(args...))
}
}
@@ -237,7 +237,7 @@ func (entry *Entry) Println(args ...interface{}) {
}
func (entry *Entry) Warnln(args ...interface{}) {
- if entry.Logger.Level >= WarnLevel {
+ if entry.Logger.level() >= WarnLevel {
entry.Warn(entry.sprintlnn(args...))
}
}
@@ -247,20 +247,20 @@ func (entry *Entry) Warningln(args ...interface{}) {
}
func (entry *Entry) Errorln(args ...interface{}) {
- if entry.Logger.Level >= ErrorLevel {
+ if entry.Logger.level() >= ErrorLevel {
entry.Error(entry.sprintlnn(args...))
}
}
func (entry *Entry) Fatalln(args ...interface{}) {
- if entry.Logger.Level >= FatalLevel {
+ if entry.Logger.level() >= FatalLevel {
entry.Fatal(entry.sprintlnn(args...))
}
Exit(1)
}
func (entry *Entry) Panicln(args ...interface{}) {
- if entry.Logger.Level >= PanicLevel {
+ if entry.Logger.level() >= PanicLevel {
entry.Panic(entry.sprintlnn(args...))
}
}
diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
similarity index 99%
rename from vendor/github.com/Sirupsen/logrus/exported.go
rename to vendor/github.com/sirupsen/logrus/exported.go
index 9a0120ac..1aeaa90b 100644
--- a/vendor/github.com/Sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -31,14 +31,14 @@ func SetFormatter(formatter Formatter) {
func SetLevel(level Level) {
std.mu.Lock()
defer std.mu.Unlock()
- std.Level = level
+ std.setLevel(level)
}
// GetLevel returns the standard logger level.
func GetLevel() Level {
std.mu.Lock()
defer std.mu.Unlock()
- return std.Level
+ return std.level()
}
// AddHook adds a hook to the standard logger hooks.
diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/formatter.go
rename to vendor/github.com/sirupsen/logrus/formatter.go
diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/hooks.go
rename to vendor/github.com/sirupsen/logrus/hooks.go
diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
similarity index 94%
rename from vendor/github.com/Sirupsen/logrus/json_formatter.go
rename to vendor/github.com/sirupsen/logrus/json_formatter.go
index 266554e9..e787ea17 100644
--- a/vendor/github.com/Sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -35,7 +35,7 @@ type JSONFormatter struct {
// FieldMap: FieldMap{
// FieldKeyTime: "@timestamp",
// FieldKeyLevel: "@level",
- // FieldKeyLevel: "@message",
+ // FieldKeyMsg: "@message",
// },
// }
FieldMap FieldMap
@@ -47,7 +47,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
switch v := v.(type) {
case error:
// Otherwise errors are ignored by `encoding/json`
- // https://github.com/Sirupsen/logrus/issues/137
+ // https://github.com/sirupsen/logrus/issues/137
data[k] = v.Error()
default:
data[k] = v
diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
similarity index 88%
rename from vendor/github.com/Sirupsen/logrus/logger.go
rename to vendor/github.com/sirupsen/logrus/logger.go
index b769f3d3..370fff5d 100644
--- a/vendor/github.com/Sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -4,6 +4,7 @@ import (
"io"
"os"
"sync"
+ "sync/atomic"
)
type Logger struct {
@@ -112,7 +113,7 @@ func (logger *Logger) WithError(err error) *Entry {
}
func (logger *Logger) Debugf(format string, args ...interface{}) {
- if logger.Level >= DebugLevel {
+ if logger.level() >= DebugLevel {
entry := logger.newEntry()
entry.Debugf(format, args...)
logger.releaseEntry(entry)
@@ -120,7 +121,7 @@ func (logger *Logger) Debugf(format string, args ...interface{}) {
}
func (logger *Logger) Infof(format string, args ...interface{}) {
- if logger.Level >= InfoLevel {
+ if logger.level() >= InfoLevel {
entry := logger.newEntry()
entry.Infof(format, args...)
logger.releaseEntry(entry)
@@ -134,7 +135,7 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
}
func (logger *Logger) Warnf(format string, args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
@@ -142,7 +143,7 @@ func (logger *Logger) Warnf(format string, args ...interface{}) {
}
func (logger *Logger) Warningf(format string, args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
@@ -150,7 +151,7 @@ func (logger *Logger) Warningf(format string, args ...interface{}) {
}
func (logger *Logger) Errorf(format string, args ...interface{}) {
- if logger.Level >= ErrorLevel {
+ if logger.level() >= ErrorLevel {
entry := logger.newEntry()
entry.Errorf(format, args...)
logger.releaseEntry(entry)
@@ -158,7 +159,7 @@ func (logger *Logger) Errorf(format string, args ...interface{}) {
}
func (logger *Logger) Fatalf(format string, args ...interface{}) {
- if logger.Level >= FatalLevel {
+ if logger.level() >= FatalLevel {
entry := logger.newEntry()
entry.Fatalf(format, args...)
logger.releaseEntry(entry)
@@ -167,7 +168,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) {
}
func (logger *Logger) Panicf(format string, args ...interface{}) {
- if logger.Level >= PanicLevel {
+ if logger.level() >= PanicLevel {
entry := logger.newEntry()
entry.Panicf(format, args...)
logger.releaseEntry(entry)
@@ -175,7 +176,7 @@ func (logger *Logger) Panicf(format string, args ...interface{}) {
}
func (logger *Logger) Debug(args ...interface{}) {
- if logger.Level >= DebugLevel {
+ if logger.level() >= DebugLevel {
entry := logger.newEntry()
entry.Debug(args...)
logger.releaseEntry(entry)
@@ -183,7 +184,7 @@ func (logger *Logger) Debug(args ...interface{}) {
}
func (logger *Logger) Info(args ...interface{}) {
- if logger.Level >= InfoLevel {
+ if logger.level() >= InfoLevel {
entry := logger.newEntry()
entry.Info(args...)
logger.releaseEntry(entry)
@@ -197,7 +198,7 @@ func (logger *Logger) Print(args ...interface{}) {
}
func (logger *Logger) Warn(args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
@@ -205,7 +206,7 @@ func (logger *Logger) Warn(args ...interface{}) {
}
func (logger *Logger) Warning(args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
@@ -213,7 +214,7 @@ func (logger *Logger) Warning(args ...interface{}) {
}
func (logger *Logger) Error(args ...interface{}) {
- if logger.Level >= ErrorLevel {
+ if logger.level() >= ErrorLevel {
entry := logger.newEntry()
entry.Error(args...)
logger.releaseEntry(entry)
@@ -221,7 +222,7 @@ func (logger *Logger) Error(args ...interface{}) {
}
func (logger *Logger) Fatal(args ...interface{}) {
- if logger.Level >= FatalLevel {
+ if logger.level() >= FatalLevel {
entry := logger.newEntry()
entry.Fatal(args...)
logger.releaseEntry(entry)
@@ -230,7 +231,7 @@ func (logger *Logger) Fatal(args ...interface{}) {
}
func (logger *Logger) Panic(args ...interface{}) {
- if logger.Level >= PanicLevel {
+ if logger.level() >= PanicLevel {
entry := logger.newEntry()
entry.Panic(args...)
logger.releaseEntry(entry)
@@ -238,7 +239,7 @@ func (logger *Logger) Panic(args ...interface{}) {
}
func (logger *Logger) Debugln(args ...interface{}) {
- if logger.Level >= DebugLevel {
+ if logger.level() >= DebugLevel {
entry := logger.newEntry()
entry.Debugln(args...)
logger.releaseEntry(entry)
@@ -246,7 +247,7 @@ func (logger *Logger) Debugln(args ...interface{}) {
}
func (logger *Logger) Infoln(args ...interface{}) {
- if logger.Level >= InfoLevel {
+ if logger.level() >= InfoLevel {
entry := logger.newEntry()
entry.Infoln(args...)
logger.releaseEntry(entry)
@@ -260,7 +261,7 @@ func (logger *Logger) Println(args ...interface{}) {
}
func (logger *Logger) Warnln(args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
@@ -268,7 +269,7 @@ func (logger *Logger) Warnln(args ...interface{}) {
}
func (logger *Logger) Warningln(args ...interface{}) {
- if logger.Level >= WarnLevel {
+ if logger.level() >= WarnLevel {
entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
@@ -276,7 +277,7 @@ func (logger *Logger) Warningln(args ...interface{}) {
}
func (logger *Logger) Errorln(args ...interface{}) {
- if logger.Level >= ErrorLevel {
+ if logger.level() >= ErrorLevel {
entry := logger.newEntry()
entry.Errorln(args...)
logger.releaseEntry(entry)
@@ -284,7 +285,7 @@ func (logger *Logger) Errorln(args ...interface{}) {
}
func (logger *Logger) Fatalln(args ...interface{}) {
- if logger.Level >= FatalLevel {
+ if logger.level() >= FatalLevel {
entry := logger.newEntry()
entry.Fatalln(args...)
logger.releaseEntry(entry)
@@ -293,7 +294,7 @@ func (logger *Logger) Fatalln(args ...interface{}) {
}
func (logger *Logger) Panicln(args ...interface{}) {
- if logger.Level >= PanicLevel {
+ if logger.level() >= PanicLevel {
entry := logger.newEntry()
entry.Panicln(args...)
logger.releaseEntry(entry)
@@ -306,3 +307,11 @@ func (logger *Logger) Panicln(args ...interface{}) {
func (logger *Logger) SetNoLock() {
logger.mu.Disable()
}
+
+func (logger *Logger) level() Level {
+ return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
+}
+
+func (logger *Logger) setLevel(level Level) {
+ atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
similarity index 99%
rename from vendor/github.com/Sirupsen/logrus/logrus.go
rename to vendor/github.com/sirupsen/logrus/logrus.go
index e5966911..dd389997 100644
--- a/vendor/github.com/Sirupsen/logrus/logrus.go
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -10,7 +10,7 @@ import (
type Fields map[string]interface{}
// Level type
-type Level uint8
+type Level uint32
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
func (level Level) String() string {
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_appengine.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/terminal_appengine.go
rename to vendor/github.com/sirupsen/logrus/terminal_appengine.go
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/terminal_bsd.go
rename to vendor/github.com/sirupsen/logrus/terminal_bsd.go
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/terminal_linux.go
rename to vendor/github.com/sirupsen/logrus/terminal_linux.go
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
rename to vendor/github.com/sirupsen/logrus/terminal_notwindows.go
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_solaris.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/terminal_solaris.go
rename to vendor/github.com/sirupsen/logrus/terminal_solaris.go
diff --git a/vendor/github.com/sirupsen/logrus/terminal_windows.go b/vendor/github.com/sirupsen/logrus/terminal_windows.go
new file mode 100644
index 00000000..7a336307
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_windows.go
@@ -0,0 +1,82 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,!appengine
+
+package logrus
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+var (
+ procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+ procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
+)
+
+const (
+ enableProcessedOutput = 0x0001
+ enableWrapAtEolOutput = 0x0002
+ enableVirtualTerminalProcessing = 0x0004
+)
+
+func getVersion() (float64, error) {
+ stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
+ cmd := exec.Command("cmd", "ver")
+ cmd.Stdout = stdout
+ cmd.Stderr = stderr
+ err := cmd.Run()
+ if err != nil {
+ return -1, err
+ }
+
+ // The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
+ version := strings.Replace(stdout.String(), "\n", "", -1)
+ version = strings.Replace(version, "\r\n", "", -1)
+
+ x1 := strings.Index(version, "[Version")
+
+ if x1 == -1 || strings.Index(version, "]") == -1 {
+ return -1, errors.New("Can't determine Windows version")
+ }
+
+ return strconv.ParseFloat(version[x1+9:x1+13], 64)
+}
+
+func init() {
+ ver, err := getVersion()
+ if err != nil {
+ return
+ }
+
+ // Activate Virtual Processing for Windows CMD
+ // Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
+ if ver >= 10 {
+ handle := syscall.Handle(os.Stderr.Fd())
+ procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
+ }
+}
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ switch v := f.(type) {
+ case *os.File:
+ var st uint32
+ r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
+ return r != 0 && e == 0
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/text_formatter.go
rename to vendor/github.com/sirupsen/logrus/text_formatter.go
diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/writer.go
rename to vendor/github.com/sirupsen/logrus/writer.go