Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
GordonTheTurtle
2017-12-12 17:05:22 +00:00
13 changed files with 113 additions and 117 deletions

View File

@ -92,6 +92,8 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.
flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
if runtime.GOOS != "windows" {
// TODO: Remove this flag after 3 release cycles (18.03)
flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
flags.MarkHidden("disable-legacy-registry")
}
}

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
@ -472,8 +473,15 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
return nil, err
}
if !conf.V2Only {
logrus.Warnf(`The "disable-legacy-registry" option is deprecated and wil be removed in Docker v17.12. Interacting with legacy (v1) registries will no longer be supported in Docker v17.12"`)
if runtime.GOOS != "windows" {
if flags.Changed("disable-legacy-registry") {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported")
}
if !conf.V2Only {
// TODO: Remove this error after 3 release cycles (18.03)
return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported")
}
}
if flags.Changed("graph") {

View File

@ -97,15 +97,3 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
assert.True(t, loadedConfig.EnableUserlandProxy)
}
func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) {
content := `{"disable-legacy-registry": false}`
tempFile := fs.NewFile(t, "config", fs.WithContent(content))
defer tempFile.Remove()
opts := defaultOptions(tempFile.Path())
loadedConfig, err := loadDaemonCliConfig(opts)
require.NoError(t, err)
require.NotNil(t, loadedConfig)
assert.False(t, loadedConfig.V2Only)
}

View File

@ -1201,7 +1201,7 @@ func (devices *DeviceSet) growFS(info *devInfo) error {
options = joinMountOptions(options, devices.mountOptions)
if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256)))
return fmt.Errorf("Error mounting '%s' on '%s' (fstype='%s' options='%s'): %s\n%v", info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options, err, string(dmesg.Dmesg(256)))
}
defer unix.Unmount(fsMountPoint, unix.MNT_DETACH)
@ -2392,7 +2392,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
if err := mount.Mount(info.DevName(), path, fstype, options); err != nil {
return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256)))
return fmt.Errorf("devmapper: Error mounting '%s' on '%s' (fstype='%s' options='%s'): %s\n%v", info.DevName(), path, fstype, options, err, string(dmesg.Dmesg(256)))
}
if fstype == "xfs" && devices.xfsNospaceRetries != "" {

View File

@ -151,7 +151,7 @@ func (s *DockerSuite) TestLogsAPIUntilFutureFollow(c *check.C) {
func (s *DockerSuite) TestLogsAPIUntil(c *check.C) {
name := "logsuntil"
dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; done")
dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; sleep 1; done")
client, err := request.NewClient()
if err != nil {

View File

@ -13,9 +13,7 @@ import (
)
func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C) {
// @TODO TestLogoutWithExternalAuth expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported
s.d.StartWithBusybox(c, "--disable-legacy-registry=false")
s.d.StartWithBusybox(c)
osPath := os.Getenv("PATH")
defer os.Setenv("PATH", osPath)
@ -62,7 +60,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C)
// check I cannot pull anymore
out, err := s.d.Cmd("--config", tmp, "pull", repoName)
c.Assert(err, check.NotNil, check.Commentf(out))
c.Assert(out, checker.Contains, "Error: image dockercli/busybox:authtest not found")
c.Assert(out, checker.Contains, "no basic auth credentials")
}
// #23100

View File

@ -259,18 +259,6 @@ func (s *DockerHubPullSuite) TestPullClientDisconnect(c *check.C) {
c.Assert(err, checker.NotNil, check.Commentf("image was pulled after client disconnected"))
}
func (s *DockerRegistryAuthHtpasswdSuite) TestPullNoCredentialsNotFound(c *check.C) {
// @TODO TestPullNoCredentialsNotFound expects docker to fall back to a v1 registry, so has to be updated for v17.12, when v1 registries are no longer supported
s.d.StartWithBusybox(c, "--disable-legacy-registry=false")
// we don't care about the actual image, we just want to see image not found
// because that means v2 call returned 401 and we fell back to v1 which usually
// gives a 404 (in this case the test registry doesn't handle v1 at all)
out, err := s.d.Cmd("pull", privateRegistryURL+"/busybox")
c.Assert(err, check.NotNil, check.Commentf(out))
c.Assert(out, checker.Contains, "Error: image busybox:latest not found")
}
// Regression test for https://github.com/docker/docker/issues/26429
func (s *DockerSuite) TestPullLinuxImageFailsOnWindows(c *check.C) {
testRequires(c, DaemonIsWindows, Network)

View File

@ -22,7 +22,7 @@ func makefile(path string, contents string) (string, error) {
return f.Name(), nil
}
// TestV2Only ensures that a daemon by default does not
// TestV2Only ensures that a daemon does not
// attempt to contact any v1 registry endpoints.
func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
reg, err := registry.NewMock(c)
@ -56,65 +56,3 @@ func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
s.d.Cmd("push", repoName)
s.d.Cmd("pull", repoName)
}
// TestV1 starts a daemon with legacy registries enabled
// and ensure v1 endpoints are hit for the following operations:
// login, push, pull, build & run
func (s *DockerRegistrySuite) TestV1(c *check.C) {
reg, err := registry.NewMock(c)
defer reg.Close()
c.Assert(err, check.IsNil)
v2Pings := 0
reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
v2Pings++
// V2 ping 404 causes fallback to v1
w.WriteHeader(404)
})
v1Pings := 0
reg.RegisterHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
v1Pings++
})
v1Logins := 0
reg.RegisterHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
v1Logins++
})
v1Repo := 0
reg.RegisterHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
v1Repo++
})
reg.RegisterHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
v1Repo++
})
s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=false")
tmp, err := ioutil.TempDir("", "integration-cli-")
c.Assert(err, check.IsNil)
defer os.RemoveAll(tmp)
dockerfileName, err := makefile(tmp, fmt.Sprintf("FROM %s/busybox", reg.URL()))
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
s.d.Cmd("build", "--file", dockerfileName, tmp)
c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build"))
repoName := fmt.Sprintf("%s/busybox", reg.URL())
s.d.Cmd("run", repoName)
c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run"))
s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL())
c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt"))
s.d.Cmd("tag", "busybox", repoName)
s.d.Cmd("push", repoName)
c.Assert(v1Repo, check.Equals, 2)
s.d.Cmd("pull", repoName)
c.Assert(v1Repo, check.Equals, 3, check.Commentf("Expected v1 repository access after pull"))
}

View File

@ -278,7 +278,7 @@ func (r *remote) monitorConnection(client *containerd.Client) {
select {
case <-r.shutdownContext.Done():
r.logger.Info("stopping healtcheck following graceful shutdown")
r.logger.Info("stopping healthcheck following graceful shutdown")
client.Close()
return
default:

View File

@ -77,7 +77,7 @@ github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
# gelf logging driver deps
github.com/Graylog2/go-gelf v2
github.com/Graylog2/go-gelf 4143646226541087117ff2f83334ea48b3201841
github.com/fluent/fluent-logger-golang v1.3.0
# fluent-logger-golang deps

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net"
"time"
)
type TCPReader struct {
@ -13,16 +14,21 @@ type TCPReader struct {
messages chan []byte
}
func newTCPReader(addr string) (*TCPReader, chan string, error) {
type connChannels struct {
drop chan string
confirm chan string
}
func newTCPReader(addr string) (*TCPReader, chan string, chan string, error) {
var err error
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, nil, fmt.Errorf("ResolveTCPAddr('%s'): %s", addr, err)
return nil, nil, nil, fmt.Errorf("ResolveTCPAddr('%s'): %s", addr, err)
}
listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
return nil, nil, fmt.Errorf("ListenTCP: %s", err)
return nil, nil, nil, fmt.Errorf("ListenTCP: %s", err)
}
r := &TCPReader{
@ -30,26 +36,61 @@ func newTCPReader(addr string) (*TCPReader, chan string, error) {
messages: make(chan []byte, 100), // Make a buffered channel with at most 100 messages
}
signal := make(chan string, 1)
closeSignal := make(chan string, 1)
doneSignal := make(chan string, 1)
go r.listenUntilCloseSignal(signal)
go r.listenUntilCloseSignal(closeSignal, doneSignal)
return r, signal, nil
return r, closeSignal, doneSignal, nil
}
func (r *TCPReader) listenUntilCloseSignal(signal chan string) {
defer func() { signal <- "done" }()
defer r.listener.Close()
func (r *TCPReader) accepter(connections chan net.Conn) {
for {
conn, err := r.listener.Accept()
if err != nil {
break
}
go handleConnection(conn, r.messages)
connections <- conn
}
}
func (r *TCPReader) listenUntilCloseSignal(closeSignal chan string, doneSignal chan string) {
defer func() { doneSignal <- "done" }()
defer r.listener.Close()
var conns []connChannels
connectionsChannel := make(chan net.Conn, 1)
go r.accepter(connectionsChannel)
for {
select {
case sig := <-signal:
if sig == "stop" {
break
case conn := <-connectionsChannel:
dropSignal := make(chan string, 1)
dropConfirm := make(chan string, 1)
channels := connChannels{drop: dropSignal, confirm: dropConfirm}
go handleConnection(conn, r.messages, dropSignal, dropConfirm)
conns = append(conns, channels)
default:
}
select {
case sig := <-closeSignal:
if sig == "stop" || sig == "drop" {
if len(conns) >= 1 {
for _, s := range conns {
if s.drop != nil {
s.drop <- "drop"
<-s.confirm
conns = append(conns[:0], conns[1:]...)
}
}
if sig == "stop" {
return
}
} else if sig == "stop" {
closeSignal <- "stop"
}
if sig == "drop" {
doneSignal <- "done"
}
}
default:
}
@ -60,19 +101,41 @@ func (r *TCPReader) addr() string {
return r.listener.Addr().String()
}
func handleConnection(conn net.Conn, messages chan<- []byte) {
func handleConnection(conn net.Conn, messages chan<- []byte, dropSignal chan string, dropConfirm chan string) {
defer func() { dropConfirm <- "done" }()
defer conn.Close()
reader := bufio.NewReader(conn)
var b []byte
var err error
drop := false
canDrop := false
for {
conn.SetDeadline(time.Now().Add(2 * time.Second))
if b, err = reader.ReadBytes(0); err != nil {
continue
}
if len(b) > 0 {
if drop {
return
}
} else if len(b) > 0 {
messages <- b
canDrop = true
if drop {
return
}
} else if drop {
return
}
select {
case sig := <-dropSignal:
if sig == "drop" {
drop = true
time.Sleep(1 * time.Second)
if canDrop {
return
}
}
default:
}
}
}

View File

@ -75,12 +75,17 @@ func (w *TCPWriter) Write(p []byte) (n int, err error) {
func (w *TCPWriter) writeToSocketWithReconnectAttempts(zBytes []byte) (n int, err error) {
var errConn error
var i int
w.mu.Lock()
for i := 0; n <= w.MaxReconnect; i++ {
for i = 0; i <= w.MaxReconnect; i++ {
errConn = nil
n, err = w.conn.Write(zBytes)
if w.conn != nil {
n, err = w.conn.Write(zBytes)
} else {
err = fmt.Errorf("Connection was nil, will attempt reconnect")
}
if err != nil {
time.Sleep(w.ReconnectDelay * time.Second)
w.conn, errConn = net.Dial("tcp", w.addr)
@ -90,6 +95,9 @@ func (w *TCPWriter) writeToSocketWithReconnectAttempts(zBytes []byte) (n int, er
}
w.mu.Unlock()
if i > w.MaxReconnect {
return 0, fmt.Errorf("Maximum reconnection attempts was reached; giving up")
}
if errConn != nil {
return 0, fmt.Errorf("Write Failed: %s\nReconnection failed: %s", err, errConn)
}

View File

@ -27,5 +27,8 @@ type GelfWriter struct {
// Close connection and interrupt blocked Read or Write operations
func (w *GelfWriter) Close() error {
if w.conn == nil {
return nil
}
return w.conn.Close()
}