2016-06-17 15:21:03 +00:00
// +build linux
2014-11-20 05:19:16 +00:00
2014-07-23 18:39:14 +00:00
package main
import (
2016-12-29 01:08:03 +00:00
"bufio"
2015-09-19 00:49:36 +00:00
"bytes"
2017-06-26 18:54:14 +00:00
"context"
2018-05-19 11:38:54 +00:00
"crypto/tls"
"crypto/x509"
2014-10-08 17:13:32 +00:00
"encoding/json"
2014-11-15 04:38:02 +00:00
"fmt"
2016-01-28 18:33:35 +00:00
"io"
2014-10-01 13:07:24 +00:00
"io/ioutil"
2015-04-27 20:16:33 +00:00
"net"
2014-10-08 17:13:32 +00:00
"os"
2014-10-05 04:21:59 +00:00
"os/exec"
2015-12-07 17:55:33 +00:00
"path"
2015-01-22 18:51:04 +00:00
"path/filepath"
2015-04-28 17:26:59 +00:00
"regexp"
2015-04-28 15:55:04 +00:00
"strconv"
2014-07-23 18:39:14 +00:00
"strings"
2015-11-24 20:25:12 +00:00
"sync"
2015-02-04 21:44:52 +00:00
"time"
2015-01-21 16:14:30 +00:00
2017-05-12 18:07:51 +00:00
"github.com/cloudflare/cfssl/helpers"
2017-06-26 18:54:14 +00:00
"github.com/docker/docker/api/types"
2017-09-22 13:52:41 +00:00
moby_daemon "github.com/docker/docker/daemon"
2016-12-30 17:23:00 +00:00
"github.com/docker/docker/integration-cli/checker"
2017-03-23 17:35:22 +00:00
"github.com/docker/docker/integration-cli/cli"
2018-04-18 14:45:55 +00:00
"github.com/docker/docker/integration-cli/cli/build"
2016-12-09 09:17:53 +00:00
"github.com/docker/docker/integration-cli/daemon"
2018-04-13 15:02:56 +00:00
testdaemon "github.com/docker/docker/internal/test/daemon"
2017-05-12 18:07:51 +00:00
"github.com/docker/docker/opts"
2016-04-19 21:16:18 +00:00
"github.com/docker/docker/pkg/mount"
2018-05-19 11:38:54 +00:00
"github.com/docker/go-units"
2015-05-06 22:39:29 +00:00
"github.com/docker/libnetwork/iptables"
2015-04-18 16:46:47 +00:00
"github.com/go-check/check"
2016-01-28 18:33:35 +00:00
"github.com/kr/pty"
2017-05-23 14:22:32 +00:00
"golang.org/x/sys/unix"
2019-04-04 13:23:19 +00:00
"gotest.tools/assert"
2018-06-11 13:32:11 +00:00
"gotest.tools/icmd"
2014-07-23 18:39:14 +00:00
)
2018-09-25 17:57:35 +00:00
const containerdSocket = "/var/run/docker/containerd/containerd.sock"
2018-09-21 22:58:34 +00:00
2016-05-26 11:14:35 +00:00
// TestLegacyDaemonCommand test starting docker daemon using "deprecated" docker daemon
// command. Remove this test when we remove this.
func ( s * DockerDaemonSuite ) TestLegacyDaemonCommand ( c * check . C ) {
cmd := exec . Command ( dockerBinary , "daemon" , "--storage-driver=vfs" , "--debug" )
err := cmd . Start ( )
2017-09-07 17:11:25 +00:00
go cmd . Wait ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "could not start daemon using 'docker daemon'" )
assert . NilError ( c , cmd . Process . Kill ( ) )
2016-05-26 11:14:35 +00:00
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithRunningContainersPorts ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2014-07-23 18:39:14 +00:00
2017-03-23 17:35:22 +00:00
cli . Docker (
2017-03-27 15:12:48 +00:00
cli . Args ( "run" , "-d" , "--name" , "top1" , "-p" , "1234:80" , "--restart" , "always" , "busybox:latest" , "top" ) ,
2017-03-23 17:35:22 +00:00
cli . Daemon ( s . d ) ,
) . Assert ( c , icmd . Success )
cli . Docker (
2017-03-27 15:12:48 +00:00
cli . Args ( "run" , "-d" , "--name" , "top2" , "-p" , "80" , "busybox:latest" , "top" ) ,
2017-03-23 17:35:22 +00:00
cli . Daemon ( s . d ) ,
) . Assert ( c , icmd . Success )
2014-07-23 18:39:14 +00:00
testRun := func ( m map [ string ] bool , prefix string ) {
var format string
2015-04-18 16:46:47 +00:00
for cont , shouldRun := range m {
2017-03-27 15:12:48 +00:00
out := cli . Docker ( cli . Args ( "ps" ) , cli . Daemon ( s . d ) ) . Assert ( c , icmd . Success ) . Combined ( )
2014-07-23 18:39:14 +00:00
if shouldRun {
format = "%scontainer %q is not running"
} else {
format = "%scontainer %q is running"
}
2015-04-18 16:46:47 +00:00
if shouldRun != strings . Contains ( out , cont ) {
c . Fatalf ( format , prefix , cont )
2014-07-23 18:39:14 +00:00
}
}
}
testRun ( map [ string ] bool { "top1" : true , "top2" : true } , "" )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2014-07-23 18:39:14 +00:00
testRun ( map [ string ] bool { "top1" : true , "top2" : false } , "After daemon restart: " )
}
2014-10-08 17:13:32 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithVolumesRefs ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2014-10-08 17:13:32 +00:00
2016-02-28 10:47:37 +00:00
if out , err := s . d . Cmd ( "run" , "--name" , "volrestarttest1" , "-v" , "/foo" , "busybox" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err , out )
2014-10-08 17:13:32 +00:00
}
2015-06-03 19:21:38 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-06-12 13:25:32 +00:00
2017-04-03 17:10:48 +00:00
if out , err := s . d . Cmd ( "run" , "-d" , "--volumes-from" , "volrestarttest1" , "--name" , "volrestarttest2" , "busybox" , "top" ) ; err != nil {
c . Fatal ( err , out )
2014-10-08 17:13:32 +00:00
}
2015-06-03 19:21:38 +00:00
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "rm" , "-fv" , "volrestarttest2" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err , out )
2014-10-08 17:13:32 +00:00
}
2015-06-03 19:21:38 +00:00
out , err := s . d . Cmd ( "inspect" , "-f" , "{{json .Mounts}}" , "volrestarttest1" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-06-03 19:21:38 +00:00
if _ , err := inspectMountPointJSON ( out , "/foo" ) ; err != nil {
c . Fatalf ( "Expected volume to exist: /foo, error: %v\n" , err )
2014-10-08 17:13:32 +00:00
}
}
2014-10-16 18:39:22 +00:00
2015-08-05 21:09:08 +00:00
// #11008
func ( s * DockerDaemonSuite ) TestDaemonRestartUnlessStopped ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-08-05 21:09:08 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top1" , "--restart" , "always" , "busybox:latest" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "run top1: %v" , out )
2015-08-05 21:09:08 +00:00
out , err = s . d . Cmd ( "run" , "-d" , "--name" , "top2" , "--restart" , "unless-stopped" , "busybox:latest" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "run top2: %v" , out )
2015-08-05 21:09:08 +00:00
2017-11-01 06:15:02 +00:00
out , err = s . d . Cmd ( "run" , "-d" , "--name" , "exit" , "--restart" , "unless-stopped" , "busybox:latest" , "false" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "run exit: %v" , out )
2017-11-01 06:15:02 +00:00
2015-08-05 21:09:08 +00:00
testRun := func ( m map [ string ] bool , prefix string ) {
var format string
for name , shouldRun := range m {
out , err := s . d . Cmd ( "ps" )
c . Assert ( err , check . IsNil , check . Commentf ( "run ps: %v" , out ) )
if shouldRun {
format = "%scontainer %q is not running"
} else {
format = "%scontainer %q is running"
}
c . Assert ( strings . Contains ( out , name ) , check . Equals , shouldRun , check . Commentf ( format , prefix , name ) )
}
}
// both running
2017-11-01 06:15:02 +00:00
testRun ( map [ string ] bool { "top1" : true , "top2" : true , "exit" : true } , "" )
out , err = s . d . Cmd ( "stop" , "exit" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-05 21:09:08 +00:00
out , err = s . d . Cmd ( "stop" , "top1" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-05 21:09:08 +00:00
out , err = s . d . Cmd ( "stop" , "top2" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-05 21:09:08 +00:00
// both stopped
2017-11-01 06:15:02 +00:00
testRun ( map [ string ] bool { "top1" : false , "top2" : false , "exit" : false } , "" )
2015-08-05 21:09:08 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-08-05 21:09:08 +00:00
// restart=always running
2017-11-01 06:15:02 +00:00
testRun ( map [ string ] bool { "top1" : true , "top2" : false , "exit" : false } , "After daemon restart: " )
2015-08-05 21:09:08 +00:00
out , err = s . d . Cmd ( "start" , "top2" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "start top2: %v" , out )
2015-08-05 21:09:08 +00:00
2017-11-01 06:15:02 +00:00
out , err = s . d . Cmd ( "start" , "exit" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "start exit: %v" , out )
2017-11-01 06:15:02 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-08-05 21:09:08 +00:00
// both running
2017-11-01 06:15:02 +00:00
testRun ( map [ string ] bool { "top1" : true , "top2" : true , "exit" : true } , "After second daemon restart: " )
2015-08-05 21:09:08 +00:00
}
2016-03-22 15:46:40 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartOnFailure ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2016-03-22 15:46:40 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "test1" , "--restart" , "on-failure:3" , "busybox:latest" , "false" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "run top1: %v" , out )
2016-03-22 15:46:40 +00:00
// wait test1 to stop
2016-12-09 09:17:53 +00:00
hostArgs := [ ] string { "--host" , s . d . Sock ( ) }
2016-03-22 15:46:40 +00:00
err = waitInspectWithArgs ( "test1" , "{{.State.Running}} {{.State.Restarting}}" , "false false" , 10 * time . Second , hostArgs ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "test1 should exit but not" )
2016-03-22 15:46:40 +00:00
// record last start time
out , err = s . d . Cmd ( "inspect" , "-f={{.State.StartedAt}}" , "test1" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "out: %v" , out )
2016-03-22 15:46:40 +00:00
lastStartTime := out
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2016-03-22 15:46:40 +00:00
// test1 shouldn't restart at all
err = waitInspectWithArgs ( "test1" , "{{.State.Running}} {{.State.Restarting}}" , "false false" , 0 , hostArgs ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "test1 should exit but not" )
2016-03-22 15:46:40 +00:00
// make sure test1 isn't restarted when daemon restart
// if "StartAt" time updates, means test1 was once restarted.
out , err = s . d . Cmd ( "inspect" , "-f={{.State.StartedAt}}" , "test1" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "out: %v" , out )
assert . Equal ( c , out , lastStartTime , "test1 shouldn't start after daemon restarts" )
2016-03-22 15:46:40 +00:00
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonStartIptablesFalse ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--iptables=false" )
2014-10-16 18:39:22 +00:00
}
2014-10-05 04:21:59 +00:00
2016-02-04 15:05:41 +00:00
// Make sure we cannot shrink base device at daemon restart.
func ( s * DockerDaemonSuite ) TestDaemonRestartWithInvalidBasesize ( c * check . C ) {
testRequires ( c , Devicemapper )
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
2016-02-04 15:05:41 +00:00
2017-08-22 21:07:52 +00:00
oldBasesizeBytes := getBaseDeviceSize ( c , s . d )
2016-02-04 15:05:41 +00:00
var newBasesizeBytes int64 = 1073741824 //1GB in bytes
if newBasesizeBytes < oldBasesizeBytes {
2016-12-09 22:20:14 +00:00
err := s . d . RestartWithError ( "--storage-opt" , fmt . Sprintf ( "dm.basesize=%d" , newBasesizeBytes ) )
2017-03-29 09:32:25 +00:00
c . Assert ( err , check . NotNil , check . Commentf ( "daemon should not have started as new base device size is less than existing base device size: %v" , err ) )
// 'err != nil' is expected behaviour, no new daemon started,
// so no need to stop daemon.
if err != nil {
return
}
2016-02-04 15:05:41 +00:00
}
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2016-02-04 15:05:41 +00:00
}
// Make sure we can grow base device at daemon restart.
func ( s * DockerDaemonSuite ) TestDaemonRestartWithIncreasedBasesize ( c * check . C ) {
testRequires ( c , Devicemapper )
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
2016-02-04 15:05:41 +00:00
2017-08-22 21:07:52 +00:00
oldBasesizeBytes := getBaseDeviceSize ( c , s . d )
2016-02-04 15:05:41 +00:00
var newBasesizeBytes int64 = 53687091200 //50GB in bytes
if newBasesizeBytes < oldBasesizeBytes {
c . Skip ( fmt . Sprintf ( "New base device size (%v) must be greater than (%s)" , units . HumanSize ( float64 ( newBasesizeBytes ) ) , units . HumanSize ( float64 ( oldBasesizeBytes ) ) ) )
}
2016-12-09 22:20:14 +00:00
err := s . d . RestartWithError ( "--storage-opt" , fmt . Sprintf ( "dm.basesize=%d" , newBasesizeBytes ) )
2016-02-04 15:05:41 +00:00
c . Assert ( err , check . IsNil , check . Commentf ( "we should have been able to start the daemon with increased base device size: %v" , err ) )
2017-08-22 21:07:52 +00:00
basesizeAfterRestart := getBaseDeviceSize ( c , s . d )
2016-02-04 15:05:41 +00:00
newBasesize , err := convertBasesize ( newBasesizeBytes )
c . Assert ( err , check . IsNil , check . Commentf ( "Error in converting base device size: %v" , err ) )
c . Assert ( newBasesize , check . Equals , basesizeAfterRestart , check . Commentf ( "Basesize passed is not equal to Basesize set" ) )
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2016-02-04 15:05:41 +00:00
}
2017-08-22 21:07:52 +00:00
func getBaseDeviceSize ( c * check . C , d * daemon . Daemon ) int64 {
info := d . Info ( c )
for _ , statusLine := range info . DriverStatus {
key , value := statusLine [ 0 ] , statusLine [ 1 ]
if key == "Base Device Size" {
return parseDeviceSize ( c , value )
}
}
c . Fatal ( "failed to parse Base Device Size from info" )
return int64 ( 0 )
}
func parseDeviceSize ( c * check . C , raw string ) int64 {
size , err := units . RAMInBytes ( strings . TrimSpace ( raw ) )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-08-22 21:07:52 +00:00
return size
}
2016-12-28 22:00:32 +00:00
func convertBasesize ( basesizeBytes int64 ) ( int64 , error ) {
basesize := units . HumanSize ( float64 ( basesizeBytes ) )
basesize = strings . Trim ( basesize , " " ) [ : len ( basesize ) - 3 ]
basesizeFloat , err := strconv . ParseFloat ( strings . Trim ( basesize , " " ) , 64 )
if err != nil {
return 0 , err
}
return int64 ( basesizeFloat ) * 1024 * 1024 * 1024 , nil
}
2016-02-04 15:05:41 +00:00
2014-10-05 04:21:59 +00:00
// Issue #8444: If docker0 bridge is modified (intentionally or unintentionally) and
// no longer has an IP associated, we should gracefully handle that case and associate
// an IP with it rather than fail daemon start
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonStartBridgeWithoutIPAssociation ( c * check . C ) {
2014-10-05 04:21:59 +00:00
// rather than depending on brctl commands to verify docker0 is created and up
// let's start the daemon and stop it, and then make a modification to run the
// actual test
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
s . d . Stop ( c )
2014-10-05 04:21:59 +00:00
// now we will remove the ip from docker0 and then try starting the daemon
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( "ip" , "addr" , "flush" , "dev" , "docker0" ) . Assert ( c , icmd . Success )
2014-10-05 04:21:59 +00:00
2016-12-09 22:20:14 +00:00
if err := s . d . StartWithError ( ) ; err != nil {
2014-10-05 04:21:59 +00:00
warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix"
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Could not start daemon when docker0 has no IP address: %v\n%s" , err , warning )
2014-10-05 04:21:59 +00:00
}
}
2014-09-30 19:18:26 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIptablesClean ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2014-09-30 19:18:26 +00:00
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top" , "-p" , "80" , "busybox:latest" , "top" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Could not run top: %s, %v" , out , err )
2014-09-30 19:18:26 +00:00
}
ipTablesSearchString := "tcp dpt:80"
2017-01-05 11:38:34 +00:00
// get output from iptables with container running
verifyIPTablesContains ( c , ipTablesSearchString )
2014-09-30 19:18:26 +00:00
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2014-09-30 19:18:26 +00:00
// get output from iptables after restart
2017-01-05 11:38:34 +00:00
verifyIPTablesDoesNotContains ( c , ipTablesSearchString )
2014-09-30 19:18:26 +00:00
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIptablesCreate ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2014-09-30 19:18:26 +00:00
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top" , "--restart=always" , "-p" , "80" , "busybox:latest" , "top" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Could not run top: %s, %v" , out , err )
2014-09-30 19:18:26 +00:00
}
// get output from iptables with container running
ipTablesSearchString := "tcp dpt:80"
2017-01-05 11:38:34 +00:00
verifyIPTablesContains ( c , ipTablesSearchString )
2014-09-30 19:18:26 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2014-09-30 19:18:26 +00:00
// make sure the container is not running
2016-06-23 16:24:28 +00:00
runningOut , err := s . d . Cmd ( "inspect" , "--format={{.State.Running}}" , "top" )
2014-09-30 19:18:26 +00:00
if err != nil {
2017-01-05 11:38:34 +00:00
c . Fatalf ( "Could not inspect on container: %s, %v" , runningOut , err )
2014-09-30 19:18:26 +00:00
}
if strings . TrimSpace ( runningOut ) != "true" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Container should have been restarted after daemon restart. Status running should have been true but was: %q" , strings . TrimSpace ( runningOut ) )
2014-09-30 19:18:26 +00:00
}
// get output from iptables after restart
2017-01-05 11:38:34 +00:00
verifyIPTablesContains ( c , ipTablesSearchString )
}
func verifyIPTablesContains ( c * check . C , ipTablesSearchString string ) {
result := icmd . RunCommand ( "iptables" , "-nvL" )
result . Assert ( c , icmd . Success )
if ! strings . Contains ( result . Combined ( ) , ipTablesSearchString ) {
c . Fatalf ( "iptables output should have contained %q, but was %q" , ipTablesSearchString , result . Combined ( ) )
2014-09-30 19:18:26 +00:00
}
2017-01-05 11:38:34 +00:00
}
2014-09-30 19:18:26 +00:00
2017-01-05 11:38:34 +00:00
func verifyIPTablesDoesNotContains ( c * check . C , ipTablesSearchString string ) {
result := icmd . RunCommand ( "iptables" , "-nvL" )
result . Assert ( c , icmd . Success )
if strings . Contains ( result . Combined ( ) , ipTablesSearchString ) {
c . Fatalf ( "iptables output should not have contained %q, but was %q" , ipTablesSearchString , result . Combined ( ) )
2014-09-30 19:18:26 +00:00
}
}
2014-10-01 13:07:24 +00:00
2015-04-28 11:50:20 +00:00
// TestDaemonIPv6Enabled checks that when the daemon is started with --ipv6=true that the docker0 bridge
// has the fe80::1 address and that a container is assigned a link-local address
2016-08-30 21:25:16 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6Enabled ( c * check . C ) {
2015-04-28 11:50:20 +00:00
testRequires ( c , IPv6 )
2016-08-03 16:20:46 +00:00
setupV6 ( c )
defer teardownV6 ( c )
2015-04-28 11:50:20 +00:00
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--ipv6" )
2015-04-28 11:50:20 +00:00
iface , err := net . InterfaceByName ( "docker0" )
if err != nil {
c . Fatalf ( "Error getting docker0 interface: %v" , err )
}
addrs , err := iface . Addrs ( )
if err != nil {
c . Fatalf ( "Error getting addresses for docker0 interface: %v" , err )
}
var found bool
expected := "fe80::1/64"
for i := range addrs {
if addrs [ i ] . String ( ) == expected {
found = true
2016-07-26 14:03:14 +00:00
break
2015-04-28 11:50:20 +00:00
}
}
if ! found {
c . Fatalf ( "Bridge does not have an IPv6 Address" )
}
2016-08-30 21:25:16 +00:00
if out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "busybox:latest" ) ; err != nil {
2015-04-28 11:50:20 +00:00
c . Fatalf ( "Could not run container: %s, %v" , out , err )
}
2016-08-30 21:25:16 +00:00
out , err := s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'" , "ipv6test" )
2015-04-28 11:50:20 +00:00
if err != nil {
c . Fatalf ( "Error inspecting container: %s, %v" , out , err )
}
2018-08-14 07:51:22 +00:00
out = strings . Trim ( out , " \r\n'" )
2015-04-28 11:50:20 +00:00
if ip := net . ParseIP ( out ) ; ip == nil {
c . Fatalf ( "Container should have a link-local IPv6 address" )
}
2016-08-30 21:25:16 +00:00
out , err = s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'" , "ipv6test" )
2015-04-28 11:50:20 +00:00
if err != nil {
c . Fatalf ( "Error inspecting container: %s, %v" , out , err )
}
2018-08-14 07:51:22 +00:00
out = strings . Trim ( out , " \r\n'" )
2015-04-28 11:50:20 +00:00
if ip := net . ParseIP ( out ) ; ip != nil {
c . Fatalf ( "Container should not have a global IPv6 address: %v" , out )
}
}
// TestDaemonIPv6FixedCIDR checks that when the daemon is started with --ipv6=true and a fixed CIDR
// that running containers are given a link-local and global IPv6 address
2016-01-25 09:23:21 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6FixedCIDR ( c * check . C ) {
2016-02-11 03:27:02 +00:00
// IPv6 setup is messing with local bridge address.
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon )
2017-01-09 19:40:27 +00:00
// Delete the docker0 bridge if its left around from previous daemon. It has to be recreated with
// ipv6 enabled
deleteInterface ( c , "docker0" )
2015-04-28 11:50:20 +00:00
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--ipv6" , "--fixed-cidr-v6=2001:db8:2::/64" , "--default-gateway-v6=2001:db8:2::100" )
2015-04-28 11:50:20 +00:00
2016-01-25 09:23:21 +00:00
out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "busybox:latest" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Could not run container: %s, %v" , out , err )
2015-04-28 11:50:20 +00:00
2016-08-03 16:20:46 +00:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}" , "ipv6test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2018-08-14 07:51:22 +00:00
out = strings . Trim ( out , " \r\n'" )
2015-04-28 11:50:20 +00:00
2016-01-25 09:23:21 +00:00
ip := net . ParseIP ( out )
c . Assert ( ip , checker . NotNil , check . Commentf ( "Container should have a global IPv6 address" ) )
2015-12-30 22:51:51 +00:00
2016-08-03 16:20:46 +00:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.IPv6Gateway}}" , "ipv6test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-01-25 09:23:21 +00:00
c . Assert ( strings . Trim ( out , " \r\n'" ) , checker . Equals , "2001:db8:2::100" , check . Commentf ( "Container should have a global IPv6 gateway" ) )
2015-04-28 11:50:20 +00:00
}
2015-11-11 05:14:05 +00:00
// TestDaemonIPv6FixedCIDRAndMac checks that when the daemon is started with ipv6 fixed CIDR
2016-05-08 01:36:10 +00:00
// the running containers are given an IPv6 address derived from the MAC address and the ipv6 fixed CIDR
2016-01-25 09:23:21 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6FixedCIDRAndMac ( c * check . C ) {
2016-02-11 03:27:02 +00:00
// IPv6 setup is messing with local bridge address.
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon )
2017-01-09 19:40:27 +00:00
// Delete the docker0 bridge if its left around from previous daemon. It has to be recreated with
// ipv6 enabled
deleteInterface ( c , "docker0" )
2015-11-11 05:14:05 +00:00
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--ipv6" , "--fixed-cidr-v6=2001:db8:1::/64" )
2015-11-11 05:14:05 +00:00
2018-08-14 07:51:22 +00:00
out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "--mac-address" , "AA:BB:CC:DD:EE:FF" , "busybox" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-11-11 05:14:05 +00:00
2018-08-14 07:51:22 +00:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}" , "ipv6test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-11-11 05:14:05 +00:00
c . Assert ( strings . Trim ( out , " \r\n'" ) , checker . Equals , "2001:db8:1::aabb:ccdd:eeff" )
}
2017-04-07 23:57:53 +00:00
// TestDaemonIPv6HostMode checks that when the running a container with
// network=host the host ipv6 addresses are not removed
func ( s * DockerDaemonSuite ) TestDaemonIPv6HostMode ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon )
2017-04-07 23:57:53 +00:00
deleteInterface ( c , "docker0" )
s . d . StartWithBusybox ( c , "--ipv6" , "--fixed-cidr-v6=2001:db8:2::/64" )
out , err := s . d . Cmd ( "run" , "-itd" , "--name=hostcnt" , "--network=host" , "busybox:latest" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Could not run container: %s, %v" , out , err )
2017-04-07 23:57:53 +00:00
out , err = s . d . Cmd ( "exec" , "hostcnt" , "ip" , "-6" , "addr" , "show" , "docker0" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2018-01-13 12:35:10 +00:00
c . Assert ( strings . Trim ( out , " \r\n'" ) , checker . Contains , "2001:db8:2::1" )
2017-04-07 23:57:53 +00:00
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelWrong ( c * check . C ) {
2016-12-09 22:20:14 +00:00
c . Assert ( s . d . StartWithError ( "--log-level=bogus" ) , check . NotNil , check . Commentf ( "Daemon shouldn't start with wrong log level" ) )
2015-04-26 02:47:42 +00:00
}
2014-10-01 13:07:24 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelDebug ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--log-level=debug" )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-03-11 17:43:56 +00:00
if ! strings . Contains ( string ( content ) , ` level=debug ` ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( ` Missing level="debug" in log file:\n%s ` , string ( content ) )
2014-10-01 13:07:24 +00:00
}
2015-04-26 02:47:42 +00:00
}
2014-10-01 13:07:24 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelFatal ( c * check . C ) {
// we creating new daemons to create new logFile
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--log-level=fatal" )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-03-11 17:43:56 +00:00
if strings . Contains ( string ( content ) , ` level=debug ` ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( ` Should not have level="debug" in log file:\n%s ` , string ( content ) )
2014-10-01 13:07:24 +00:00
}
2015-04-26 02:47:42 +00:00
}
2014-10-01 13:07:24 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonFlagD ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "-D" )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-05-14 17:07:21 +00:00
if ! strings . Contains ( string ( content ) , ` level=debug ` ) {
c . Fatalf ( ` Should have level="debug" in log file using -D:\n%s ` , string ( content ) )
2014-10-01 13:07:24 +00:00
}
2015-04-26 02:47:42 +00:00
}
2014-10-01 13:07:24 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonFlagDebug ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--debug" )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-05-14 17:07:21 +00:00
if ! strings . Contains ( string ( content ) , ` level=debug ` ) {
c . Fatalf ( ` Should have level="debug" in log file using --debug:\n%s ` , string ( content ) )
2014-10-01 13:07:24 +00:00
}
2015-04-26 02:47:42 +00:00
}
2014-10-01 13:07:24 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonFlagDebugLogLevelFatal ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--debug" , "--log-level=fatal" )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-05-14 17:07:21 +00:00
if ! strings . Contains ( string ( content ) , ` level=debug ` ) {
c . Fatalf ( ` Should have level="debug" in log file when using both --debug and --log-level=fatal:\n%s ` , string ( content ) )
2014-10-01 13:07:24 +00:00
}
}
2014-11-15 04:38:02 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonAllocatesListeningPort ( c * check . C ) {
2014-11-15 04:38:02 +00:00
listeningPorts := [ ] [ ] string {
{ "0.0.0.0" , "0.0.0.0" , "5678" } ,
{ "127.0.0.1" , "127.0.0.1" , "1234" } ,
{ "localhost" , "127.0.0.1" , "1235" } ,
}
2015-05-01 14:00:43 +00:00
cmdArgs := make ( [ ] string , 0 , len ( listeningPorts ) * 2 )
2014-11-15 04:38:02 +00:00
for _ , hostDirective := range listeningPorts {
cmdArgs = append ( cmdArgs , "--host" , fmt . Sprintf ( "tcp://%s:%s" , hostDirective [ 0 ] , hostDirective [ 2 ] ) )
}
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , cmdArgs ... )
2014-11-15 04:38:02 +00:00
for _ , hostDirective := range listeningPorts {
2015-04-26 02:47:42 +00:00
output , err := s . d . Cmd ( "run" , "-p" , fmt . Sprintf ( "%s:%s:80" , hostDirective [ 1 ] , hostDirective [ 2 ] ) , "busybox" , "true" )
2014-11-15 04:38:02 +00:00
if err == nil {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Container should not start, expected port already allocated error: %q" , output )
2014-11-15 04:38:02 +00:00
} else if ! strings . Contains ( output , "port is already allocated" ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Expected port is already allocated error: %q" , output )
2014-11-15 04:38:02 +00:00
}
}
}
2015-01-16 19:48:25 +00:00
2015-03-11 14:33:06 +00:00
// GH#11320 - verify that the daemon exits on failure properly
// Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
// to get a daemon init failure; no other tests for -b/--bip conflict are therefore required
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonExitOnFailure ( c * check . C ) {
2015-03-11 14:33:06 +00:00
//attempt to start daemon with incorrect flags (we know -b and --bip conflict)
2016-12-09 22:20:14 +00:00
if err := s . d . StartWithError ( "--bridge" , "nosuchbridge" , "--bip" , "1.1.1.1" ) ; err != nil {
2015-03-11 14:33:06 +00:00
//verify we got the right error
2016-03-25 21:42:30 +00:00
if ! strings . Contains ( err . Error ( ) , "Daemon exited" ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Expected daemon not to start, got %v" , err )
2015-03-11 14:33:06 +00:00
}
// look in the log and make sure we got the message that daemon is shutting down
2018-08-22 14:00:22 +00:00
icmd . RunCommand ( "grep" , "failed to start daemon" , s . d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-03-11 14:33:06 +00:00
} else {
//if we didn't get an error and the daemon is running, this is a failure
2015-04-18 16:46:47 +00:00
c . Fatal ( "Conflicting options should cause the daemon to error out with a failure" )
2015-03-11 14:33:06 +00:00
}
}
2015-04-27 20:16:33 +00:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeExternal ( c * check . C ) {
d := s . d
2016-12-09 22:20:14 +00:00
err := d . StartWithError ( "--bridge" , "nosuchbridge" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , ` --bridge option with an invalid bridge should cause the daemon to fail ` )
2016-12-09 22:20:14 +00:00
defer d . Restart ( c )
2015-04-27 20:16:33 +00:00
bridgeName := "external-bridge"
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
_ , bridgeIPNet , _ := net . ParseCIDR ( bridgeIP )
2015-04-27 20:16:33 +00:00
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 18:41:13 +00:00
defer deleteInterface ( c , bridgeName )
2015-04-27 20:16:33 +00:00
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bridge" , bridgeName )
2015-04-27 20:16:33 +00:00
ipTablesSearchString := bridgeIPNet . String ( )
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-27 20:16:33 +00:00
2018-08-14 07:51:22 +00:00
out , err := d . Cmd ( "run" , "-d" , "--name" , "ExtContainer" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-27 20:16:33 +00:00
2018-04-11 13:52:13 +00:00
containerIP := d . FindContainerIP ( c , "ExtContainer" )
2015-07-22 12:59:24 +00:00
ip := net . ParseIP ( containerIP )
2019-04-04 13:23:19 +00:00
assert . Assert ( c , bridgeIPNet . Contains ( ip ) , "Container IP-Address must be in the same subnet range : %s" , containerIP )
2015-04-27 20:16:33 +00:00
}
2016-09-27 20:16:00 +00:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeNone ( c * check . C ) {
// start with bridge none
d := s . d
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bridge" , "none" )
defer d . Restart ( c )
2016-09-27 20:16:00 +00:00
// verify docker0 iface is not there
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "ifconfig" , "docker0" ) . Assert ( c , icmd . Expected {
ExitCode : 1 ,
Error : "exit status 1" ,
Err : "Device not found" ,
} )
2016-09-27 20:16:00 +00:00
// verify default "bridge" network is not there
2017-01-05 11:38:34 +00:00
out , err := d . Cmd ( "network" , "inspect" , "bridge" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , ` "bridge" network should not be present if daemon started with --bridge=none ` )
assert . Assert ( c , strings . Contains ( out , "No such network" ) )
2016-09-27 20:16:00 +00:00
}
2017-01-05 11:38:34 +00:00
func createInterface ( c * check . C , ifType string , ifName string , ipNet string ) {
icmd . RunCommand ( "ip" , "link" , "add" , "name" , ifName , "type" , ifType ) . Assert ( c , icmd . Success )
icmd . RunCommand ( "ifconfig" , ifName , ipNet , "up" ) . Assert ( c , icmd . Success )
2015-04-28 23:17:00 +00:00
}
2015-04-29 18:41:13 +00:00
func deleteInterface ( c * check . C , ifName string ) {
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "ip" , "link" , "delete" , ifName ) . Assert ( c , icmd . Success )
icmd . RunCommand ( "iptables" , "-t" , "nat" , "--flush" ) . Assert ( c , icmd . Success )
icmd . RunCommand ( "iptables" , "--flush" ) . Assert ( c , icmd . Success )
2015-04-28 03:36:40 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonBridgeIP ( c * check . C ) {
// TestDaemonBridgeIP Steps
// 1. Delete the existing docker0 Bridge
// 2. Set --bip daemon configuration and start the new Docker Daemon
// 3. Check if the bip config has taken effect using ifconfig and iptables commands
// 4. Launch a Container and make sure the IP-Address is in the expected subnet
// 5. Delete the docker0 Bridge
2015-08-07 22:24:18 +00:00
// 6. Restart the Docker Daemon (via deferred action)
2015-04-28 03:36:40 +00:00
// This Restart takes care of bringing docker0 interface back to auto-assigned IP
defaultNetworkBridge := "docker0"
2015-04-28 17:26:59 +00:00
deleteInterface ( c , defaultNetworkBridge )
2015-04-28 03:36:40 +00:00
d := s . d
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
ip , bridgeIPNet , _ := net . ParseCIDR ( bridgeIP )
2015-04-28 03:36:40 +00:00
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bip" , bridgeIP )
defer d . Restart ( c )
2015-04-28 03:36:40 +00:00
ifconfigSearchString := ip . String ( )
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( "ifconfig" , defaultNetworkBridge ) . Assert ( c , icmd . Expected {
Out : ifconfigSearchString ,
} )
2015-04-28 03:36:40 +00:00
ipTablesSearchString := bridgeIPNet . String ( )
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-28 03:36:40 +00:00
2018-08-14 07:51:22 +00:00
out , err := d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-28 03:36:40 +00:00
2018-04-11 13:52:13 +00:00
containerIP := d . FindContainerIP ( c , "test" )
2015-07-22 12:59:24 +00:00
ip = net . ParseIP ( containerIP )
2015-04-28 03:36:40 +00:00
c . Assert ( bridgeIPNet . Contains ( ip ) , check . Equals , true ,
check . Commentf ( "Container IP-Address must be in the same subnet range : %s" ,
2015-07-22 12:59:24 +00:00
containerIP ) )
2015-04-28 17:26:59 +00:00
deleteInterface ( c , defaultNetworkBridge )
2015-04-28 03:36:40 +00:00
}
2015-04-16 07:09:36 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithBridgeIPChange ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
defer s . d . Restart ( c )
s . d . Stop ( c )
2015-04-16 07:09:36 +00:00
// now we will change the docker0's IP and then try starting the daemon
bridgeIP := "192.169.100.1/24"
_ , bridgeIPNet , _ := net . ParseCIDR ( bridgeIP )
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( "ifconfig" , "docker0" , bridgeIP ) . Assert ( c , icmd . Success )
2015-04-16 07:09:36 +00:00
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--bip" , bridgeIP )
2015-04-16 07:09:36 +00:00
//check if the iptables contains new bridgeIP MASQUERADE rule
ipTablesSearchString := bridgeIPNet . String ( )
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-16 07:09:36 +00:00
}
2015-04-28 15:55:04 +00:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCidr ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
2015-04-28 15:55:04 +00:00
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 18:41:13 +00:00
defer deleteInterface ( c , bridgeName )
2015-04-28 15:55:04 +00:00
2015-04-28 23:17:00 +00:00
args := [ ] string { "--bridge" , bridgeName , "--fixed-cidr" , "192.169.1.0/30" }
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , args ... )
defer d . Restart ( c )
2015-04-28 15:55:04 +00:00
for i := 0 ; i < 4 ; i ++ {
cName := "Container" + strconv . Itoa ( i )
out , err := d . Cmd ( "run" , "-d" , "--name" , cName , "busybox" , "top" )
if err != nil {
2019-04-04 13:23:19 +00:00
assert . Assert ( c , strings . Contains ( out , "no available IPv4 addresses" ) , "Could not run a Container : %s %s" , err . Error ( ) , out )
2015-04-28 15:55:04 +00:00
}
}
2015-04-28 17:26:59 +00:00
}
2015-11-09 23:30:30 +00:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCidr2 ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
bridgeIP := "10.2.2.1/16"
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-11-09 23:30:30 +00:00
defer deleteInterface ( c , bridgeName )
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bip" , bridgeIP , "--fixed-cidr" , "10.2.2.0/24" )
defer s . d . Restart ( c )
2015-11-09 23:30:30 +00:00
2017-01-05 11:38:34 +00:00
out , err := d . Cmd ( "run" , "-d" , "--name" , "bb" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-11-09 23:30:30 +00:00
defer d . Cmd ( "stop" , "bb" )
out , err = d . Cmd ( "exec" , "bb" , "/bin/sh" , "-c" , "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
assert . Equal ( c , out , "10.2.2.0\n" )
2015-11-09 23:30:30 +00:00
out , err = d . Cmd ( "run" , "--rm" , "busybox" , "/bin/sh" , "-c" , "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
assert . Equal ( c , out , "10.2.2.2\n" )
2015-11-09 23:30:30 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCIDREqualBridgeNetwork ( c * check . C ) {
2015-10-22 20:51:52 +00:00
d := s . d
bridgeName := "external-bridge"
bridgeIP := "172.27.42.1/16"
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-10-22 20:51:52 +00:00
defer deleteInterface ( c , bridgeName )
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--fixed-cidr" , bridgeIP )
defer s . d . Restart ( c )
2015-10-22 20:51:52 +00:00
2017-01-05 11:38:34 +00:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-10-22 20:51:52 +00:00
cid1 := strings . TrimSpace ( out )
defer d . Cmd ( "stop" , cid1 )
}
2015-06-05 05:57:59 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDefaultGatewayIPv4Implicit ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
d := s . d
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1"
bridgeIPNet := fmt . Sprintf ( "%s/24" , bridgeIP )
2015-06-05 05:57:59 +00:00
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bip" , bridgeIPNet )
defer d . Restart ( c )
2015-06-05 05:57:59 +00:00
2015-07-22 12:59:24 +00:00
expectedMessage := fmt . Sprintf ( "default via %s dev" , bridgeIP )
2015-06-05 05:57:59 +00:00
out , err := d . Cmd ( "run" , "busybox" , "ip" , "-4" , "route" , "list" , "0/0" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-06-05 05:57:59 +00:00
c . Assert ( strings . Contains ( out , expectedMessage ) , check . Equals , true ,
check . Commentf ( "Implicit default gateway should be bridge IP %s, but default route was '%s'" ,
2015-07-22 12:59:24 +00:00
bridgeIP , strings . TrimSpace ( out ) ) )
2015-06-05 05:57:59 +00:00
deleteInterface ( c , defaultNetworkBridge )
}
func ( s * DockerDaemonSuite ) TestDaemonDefaultGatewayIPv4Explicit ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
d := s . d
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1"
bridgeIPNet := fmt . Sprintf ( "%s/24" , bridgeIP )
gatewayIP := "192.169.1.254"
2015-06-05 05:57:59 +00:00
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , "--bip" , bridgeIPNet , "--default-gateway" , gatewayIP )
defer d . Restart ( c )
2015-06-05 05:57:59 +00:00
2015-07-22 12:59:24 +00:00
expectedMessage := fmt . Sprintf ( "default via %s dev" , gatewayIP )
2015-06-05 05:57:59 +00:00
out , err := d . Cmd ( "run" , "busybox" , "ip" , "-4" , "route" , "list" , "0/0" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-06-05 05:57:59 +00:00
c . Assert ( strings . Contains ( out , expectedMessage ) , check . Equals , true ,
check . Commentf ( "Explicit default gateway should be %s, but default route was '%s'" ,
2015-07-22 12:59:24 +00:00
gatewayIP , strings . TrimSpace ( out ) ) )
2015-06-05 05:57:59 +00:00
deleteInterface ( c , defaultNetworkBridge )
}
2015-07-31 00:29:02 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainerSubnet ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
// Program a custom default gateway outside of the container subnet, daemon should accept it and start
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--bip" , "172.16.0.10/16" , "--fixed-cidr" , "172.16.1.0/24" , "--default-gateway" , "172.16.0.254" )
2015-07-31 00:29:02 +00:00
deleteInterface ( c , defaultNetworkBridge )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-07-31 00:29:02 +00:00
}
2015-10-21 02:17:18 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDefaultNetworkInvalidClusterConfig ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , DaemonIsLinux , testEnv . IsLocalDaemon )
2015-10-21 02:17:18 +00:00
// Start daemon without docker0 bridge
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
discoveryBackend := "consul://consuladdr:consulport/some/path"
2016-12-09 22:20:14 +00:00
s . d . Start ( c , fmt . Sprintf ( "--cluster-store=%s" , discoveryBackend ) )
2015-10-21 02:17:18 +00:00
// Start daemon with docker0 bridge
2016-08-04 16:57:34 +00:00
result := icmd . RunCommand ( "ifconfig" , defaultNetworkBridge )
2017-08-23 21:01:29 +00:00
result . Assert ( c , icmd . Success )
2015-10-21 02:17:18 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c , fmt . Sprintf ( "--cluster-store=%s" , discoveryBackend ) )
2015-10-21 02:17:18 +00:00
}
2015-04-28 17:26:59 +00:00
func ( s * DockerDaemonSuite ) TestDaemonIP ( c * check . C ) {
d := s . d
ipStr := "192.170.1.1/24"
ip , _ , _ := net . ParseCIDR ( ipStr )
args := [ ] string { "--ip" , ip . String ( ) }
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c , args ... )
defer d . Restart ( c )
2015-04-28 17:26:59 +00:00
out , err := d . Cmd ( "run" , "-d" , "-p" , "8000:8000" , "busybox" , "top" )
2015-04-28 23:17:00 +00:00
c . Assert ( err , check . NotNil ,
2015-04-28 17:26:59 +00:00
check . Commentf ( "Running a container must fail with an invalid --ip option" ) )
2015-09-16 16:55:14 +00:00
c . Assert ( strings . Contains ( out , "Error starting userland proxy" ) , check . Equals , true )
2015-04-28 17:26:59 +00:00
ifName := "dummy"
2017-01-05 11:38:34 +00:00
createInterface ( c , "dummy" , ifName , ipStr )
2015-04-29 18:41:13 +00:00
defer deleteInterface ( c , ifName )
2015-04-28 17:26:59 +00:00
_ , err = d . Cmd ( "run" , "-d" , "-p" , "8000:8000" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-28 17:26:59 +00:00
2017-01-05 11:38:34 +00:00
result := icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" )
result . Assert ( c , icmd . Success )
2015-04-28 17:26:59 +00:00
regex := fmt . Sprintf ( "DNAT.*%s.*dpt:8000" , ip . String ( ) )
2017-01-05 11:38:34 +00:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 17:26:59 +00:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 11:38:34 +00:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 15:55:04 +00:00
}
2015-04-28 23:17:00 +00:00
func ( s * DockerDaemonSuite ) TestDaemonICCPing ( c * check . C ) {
2016-02-27 00:53:35 +00:00
testRequires ( c , bridgeNfIptables )
2015-04-28 23:17:00 +00:00
d := s . d
bridgeName := "external-bridge"
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 18:41:13 +00:00
defer deleteInterface ( c , bridgeName )
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
2016-12-09 22:20:14 +00:00
defer d . Restart ( c )
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
result := icmd . RunCommand ( "iptables" , "-nvL" , "FORWARD" )
result . Assert ( c , icmd . Success )
2015-04-28 23:17:00 +00:00
regex := fmt . Sprintf ( "DROP.*all.*%s.*%s" , bridgeName , bridgeName )
2017-01-05 11:38:34 +00:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 23:17:00 +00:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 11:38:34 +00:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 23:17:00 +00:00
// Pinging another container must fail with --icc=false
pingContainers ( c , d , true )
ipStr := "192.171.1.1/24"
ip , _ , _ := net . ParseCIDR ( ipStr )
ifName := "icc-dummy"
createInterface ( c , "dummy" , ifName , ipStr )
// But, Pinging external or a Host interface must succeed
pingCmd := fmt . Sprintf ( "ping -c 1 %s -W 1" , ip . String ( ) )
2016-07-22 16:14:05 +00:00
runArgs := [ ] string { "run" , "--rm" , "busybox" , "sh" , "-c" , pingCmd }
2018-08-14 07:51:22 +00:00
out , err := d . Cmd ( runArgs ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-28 23:17:00 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonICCLinkExpose ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 18:41:13 +00:00
defer deleteInterface ( c , bridgeName )
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
2016-12-09 22:20:14 +00:00
defer d . Restart ( c )
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
result := icmd . RunCommand ( "iptables" , "-nvL" , "FORWARD" )
result . Assert ( c , icmd . Success )
2015-04-28 23:17:00 +00:00
regex := fmt . Sprintf ( "DROP.*all.*%s.*%s" , bridgeName , bridgeName )
2017-01-05 11:38:34 +00:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 23:17:00 +00:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 11:38:34 +00:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 23:17:00 +00:00
2017-01-05 11:38:34 +00:00
out , err := d . Cmd ( "run" , "-d" , "--expose" , "4567" , "--name" , "icc1" , "busybox" , "nc" , "-l" , "-p" , "4567" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-28 23:17:00 +00:00
out , err = d . Cmd ( "run" , "--link" , "icc1:icc1" , "busybox" , "nc" , "icc1" , "4567" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-04-28 23:17:00 +00:00
}
2015-05-06 22:39:29 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink ( c * check . C ) {
bridgeName := "external-bridge"
2015-07-22 12:59:24 +00:00
bridgeIP := "192.169.1.1/24"
2015-05-06 22:39:29 +00:00
2017-01-05 11:38:34 +00:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-05-06 22:39:29 +00:00
defer deleteInterface ( c , bridgeName )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
defer s . d . Restart ( c )
2015-05-06 22:39:29 +00:00
2018-08-14 07:51:22 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "child" , "--publish" , "8080:80" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2018-08-14 07:51:22 +00:00
out , err = s . d . Cmd ( "run" , "-d" , "--name" , "parent" , "--link" , "child:http" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-05-06 22:39:29 +00:00
2018-04-11 13:52:13 +00:00
childIP := s . d . FindContainerIP ( c , "child" )
parentIP := s . d . FindContainerIP ( c , "parent" )
2015-05-06 22:39:29 +00:00
sourceRule := [ ] string { "-i" , bridgeName , "-o" , bridgeName , "-p" , "tcp" , "-s" , childIP , "--sport" , "80" , "-d" , parentIP , "-j" , "ACCEPT" }
destinationRule := [ ] string { "-i" , bridgeName , "-o" , bridgeName , "-p" , "tcp" , "-s" , parentIP , "--dport" , "80" , "-d" , childIP , "-j" , "ACCEPT" }
if ! iptables . Exists ( "filter" , "DOCKER" , sourceRule ... ) || ! iptables . Exists ( "filter" , "DOCKER" , destinationRule ... ) {
c . Fatal ( "Iptables rules not found" )
}
s . d . Cmd ( "rm" , "--link" , "parent/http" )
if iptables . Exists ( "filter" , "DOCKER" , sourceRule ... ) || iptables . Exists ( "filter" , "DOCKER" , destinationRule ... ) {
c . Fatal ( "Iptables rules should be removed when unlink" )
}
s . d . Cmd ( "kill" , "child" )
s . d . Cmd ( "kill" , "parent" )
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonUlimitDefaults ( c * check . C ) {
2015-11-05 00:40:58 +00:00
testRequires ( c , DaemonIsLinux )
2015-02-11 19:21:38 +00:00
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--default-ulimit" , "nofile=42:42" , "--default-ulimit" , "nproc=1024:1024" )
2015-02-11 19:21:38 +00:00
2015-04-26 02:47:42 +00:00
out , err := s . d . Cmd ( "run" , "--ulimit" , "nproc=2048" , "--name=test" , "busybox" , "/bin/sh" , "-c" , "echo $(ulimit -n); echo $(ulimit -p)" )
2015-02-11 19:21:38 +00:00
if err != nil {
2018-08-14 07:51:22 +00:00
c . Fatal ( err , out )
2015-02-11 19:21:38 +00:00
}
outArr := strings . Split ( out , "\n" )
if len ( outArr ) < 2 {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "got unexpected output: %s" , out )
2015-02-11 19:21:38 +00:00
}
nofile := strings . TrimSpace ( outArr [ 0 ] )
nproc := strings . TrimSpace ( outArr [ 1 ] )
if nofile != "42" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "expected `ulimit -n` to be `42`, got: %s" , nofile )
2015-02-11 19:21:38 +00:00
}
if nproc != "2048" {
2017-05-21 23:24:07 +00:00
c . Fatalf ( "expected `ulimit -p` to be 2048, got: %s" , nproc )
2015-02-11 19:21:38 +00:00
}
// Now restart daemon with a new default
2016-12-09 22:20:14 +00:00
s . d . Restart ( c , "--default-ulimit" , "nofile=43" )
2015-02-11 19:21:38 +00:00
2015-04-26 02:47:42 +00:00
out , err = s . d . Cmd ( "start" , "-a" , "test" )
2015-02-11 19:21:38 +00:00
if err != nil {
2018-08-14 07:51:22 +00:00
c . Fatal ( err , out )
2015-02-11 19:21:38 +00:00
}
outArr = strings . Split ( out , "\n" )
if len ( outArr ) < 2 {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "got unexpected output: %s" , out )
2015-02-11 19:21:38 +00:00
}
nofile = strings . TrimSpace ( outArr [ 0 ] )
nproc = strings . TrimSpace ( outArr [ 1 ] )
if nofile != "43" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "expected `ulimit -n` to be `43`, got: %s" , nofile )
2015-02-11 19:21:38 +00:00
}
if nproc != "2048" {
2017-05-21 23:24:07 +00:00
c . Fatalf ( "expected `ulimit -p` to be 2048, got: %s" , nproc )
2015-02-11 19:21:38 +00:00
}
}
2015-03-11 16:17:23 +00:00
// #11315
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartRenameContainer ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-03-11 16:17:23 +00:00
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err , out )
2015-03-11 16:17:23 +00:00
}
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "rename" , "test" , "test2" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err , out )
2015-03-11 16:17:23 +00:00
}
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-03-11 16:17:23 +00:00
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "start" , "test2" ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err , out )
2015-03-11 16:17:23 +00:00
}
}
2015-02-04 21:44:52 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverDefault ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-02-04 21:44:52 +00:00
2016-02-28 10:47:37 +00:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-12-09 09:17:53 +00:00
id , err := s . d . GetIDByName ( "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-02-04 21:44:52 +00:00
2016-12-09 09:17:53 +00:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 21:44:52 +00:00
if _ , err := os . Stat ( logPath ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
f , err := os . Open ( logPath )
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
2016-06-25 03:57:21 +00:00
defer f . Close ( )
2015-02-04 21:44:52 +00:00
var res struct {
2015-03-26 03:18:42 +00:00
Log string ` json:"log" `
Stream string ` json:"stream" `
Time time . Time ` json:"time" `
2015-02-04 21:44:52 +00:00
}
if err := json . NewDecoder ( f ) . Decode ( & res ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
if res . Log != "testline\n" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Unexpected log line: %q, expected: %q" , res . Log , "testline\n" )
2015-02-04 21:44:52 +00:00
}
if res . Stream != "stdout" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Unexpected stream: %q, expected: %q" , res . Stream , "stdout" )
2015-02-04 21:44:52 +00:00
}
if ! time . Now ( ) . After ( res . Time ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Log time %v in future" , res . Time )
2015-02-04 21:44:52 +00:00
}
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverDefaultOverride ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-02-04 21:44:52 +00:00
2016-02-28 10:47:37 +00:00
out , err := s . d . Cmd ( "run" , "--name=test" , "--log-driver=none" , "busybox" , "echo" , "testline" )
2015-02-04 21:44:52 +00:00
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( out , err )
2015-02-04 21:44:52 +00:00
}
2016-12-09 09:17:53 +00:00
id , err := s . d . GetIDByName ( "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-02-04 21:44:52 +00:00
2016-12-09 09:17:53 +00:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 21:44:52 +00:00
if _ , err := os . Stat ( logPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "%s shouldn't exits, error on Stat: %s" , logPath , err )
2015-02-04 21:44:52 +00:00
}
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNone ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-04 21:44:52 +00:00
2016-02-28 10:47:37 +00:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
2015-02-04 21:44:52 +00:00
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( out , err )
2015-02-04 21:44:52 +00:00
}
2016-12-09 09:17:53 +00:00
id , err := s . d . GetIDByName ( "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-02-04 21:44:52 +00:00
2016-12-09 09:17:53 +00:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 21:44:52 +00:00
if _ , err := os . Stat ( logPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "%s shouldn't exits, error on Stat: %s" , logPath , err )
2015-02-04 21:44:52 +00:00
}
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNoneOverride ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-04 21:44:52 +00:00
2016-02-28 10:47:37 +00:00
out , err := s . d . Cmd ( "run" , "--name=test" , "--log-driver=json-file" , "busybox" , "echo" , "testline" )
2015-02-04 21:44:52 +00:00
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( out , err )
2015-02-04 21:44:52 +00:00
}
2016-12-09 09:17:53 +00:00
id , err := s . d . GetIDByName ( "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-02-04 21:44:52 +00:00
2016-12-09 09:17:53 +00:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 21:44:52 +00:00
if _ , err := os . Stat ( logPath ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
f , err := os . Open ( logPath )
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
2016-06-25 03:57:21 +00:00
defer f . Close ( )
2015-02-04 21:44:52 +00:00
var res struct {
2015-03-26 03:18:42 +00:00
Log string ` json:"log" `
Stream string ` json:"stream" `
Time time . Time ` json:"time" `
2015-02-04 21:44:52 +00:00
}
if err := json . NewDecoder ( f ) . Decode ( & res ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-02-04 21:44:52 +00:00
}
if res . Log != "testline\n" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Unexpected log line: %q, expected: %q" , res . Log , "testline\n" )
2015-02-04 21:44:52 +00:00
}
if res . Stream != "stdout" {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Unexpected stream: %q, expected: %q" , res . Stream , "stdout" )
2015-02-04 21:44:52 +00:00
}
if ! time . Now ( ) . After ( res . Time ) {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Log time %v in future" , res . Time )
2015-02-04 21:44:52 +00:00
}
}
2015-02-06 00:24:47 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNoneLogsError ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-06 00:24:47 +00:00
2016-02-27 17:07:39 +00:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-02-27 17:07:39 +00:00
out , err = s . d . Cmd ( "logs" , "test" )
c . Assert ( err , check . NotNil , check . Commentf ( "Logs should fail with 'none' driver" ) )
2016-11-22 13:51:22 +00:00
expected := ` configured logging driver does not support reading `
2019-04-04 13:23:19 +00:00
assert . Assert ( c , strings . Contains ( out , expected ) )
2015-02-06 00:24:47 +00:00
}
2015-03-18 00:27:53 +00:00
2016-12-19 20:18:06 +00:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverShouldBeIgnoredForBuild ( c * check . C ) {
s . d . StartWithBusybox ( c , "--log-driver=splunk" )
2018-04-18 14:45:55 +00:00
result := cli . BuildCmd ( c , "busyboxs" , cli . Daemon ( s . d ) ,
build . WithDockerfile ( `
2016-12-19 20:18:06 +00:00
FROM busybox
2018-04-18 14:45:55 +00:00
RUN echo foo ` ) ,
build . WithoutCache ,
)
comment := check . Commentf ( "Failed to build image. output %s, exitCode %d, err %v" , result . Combined ( ) , result . ExitCode , result . Error )
c . Assert ( result . Error , check . IsNil , comment )
c . Assert ( result . ExitCode , check . Equals , 0 , comment )
c . Assert ( result . Combined ( ) , checker . Contains , "foo" , comment )
2016-12-19 20:18:06 +00:00
}
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonUnixSockCleanedUp ( c * check . C ) {
2015-03-18 21:26:14 +00:00
dir , err := ioutil . TempDir ( "" , "socket-cleanup-test" )
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-03-18 21:26:14 +00:00
}
defer os . RemoveAll ( dir )
sockPath := filepath . Join ( dir , "docker.sock" )
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--host" , "unix://" + sockPath )
2015-03-18 21:26:14 +00:00
if _ , err := os . Stat ( sockPath ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( "socket does not exist" )
2015-03-18 21:26:14 +00:00
}
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2015-03-18 21:26:14 +00:00
if _ , err := os . Stat ( sockPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 16:46:47 +00:00
c . Fatal ( "unix socket is not cleaned up" )
2015-03-18 21:26:14 +00:00
}
}
2015-04-06 00:57:19 +00:00
2015-04-26 02:47:42 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartKillWait ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-04-09 21:11:11 +00:00
2015-04-26 02:47:42 +00:00
out , err := s . d . Cmd ( "run" , "-id" , "busybox" , "/bin/cat" )
2015-04-09 21:11:11 +00:00
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Could not run /bin/cat: err=%v\n%s" , err , out )
2015-04-09 21:11:11 +00:00
}
containerID := strings . TrimSpace ( out )
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "kill" , containerID ) ; err != nil {
2015-04-18 16:46:47 +00:00
c . Fatalf ( "Could not kill %s: err=%v\n%s" , containerID , err , out )
2015-04-09 21:11:11 +00:00
}
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-04-09 21:11:11 +00:00
errchan := make ( chan error )
go func ( ) {
2015-04-26 02:47:42 +00:00
if out , err := s . d . Cmd ( "wait" , containerID ) ; err != nil {
2015-04-09 21:11:11 +00:00
errchan <- fmt . Errorf ( "%v:\n%s" , err , out )
}
close ( errchan )
} ( )
select {
case <- time . After ( 5 * time . Second ) :
2015-04-18 16:46:47 +00:00
c . Fatal ( "Waiting on a stopped (killed) container timed out" )
2015-04-09 21:11:11 +00:00
case err := <- errchan :
if err != nil {
2015-04-18 16:46:47 +00:00
c . Fatal ( err )
2015-04-09 21:11:11 +00:00
}
}
}
2015-04-20 23:21:46 +00:00
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
// TestHTTPSInfo connects via two-way authenticated HTTPS to the info endpoint
func ( s * DockerDaemonSuite ) TestHTTPSInfo ( c * check . C ) {
2015-04-20 23:21:46 +00:00
const (
2015-05-01 14:00:43 +00:00
testDaemonHTTPSAddr = "tcp://localhost:4271"
2015-04-20 23:21:46 +00:00
)
2016-12-09 22:20:14 +00:00
s . d . Start ( c ,
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/server-cert.pem" ,
"--tlskey" , "fixtures/https/server-key.pem" ,
"-H" , testDaemonHTTPSAddr )
2015-04-20 23:21:46 +00:00
2016-07-22 16:14:05 +00:00
args := [ ] string {
"--host" , testDaemonHTTPSAddr ,
2016-12-09 22:20:14 +00:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 16:14:05 +00:00
"--tlscert" , "fixtures/https/client-cert.pem" ,
"--tlskey" , "fixtures/https/client-key.pem" ,
"info" ,
}
out , err := s . d . Cmd ( args ... )
2015-04-20 23:21:46 +00:00
if err != nil {
c . Fatalf ( "Error Occurred: %s and output: %s" , err , out )
}
}
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
// TestHTTPSRun connects via two-way authenticated HTTPS to the create, attach, start, and wait endpoints.
2016-01-14 01:18:06 +00:00
// https://github.com/docker/docker/issues/19280
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
func ( s * DockerDaemonSuite ) TestHTTPSRun ( c * check . C ) {
2016-01-14 01:18:06 +00:00
const (
testDaemonHTTPSAddr = "tcp://localhost:4271"
)
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--tlsverify" , "--tlscacert" , "fixtures/https/ca.pem" , "--tlscert" , "fixtures/https/server-cert.pem" ,
"--tlskey" , "fixtures/https/server-key.pem" , "-H" , testDaemonHTTPSAddr )
2016-01-14 01:18:06 +00:00
2016-07-22 16:14:05 +00:00
args := [ ] string {
"--host" , testDaemonHTTPSAddr ,
"--tlsverify" , "--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/client-cert.pem" ,
"--tlskey" , "fixtures/https/client-key.pem" ,
"run" , "busybox" , "echo" , "TLS response" ,
}
out , err := s . d . Cmd ( args ... )
2016-01-14 01:18:06 +00:00
if err != nil {
c . Fatalf ( "Error Occurred: %s and output: %s" , err , out )
}
if ! strings . Contains ( out , "TLS response" ) {
c . Fatalf ( "expected output to include `TLS response`, got %v" , out )
}
}
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
// TestTLSVerify verifies that --tlsverify=false turns on tls
func ( s * DockerDaemonSuite ) TestTLSVerify ( c * check . C ) {
2016-05-26 11:14:35 +00:00
out , err := exec . Command ( dockerdBinary , "--tlsverify=false" ) . CombinedOutput ( )
2015-07-31 01:38:02 +00:00
if err == nil || ! strings . Contains ( string ( out ) , "Could not load X509 key pair" ) {
c . Fatalf ( "Daemon should not have started due to missing certs: %v\n%s" , err , string ( out ) )
}
}
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
// TestHTTPSInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint
2015-04-20 23:21:46 +00:00
// by using a rogue client certificate and checks that it fails with the expected error.
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
func ( s * DockerDaemonSuite ) TestHTTPSInfoRogueCert ( c * check . C ) {
2015-04-20 23:21:46 +00:00
const (
2016-06-04 12:17:24 +00:00
errBadCertificate = "bad certificate"
2015-05-01 14:00:43 +00:00
testDaemonHTTPSAddr = "tcp://localhost:4271"
2015-04-20 23:21:46 +00:00
)
2015-05-01 14:00:43 +00:00
2016-12-09 22:20:14 +00:00
s . d . Start ( c ,
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/server-cert.pem" ,
"--tlskey" , "fixtures/https/server-key.pem" ,
"-H" , testDaemonHTTPSAddr )
2015-04-20 23:21:46 +00:00
2016-07-22 16:14:05 +00:00
args := [ ] string {
"--host" , testDaemonHTTPSAddr ,
2016-12-09 22:20:14 +00:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 16:14:05 +00:00
"--tlscert" , "fixtures/https/client-rogue-cert.pem" ,
"--tlskey" , "fixtures/https/client-rogue-key.pem" ,
"info" ,
}
out , err := s . d . Cmd ( args ... )
2015-04-20 23:21:46 +00:00
if err == nil || ! strings . Contains ( out , errBadCertificate ) {
c . Fatalf ( "Expected err: %s, got instead: %s and output: %s" , errBadCertificate , err , out )
}
}
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
// TestHTTPSInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint
2015-04-20 23:21:46 +00:00
// which provides a rogue server certificate and checks that it fails with the expected error
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
func ( s * DockerDaemonSuite ) TestHTTPSInfoRogueServerCert ( c * check . C ) {
2015-04-20 23:21:46 +00:00
const (
errCaUnknown = "x509: certificate signed by unknown authority"
2015-05-01 14:00:43 +00:00
testDaemonRogueHTTPSAddr = "tcp://localhost:4272"
2015-04-20 23:21:46 +00:00
)
2016-12-09 22:20:14 +00:00
s . d . Start ( c ,
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/server-rogue-cert.pem" ,
"--tlskey" , "fixtures/https/server-rogue-key.pem" ,
"-H" , testDaemonRogueHTTPSAddr )
2015-04-20 23:21:46 +00:00
2016-07-22 16:14:05 +00:00
args := [ ] string {
"--host" , testDaemonRogueHTTPSAddr ,
2016-12-09 22:20:14 +00:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 16:14:05 +00:00
"--tlscert" , "fixtures/https/client-rogue-cert.pem" ,
"--tlskey" , "fixtures/https/client-rogue-key.pem" ,
"info" ,
}
out , err := s . d . Cmd ( args ... )
2015-04-20 23:21:46 +00:00
if err == nil || ! strings . Contains ( out , errCaUnknown ) {
c . Fatalf ( "Expected err: %s, got instead: %s and output: %s" , errCaUnknown , err , out )
}
}
2015-04-28 03:36:40 +00:00
2016-12-09 09:17:53 +00:00
func pingContainers ( c * check . C , d * daemon . Daemon , expectFailure bool ) {
2015-04-28 23:17:00 +00:00
var dargs [ ] string
if d != nil {
2016-12-09 09:17:53 +00:00
dargs = [ ] string { "--host" , d . Sock ( ) }
2015-04-28 23:17:00 +00:00
}
args := append ( dargs , "run" , "-d" , "--name" , "container1" , "busybox" , "top" )
2015-07-20 06:55:40 +00:00
dockerCmd ( c , args ... )
2015-04-28 03:36:40 +00:00
2015-04-28 23:17:00 +00:00
args = append ( dargs , "run" , "--rm" , "--link" , "container1:alias1" , "busybox" , "sh" , "-c" )
2015-04-28 03:36:40 +00:00
pingCmd := "ping -c 1 %s -W 1"
2015-04-28 23:17:00 +00:00
args = append ( args , fmt . Sprintf ( pingCmd , "alias1" ) )
2015-07-27 18:13:25 +00:00
_ , _ , err := dockerCmdWithError ( args ... )
2015-04-28 23:17:00 +00:00
if expectFailure {
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2015-04-28 23:17:00 +00:00
} else {
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-04-28 23:17:00 +00:00
}
2015-04-28 03:36:40 +00:00
2015-04-28 23:17:00 +00:00
args = append ( dargs , "rm" , "-f" , "container1" )
2015-07-20 06:55:40 +00:00
dockerCmd ( c , args ... )
2015-04-28 03:36:40 +00:00
}
2015-05-07 22:35:12 +00:00
2015-05-19 16:32:19 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithSocketAsVolume ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-05-07 22:35:12 +00:00
2016-12-09 09:18:02 +00:00
socket := filepath . Join ( s . d . Folder , "docker.sock" )
2015-05-07 22:35:12 +00:00
2016-02-28 10:47:37 +00:00
out , err := s . d . Cmd ( "run" , "--restart=always" , "-v" , socket + ":/sock" , "busybox" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-05-07 22:35:12 +00:00
}
2015-05-19 16:32:19 +00:00
2016-03-04 22:41:53 +00:00
// os.Kill should kill daemon ungracefully, leaving behind container mounts.
2017-05-21 23:24:07 +00:00
// A subsequent daemon restart should clean up said mounts.
2016-03-04 22:41:53 +00:00
func ( s * DockerDaemonSuite ) TestCleanupMountsAfterDaemonAndContainerKill ( c * check . C ) {
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary , testdaemon . WithEnvironment ( testEnv . Execution ) )
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c )
2015-05-19 16:32:19 +00:00
2016-12-09 22:20:14 +00:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2015-05-19 16:32:19 +00:00
id := strings . TrimSpace ( out )
2017-12-20 01:28:13 +00:00
// If there are no mounts with container id visible from the host
// (as those are in container's own mount ns), there is nothing
// to check here and the test should be skipped.
2016-03-04 22:41:53 +00:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , mountOut )
2017-12-20 01:28:13 +00:00
if ! strings . Contains ( string ( mountOut ) , id ) {
d . Stop ( c )
c . Skip ( "no container mounts visible in host ns" )
}
2016-03-04 22:41:53 +00:00
2017-12-20 01:28:13 +00:00
// kill the daemon
2019-04-04 13:23:19 +00:00
assert . NilError ( c , d . Kill ( ) )
2016-03-18 18:50:19 +00:00
// kill the container
2018-09-21 22:58:34 +00:00
icmd . RunCommand ( ctrBinary , "--address" , containerdSocket ,
2017-12-15 22:48:31 +00:00
"--namespace" , moby_daemon . ContainersNamespace , "tasks" , "kill" , id ) . Assert ( c , icmd . Success )
2016-03-04 22:41:53 +00:00
// restart daemon.
2016-12-09 22:20:14 +00:00
d . Restart ( c )
2016-03-18 18:50:19 +00:00
2016-03-04 22:41:53 +00:00
// Now, container mounts should be gone.
mountOut , err = ioutil . ReadFile ( "/proc/self/mountinfo" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , mountOut )
assert . Assert ( c , ! strings . Contains ( string ( mountOut ) , id ) , "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s" , id , d . Root , mountOut )
2016-12-09 22:20:14 +00:00
d . Stop ( c )
2016-03-04 22:41:53 +00:00
}
// os.Interrupt should perform a graceful daemon shutdown and hence cleanup mounts.
func ( s * DockerDaemonSuite ) TestCleanupMountsAfterGracefulShutdown ( c * check . C ) {
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary , testdaemon . WithEnvironment ( testEnv . Execution ) )
2016-12-09 22:20:14 +00:00
d . StartWithBusybox ( c )
2016-03-04 22:41:53 +00:00
2016-12-09 22:20:14 +00:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-03-04 22:41:53 +00:00
id := strings . TrimSpace ( out )
// Send SIGINT and daemon should clean up
2019-04-04 13:23:19 +00:00
assert . NilError ( c , d . Signal ( os . Interrupt ) )
2016-06-14 20:41:29 +00:00
// Wait for the daemon to stop.
2019-04-04 13:23:19 +00:00
assert . NilError ( c , <- d . Wait )
2016-03-18 18:50:19 +00:00
2015-08-26 12:00:01 +00:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , mountOut )
2015-08-26 12:00:01 +00:00
2019-04-04 13:23:19 +00:00
assert . Assert ( c , ! strings . Contains ( string ( mountOut ) , id ) , "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s" , id , d . Root , mountOut )
2015-05-19 16:32:19 +00:00
}
2015-05-24 15:26:56 +00:00
2015-05-26 01:25:34 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithContainerRunning ( t * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( t )
2016-01-25 15:45:13 +00:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" ) ; err != nil {
2015-05-26 01:25:34 +00:00
t . Fatal ( out , err )
}
2015-06-05 22:02:56 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( t )
2015-05-26 01:25:34 +00:00
// Container 'test' should be removed without error
if out , err := s . d . Cmd ( "rm" , "test" ) ; err != nil {
t . Fatal ( out , err )
}
}
2015-06-05 22:02:56 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartCleanupNetns ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-06-05 22:02:56 +00:00
out , err := s . d . Cmd ( "run" , "--name" , "netns" , "-d" , "busybox" , "top" )
if err != nil {
c . Fatal ( out , err )
}
2015-09-02 23:43:28 +00:00
// Get sandbox key via inspect
out , err = s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.SandboxKey}}'" , "netns" )
if err != nil {
c . Fatalf ( "Error inspecting container: %s, %v" , out , err )
}
fileName := strings . Trim ( out , " \r\n'" )
2015-06-05 22:02:56 +00:00
if out , err := s . d . Cmd ( "stop" , "netns" ) ; err != nil {
c . Fatal ( out , err )
}
// Test if the file still exists
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "stat" , "-c" , "%n" , fileName ) . Assert ( c , icmd . Expected {
Out : fileName ,
} )
2015-06-05 22:02:56 +00:00
// Remove the container and restart the daemon
if out , err := s . d . Cmd ( "rm" , "netns" ) ; err != nil {
c . Fatal ( out , err )
}
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-06-05 22:02:56 +00:00
// Test again and see now the netns file does not exist
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "stat" , "-c" , "%n" , fileName ) . Assert ( c , icmd . Expected {
Err : "No such file or directory" ,
ExitCode : 1 ,
} )
2015-06-05 22:02:56 +00:00
}
2015-06-16 15:00:54 +00:00
// tests regression detailed in #13964 where DOCKER_TLS_VERIFY env is ignored
[nit] integration-cli: obey Go's naming convention
No substantial code change.
- Api --> API
- Cli --> CLI
- Http, Https --> HTTP, HTTPS
- Id --> ID
- Uid,Gid,Pid --> UID,PID,PID
- Ipam --> IPAM
- Tls --> TLS (TestDaemonNoTlsCliTlsVerifyWithEnv --> TestDaemonTLSVerifyIssue13964)
Didn't touch in this commit:
- Git: because it is officially "Git": https://git-scm.com/
- Tar: because it is officially "Tar": https://www.gnu.org/software/tar/
- Cpu, Nat, Mac, Ipc, Shm: for keeping a consistency with existing production code (not changable, for compatibility)
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
2016-09-28 01:50:12 +00:00
func ( s * DockerDaemonSuite ) TestDaemonTLSVerifyIssue13964 ( c * check . C ) {
2015-06-16 15:00:54 +00:00
host := "tcp://localhost:4271"
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "-H" , host )
2017-01-05 11:38:34 +00:00
icmd . RunCmd ( icmd . Cmd {
Command : [ ] string { dockerBinary , "-H" , host , "info" } ,
Env : [ ] string { "DOCKER_TLS_VERIFY=1" , "DOCKER_CERT_PATH=fixtures/https" } ,
} ) . Assert ( c , icmd . Expected {
ExitCode : 1 ,
Err : "error during connect" ,
} )
2015-04-28 11:50:20 +00:00
}
2016-08-03 16:20:46 +00:00
func setupV6 ( c * check . C ) {
2015-04-28 11:50:20 +00:00
// Hack to get the right IPv6 address on docker0, which has already been created
2016-08-03 16:20:46 +00:00
result := icmd . RunCommand ( "ip" , "addr" , "add" , "fe80::1/64" , "dev" , "docker0" )
2017-01-05 11:38:34 +00:00
result . Assert ( c , icmd . Success )
2015-04-28 11:50:20 +00:00
}
2016-08-03 16:20:46 +00:00
func teardownV6 ( c * check . C ) {
result := icmd . RunCommand ( "ip" , "addr" , "del" , "fe80::1/64" , "dev" , "docker0" )
2017-01-05 11:38:34 +00:00
result . Assert ( c , icmd . Success )
2015-06-16 15:00:54 +00:00
}
2015-08-01 12:52:00 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithContainerWithRestartPolicyAlways ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-08-01 12:52:00 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--restart" , "always" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-01 12:52:00 +00:00
id := strings . TrimSpace ( out )
2018-08-14 07:51:22 +00:00
out , err = s . d . Cmd ( "stop" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2018-08-14 07:51:22 +00:00
out , err = s . d . Cmd ( "wait" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-01 12:52:00 +00:00
out , err = s . d . Cmd ( "ps" , "-q" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
assert . Equal ( c , out , "" )
2015-08-01 12:52:00 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-08-01 12:52:00 +00:00
out , err = s . d . Cmd ( "ps" , "-q" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-01 12:52:00 +00:00
c . Assert ( strings . TrimSpace ( out ) , check . Equals , id [ : 12 ] )
}
2015-08-17 18:38:37 +00:00
2015-08-17 22:27:44 +00:00
func ( s * DockerDaemonSuite ) TestDaemonWideLogConfig ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--log-opt=max-size=1k" )
2016-03-12 12:50:37 +00:00
name := "logtest"
out , err := s . d . Cmd ( "run" , "-d" , "--log-opt=max-file=5" , "--name" , name , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s, err: %v" , out , err )
2016-03-12 12:50:37 +00:00
out , err = s . d . Cmd ( "inspect" , "-f" , "{{ .HostConfig.LogConfig.Config }}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
assert . Assert ( c , strings . Contains ( out , "max-size:1k" ) )
assert . Assert ( c , strings . Contains ( out , "max-file:5" ) )
2016-03-12 12:50:37 +00:00
out , err = s . d . Cmd ( "inspect" , "-f" , "{{ .HostConfig.LogConfig.Type }}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
assert . Equal ( c , strings . TrimSpace ( out ) , "json-file" )
2015-08-17 22:27:44 +00:00
}
2015-08-25 01:42:58 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithPausedContainer ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-08-25 01:42:58 +00:00
if out , err := s . d . Cmd ( "run" , "-i" , "-d" , "--name" , "test" , "busybox" , "top" ) ; err != nil {
c . Fatal ( err , out )
}
if out , err := s . d . Cmd ( "pause" , "test" ) ; err != nil {
c . Fatal ( err , out )
}
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-08-25 01:42:58 +00:00
errchan := make ( chan error )
go func ( ) {
out , err := s . d . Cmd ( "start" , "test" )
if err != nil {
errchan <- fmt . Errorf ( "%v:\n%s" , err , out )
}
name := strings . TrimSpace ( out )
if name != "test" {
errchan <- fmt . Errorf ( "Paused container start error on docker daemon restart, expected 'test' but got '%s'" , name )
}
close ( errchan )
} ( )
select {
case <- time . After ( 5 * time . Second ) :
c . Fatal ( "Waiting on start a container timed out" )
case err := <- errchan :
if err != nil {
c . Fatal ( err )
}
}
2015-06-12 13:25:32 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonRestartRmVolumeInUse ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-06-12 13:25:32 +00:00
out , err := s . d . Cmd ( "create" , "-v" , "test:/foo" , "busybox" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-06-12 13:25:32 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-08-25 01:42:58 +00:00
2015-06-12 13:25:32 +00:00
out , err = s . d . Cmd ( "volume" , "rm" , "test" )
2015-09-23 20:29:14 +00:00
c . Assert ( err , check . NotNil , check . Commentf ( "should not be able to remove in use volume after daemon restart" ) )
c . Assert ( out , checker . Contains , "in use" )
2015-06-12 13:25:32 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonRestartLocalVolumes ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
2015-06-12 13:25:32 +00:00
2018-08-14 07:51:22 +00:00
out , err := s . d . Cmd ( "volume" , "create" , "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-06-12 13:25:32 +00:00
2018-08-14 07:51:22 +00:00
out , err = s . d . Cmd ( "volume" , "inspect" , "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-08-25 01:42:58 +00:00
}
2015-09-20 11:03:09 +00:00
2016-12-09 22:20:14 +00:00
// FIXME(vdemeester) should be a unit test
2015-09-20 11:03:09 +00:00
func ( s * DockerDaemonSuite ) TestDaemonCorruptedLogDriverAddress ( c * check . C ) {
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary , testdaemon . WithEnvironment ( testEnv . Execution ) )
2016-12-09 22:20:14 +00:00
c . Assert ( d . StartWithError ( "--log-driver=syslog" , "--log-opt" , "syslog-address=corrupted:42" ) , check . NotNil )
2018-02-08 22:16:20 +00:00
expected := "syslog-address should be in form proto://address"
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "grep" , expected , d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-09-20 11:03:09 +00:00
}
2016-12-09 22:20:14 +00:00
// FIXME(vdemeester) should be a unit test
2015-09-20 11:03:09 +00:00
func ( s * DockerDaemonSuite ) TestDaemonCorruptedFluentdAddress ( c * check . C ) {
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary , testdaemon . WithEnvironment ( testEnv . Execution ) )
2016-12-09 22:20:14 +00:00
c . Assert ( d . StartWithError ( "--log-driver=fluentd" , "--log-opt" , "fluentd-address=corrupted:c" ) , check . NotNil )
2018-02-08 22:16:20 +00:00
expected := "invalid fluentd-address corrupted:c: "
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "grep" , expected , d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-09-20 11:03:09 +00:00
}
2015-10-12 08:49:25 +00:00
2016-12-09 09:17:53 +00:00
// FIXME(vdemeester) Use a new daemon instance instead of the Suite one
2015-10-12 08:49:25 +00:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithoutHost ( c * check . C ) {
2016-12-09 09:17:53 +00:00
s . d . UseDefaultHost = true
2015-10-12 08:49:25 +00:00
defer func ( ) {
2016-12-09 09:17:53 +00:00
s . d . UseDefaultHost = false
2015-10-12 08:49:25 +00:00
} ( )
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
2015-10-12 08:49:25 +00:00
}
2015-10-19 13:17:37 +00:00
2016-12-09 09:17:53 +00:00
// FIXME(vdemeester) Use a new daemon instance instead of the Suite one
2017-05-12 18:07:51 +00:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithDefaultTLSHost ( c * check . C ) {
2016-12-09 09:17:53 +00:00
s . d . UseDefaultTLSHost = true
2015-10-19 13:17:37 +00:00
defer func ( ) {
2016-12-09 09:17:53 +00:00
s . d . UseDefaultTLSHost = false
2015-10-19 13:17:37 +00:00
} ( )
2016-12-09 22:20:14 +00:00
s . d . Start ( c ,
2015-10-19 13:17:37 +00:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/server-cert.pem" ,
2016-12-09 22:20:14 +00:00
"--tlskey" , "fixtures/https/server-key.pem" )
2015-10-19 13:17:37 +00:00
// The client with --tlsverify should also use default host localhost:2376
tmpHost := os . Getenv ( "DOCKER_HOST" )
defer func ( ) {
os . Setenv ( "DOCKER_HOST" , tmpHost )
} ( )
os . Setenv ( "DOCKER_HOST" , "" )
out , _ := dockerCmd (
c ,
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/client-cert.pem" ,
"--tlskey" , "fixtures/https/client-key.pem" ,
"version" ,
)
if ! strings . Contains ( out , "Server" ) {
c . Fatalf ( "docker version should return information of server side" )
}
2017-05-12 18:07:51 +00:00
// ensure when connecting to the server that only a single acceptable CA is requested
contents , err := ioutil . ReadFile ( "fixtures/https/ca.pem" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-05-12 18:07:51 +00:00
rootCert , err := helpers . ParseCertificatePEM ( contents )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-05-12 18:07:51 +00:00
rootPool := x509 . NewCertPool ( )
rootPool . AddCert ( rootCert )
var certRequestInfo * tls . CertificateRequestInfo
conn , err := tls . Dial ( "tcp" , fmt . Sprintf ( "%s:%d" , opts . DefaultHTTPHost , opts . DefaultTLSHTTPPort ) , & tls . Config {
RootCAs : rootPool ,
GetClientCertificate : func ( cri * tls . CertificateRequestInfo ) ( * tls . Certificate , error ) {
certRequestInfo = cri
cert , err := tls . LoadX509KeyPair ( "fixtures/https/client-cert.pem" , "fixtures/https/client-key.pem" )
if err != nil {
return nil , err
}
return & cert , nil
} ,
} )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-05-12 18:07:51 +00:00
conn . Close ( )
c . Assert ( certRequestInfo , checker . NotNil )
c . Assert ( certRequestInfo . AcceptableCAs , checker . HasLen , 1 )
c . Assert ( certRequestInfo . AcceptableCAs [ 0 ] , checker . DeepEquals , rootCert . RawSubject )
2015-10-19 13:17:37 +00:00
}
2015-10-25 08:36:18 +00:00
func ( s * DockerDaemonSuite ) TestBridgeIPIsExcludedFromAllocatorPool ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
bridgeIP := "192.169.1.1"
bridgeRange := bridgeIP + "/30"
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--bip" , bridgeRange )
defer s . d . Restart ( c )
2015-10-25 08:36:18 +00:00
var cont int
for {
contName := fmt . Sprintf ( "container%d" , cont )
2016-12-09 22:20:14 +00:00
_ , err := s . d . Cmd ( "run" , "--name" , contName , "-d" , "busybox" , "/bin/sleep" , "2" )
2015-10-25 08:36:18 +00:00
if err != nil {
// pool exhausted
break
}
ip , err := s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.IPAddress}}'" , contName )
2018-08-14 07:51:22 +00:00
c . Assert ( err , check . IsNil , check . Commentf ( "%s" , ip ) )
2015-10-25 08:36:18 +00:00
c . Assert ( ip , check . Not ( check . Equals ) , bridgeIP )
cont ++
}
}
2015-11-13 05:53:35 +00:00
// Test daemon for no space left on device error
2016-04-19 21:16:18 +00:00
func ( s * DockerDaemonSuite ) TestDaemonNoSpaceLeftOnDeviceError ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux , Network )
2015-11-18 13:20:49 +00:00
2016-04-19 21:16:18 +00:00
testDir , err := ioutil . TempDir ( "" , "no-space-left-on-device-test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-04-19 21:16:18 +00:00
defer os . RemoveAll ( testDir )
c . Assert ( mount . MakeRShared ( testDir ) , checker . IsNil )
defer mount . Unmount ( testDir )
2016-03-29 22:24:05 +00:00
2018-03-30 01:31:14 +00:00
// create a 3MiB image (with a 2MiB ext4 fs) and mount it as graph root
2016-04-19 21:16:18 +00:00
// Why in a container? Because `mount` sometimes behaves weirdly and often fails outright on this test in debian:jessie (which is what the test suite runs under if run from the Makefile)
2017-05-15 21:54:27 +00:00
dockerCmd ( c , "run" , "--rm" , "-v" , testDir + ":/test" , "busybox" , "sh" , "-c" , "dd of=/test/testfs.img bs=1M seek=3 count=0" )
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "mkfs.ext4" , "-F" , filepath . Join ( testDir , "testfs.img" ) ) . Assert ( c , icmd . Success )
2016-05-06 21:19:27 +00:00
2018-06-19 23:14:12 +00:00
dockerCmd ( c , "run" , "--privileged" , "--rm" , "-v" , testDir + ":/test:shared" , "busybox" , "sh" , "-c" , "mkdir -p /test/test-mount/vfs && mount -n /test/testfs.img /test/test-mount/vfs" )
2016-05-06 21:19:27 +00:00
defer mount . Unmount ( filepath . Join ( testDir , "test-mount" ) )
2016-03-29 22:24:05 +00:00
2018-06-19 23:14:12 +00:00
s . d . Start ( c , "--storage-driver" , "vfs" , "--data-root" , filepath . Join ( testDir , "test-mount" ) )
2016-12-09 22:20:14 +00:00
defer s . d . Stop ( c )
2015-11-13 05:53:35 +00:00
2018-03-30 01:31:14 +00:00
// pull a repository large enough to overfill the mounted filesystem
2017-09-13 15:30:44 +00:00
pullOut , err := s . d . Cmd ( "pull" , "debian:stretch" )
2018-08-14 07:51:22 +00:00
c . Assert ( err , checker . NotNil , check . Commentf ( "%s" , pullOut ) )
2016-03-29 22:24:05 +00:00
c . Assert ( pullOut , checker . Contains , "no space left on device" )
2015-11-13 05:53:35 +00:00
}
2015-11-24 20:25:12 +00:00
// Test daemon restart with container links + auto restart
func ( s * DockerDaemonSuite ) TestDaemonRestartContainerLinksRestart ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-11-24 20:25:12 +00:00
2018-05-19 11:38:54 +00:00
var parent1Args [ ] string
var parent2Args [ ] string
2015-11-24 20:25:12 +00:00
wg := sync . WaitGroup { }
maxChildren := 10
chErr := make ( chan error , maxChildren )
for i := 0 ; i < maxChildren ; i ++ {
wg . Add ( 1 )
name := fmt . Sprintf ( "test%d" , i )
if i < maxChildren / 2 {
parent1Args = append ( parent1Args , [ ] string { "--link" , name } ... )
} else {
parent2Args = append ( parent2Args , [ ] string { "--link" , name } ... )
}
go func ( ) {
2016-12-09 22:20:14 +00:00
_ , err := s . d . Cmd ( "run" , "-d" , "--name" , name , "--restart=always" , "busybox" , "top" )
2015-11-24 20:25:12 +00:00
chErr <- err
wg . Done ( )
} ( )
}
wg . Wait ( )
close ( chErr )
for err := range chErr {
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-11-24 20:25:12 +00:00
}
parent1Args = append ( [ ] string { "run" , "-d" } , parent1Args ... )
parent1Args = append ( parent1Args , [ ] string { "--name=parent1" , "--restart=always" , "busybox" , "top" } ... )
parent2Args = append ( [ ] string { "run" , "-d" } , parent2Args ... )
parent2Args = append ( parent2Args , [ ] string { "--name=parent2" , "--restart=always" , "busybox" , "top" } ... )
2016-12-09 22:20:14 +00:00
_ , err := s . d . Cmd ( parent1Args ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-08-30 21:25:16 +00:00
_ , err = s . d . Cmd ( parent2Args ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-11-24 20:25:12 +00:00
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2015-11-24 20:25:12 +00:00
// clear the log file -- we don't need any of it but may for the next part
// can ignore the error here, this is just a cleanup
2016-08-30 21:25:16 +00:00
os . Truncate ( s . d . LogFileName ( ) , 0 )
2016-12-09 22:20:14 +00:00
s . d . Start ( c )
2015-11-24 20:25:12 +00:00
for _ , num := range [ ] string { "1" , "2" } {
2016-08-30 21:25:16 +00:00
out , err := s . d . Cmd ( "inspect" , "-f" , "{{ .State.Running }}" , "parent" + num )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-11-24 20:25:12 +00:00
if strings . TrimSpace ( out ) != "true" {
2016-08-30 21:25:16 +00:00
log , _ := ioutil . ReadFile ( s . d . LogFileName ( ) )
2015-11-24 20:25:12 +00:00
c . Fatalf ( "parent container is not running\n%s" , string ( log ) )
}
}
}
2015-12-07 17:55:33 +00:00
func ( s * DockerDaemonSuite ) TestDaemonCgroupParent ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
cgroupParent := "test"
name := "cgroup-test"
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--cgroup-parent" , cgroupParent )
defer s . d . Restart ( c )
2015-12-07 17:55:33 +00:00
out , err := s . d . Cmd ( "run" , "--name" , name , "busybox" , "cat" , "/proc/self/cgroup" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-08-21 23:03:58 +00:00
cgroupPaths := ParseCgroupPaths ( string ( out ) )
2015-12-07 17:55:33 +00:00
c . Assert ( len ( cgroupPaths ) , checker . Not ( checker . Equals ) , 0 , check . Commentf ( "unexpected output - %q" , string ( out ) ) )
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.Id}}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-12-07 17:55:33 +00:00
id := strings . TrimSpace ( string ( out ) )
expectedCgroup := path . Join ( cgroupParent , id )
found := false
for _ , path := range cgroupPaths {
if strings . HasSuffix ( path , expectedCgroup ) {
found = true
break
}
}
c . Assert ( found , checker . True , check . Commentf ( "Cgroup path for container (%s) doesn't found in cgroups file: %s" , expectedCgroup , cgroupPaths ) )
}
2015-09-04 00:51:04 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithLinks ( c * check . C ) {
testRequires ( c , DaemonIsLinux ) // Windows does not support links
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-09-04 00:51:04 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "run" , "--name=test2" , "--link" , "test:abc" , "busybox" , "sh" , "-c" , "ping -c 1 -w 1 abc" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-09-04 00:51:04 +00:00
// should fail since test is not running yet
out , err = s . d . Cmd ( "start" , "test2" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "start" , "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2018-08-14 07:45:39 +00:00
c . Assert ( strings . Contains ( out , "1 packets transmitted, 1 packets received" ) , check . Equals , true , check . Commentf ( "%s" , out ) )
2015-09-04 00:51:04 +00:00
}
func ( s * DockerDaemonSuite ) TestDaemonRestartWithNames ( c * check . C ) {
testRequires ( c , DaemonIsLinux ) // Windows does not support links
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-09-04 00:51:04 +00:00
out , err := s . d . Cmd ( "create" , "--name=test" , "busybox" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "run" , "-d" , "--name=test2" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
test2ID := strings . TrimSpace ( out )
out , err = s . d . Cmd ( "run" , "-d" , "--name=test3" , "--link" , "test2:abc" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2015-09-04 00:51:04 +00:00
test3ID := strings . TrimSpace ( out )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-09-04 00:51:04 +00:00
2018-07-09 17:40:34 +00:00
_ , err = s . d . Cmd ( "create" , "--name=test" , "busybox" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , "expected error trying to create container with duplicate name" )
2015-09-04 00:51:04 +00:00
// this one is no longer needed, removing simplifies the remainder of the test
out , err = s . d . Cmd ( "rm" , "-f" , "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "ps" , "-a" , "--no-trunc" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
lines := strings . Split ( strings . TrimSpace ( out ) , "\n" ) [ 1 : ]
test2validated := false
test3validated := false
for _ , line := range lines {
fields := strings . Fields ( line )
names := fields [ len ( fields ) - 1 ]
switch fields [ 0 ] {
case test2ID :
2019-04-04 13:23:19 +00:00
assert . Equal ( c , names , "test2,test3/abc" )
2015-09-04 00:51:04 +00:00
test2validated = true
case test3ID :
2019-04-04 13:23:19 +00:00
assert . Equal ( c , names , "test3" )
2015-09-04 00:51:04 +00:00
test3validated = true
}
}
2019-04-04 13:23:19 +00:00
assert . Assert ( c , test2validated )
assert . Assert ( c , test3validated )
2015-09-04 00:51:04 +00:00
}
2016-06-17 15:21:03 +00:00
// TestDaemonRestartWithKilledRunningContainer requires live restore of running containers
func ( s * DockerDaemonSuite ) TestDaemonRestartWithKilledRunningContainer ( t * check . C ) {
testRequires ( t , DaemonIsLinux )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( t )
2016-06-17 15:21:03 +00:00
cid , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2016-12-09 22:20:14 +00:00
defer s . d . Stop ( t )
2016-06-17 15:21:03 +00:00
if err != nil {
t . Fatal ( cid , err )
}
cid = strings . TrimSpace ( cid )
2016-06-28 03:32:03 +00:00
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , cid )
2019-04-04 13:23:19 +00:00
assert . NilError ( t , err )
2016-06-28 03:32:03 +00:00
pid = strings . TrimSpace ( pid )
2016-06-17 15:21:03 +00:00
// Kill the daemon
if err := s . d . Kill ( ) ; err != nil {
t . Fatal ( err )
}
// kill the container
2018-09-21 22:58:34 +00:00
icmd . RunCommand ( ctrBinary , "--address" , containerdSocket ,
2017-12-15 22:48:31 +00:00
"--namespace" , moby_daemon . ContainersNamespace , "tasks" , "kill" , cid ) . Assert ( t , icmd . Success )
2016-06-17 15:21:03 +00:00
// Give time to containerd to process the command if we don't
// the exit event might be received after we do the inspect
2017-01-16 15:39:12 +00:00
result := icmd . RunCommand ( "kill" , "-0" , pid )
for result . ExitCode == 0 {
2016-06-28 03:32:03 +00:00
time . Sleep ( 1 * time . Second )
2017-01-16 15:39:12 +00:00
// FIXME(vdemeester) should we check it doesn't error out ?
result = icmd . RunCommand ( "kill" , "-0" , pid )
2016-06-17 15:21:03 +00:00
}
// restart the daemon
2016-12-09 22:20:14 +00:00
s . d . Start ( t )
2016-06-17 15:21:03 +00:00
// Check that we've got the correct exit code
out , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , cid )
2019-04-04 13:23:19 +00:00
assert . NilError ( t , err )
2016-06-17 15:21:03 +00:00
out = strings . TrimSpace ( out )
if out != "143" {
t . Fatalf ( "Expected exit code '%s' got '%s' for container '%s'\n" , "143" , out , cid )
}
}
// os.Kill should kill daemon ungracefully, leaving behind live containers.
// The live containers should be known to the restarted daemon. Stopping
// them now, should remove the mounts.
func ( s * DockerDaemonSuite ) TestCleanupMountsAfterDaemonCrash ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--live-restore" )
2016-06-17 15:21:03 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-06-17 15:21:03 +00:00
id := strings . TrimSpace ( out )
2017-12-20 01:28:13 +00:00
// kill the daemon
c . Assert ( s . d . Kill ( ) , check . IsNil )
// Check if there are mounts with container id visible from the host.
// If not, those mounts exist in container's own mount ns, and so
// the following check for mounts being cleared is pointless.
skipMountCheck := false
2016-06-17 15:21:03 +00:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
2017-12-20 01:28:13 +00:00
if ! strings . Contains ( string ( mountOut ) , id ) {
skipMountCheck = true
}
2016-06-17 15:21:03 +00:00
// restart daemon.
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--live-restore" )
2016-06-17 15:21:03 +00:00
// container should be running.
2016-06-23 16:24:28 +00:00
out , err = s . d . Cmd ( "inspect" , "--format={{.State.Running}}" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-06-17 15:21:03 +00:00
out = strings . TrimSpace ( out )
if out != "true" {
c . Fatalf ( "Container %s expected to stay alive after daemon restart" , id )
}
// 'docker stop' should work.
out , err = s . d . Cmd ( "stop" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-06-17 15:21:03 +00:00
2017-12-20 01:28:13 +00:00
if skipMountCheck {
return
}
2016-06-17 15:21:03 +00:00
// Now, container mounts should be gone.
mountOut , err = ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
2017-12-20 01:28:13 +00:00
comment := check . Commentf ( "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s" , id , s . d . Root , mountOut )
2016-06-17 15:21:03 +00:00
c . Assert ( strings . Contains ( string ( mountOut ) , id ) , check . Equals , false , comment )
}
// TestDaemonRestartWithUnpausedRunningContainer requires live restore of running containers.
func ( s * DockerDaemonSuite ) TestDaemonRestartWithUnpausedRunningContainer ( t * check . C ) {
testRequires ( t , DaemonIsLinux )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( t , "--live-restore" )
2016-06-17 15:21:03 +00:00
cid , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2016-12-09 22:20:14 +00:00
defer s . d . Stop ( t )
2016-06-17 15:21:03 +00:00
if err != nil {
t . Fatal ( cid , err )
}
cid = strings . TrimSpace ( cid )
2016-06-28 03:32:03 +00:00
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , cid )
2019-04-04 13:23:19 +00:00
assert . NilError ( t , err )
2016-06-28 03:32:03 +00:00
2016-06-17 15:21:03 +00:00
// pause the container
if _ , err := s . d . Cmd ( "pause" , cid ) ; err != nil {
t . Fatal ( cid , err )
}
// Kill the daemon
if err := s . d . Kill ( ) ; err != nil {
t . Fatal ( err )
}
// resume the container
2016-08-04 16:57:34 +00:00
result := icmd . RunCommand (
ctrBinary ,
2018-09-21 22:58:34 +00:00
"--address" , containerdSocket ,
2017-12-15 22:48:31 +00:00
"--namespace" , moby_daemon . ContainersNamespace ,
2017-09-22 13:52:41 +00:00
"tasks" , "resume" , cid )
2017-08-23 21:01:29 +00:00
result . Assert ( t , icmd . Success )
2016-06-17 15:21:03 +00:00
// Give time to containerd to process the command if we don't
// the resume event might be received after we do the inspect
2016-08-04 16:57:34 +00:00
waitAndAssert ( t , defaultReconciliationTimeout , func ( * check . C ) ( interface { } , check . CommentInterface ) {
result := icmd . RunCommand ( "kill" , "-0" , strings . TrimSpace ( pid ) )
return result . ExitCode , nil
} , checker . Equals , 0 )
2016-06-17 15:21:03 +00:00
// restart the daemon
2016-12-09 22:20:14 +00:00
s . d . Start ( t , "--live-restore" )
2016-06-17 15:21:03 +00:00
// Check that we've got the correct status
out , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Status}}" , cid )
2019-04-04 13:23:19 +00:00
assert . NilError ( t , err )
2016-06-17 15:21:03 +00:00
out = strings . TrimSpace ( out )
if out != "running" {
t . Fatalf ( "Expected exit code '%s' got '%s' for container '%s'\n" , "running" , out , cid )
}
if _ , err := s . d . Cmd ( "kill" , cid ) ; err != nil {
t . Fatal ( err )
}
2015-09-04 00:51:04 +00:00
}
// TestRunLinksChanged checks that creating a new container with the same name does not update links
// this ensures that the old, pre gh#16032 functionality continues on
func ( s * DockerDaemonSuite ) TestRunLinksChanged ( c * check . C ) {
testRequires ( c , DaemonIsLinux ) // Windows does not support links
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2015-09-04 00:51:04 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "run" , "--name=test2" , "--link=test:abc" , "busybox" , "sh" , "-c" , "ping -c 1 abc" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
c . Assert ( out , checker . Contains , "1 packets transmitted, 1 packets received" )
out , err = s . d . Cmd ( "rm" , "-f" , "test" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2015-09-04 00:51:04 +00:00
c . Assert ( out , check . Not ( checker . Contains ) , "1 packets transmitted, 1 packets received" )
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2015-09-04 00:51:04 +00:00
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2015-09-04 00:51:04 +00:00
c . Assert ( out , check . Not ( checker . Contains ) , "1 packets transmitted, 1 packets received" )
}
2016-01-28 18:33:35 +00:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithoutColors ( c * check . C ) {
2017-08-08 17:39:55 +00:00
testRequires ( c , DaemonIsLinux )
2016-01-28 18:33:35 +00:00
2017-08-08 17:39:55 +00:00
infoLog := "\x1b[36mINFO\x1b"
2016-01-28 18:33:35 +00:00
2016-12-29 08:34:11 +00:00
b := bytes . NewBuffer ( nil )
done := make ( chan bool )
2016-01-28 18:33:35 +00:00
p , tty , err := pty . Open ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-01-28 18:33:35 +00:00
defer func ( ) {
tty . Close ( )
p . Close ( )
} ( )
2016-12-29 08:34:11 +00:00
go func ( ) {
io . Copy ( b , p )
done <- true
} ( )
2016-01-28 18:33:35 +00:00
// Enable coloring explicitly
2016-08-30 21:25:16 +00:00
s . d . StartWithLogFile ( tty , "--raw-logs=false" )
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2016-12-29 08:34:11 +00:00
// Wait for io.Copy() before checking output
<- done
2016-01-28 18:33:35 +00:00
c . Assert ( b . String ( ) , checker . Contains , infoLog )
b . Reset ( )
2016-12-29 08:34:11 +00:00
// "tty" is already closed in prev s.d.Stop(),
// we have to close the other side "p" and open another pair of
// pty for the next test.
p . Close ( )
p , tty , err = pty . Open ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-29 08:34:11 +00:00
go func ( ) {
io . Copy ( b , p )
done <- true
} ( )
2016-01-28 18:33:35 +00:00
// Disable coloring explicitly
2016-08-30 21:25:16 +00:00
s . d . StartWithLogFile ( tty , "--raw-logs=true" )
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2016-12-29 08:34:11 +00:00
// Wait for io.Copy() before checking output
<- done
c . Assert ( b . String ( ) , check . Not ( check . Equals ) , "" )
2016-01-28 18:33:35 +00:00
c . Assert ( b . String ( ) , check . Not ( checker . Contains ) , infoLog )
}
2016-02-01 23:09:25 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDebugLog ( c * check . C ) {
2017-08-08 17:39:55 +00:00
testRequires ( c , DaemonIsLinux )
2016-02-01 23:09:25 +00:00
debugLog := "\x1b[37mDEBU\x1b"
p , tty , err := pty . Open ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-02-01 23:09:25 +00:00
defer func ( ) {
tty . Close ( )
p . Close ( )
} ( )
b := bytes . NewBuffer ( nil )
go io . Copy ( b , p )
2016-08-30 21:25:16 +00:00
s . d . StartWithLogFile ( tty , "--debug" )
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2016-02-01 23:09:25 +00:00
c . Assert ( b . String ( ) , checker . Contains , debugLog )
}
2016-02-18 19:00:26 +00:00
2016-08-30 21:25:16 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDiscoveryBackendConfigReload ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-02-18 19:00:26 +00:00
// daemon config file
2016-07-28 15:58:06 +00:00
daemonConfig := ` { "debug" : false } `
configFile , err := ioutil . TempFile ( "" , "test-daemon-discovery-backend-config-reload-config" )
c . Assert ( err , checker . IsNil , check . Commentf ( "could not create temp file for config reload" ) )
configFilePath := configFile . Name ( )
defer func ( ) {
configFile . Close ( )
os . RemoveAll ( configFile . Name ( ) )
} ( )
_ , err = configFile . Write ( [ ] byte ( daemonConfig ) )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-02-18 19:00:26 +00:00
2016-08-03 16:20:46 +00:00
// --log-level needs to be set so that d.Start() doesn't add --debug causing
// a conflict with the config
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--config-file" , configFilePath , "--log-level=info" )
2016-02-18 19:00:26 +00:00
// daemon config file
2016-07-28 15:58:06 +00:00
daemonConfig = ` {
2016-02-18 19:00:26 +00:00
"cluster-store" : "consul://consuladdr:consulport/some/path" ,
"cluster-advertise" : "192.168.56.100:0" ,
"debug" : false
} `
2016-07-28 15:58:06 +00:00
err = configFile . Truncate ( 0 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-07-28 15:58:06 +00:00
_ , err = configFile . Seek ( 0 , os . SEEK_SET )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-02-18 19:00:26 +00:00
2016-07-28 15:58:06 +00:00
_ , err = configFile . Write ( [ ] byte ( daemonConfig ) )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-02-18 19:00:26 +00:00
2016-12-09 09:17:53 +00:00
err = s . d . ReloadConfig ( )
2016-07-28 15:58:06 +00:00
c . Assert ( err , checker . IsNil , check . Commentf ( "error reloading daemon config" ) )
2016-02-18 19:00:26 +00:00
2016-08-30 21:25:16 +00:00
out , err := s . d . Cmd ( "info" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-08-03 16:20:46 +00:00
2016-03-28 07:46:53 +00:00
c . Assert ( out , checker . Contains , fmt . Sprintf ( "Cluster Store: consul://consuladdr:consulport/some/path" ) )
c . Assert ( out , checker . Contains , fmt . Sprintf ( "Cluster Advertise: 192.168.56.100:0" ) )
2016-02-18 19:00:26 +00:00
}
2016-04-11 23:07:02 +00:00
// Test for #21956
func ( s * DockerDaemonSuite ) TestDaemonLogOptions ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--log-driver=syslog" , "--log-opt=syslog-address=udp://127.0.0.1:514" )
2016-04-11 23:07:02 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--log-driver=json-file" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-04-11 23:07:02 +00:00
id := strings . TrimSpace ( out )
out , err = s . d . Cmd ( "inspect" , "--format='{{.HostConfig.LogConfig}}'" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-04-11 23:07:02 +00:00
c . Assert ( out , checker . Contains , "{json-file map[]}" )
}
2016-05-06 04:45:55 +00:00
// Test case for #20936, #22443
func ( s * DockerDaemonSuite ) TestDaemonMaxConcurrency ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . Start ( c , "--max-concurrent-uploads=6" , "--max-concurrent-downloads=8" )
2016-05-06 04:45:55 +00:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 6" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 8" `
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
}
// Test case for #20936, #22443
func ( s * DockerDaemonSuite ) TestDaemonMaxConcurrencyWithConfigFile ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-05-06 04:45:55 +00:00
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
defer os . Remove ( configFilePath )
daemonConfig := ` { "max-concurrent-downloads" : 8 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 22:20:14 +00:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-06 04:45:55 +00:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 5" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 8" `
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
daemonConfig = ` { "max-concurrent-uploads" : 7, "max-concurrent-downloads" : 9 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
// unix.Kill(s.d.cmd.Process.Pid, unix.SIGHUP)
2016-05-06 04:45:55 +00:00
time . Sleep ( 3 * time . Second )
expectedMaxConcurrentUploads = ` level=debug msg="Reset Max Concurrent Uploads: 7" `
expectedMaxConcurrentDownloads = ` level=debug msg="Reset Max Concurrent Downloads: 9" `
2016-12-09 09:17:53 +00:00
content , err = s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
}
// Test case for #20936, #22443
func ( s * DockerDaemonSuite ) TestDaemonMaxConcurrencyWithConfigFileReload ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-05-06 04:45:55 +00:00
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
defer os . Remove ( configFilePath )
daemonConfig := ` { "max-concurrent-uploads" : null } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 22:20:14 +00:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-06 04:45:55 +00:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 5" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 3" `
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
daemonConfig = ` { "max-concurrent-uploads" : 1, "max-concurrent-downloads" : null } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
// unix.Kill(s.d.cmd.Process.Pid, unix.SIGHUP)
2016-05-06 04:45:55 +00:00
time . Sleep ( 3 * time . Second )
expectedMaxConcurrentUploads = ` level=debug msg="Reset Max Concurrent Uploads: 1" `
expectedMaxConcurrentDownloads = ` level=debug msg="Reset Max Concurrent Downloads: 3" `
2016-12-09 09:17:53 +00:00
content , err = s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
daemonConfig = ` { "labels":["foo=bar"] } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-06 04:45:55 +00:00
time . Sleep ( 3 * time . Second )
expectedMaxConcurrentUploads = ` level=debug msg="Reset Max Concurrent Uploads: 5" `
expectedMaxConcurrentDownloads = ` level=debug msg="Reset Max Concurrent Downloads: 3" `
2016-12-09 09:17:53 +00:00
content , err = s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-06 04:45:55 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
}
2016-05-24 08:13:54 +00:00
func ( s * DockerDaemonSuite ) TestBuildOnDisabledBridgeNetworkDaemon ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "-b=none" , "--iptables=false" )
2018-04-18 14:45:55 +00:00
result := cli . BuildCmd ( c , "busyboxs" , cli . Daemon ( s . d ) ,
build . WithDockerfile ( `
FROM busybox
RUN cat / etc / hosts ` ) ,
build . WithoutCache ,
)
comment := check . Commentf ( "Failed to build image. output %s, exitCode %d, err %v" , result . Combined ( ) , result . ExitCode , result . Error )
c . Assert ( result . Error , check . IsNil , comment )
c . Assert ( result . ExitCode , check . Equals , 0 , comment )
2016-05-24 08:13:54 +00:00
}
2016-04-29 05:46:57 +00:00
// Test case for #21976
2017-01-02 22:42:45 +00:00
func ( s * DockerDaemonSuite ) TestDaemonDNSFlagsInHostMode ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-04-29 05:46:57 +00:00
2017-01-02 22:42:45 +00:00
s . d . StartWithBusybox ( c , "--dns" , "1.2.3.4" , "--dns-search" , "example.com" , "--dns-opt" , "timeout:3" )
2016-04-29 05:46:57 +00:00
expectedOutput := "nameserver 1.2.3.4"
out , _ := s . d . Cmd ( "run" , "--net=host" , "busybox" , "cat" , "/etc/resolv.conf" )
c . Assert ( out , checker . Contains , expectedOutput , check . Commentf ( "Expected '%s', but got %q" , expectedOutput , out ) )
2017-01-02 22:42:45 +00:00
expectedOutput = "search example.com"
2016-04-29 05:46:57 +00:00
c . Assert ( out , checker . Contains , expectedOutput , check . Commentf ( "Expected '%s', but got %q" , expectedOutput , out ) )
2017-01-02 22:42:45 +00:00
expectedOutput = "options timeout:3"
2016-04-29 05:46:57 +00:00
c . Assert ( out , checker . Contains , expectedOutput , check . Commentf ( "Expected '%s', but got %q" , expectedOutput , out ) )
}
2016-05-23 21:49:50 +00:00
func ( s * DockerDaemonSuite ) TestRunWithRuntimeFromConfigFile ( c * check . C ) {
conf , err := ioutil . TempFile ( "" , "config-file-" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-23 21:49:50 +00:00
configName := conf . Name ( )
conf . Close ( )
defer os . Remove ( configName )
config := `
{
"runtimes" : {
"oci" : {
2018-09-25 17:57:35 +00:00
"path" : "runc"
2016-05-23 21:49:50 +00:00
} ,
"vm" : {
"path" : "/usr/local/bin/vm-manager" ,
"runtimeArgs" : [
"--debug"
]
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--config-file" , configName )
2016-05-23 21:49:50 +00:00
// Run with default runtime
out , err := s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
2016-06-19 16:53:31 +00:00
// Run with default runtime explicitly
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with oci (same path as default) but keep it around
out , err = s . d . Cmd ( "run" , "--name" , "oci-runtime-ls" , "--runtime=oci" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with "vm"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=vm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
// Reset config to only have the default
config = `
{
"runtimes" : {
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 21:49:50 +00:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
// Run with default runtime
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with "oci"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=oci" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Start previously created container with oci
out , err = s . d . Cmd ( "start" , "oci-runtime-ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Check that we can't override the default runtime
config = `
{
"runtimes" : {
2016-06-20 19:14:27 +00:00
"runc" : {
"path" : "my-runc"
2016-05-23 21:49:50 +00:00
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 21:49:50 +00:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2018-11-24 13:47:40 +00:00
c . Assert ( string ( content ) , checker . Contains , ` file configuration validation failed: runtime name 'runc' is reserved ` )
2016-05-23 21:49:50 +00:00
// Check that we can select a default runtime
config = `
{
"default-runtime" : "vm" ,
"runtimes" : {
"oci" : {
2018-09-25 17:57:35 +00:00
"path" : "runc"
2016-05-23 21:49:50 +00:00
} ,
"vm" : {
"path" : "/usr/local/bin/vm-manager" ,
"runtimeArgs" : [
"--debug"
]
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 21:49:50 +00:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
out , err = s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
2016-06-19 16:53:31 +00:00
// Run with default runtime explicitly
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
}
func ( s * DockerDaemonSuite ) TestRunWithRuntimeFromCommandLine ( c * check . C ) {
2018-09-25 17:57:35 +00:00
s . d . StartWithBusybox ( c , "--add-runtime" , "oci=runc" , "--add-runtime" , "vm=/usr/local/bin/vm-manager" )
2016-05-23 21:49:50 +00:00
// Run with default runtime
out , err := s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
2016-06-19 16:53:31 +00:00
// Run with default runtime explicitly
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with oci (same path as default) but keep it around
out , err = s . d . Cmd ( "run" , "--name" , "oci-runtime-ls" , "--runtime=oci" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with "vm"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=vm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
// Start a daemon without any extra runtimes
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
s . d . StartWithBusybox ( c )
2016-05-23 21:49:50 +00:00
// Run with default runtime
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
// Run with "oci"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=oci" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Start previously created container with oci
out , err = s . d . Cmd ( "start" , "oci-runtime-ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Check that we can't override the default runtime
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
c . Assert ( s . d . StartWithError ( "--add-runtime" , "runc=my-runc" ) , checker . NotNil )
2016-05-23 21:49:50 +00:00
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-06-20 19:14:27 +00:00
c . Assert ( string ( content ) , checker . Contains , ` runtime name 'runc' is reserved ` )
2016-05-23 21:49:50 +00:00
// Check that we can select a default runtime
2016-12-09 22:20:14 +00:00
s . d . Stop ( c )
2018-09-25 17:57:35 +00:00
s . d . StartWithBusybox ( c , "--default-runtime=vm" , "--add-runtime" , "oci=runc" , "--add-runtime" , "vm=/usr/local/bin/vm-manager" )
2016-05-23 21:49:50 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-05-23 21:49:50 +00:00
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
2016-06-19 16:53:31 +00:00
// Run with default runtime explicitly
2016-06-20 19:14:27 +00:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-05-23 21:49:50 +00:00
}
2016-03-01 16:30:27 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithAutoRemoveContainer ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2016-03-01 16:30:27 +00:00
// top1 will exist after daemon restarts
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top1" , "busybox:latest" , "top" )
c . Assert ( err , checker . IsNil , check . Commentf ( "run top1: %v" , out ) )
// top2 will be removed after daemon restarts
out , err = s . d . Cmd ( "run" , "-d" , "--rm" , "--name" , "top2" , "busybox:latest" , "top" )
c . Assert ( err , checker . IsNil , check . Commentf ( "run top2: %v" , out ) )
out , err = s . d . Cmd ( "ps" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-03-01 16:30:27 +00:00
c . Assert ( out , checker . Contains , "top1" , check . Commentf ( "top1 should be running" ) )
c . Assert ( out , checker . Contains , "top2" , check . Commentf ( "top2 should be running" ) )
// now restart daemon gracefully
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2016-03-01 16:30:27 +00:00
out , err = s . d . Cmd ( "ps" , "-a" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "out: %v" , out )
2016-03-01 16:30:27 +00:00
c . Assert ( out , checker . Contains , "top1" , check . Commentf ( "top1 should exist after daemon restarts" ) )
c . Assert ( out , checker . Not ( checker . Contains ) , "top2" , check . Commentf ( "top2 should be removed after daemon restarts" ) )
}
2016-08-30 19:00:27 +00:00
func ( s * DockerDaemonSuite ) TestDaemonRestartSaveContainerExitCode ( c * check . C ) {
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c )
2016-08-30 19:00:27 +00:00
containerName := "error-values"
// Make a container with both a non 0 exit code and an error message
2017-01-18 02:08:31 +00:00
// We explicitly disable `--init` for this test, because `--init` is enabled by default
// on "experimental". Enabling `--init` results in a different behavior; because the "init"
// process itself is PID1, the container does not fail on _startup_ (i.e., `docker-init` starting),
// but directly after. The exit code of the container is still 127, but the Error Message is not
// captured, so `.State.Error` is empty.
// See the discussion on https://github.com/docker/docker/pull/30227#issuecomment-274161426,
// and https://github.com/docker/docker/pull/26061#r78054578 for more information.
2018-07-09 17:40:34 +00:00
_ , err := s . d . Cmd ( "run" , "--name" , containerName , "--init=false" , "busybox" , "toto" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2016-08-30 19:00:27 +00:00
// Check that those values were saved on disk
2018-07-09 17:40:34 +00:00
out , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , containerName )
2016-08-30 19:00:27 +00:00
out = strings . TrimSpace ( out )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
assert . Equal ( c , out , "127" )
2016-08-30 19:00:27 +00:00
2017-01-18 02:08:31 +00:00
errMsg1 , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Error}}" , containerName )
errMsg1 = strings . TrimSpace ( errMsg1 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-01-18 02:08:31 +00:00
c . Assert ( errMsg1 , checker . Contains , "executable file not found" )
2016-08-30 19:00:27 +00:00
// now restart daemon
2016-12-09 22:20:14 +00:00
s . d . Restart ( c )
2016-08-30 19:00:27 +00:00
// Check that those values are still around
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , containerName )
out = strings . TrimSpace ( out )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
assert . Equal ( c , out , "127" )
2016-08-30 19:00:27 +00:00
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.State.Error}}" , containerName )
out = strings . TrimSpace ( out )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
assert . Equal ( c , out , errMsg1 )
2016-08-30 19:00:27 +00:00
}
2016-09-06 13:49:10 +00:00
2016-09-24 13:44:25 +00:00
func ( s * DockerDaemonSuite ) TestDaemonWithUserlandProxyPath ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-09-24 13:44:25 +00:00
dockerProxyPath , err := exec . LookPath ( "docker-proxy" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-09-24 13:44:25 +00:00
tmpDir , err := ioutil . TempDir ( "" , "test-docker-proxy" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-09-24 13:44:25 +00:00
newProxyPath := filepath . Join ( tmpDir , "docker-proxy" )
cmd := exec . Command ( "cp" , dockerProxyPath , newProxyPath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , cmd . Run ( ) )
2016-09-24 13:44:25 +00:00
// custom one
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--userland-proxy-path" , newProxyPath )
2016-09-24 13:44:25 +00:00
out , err := s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-09-24 13:44:25 +00:00
// try with the original one
2016-12-09 22:20:14 +00:00
s . d . Restart ( c , "--userland-proxy-path" , dockerProxyPath )
2016-09-24 13:44:25 +00:00
out , err = s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-09-24 13:44:25 +00:00
// not exist
2016-12-09 22:20:14 +00:00
s . d . Restart ( c , "--userland-proxy-path" , "/does/not/exist" )
2016-09-24 13:44:25 +00:00
out , err = s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" , out )
2016-09-24 13:44:25 +00:00
c . Assert ( out , checker . Contains , "driver failed programming external connectivity on endpoint" )
c . Assert ( out , checker . Contains , "/does/not/exist: no such file or directory" )
}
2016-05-26 21:07:30 +00:00
// Test case for #22471
func ( s * DockerDaemonSuite ) TestDaemonShutdownTimeout ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon )
2016-12-09 22:20:14 +00:00
s . d . StartWithBusybox ( c , "--shutdown-timeout=3" )
2016-05-26 21:07:30 +00:00
_ , err := s . d . Cmd ( "run" , "-d" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-26 21:07:30 +00:00
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGINT ) , checker . IsNil )
2016-05-26 21:07:30 +00:00
select {
2016-12-09 09:17:53 +00:00
case <- s . d . Wait :
2016-05-26 21:07:30 +00:00
case <- time . After ( 5 * time . Second ) :
}
2017-10-12 23:31:33 +00:00
expectedMessage := ` level=debug msg="daemon configured with a 3 seconds minimum shutdown timeout" `
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-26 21:07:30 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMessage )
}
// Test case for #22471
func ( s * DockerDaemonSuite ) TestDaemonShutdownTimeoutWithConfigFile ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon )
2016-05-26 21:07:30 +00:00
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-26 21:07:30 +00:00
defer os . Remove ( configFilePath )
daemonConfig := ` { "shutdown-timeout" : 8 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 22:20:14 +00:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-26 21:07:30 +00:00
configFile , err = os . Create ( configFilePath )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-26 21:07:30 +00:00
daemonConfig = ` { "shutdown-timeout" : 5 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 14:22:32 +00:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-26 21:07:30 +00:00
select {
2016-12-09 09:17:53 +00:00
case <- s . d . Wait :
2016-05-26 21:07:30 +00:00
case <- time . After ( 3 * time . Second ) :
}
expectedMessage := ` level=debug msg="Reset Shutdown Timeout: 5" `
2016-12-09 09:17:53 +00:00
content , err := s . d . ReadLogFile ( )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-05-26 21:07:30 +00:00
c . Assert ( string ( content ) , checker . Contains , expectedMessage )
}
2016-12-13 16:06:42 +00:00
// Test case for 29342
func ( s * DockerDaemonSuite ) TestExecWithUserAfterLiveRestore ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
s . d . StartWithBusybox ( c , "--live-restore" )
2017-04-06 08:33:49 +00:00
out , err := s . d . Cmd ( "run" , "-d" , "--name=top" , "busybox" , "sh" , "-c" , "addgroup -S test && adduser -S -G test test -D -s /bin/sh && touch /adduser_end && top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-13 16:06:42 +00:00
2016-12-29 01:08:03 +00:00
s . d . WaitRun ( "top" )
2016-12-13 16:06:42 +00:00
2017-04-06 08:33:49 +00:00
// Wait for shell command to be completed
_ , err = s . d . Cmd ( "exec" , "top" , "sh" , "-c" , ` for i in $(seq 1 5); do if [ -e /adduser_end ]; then rm -f /adduser_end && break; else sleep 1 && false; fi; done ` )
c . Assert ( err , check . IsNil , check . Commentf ( "Timeout waiting for shell command to be completed" ) )
2016-12-13 16:06:42 +00:00
out1 , err := s . d . Cmd ( "exec" , "-u" , "test" , "top" , "id" )
// uid=100(test) gid=101(test) groups=101(test)
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out1 ) )
// restart daemon.
s . d . Restart ( c , "--live-restore" )
out2 , err := s . d . Cmd ( "exec" , "-u" , "test" , "top" , "id" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out2 ) )
2017-06-29 09:38:13 +00:00
c . Assert ( out2 , check . Equals , out1 , check . Commentf ( "Output: before restart '%s', after restart '%s'" , out1 , out2 ) )
2016-12-13 16:06:42 +00:00
out , err = s . d . Cmd ( "stop" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-13 16:06:42 +00:00
}
2016-12-29 01:08:03 +00:00
func ( s * DockerDaemonSuite ) TestRemoveContainerAfterLiveRestore ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , DaemonIsLinux , overlayFSSupported , testEnv . IsLocalDaemon )
2016-12-29 01:08:03 +00:00
s . d . StartWithBusybox ( c , "--live-restore" , "--storage-driver" , "overlay" )
out , err := s . d . Cmd ( "run" , "-d" , "--name=top" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-29 01:08:03 +00:00
s . d . WaitRun ( "top" )
// restart daemon.
s . d . Restart ( c , "--live-restore" , "--storage-driver" , "overlay" )
out , err = s . d . Cmd ( "stop" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-29 01:08:03 +00:00
// test if the rootfs mountpoint still exist
mountpoint , err := s . d . InspectField ( "top" , ".GraphDriver.Data.MergedDir" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-29 01:08:03 +00:00
f , err := os . Open ( "/proc/self/mountinfo" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-29 01:08:03 +00:00
defer f . Close ( )
sc := bufio . NewScanner ( f )
for sc . Scan ( ) {
line := sc . Text ( )
if strings . Contains ( line , mountpoint ) {
c . Fatalf ( "mountinfo should not include the mountpoint of stop container" )
}
}
out , err = s . d . Cmd ( "rm" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-28 01:44:38 +00:00
}
// #29598
func ( s * DockerDaemonSuite ) TestRestartPolicyWithLiveRestore ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , DaemonIsLinux , testEnv . IsLocalDaemon )
2016-12-28 01:44:38 +00:00
s . d . StartWithBusybox ( c , "--live-restore" )
out , err := s . d . Cmd ( "run" , "-d" , "--restart" , "always" , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-28 01:44:38 +00:00
id := strings . TrimSpace ( out )
2016-12-29 01:08:03 +00:00
2016-12-28 01:44:38 +00:00
type state struct {
Running bool
StartedAt time . Time
}
out , err = s . d . Cmd ( "inspect" , "-f" , "{{json .State}}" , id )
c . Assert ( err , checker . IsNil , check . Commentf ( "output: %s" , out ) )
var origState state
err = json . Unmarshal ( [ ] byte ( strings . TrimSpace ( out ) ) , & origState )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-28 01:44:38 +00:00
s . d . Restart ( c , "--live-restore" )
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-28 01:44:38 +00:00
pidint , err := strconv . Atoi ( strings . TrimSpace ( pid ) )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
assert . Assert ( c , pidint > 0 )
assert . NilError ( c , unix . Kill ( pidint , unix . SIGKILL ) )
2016-12-28 01:44:38 +00:00
ticker := time . NewTicker ( 50 * time . Millisecond )
timeout := time . After ( 10 * time . Second )
for range ticker . C {
select {
case <- timeout :
c . Fatal ( "timeout waiting for container restart" )
default :
}
out , err := s . d . Cmd ( "inspect" , "-f" , "{{json .State}}" , id )
c . Assert ( err , checker . IsNil , check . Commentf ( "output: %s" , out ) )
var newState state
err = json . Unmarshal ( [ ] byte ( strings . TrimSpace ( out ) ) , & newState )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-28 01:44:38 +00:00
if ! newState . Running {
continue
}
if newState . StartedAt . After ( origState . StartedAt ) {
break
}
}
out , err = s . d . Cmd ( "stop" , id )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-29 01:08:03 +00:00
}
2016-12-25 09:11:12 +00:00
func ( s * DockerDaemonSuite ) TestShmSize ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
size := 67108864 * 2
pattern := regexp . MustCompile ( fmt . Sprintf ( "shm on /dev/shm type tmpfs(.*)size=%dk" , size / 1024 ) )
s . d . StartWithBusybox ( c , "--default-shm-size" , fmt . Sprintf ( "%v" , size ) )
name := "shm1"
out , err := s . d . Cmd ( "run" , "--name" , name , "busybox" , "mount" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( strings . TrimSpace ( out ) , check . Equals , fmt . Sprintf ( "%v" , size ) )
}
func ( s * DockerDaemonSuite ) TestShmSizeReload ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
configPath , err := ioutil . TempDir ( "" , "test-daemon-shm-size-reload-config" )
c . Assert ( err , checker . IsNil , check . Commentf ( "could not create temp file for config reload" ) )
defer os . RemoveAll ( configPath ) // clean up
configFile := filepath . Join ( configPath , "config.json" )
size := 67108864 * 2
configData := [ ] byte ( fmt . Sprintf ( ` { "default-shm-size": "%dM"} ` , size / 1024 / 1024 ) )
c . Assert ( ioutil . WriteFile ( configFile , configData , 0666 ) , checker . IsNil , check . Commentf ( "could not write temp file for config reload" ) )
pattern := regexp . MustCompile ( fmt . Sprintf ( "shm on /dev/shm type tmpfs(.*)size=%dk" , size / 1024 ) )
s . d . StartWithBusybox ( c , "--config-file" , configFile )
name := "shm1"
out , err := s . d . Cmd ( "run" , "--name" , name , "busybox" , "mount" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( strings . TrimSpace ( out ) , check . Equals , fmt . Sprintf ( "%v" , size ) )
size = 67108864 * 3
configData = [ ] byte ( fmt . Sprintf ( ` { "default-shm-size": "%dM"} ` , size / 1024 / 1024 ) )
c . Assert ( ioutil . WriteFile ( configFile , configData , 0666 ) , checker . IsNil , check . Commentf ( "could not write temp file for config reload" ) )
pattern = regexp . MustCompile ( fmt . Sprintf ( "shm on /dev/shm type tmpfs(.*)size=%dk" , size / 1024 ) )
err = s . d . ReloadConfig ( )
c . Assert ( err , checker . IsNil , check . Commentf ( "error reloading daemon config" ) )
name = "shm2"
out , err = s . d . Cmd ( "run" , "--name" , name , "busybox" , "mount" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err , "Output: %s" , out )
2016-12-25 09:11:12 +00:00
c . Assert ( strings . TrimSpace ( out ) , check . Equals , fmt . Sprintf ( "%v" , size ) )
}
2017-06-26 18:54:14 +00:00
2017-07-19 18:24:54 +00:00
func testDaemonStartIpcMode ( c * check . C , from , mode string , valid bool ) {
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary , testdaemon . WithEnvironment ( testEnv . Execution ) )
2017-07-19 18:24:54 +00:00
c . Logf ( "Checking IpcMode %s set from %s\n" , mode , from )
var serr error
switch from {
case "config" :
f , err := ioutil . TempFile ( "" , "test-daemon-ipc-config" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-07-19 18:24:54 +00:00
defer os . Remove ( f . Name ( ) )
config := ` { "default-ipc-mode": " ` + mode + ` "} `
_ , err = f . WriteString ( config )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , f . Close ( ) )
assert . NilError ( c , err )
2017-07-19 18:24:54 +00:00
serr = d . StartWithError ( "--config-file" , f . Name ( ) )
case "cli" :
serr = d . StartWithError ( "--default-ipc-mode" , mode )
default :
c . Fatalf ( "testDaemonStartIpcMode: invalid 'from' argument" )
}
if serr == nil {
d . Stop ( c )
}
if valid {
2019-04-04 13:23:19 +00:00
assert . NilError ( c , serr )
2017-07-19 18:24:54 +00:00
} else {
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , serr , "" )
2017-07-19 18:24:54 +00:00
icmd . RunCommand ( "grep" , "-E" , "IPC .* is (invalid|not supported)" , d . LogFileName ( ) ) . Assert ( c , icmd . Success )
}
}
// TestDaemonStartWithIpcModes checks that daemon starts fine given correct
// arguments for default IPC mode, and bails out with incorrect ones.
// Both CLI option (--default-ipc-mode) and config parameter are tested.
func ( s * DockerDaemonSuite ) TestDaemonStartWithIpcModes ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , DaemonIsLinux , testEnv . IsLocalDaemon )
2017-08-24 13:46:41 +00:00
2017-07-19 18:24:54 +00:00
ipcModes := [ ] struct {
mode string
valid bool
} {
{ "private" , true } ,
{ "shareable" , true } ,
{ "host" , false } ,
{ "container:123" , false } ,
{ "nosuchmode" , false } ,
}
for _ , from := range [ ] string { "config" , "cli" } {
for _ , m := range ipcModes {
testDaemonStartIpcMode ( c , from , m . mode , m . valid )
}
}
}
2017-06-26 18:54:14 +00:00
// TestFailedPluginRemove makes sure that a failed plugin remove does not block
// the daemon from starting
func ( s * DockerDaemonSuite ) TestFailedPluginRemove ( c * check . C ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , DaemonIsLinux , IsAmd64 , testEnv . IsLocalDaemon )
2018-04-13 15:02:56 +00:00
d := daemon . New ( c , dockerBinary , dockerdBinary )
2017-06-26 18:54:14 +00:00
d . Start ( c )
2019-01-21 11:32:56 +00:00
cli := d . NewClientT ( c )
2017-06-26 18:54:14 +00:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , 300 * time . Second )
defer cancel ( )
name := "test-plugin-rm-fail"
out , err := cli . PluginInstall ( ctx , name , types . PluginInstallOptions {
Disabled : true ,
AcceptAllPermissions : true ,
RemoteRef : "cpuguy83/docker-logdriver-test" ,
} )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-06-26 18:54:14 +00:00
defer out . Close ( )
io . Copy ( ioutil . Discard , out )
ctx , cancel = context . WithTimeout ( context . Background ( ) , 30 * time . Second )
defer cancel ( )
p , _ , err := cli . PluginInspectWithRaw ( ctx , name )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-06-26 18:54:14 +00:00
// simulate a bad/partial removal by removing the plugin config.
configPath := filepath . Join ( d . Root , "plugins" , p . ID , "config.json" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , os . Remove ( configPath ) )
2017-06-26 18:54:14 +00:00
d . Restart ( c )
ctx , cancel = context . WithTimeout ( context . Background ( ) , 30 * time . Second )
defer cancel ( )
_ , err = cli . Ping ( ctx )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-06-26 18:54:14 +00:00
_ , _ , err = cli . PluginInspectWithRaw ( ctx , name )
// plugin should be gone since the config.json is gone
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2017-06-26 18:54:14 +00:00
}