2016-06-17 11:21:03 -04:00
// +build linux
2014-11-20 00:19:16 -05:00
2014-07-23 14:39:14 -04:00
package main
import (
2016-12-28 20:08:03 -05:00
"bufio"
2015-09-18 20:49:36 -04:00
"bytes"
2017-06-26 14:54:14 -04:00
"context"
2014-10-08 13:13:32 -04:00
"encoding/json"
2014-11-14 23:38:02 -05:00
"fmt"
2016-01-28 13:33:35 -05:00
"io"
2014-10-01 09:07:24 -04:00
"io/ioutil"
2015-04-27 16:16:33 -04:00
"net"
2014-10-08 13:13:32 -04:00
"os"
2014-10-05 00:21:59 -04:00
"os/exec"
2015-12-07 12:55:33 -05:00
"path"
2015-01-22 13:51:04 -05:00
"path/filepath"
2015-04-28 13:26:59 -04:00
"regexp"
2015-04-28 11:55:04 -04:00
"strconv"
2014-07-23 14:39:14 -04:00
"strings"
2015-11-24 15:25:12 -05:00
"sync"
2015-02-04 16:44:52 -05:00
"time"
2015-01-21 11:14:30 -05:00
2017-05-12 14:07:51 -04:00
"crypto/tls"
"crypto/x509"
"github.com/cloudflare/cfssl/helpers"
2017-06-26 14:54:14 -04:00
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
2016-12-30 12:23:00 -05:00
"github.com/docker/docker/integration-cli/checker"
2017-03-23 13:35:22 -04:00
"github.com/docker/docker/integration-cli/cli"
2016-12-09 04:17:53 -05:00
"github.com/docker/docker/integration-cli/daemon"
2017-05-12 14:07:51 -04:00
"github.com/docker/docker/opts"
2016-04-19 17:16:18 -04:00
"github.com/docker/docker/pkg/mount"
2016-09-06 09:49:10 -04:00
"github.com/docker/docker/pkg/stringid"
2016-12-27 20:44:38 -05:00
units "github.com/docker/go-units"
2015-05-06 18:39:29 -04:00
"github.com/docker/libnetwork/iptables"
2015-01-21 11:14:30 -05:00
"github.com/docker/libtrust"
2015-04-18 12:46:47 -04:00
"github.com/go-check/check"
2017-08-23 17:01:29 -04:00
"github.com/gotestyourself/gotestyourself/icmd"
2016-01-28 13:33:35 -05:00
"github.com/kr/pty"
2017-05-23 10:22:32 -04:00
"golang.org/x/sys/unix"
2014-07-23 14:39:14 -04:00
)
2016-05-26 07:14:35 -04: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 ( )
c . Assert ( err , checker . IsNil , check . Commentf ( "could not start daemon using 'docker daemon'" ) )
c . Assert ( cmd . Process . Kill ( ) , checker . IsNil )
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithRunningContainersPorts ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2014-07-23 14:39:14 -04:00
2017-03-23 13:35:22 -04:00
cli . Docker (
2017-03-27 11:12:48 -04:00
cli . Args ( "run" , "-d" , "--name" , "top1" , "-p" , "1234:80" , "--restart" , "always" , "busybox:latest" , "top" ) ,
2017-03-23 13:35:22 -04:00
cli . Daemon ( s . d ) ,
) . Assert ( c , icmd . Success )
cli . Docker (
2017-03-27 11:12:48 -04:00
cli . Args ( "run" , "-d" , "--name" , "top2" , "-p" , "80" , "busybox:latest" , "top" ) ,
2017-03-23 13:35:22 -04:00
cli . Daemon ( s . d ) ,
) . Assert ( c , icmd . Success )
2014-07-23 14:39:14 -04:00
testRun := func ( m map [ string ] bool , prefix string ) {
var format string
2015-04-18 12:46:47 -04:00
for cont , shouldRun := range m {
2017-03-27 11:12:48 -04:00
out := cli . Docker ( cli . Args ( "ps" ) , cli . Daemon ( s . d ) ) . Assert ( c , icmd . Success ) . Combined ( )
2014-07-23 14:39:14 -04:00
if shouldRun {
format = "%scontainer %q is not running"
} else {
format = "%scontainer %q is running"
}
2015-04-18 12:46:47 -04:00
if shouldRun != strings . Contains ( out , cont ) {
c . Fatalf ( format , prefix , cont )
2014-07-23 14:39:14 -04:00
}
}
}
testRun ( map [ string ] bool { "top1" : true , "top2" : true } , "" )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2014-07-23 14:39:14 -04:00
testRun ( map [ string ] bool { "top1" : true , "top2" : false } , "After daemon restart: " )
}
2014-10-08 13:13:32 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithVolumesRefs ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2014-10-08 13:13:32 -04:00
2016-02-28 05:47:37 -05:00
if out , err := s . d . Cmd ( "run" , "--name" , "volrestarttest1" , "-v" , "/foo" , "busybox" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err , out )
2014-10-08 13:13:32 -04:00
}
2015-06-03 15:21:38 -04:00
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-06-12 09:25:32 -04:00
2017-04-03 13:10:48 -04: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 13:13:32 -04:00
}
2015-06-03 15:21:38 -04:00
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "rm" , "-fv" , "volrestarttest2" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err , out )
2014-10-08 13:13:32 -04:00
}
2015-06-03 15:21:38 -04:00
out , err := s . d . Cmd ( "inspect" , "-f" , "{{json .Mounts}}" , "volrestarttest1" )
c . Assert ( err , check . IsNil )
if _ , err := inspectMountPointJSON ( out , "/foo" ) ; err != nil {
c . Fatalf ( "Expected volume to exist: /foo, error: %v\n" , err )
2014-10-08 13:13:32 -04:00
}
}
2014-10-16 14:39:22 -04:00
2015-08-05 17:09:08 -04:00
// #11008
func ( s * DockerDaemonSuite ) TestDaemonRestartUnlessStopped ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-08-05 17:09:08 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top1" , "--restart" , "always" , "busybox:latest" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "run top1: %v" , out ) )
out , err = s . d . Cmd ( "run" , "-d" , "--name" , "top2" , "--restart" , "unless-stopped" , "busybox:latest" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "run top2: %v" , out ) )
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
testRun ( map [ string ] bool { "top1" : true , "top2" : true } , "" )
out , err = s . d . Cmd ( "stop" , "top1" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "stop" , "top2" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// both stopped
testRun ( map [ string ] bool { "top1" : false , "top2" : false } , "" )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-08-05 17:09:08 -04:00
// restart=always running
testRun ( map [ string ] bool { "top1" : true , "top2" : false } , "After daemon restart: " )
out , err = s . d . Cmd ( "start" , "top2" )
c . Assert ( err , check . IsNil , check . Commentf ( "start top2: %v" , out ) )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-08-05 17:09:08 -04:00
// both running
testRun ( map [ string ] bool { "top1" : true , "top2" : true } , "After second daemon restart: " )
}
2016-03-22 11:46:40 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartOnFailure ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2016-03-22 11:46:40 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--name" , "test1" , "--restart" , "on-failure:3" , "busybox:latest" , "false" )
c . Assert ( err , check . IsNil , check . Commentf ( "run top1: %v" , out ) )
// wait test1 to stop
2016-12-09 04:17:53 -05:00
hostArgs := [ ] string { "--host" , s . d . Sock ( ) }
2016-03-22 11:46:40 -04:00
err = waitInspectWithArgs ( "test1" , "{{.State.Running}} {{.State.Restarting}}" , "false false" , 10 * time . Second , hostArgs ... )
c . Assert ( err , checker . IsNil , check . Commentf ( "test1 should exit but not" ) )
// record last start time
out , err = s . d . Cmd ( "inspect" , "-f={{.State.StartedAt}}" , "test1" )
c . Assert ( err , checker . IsNil , check . Commentf ( "out: %v" , out ) )
lastStartTime := out
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2016-03-22 11:46:40 -04:00
// test1 shouldn't restart at all
err = waitInspectWithArgs ( "test1" , "{{.State.Running}} {{.State.Restarting}}" , "false false" , 0 , hostArgs ... )
c . Assert ( err , checker . IsNil , check . Commentf ( "test1 should exit but not" ) )
// 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" )
c . Assert ( err , checker . IsNil , check . Commentf ( "out: %v" , out ) )
c . Assert ( out , checker . Equals , lastStartTime , check . Commentf ( "test1 shouldn't start after daemon restarts" ) )
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonStartIptablesFalse ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--iptables=false" )
2014-10-16 14:39:22 -04:00
}
2014-10-05 00:21:59 -04:00
2016-02-04 10:05:41 -05:00
// Make sure we cannot shrink base device at daemon restart.
func ( s * DockerDaemonSuite ) TestDaemonRestartWithInvalidBasesize ( c * check . C ) {
testRequires ( c , Devicemapper )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
2016-02-04 10:05:41 -05:00
2017-08-22 17:07:52 -04:00
oldBasesizeBytes := getBaseDeviceSize ( c , s . d )
2016-02-04 10:05:41 -05:00
var newBasesizeBytes int64 = 1073741824 //1GB in bytes
if newBasesizeBytes < oldBasesizeBytes {
2016-12-09 17:20:14 -05:00
err := s . d . RestartWithError ( "--storage-opt" , fmt . Sprintf ( "dm.basesize=%d" , newBasesizeBytes ) )
2017-03-29 05:32:25 -04: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 10:05:41 -05:00
}
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2016-02-04 10:05:41 -05:00
}
// Make sure we can grow base device at daemon restart.
func ( s * DockerDaemonSuite ) TestDaemonRestartWithIncreasedBasesize ( c * check . C ) {
testRequires ( c , Devicemapper )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
2016-02-04 10:05:41 -05:00
2017-08-22 17:07:52 -04:00
oldBasesizeBytes := getBaseDeviceSize ( c , s . d )
2016-02-04 10:05:41 -05: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 17:20:14 -05:00
err := s . d . RestartWithError ( "--storage-opt" , fmt . Sprintf ( "dm.basesize=%d" , newBasesizeBytes ) )
2016-02-04 10:05:41 -05: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 17:07:52 -04:00
basesizeAfterRestart := getBaseDeviceSize ( c , s . d )
2016-02-04 10:05:41 -05: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 17:20:14 -05:00
s . d . Stop ( c )
2016-02-04 10:05:41 -05:00
}
2017-08-22 17:07:52 -04: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 ) )
c . Assert ( err , check . IsNil )
return size
}
2016-12-28 17:00:32 -05: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 10:05:41 -05:00
2014-10-05 00:21:59 -04: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-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonStartBridgeWithoutIPAssociation ( c * check . C ) {
2014-10-05 00:21:59 -04: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 17:20:14 -05:00
s . d . Start ( c )
s . d . Stop ( c )
2014-10-05 00:21:59 -04:00
// now we will remove the ip from docker0 and then try starting the daemon
2016-12-13 15:21:51 -05:00
icmd . RunCommand ( "ip" , "addr" , "flush" , "dev" , "docker0" ) . Assert ( c , icmd . Success )
2014-10-05 00:21:59 -04:00
2016-12-09 17:20:14 -05:00
if err := s . d . StartWithError ( ) ; err != nil {
2014-10-05 00:21:59 -04:00
warning := "**WARNING: Docker bridge network in bad state--delete docker0 bridge interface to fix"
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not start daemon when docker0 has no IP address: %v\n%s" , err , warning )
2014-10-05 00:21:59 -04:00
}
}
2014-09-30 15:18:26 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonIptablesClean ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2014-09-30 15:18:26 -04:00
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top" , "-p" , "80" , "busybox:latest" , "top" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not run top: %s, %v" , out , err )
2014-09-30 15:18:26 -04:00
}
ipTablesSearchString := "tcp dpt:80"
2017-01-05 06:38:34 -05:00
// get output from iptables with container running
verifyIPTablesContains ( c , ipTablesSearchString )
2014-09-30 15:18:26 -04:00
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2014-09-30 15:18:26 -04:00
// get output from iptables after restart
2017-01-05 06:38:34 -05:00
verifyIPTablesDoesNotContains ( c , ipTablesSearchString )
2014-09-30 15:18:26 -04:00
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonIptablesCreate ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2014-09-30 15:18:26 -04:00
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "top" , "--restart=always" , "-p" , "80" , "busybox:latest" , "top" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not run top: %s, %v" , out , err )
2014-09-30 15:18:26 -04:00
}
// get output from iptables with container running
ipTablesSearchString := "tcp dpt:80"
2017-01-05 06:38:34 -05:00
verifyIPTablesContains ( c , ipTablesSearchString )
2014-09-30 15:18:26 -04:00
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2014-09-30 15:18:26 -04:00
// make sure the container is not running
2016-06-23 12:24:28 -04:00
runningOut , err := s . d . Cmd ( "inspect" , "--format={{.State.Running}}" , "top" )
2014-09-30 15:18:26 -04:00
if err != nil {
2017-01-05 06:38:34 -05:00
c . Fatalf ( "Could not inspect on container: %s, %v" , runningOut , err )
2014-09-30 15:18:26 -04:00
}
if strings . TrimSpace ( runningOut ) != "true" {
2015-04-18 12:46:47 -04: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 15:18:26 -04:00
}
// get output from iptables after restart
2017-01-05 06:38:34 -05: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 15:18:26 -04:00
}
2017-01-05 06:38:34 -05:00
}
2014-09-30 15:18:26 -04:00
2017-01-05 06:38:34 -05: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 15:18:26 -04:00
}
}
2014-10-01 09:07:24 -04:00
2015-04-28 07:50:20 -04: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 17:25:16 -04:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6Enabled ( c * check . C ) {
2015-04-28 07:50:20 -04:00
testRequires ( c , IPv6 )
2016-08-03 12:20:46 -04:00
setupV6 ( c )
defer teardownV6 ( c )
2015-04-28 07:50:20 -04:00
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--ipv6" )
2015-04-28 07:50:20 -04: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 10:03:14 -04:00
break
2015-04-28 07:50:20 -04:00
}
}
if ! found {
c . Fatalf ( "Bridge does not have an IPv6 Address" )
}
2016-08-30 17:25:16 -04:00
if out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "busybox:latest" ) ; err != nil {
2015-04-28 07:50:20 -04:00
c . Fatalf ( "Could not run container: %s, %v" , out , err )
}
2016-08-30 17:25:16 -04:00
out , err := s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.Networks.bridge.LinkLocalIPv6Address}}'" , "ipv6test" )
2015-04-28 07:50:20 -04:00
out = strings . Trim ( out , " \r\n'" )
if err != nil {
c . Fatalf ( "Error inspecting container: %s, %v" , out , err )
}
if ip := net . ParseIP ( out ) ; ip == nil {
c . Fatalf ( "Container should have a link-local IPv6 address" )
}
2016-08-30 17:25:16 -04:00
out , err = s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'" , "ipv6test" )
2015-04-28 07:50:20 -04:00
out = strings . Trim ( out , " \r\n'" )
if err != nil {
c . Fatalf ( "Error inspecting container: %s, %v" , out , err )
}
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 04:23:21 -05:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6FixedCIDR ( c * check . C ) {
2016-02-10 22:27:02 -05:00
// IPv6 setup is messing with local bridge address.
testRequires ( c , SameHostDaemon )
2017-01-09 14:40:27 -05: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 07:50:20 -04:00
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--ipv6" , "--fixed-cidr-v6=2001:db8:2::/64" , "--default-gateway-v6=2001:db8:2::100" )
2015-04-28 07:50:20 -04:00
2016-01-25 04:23:21 -05:00
out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "busybox:latest" )
c . Assert ( err , checker . IsNil , check . Commentf ( "Could not run container: %s, %v" , out , err ) )
2015-04-28 07:50:20 -04:00
2016-08-03 12:20:46 -04:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}" , "ipv6test" )
2015-04-28 07:50:20 -04:00
out = strings . Trim ( out , " \r\n'" )
2016-01-25 04:23:21 -05:00
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
2015-04-28 07:50:20 -04:00
2016-01-25 04:23:21 -05:00
ip := net . ParseIP ( out )
c . Assert ( ip , checker . NotNil , check . Commentf ( "Container should have a global IPv6 address" ) )
2015-12-30 17:51:51 -05:00
2016-08-03 12:20:46 -04:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.IPv6Gateway}}" , "ipv6test" )
2016-01-25 04:23:21 -05:00
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
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 07:50:20 -04:00
}
2015-11-11 00:14:05 -05:00
// TestDaemonIPv6FixedCIDRAndMac checks that when the daemon is started with ipv6 fixed CIDR
2016-05-07 21:36:10 -04:00
// the running containers are given an IPv6 address derived from the MAC address and the ipv6 fixed CIDR
2016-01-25 04:23:21 -05:00
func ( s * DockerDaemonSuite ) TestDaemonIPv6FixedCIDRAndMac ( c * check . C ) {
2016-02-10 22:27:02 -05:00
// IPv6 setup is messing with local bridge address.
testRequires ( c , SameHostDaemon )
2017-01-09 14:40:27 -05: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 00:14:05 -05:00
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--ipv6" , "--fixed-cidr-v6=2001:db8:1::/64" )
2015-11-11 00:14:05 -05:00
2016-01-25 04:23:21 -05:00
out , err := s . d . Cmd ( "run" , "-itd" , "--name=ipv6test" , "--mac-address" , "AA:BB:CC:DD:EE:FF" , "busybox" )
2015-11-11 00:14:05 -05:00
c . Assert ( err , checker . IsNil )
2016-08-03 12:20:46 -04:00
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}" , "ipv6test" )
2015-11-11 00:14:05 -05:00
c . Assert ( err , checker . IsNil )
c . Assert ( strings . Trim ( out , " \r\n'" ) , checker . Equals , "2001:db8:1::aabb:ccdd:eeff" )
}
2017-04-07 19:57:53 -04: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 ) {
testRequires ( c , SameHostDaemon )
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" )
c . Assert ( err , checker . IsNil , check . Commentf ( "Could not run container: %s, %v" , out , err ) )
out , err = s . d . Cmd ( "exec" , "hostcnt" , "ip" , "-6" , "addr" , "show" , "docker0" )
out = strings . Trim ( out , " \r\n'" )
c . Assert ( out , checker . Contains , "2001:db8:2::1" )
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelWrong ( c * check . C ) {
2016-12-09 17:20:14 -05:00
c . Assert ( s . d . StartWithError ( "--log-level=bogus" ) , check . NotNil , check . Commentf ( "Daemon shouldn't start with wrong log level" ) )
2015-04-25 22:47:42 -04:00
}
2014-10-01 09:07:24 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelDebug ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--log-level=debug" )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-03-11 13:43:56 -04:00
if ! strings . Contains ( string ( content ) , ` level=debug ` ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( ` Missing level="debug" in log file:\n%s ` , string ( content ) )
2014-10-01 09:07:24 -04:00
}
2015-04-25 22:47:42 -04:00
}
2014-10-01 09:07:24 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLogLevelFatal ( c * check . C ) {
// we creating new daemons to create new logFile
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--log-level=fatal" )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-03-11 13:43:56 -04:00
if strings . Contains ( string ( content ) , ` level=debug ` ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( ` Should not have level="debug" in log file:\n%s ` , string ( content ) )
2014-10-01 09:07:24 -04:00
}
2015-04-25 22:47:42 -04:00
}
2014-10-01 09:07:24 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonFlagD ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "-D" )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-05-14 13:07:21 -04: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 09:07:24 -04:00
}
2015-04-25 22:47:42 -04:00
}
2014-10-01 09:07:24 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonFlagDebug ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--debug" )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-05-14 13:07:21 -04: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 09:07:24 -04:00
}
2015-04-25 22:47:42 -04:00
}
2014-10-01 09:07:24 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonFlagDebugLogLevelFatal ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--debug" , "--log-level=fatal" )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-05-14 13:07:21 -04: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 09:07:24 -04:00
}
}
2014-11-14 23:38:02 -05:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonAllocatesListeningPort ( c * check . C ) {
2014-11-14 23:38:02 -05: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 10:00:43 -04:00
cmdArgs := make ( [ ] string , 0 , len ( listeningPorts ) * 2 )
2014-11-14 23:38:02 -05:00
for _ , hostDirective := range listeningPorts {
cmdArgs = append ( cmdArgs , "--host" , fmt . Sprintf ( "tcp://%s:%s" , hostDirective [ 0 ] , hostDirective [ 2 ] ) )
}
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , cmdArgs ... )
2014-11-14 23:38:02 -05:00
for _ , hostDirective := range listeningPorts {
2015-04-25 22:47:42 -04:00
output , err := s . d . Cmd ( "run" , "-p" , fmt . Sprintf ( "%s:%s:80" , hostDirective [ 1 ] , hostDirective [ 2 ] ) , "busybox" , "true" )
2014-11-14 23:38:02 -05:00
if err == nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Container should not start, expected port already allocated error: %q" , output )
2014-11-14 23:38:02 -05:00
} else if ! strings . Contains ( output , "port is already allocated" ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Expected port is already allocated error: %q" , output )
2014-11-14 23:38:02 -05:00
}
}
}
2015-01-16 14:48:25 -05:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonKeyGeneration ( c * check . C ) {
2015-01-22 13:29:15 -05:00
// TODO: skip or update for Windows daemon
2015-01-21 11:14:30 -05:00
os . Remove ( "/etc/docker/key.json" )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
s . d . Stop ( c )
2015-01-21 11:14:30 -05:00
k , err := libtrust . LoadKeyFile ( "/etc/docker/key.json" )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error opening key file" )
2015-01-21 11:14:30 -05:00
}
kid := k . KeyID ( )
// Test Key ID is a valid fingerprint (e.g. QQXN:JY5W:TBXI:MK3X:GX6P:PD5D:F56N:NHCS:LVRZ:JA46:R24J:XEFF)
if len ( kid ) != 59 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Bad key ID: %s" , kid )
2015-01-21 11:14:30 -05:00
}
}
2015-01-22 13:51:04 -05:00
2015-03-11 10:33:06 -04: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-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonExitOnFailure ( c * check . C ) {
2015-03-11 10:33:06 -04:00
//attempt to start daemon with incorrect flags (we know -b and --bip conflict)
2016-12-09 17:20:14 -05:00
if err := s . d . StartWithError ( "--bridge" , "nosuchbridge" , "--bip" , "1.1.1.1" ) ; err != nil {
2015-03-11 10:33:06 -04:00
//verify we got the right error
2016-03-25 17:42:30 -04:00
if ! strings . Contains ( err . Error ( ) , "Daemon exited" ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Expected daemon not to start, got %v" , err )
2015-03-11 10:33:06 -04:00
}
// look in the log and make sure we got the message that daemon is shutting down
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "grep" , "Error starting daemon" , s . d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-03-11 10:33:06 -04:00
} else {
//if we didn't get an error and the daemon is running, this is a failure
2015-04-18 12:46:47 -04:00
c . Fatal ( "Conflicting options should cause the daemon to error out with a failure" )
2015-03-11 10:33:06 -04:00
}
}
2015-04-27 16:16:33 -04:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeExternal ( c * check . C ) {
d := s . d
2016-12-09 17:20:14 -05:00
err := d . StartWithError ( "--bridge" , "nosuchbridge" )
2015-04-28 19:17:00 -04:00
c . Assert ( err , check . NotNil , check . Commentf ( "--bridge option with an invalid bridge should cause the daemon to fail" ) )
2016-12-09 17:20:14 -05:00
defer d . Restart ( c )
2015-04-27 16:16:33 -04:00
bridgeName := "external-bridge"
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
_ , bridgeIPNet , _ := net . ParseCIDR ( bridgeIP )
2015-04-27 16:16:33 -04:00
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 14:41:13 -04:00
defer deleteInterface ( c , bridgeName )
2015-04-27 16:16:33 -04:00
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bridge" , bridgeName )
2015-04-27 16:16:33 -04:00
ipTablesSearchString := bridgeIPNet . String ( )
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-27 16:16:33 -04:00
_ , err = d . Cmd ( "run" , "-d" , "--name" , "ExtContainer" , "busybox" , "top" )
c . Assert ( err , check . IsNil )
2016-12-09 04:18:02 -05:00
containerIP , err := d . FindContainerIP ( "ExtContainer" )
c . Assert ( err , checker . IsNil )
2015-07-22 08:59:24 -04:00
ip := net . ParseIP ( containerIP )
2015-04-27 16:16:33 -04: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 08:59:24 -04:00
containerIP ) )
2015-04-27 16:16:33 -04:00
}
2016-09-27 16:16:00 -04:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeNone ( c * check . C ) {
// start with bridge none
d := s . d
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bridge" , "none" )
defer d . Restart ( c )
2016-09-27 16:16:00 -04:00
// verify docker0 iface is not there
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "ifconfig" , "docker0" ) . Assert ( c , icmd . Expected {
ExitCode : 1 ,
Error : "exit status 1" ,
Err : "Device not found" ,
} )
2016-09-27 16:16:00 -04:00
// verify default "bridge" network is not there
2017-01-05 06:38:34 -05:00
out , err := d . Cmd ( "network" , "inspect" , "bridge" )
2016-09-27 16:16:00 -04:00
c . Assert ( err , check . NotNil , check . Commentf ( "\"bridge\" network should not be present if daemon started with --bridge=none" ) )
c . Assert ( strings . Contains ( out , "No such network" ) , check . Equals , true )
}
2017-01-05 06:38:34 -05: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 19:17:00 -04:00
}
2015-04-29 14:41:13 -04:00
func deleteInterface ( c * check . C , ifName string ) {
2017-01-05 06:38:34 -05: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-27 23:36:40 -04: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 18:24:18 -04:00
// 6. Restart the Docker Daemon (via deferred action)
2015-04-27 23:36:40 -04:00
// This Restart takes care of bringing docker0 interface back to auto-assigned IP
defaultNetworkBridge := "docker0"
2015-04-28 13:26:59 -04:00
deleteInterface ( c , defaultNetworkBridge )
2015-04-27 23:36:40 -04:00
d := s . d
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
ip , bridgeIPNet , _ := net . ParseCIDR ( bridgeIP )
2015-04-27 23:36:40 -04:00
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bip" , bridgeIP )
defer d . Restart ( c )
2015-04-27 23:36:40 -04:00
ifconfigSearchString := ip . String ( )
2016-12-13 15:21:51 -05:00
icmd . RunCommand ( "ifconfig" , defaultNetworkBridge ) . Assert ( c , icmd . Expected {
Out : ifconfigSearchString ,
} )
2015-04-27 23:36:40 -04:00
ipTablesSearchString := bridgeIPNet . String ( )
2016-12-13 15:21:51 -05:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-27 23:36:40 -04:00
2016-12-13 15:21:51 -05:00
_ , err := d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2015-04-27 23:36:40 -04:00
c . Assert ( err , check . IsNil )
2016-12-09 04:18:02 -05:00
containerIP , err := d . FindContainerIP ( "test" )
c . Assert ( err , checker . IsNil )
2015-07-22 08:59:24 -04:00
ip = net . ParseIP ( containerIP )
2015-04-27 23:36:40 -04: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 08:59:24 -04:00
containerIP ) )
2015-04-28 13:26:59 -04:00
deleteInterface ( c , defaultNetworkBridge )
2015-04-27 23:36:40 -04:00
}
2015-04-16 03:09:36 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithBridgeIPChange ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
defer s . d . Restart ( c )
s . d . Stop ( c )
2015-04-16 03:09:36 -04: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 15:21:51 -05:00
icmd . RunCommand ( "ifconfig" , "docker0" , bridgeIP ) . Assert ( c , icmd . Success )
2015-04-16 03:09:36 -04:00
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--bip" , bridgeIP )
2015-04-16 03:09:36 -04:00
//check if the iptables contains new bridgeIP MASQUERADE rule
ipTablesSearchString := bridgeIPNet . String ( )
2016-12-13 15:21:51 -05:00
icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" ) . Assert ( c , icmd . Expected {
Out : ipTablesSearchString ,
} )
2015-04-16 03:09:36 -04:00
}
2015-04-28 11:55:04 -04:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCidr ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
2015-04-28 11:55:04 -04:00
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 14:41:13 -04:00
defer deleteInterface ( c , bridgeName )
2015-04-28 11:55:04 -04:00
2015-04-28 19:17:00 -04:00
args := [ ] string { "--bridge" , bridgeName , "--fixed-cidr" , "192.169.1.0/30" }
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , args ... )
defer d . Restart ( c )
2015-04-28 11:55:04 -04: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 {
2015-10-10 12:43:03 -04:00
c . Assert ( strings . Contains ( out , "no available IPv4 addresses" ) , check . Equals , true ,
2015-04-28 11:55:04 -04:00
check . Commentf ( "Could not run a Container : %s %s" , err . Error ( ) , out ) )
}
}
2015-04-28 13:26:59 -04:00
}
2015-11-09 18:30:30 -05:00
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCidr2 ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
bridgeIP := "10.2.2.1/16"
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-11-09 18:30:30 -05:00
defer deleteInterface ( c , bridgeName )
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bip" , bridgeIP , "--fixed-cidr" , "10.2.2.0/24" )
defer s . d . Restart ( c )
2015-11-09 18:30:30 -05:00
2017-01-05 06:38:34 -05:00
out , err := d . Cmd ( "run" , "-d" , "--name" , "bb" , "busybox" , "top" )
2015-11-09 18:30:30 -05:00
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
defer d . Cmd ( "stop" , "bb" )
out , err = d . Cmd ( "exec" , "bb" , "/bin/sh" , "-c" , "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'" )
c . Assert ( out , checker . Equals , "10.2.2.0\n" )
out , err = d . Cmd ( "run" , "--rm" , "busybox" , "/bin/sh" , "-c" , "ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
c . Assert ( out , checker . Equals , "10.2.2.2\n" )
}
func ( s * DockerDaemonSuite ) TestDaemonBridgeFixedCIDREqualBridgeNetwork ( c * check . C ) {
2015-10-22 16:51:52 -04:00
d := s . d
bridgeName := "external-bridge"
bridgeIP := "172.27.42.1/16"
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-10-22 16:51:52 -04:00
defer deleteInterface ( c , bridgeName )
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--fixed-cidr" , bridgeIP )
defer s . d . Restart ( c )
2015-10-22 16:51:52 -04:00
2017-01-05 06:38:34 -05:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2015-10-22 16:51:52 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
cid1 := strings . TrimSpace ( out )
defer d . Cmd ( "stop" , cid1 )
}
2015-06-05 01:57:59 -04:00
func ( s * DockerDaemonSuite ) TestDaemonDefaultGatewayIPv4Implicit ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
d := s . d
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1"
bridgeIPNet := fmt . Sprintf ( "%s/24" , bridgeIP )
2015-06-05 01:57:59 -04:00
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bip" , bridgeIPNet )
defer d . Restart ( c )
2015-06-05 01:57:59 -04:00
2015-07-22 08:59:24 -04:00
expectedMessage := fmt . Sprintf ( "default via %s dev" , bridgeIP )
2015-06-05 01:57:59 -04:00
out , err := d . Cmd ( "run" , "busybox" , "ip" , "-4" , "route" , "list" , "0/0" )
2016-12-09 17:20:14 -05:00
c . Assert ( err , checker . IsNil )
2015-06-05 01:57:59 -04: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 08:59:24 -04:00
bridgeIP , strings . TrimSpace ( out ) ) )
2015-06-05 01:57:59 -04:00
deleteInterface ( c , defaultNetworkBridge )
}
func ( s * DockerDaemonSuite ) TestDaemonDefaultGatewayIPv4Explicit ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
d := s . d
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1"
bridgeIPNet := fmt . Sprintf ( "%s/24" , bridgeIP )
gatewayIP := "192.169.1.254"
2015-06-05 01:57:59 -04:00
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c , "--bip" , bridgeIPNet , "--default-gateway" , gatewayIP )
defer d . Restart ( c )
2015-06-05 01:57:59 -04:00
2015-07-22 08:59:24 -04:00
expectedMessage := fmt . Sprintf ( "default via %s dev" , gatewayIP )
2015-06-05 01:57:59 -04:00
out , err := d . Cmd ( "run" , "busybox" , "ip" , "-4" , "route" , "list" , "0/0" )
2016-12-09 17:20:14 -05:00
c . Assert ( err , checker . IsNil )
2015-06-05 01:57:59 -04: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 08:59:24 -04:00
gatewayIP , strings . TrimSpace ( out ) ) )
2015-06-05 01:57:59 -04:00
deleteInterface ( c , defaultNetworkBridge )
}
2015-07-30 20:29:02 -04: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 17:20:14 -05: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-30 20:29:02 -04:00
deleteInterface ( c , defaultNetworkBridge )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-07-30 20:29:02 -04:00
}
2015-10-20 22:17:18 -04:00
func ( s * DockerDaemonSuite ) TestDaemonDefaultNetworkInvalidClusterConfig ( c * check . C ) {
2015-11-04 19:40:58 -05:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2015-10-20 22:17:18 -04:00
// Start daemon without docker0 bridge
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
discoveryBackend := "consul://consuladdr:consulport/some/path"
2016-12-09 17:20:14 -05:00
s . d . Start ( c , fmt . Sprintf ( "--cluster-store=%s" , discoveryBackend ) )
2015-10-20 22:17:18 -04:00
// Start daemon with docker0 bridge
2016-08-04 12:57:34 -04:00
result := icmd . RunCommand ( "ifconfig" , defaultNetworkBridge )
2017-08-23 17:01:29 -04:00
result . Assert ( c , icmd . Success )
2015-10-20 22:17:18 -04:00
2016-12-09 17:20:14 -05:00
s . d . Restart ( c , fmt . Sprintf ( "--cluster-store=%s" , discoveryBackend ) )
2015-10-20 22:17:18 -04:00
}
2015-04-28 13:26:59 -04: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 17:20:14 -05:00
d . StartWithBusybox ( c , args ... )
defer d . Restart ( c )
2015-04-28 13:26:59 -04:00
out , err := d . Cmd ( "run" , "-d" , "-p" , "8000:8000" , "busybox" , "top" )
2015-04-28 19:17:00 -04:00
c . Assert ( err , check . NotNil ,
2015-04-28 13:26:59 -04:00
check . Commentf ( "Running a container must fail with an invalid --ip option" ) )
2015-09-16 12:55:14 -04:00
c . Assert ( strings . Contains ( out , "Error starting userland proxy" ) , check . Equals , true )
2015-04-28 13:26:59 -04:00
ifName := "dummy"
2017-01-05 06:38:34 -05:00
createInterface ( c , "dummy" , ifName , ipStr )
2015-04-29 14:41:13 -04:00
defer deleteInterface ( c , ifName )
2015-04-28 13:26:59 -04:00
_ , err = d . Cmd ( "run" , "-d" , "-p" , "8000:8000" , "busybox" , "top" )
c . Assert ( err , check . IsNil )
2017-01-05 06:38:34 -05:00
result := icmd . RunCommand ( "iptables" , "-t" , "nat" , "-nvL" )
result . Assert ( c , icmd . Success )
2015-04-28 13:26:59 -04:00
regex := fmt . Sprintf ( "DNAT.*%s.*dpt:8000" , ip . String ( ) )
2017-01-05 06:38:34 -05:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 13:26:59 -04:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 06:38:34 -05:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 11:55:04 -04:00
}
2015-04-28 19:17:00 -04:00
func ( s * DockerDaemonSuite ) TestDaemonICCPing ( c * check . C ) {
2016-02-26 19:53:35 -05:00
testRequires ( c , bridgeNfIptables )
2015-04-28 19:17:00 -04:00
d := s . d
bridgeName := "external-bridge"
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 14:41:13 -04:00
defer deleteInterface ( c , bridgeName )
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
2016-12-09 17:20:14 -05:00
defer d . Restart ( c )
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
result := icmd . RunCommand ( "iptables" , "-nvL" , "FORWARD" )
result . Assert ( c , icmd . Success )
2015-04-28 19:17:00 -04:00
regex := fmt . Sprintf ( "DROP.*all.*%s.*%s" , bridgeName , bridgeName )
2017-01-05 06:38:34 -05:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 19:17:00 -04:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 06:38:34 -05:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 19:17:00 -04: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 12:14:05 -04:00
runArgs := [ ] string { "run" , "--rm" , "busybox" , "sh" , "-c" , pingCmd }
2017-01-05 06:38:34 -05:00
_ , err := d . Cmd ( runArgs ... )
2015-04-28 19:17:00 -04:00
c . Assert ( err , check . IsNil )
}
func ( s * DockerDaemonSuite ) TestDaemonICCLinkExpose ( c * check . C ) {
d := s . d
bridgeName := "external-bridge"
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-04-29 14:41:13 -04:00
defer deleteInterface ( c , bridgeName )
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
2016-12-09 17:20:14 -05:00
defer d . Restart ( c )
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
result := icmd . RunCommand ( "iptables" , "-nvL" , "FORWARD" )
result . Assert ( c , icmd . Success )
2015-04-28 19:17:00 -04:00
regex := fmt . Sprintf ( "DROP.*all.*%s.*%s" , bridgeName , bridgeName )
2017-01-05 06:38:34 -05:00
matched , _ := regexp . MatchString ( regex , result . Combined ( ) )
2015-04-28 19:17:00 -04:00
c . Assert ( matched , check . Equals , true ,
2017-01-05 06:38:34 -05:00
check . Commentf ( "iptables output should have contained %q, but was %q" , regex , result . Combined ( ) ) )
2015-04-28 19:17:00 -04:00
2017-01-05 06:38:34 -05:00
out , err := d . Cmd ( "run" , "-d" , "--expose" , "4567" , "--name" , "icc1" , "busybox" , "nc" , "-l" , "-p" , "4567" )
2015-05-06 18:39:29 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2015-04-28 19:17:00 -04:00
out , err = d . Cmd ( "run" , "--link" , "icc1:icc1" , "busybox" , "nc" , "icc1" , "4567" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
}
2015-05-06 18:39:29 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink ( c * check . C ) {
bridgeName := "external-bridge"
2015-07-22 08:59:24 -04:00
bridgeIP := "192.169.1.1/24"
2015-05-06 18:39:29 -04:00
2017-01-05 06:38:34 -05:00
createInterface ( c , "bridge" , bridgeName , bridgeIP )
2015-05-06 18:39:29 -04:00
defer deleteInterface ( c , bridgeName )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--bridge" , bridgeName , "--icc=false" )
defer s . d . Restart ( c )
2015-05-06 18:39:29 -04:00
2017-01-05 06:38:34 -05:00
_ , err := s . d . Cmd ( "run" , "-d" , "--name" , "child" , "--publish" , "8080:80" , "busybox" , "top" )
2015-05-06 18:39:29 -04:00
c . Assert ( err , check . IsNil )
_ , err = s . d . Cmd ( "run" , "-d" , "--name" , "parent" , "--link" , "child:http" , "busybox" , "top" )
c . Assert ( err , check . IsNil )
2016-12-09 04:18:02 -05:00
childIP , err := s . d . FindContainerIP ( "child" )
c . Assert ( err , checker . IsNil )
parentIP , err := s . d . FindContainerIP ( "parent" )
c . Assert ( err , checker . IsNil )
2015-05-06 18:39:29 -04: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-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonUlimitDefaults ( c * check . C ) {
2015-11-04 19:40:58 -05:00
testRequires ( c , DaemonIsLinux )
2015-02-11 14:21:38 -05:00
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--default-ulimit" , "nofile=42:42" , "--default-ulimit" , "nproc=1024:1024" )
2015-02-11 14:21:38 -05:00
2015-04-25 22:47:42 -04: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 14:21:38 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( out , err )
2015-02-11 14:21:38 -05:00
}
outArr := strings . Split ( out , "\n" )
if len ( outArr ) < 2 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "got unexpected output: %s" , out )
2015-02-11 14:21:38 -05:00
}
nofile := strings . TrimSpace ( outArr [ 0 ] )
nproc := strings . TrimSpace ( outArr [ 1 ] )
if nofile != "42" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "expected `ulimit -n` to be `42`, got: %s" , nofile )
2015-02-11 14:21:38 -05:00
}
if nproc != "2048" {
2017-05-21 19:24:07 -04:00
c . Fatalf ( "expected `ulimit -p` to be 2048, got: %s" , nproc )
2015-02-11 14:21:38 -05:00
}
// Now restart daemon with a new default
2016-12-09 17:20:14 -05:00
s . d . Restart ( c , "--default-ulimit" , "nofile=43" )
2015-02-11 14:21:38 -05:00
2015-04-25 22:47:42 -04:00
out , err = s . d . Cmd ( "start" , "-a" , "test" )
2015-02-11 14:21:38 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-11 14:21:38 -05:00
}
outArr = strings . Split ( out , "\n" )
if len ( outArr ) < 2 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "got unexpected output: %s" , out )
2015-02-11 14:21:38 -05:00
}
nofile = strings . TrimSpace ( outArr [ 0 ] )
nproc = strings . TrimSpace ( outArr [ 1 ] )
if nofile != "43" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "expected `ulimit -n` to be `43`, got: %s" , nofile )
2015-02-11 14:21:38 -05:00
}
if nproc != "2048" {
2017-05-21 19:24:07 -04:00
c . Fatalf ( "expected `ulimit -p` to be 2048, got: %s" , nproc )
2015-02-11 14:21:38 -05:00
}
}
2015-03-11 12:17:23 -04:00
// #11315
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartRenameContainer ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-03-11 12:17:23 -04:00
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err , out )
2015-03-11 12:17:23 -04:00
}
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "rename" , "test" , "test2" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err , out )
2015-03-11 12:17:23 -04:00
}
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-03-11 12:17:23 -04:00
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "start" , "test2" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err , out )
2015-03-11 12:17:23 -04:00
}
}
2015-02-04 16:44:52 -05:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverDefault ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-02-04 16:44:52 -05:00
2016-02-28 05:47:37 -05:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2016-12-09 04:17:53 -05:00
id , err := s . d . GetIDByName ( "test" )
2016-02-28 05:47:37 -05:00
c . Assert ( err , check . IsNil )
2015-02-04 16:44:52 -05:00
2016-12-09 04:17:53 -05:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 16:44:52 -05:00
if _ , err := os . Stat ( logPath ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
f , err := os . Open ( logPath )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
2016-06-24 23:57:21 -04:00
defer f . Close ( )
2015-02-04 16:44:52 -05:00
var res struct {
2015-03-25 23:18:42 -04:00
Log string ` json:"log" `
Stream string ` json:"stream" `
Time time . Time ` json:"time" `
2015-02-04 16:44:52 -05:00
}
if err := json . NewDecoder ( f ) . Decode ( & res ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
if res . Log != "testline\n" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Unexpected log line: %q, expected: %q" , res . Log , "testline\n" )
2015-02-04 16:44:52 -05:00
}
if res . Stream != "stdout" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Unexpected stream: %q, expected: %q" , res . Stream , "stdout" )
2015-02-04 16:44:52 -05:00
}
if ! time . Now ( ) . After ( res . Time ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Log time %v in future" , res . Time )
2015-02-04 16:44:52 -05:00
}
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverDefaultOverride ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-02-04 16:44:52 -05:00
2016-02-28 05:47:37 -05:00
out , err := s . d . Cmd ( "run" , "--name=test" , "--log-driver=none" , "busybox" , "echo" , "testline" )
2015-02-04 16:44:52 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( out , err )
2015-02-04 16:44:52 -05:00
}
2016-12-09 04:17:53 -05:00
id , err := s . d . GetIDByName ( "test" )
2016-02-28 05:47:37 -05:00
c . Assert ( err , check . IsNil )
2015-02-04 16:44:52 -05:00
2016-12-09 04:17:53 -05:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 16:44:52 -05:00
if _ , err := os . Stat ( logPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "%s shouldn't exits, error on Stat: %s" , logPath , err )
2015-02-04 16:44:52 -05:00
}
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNone ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-04 16:44:52 -05:00
2016-02-28 05:47:37 -05:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
2015-02-04 16:44:52 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( out , err )
2015-02-04 16:44:52 -05:00
}
2016-12-09 04:17:53 -05:00
id , err := s . d . GetIDByName ( "test" )
2016-02-28 05:47:37 -05:00
c . Assert ( err , check . IsNil )
2015-02-04 16:44:52 -05:00
2016-12-09 04:17:53 -05:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 16:44:52 -05:00
if _ , err := os . Stat ( logPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "%s shouldn't exits, error on Stat: %s" , logPath , err )
2015-02-04 16:44:52 -05:00
}
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNoneOverride ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-04 16:44:52 -05:00
2016-02-28 05:47:37 -05:00
out , err := s . d . Cmd ( "run" , "--name=test" , "--log-driver=json-file" , "busybox" , "echo" , "testline" )
2015-02-04 16:44:52 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( out , err )
2015-02-04 16:44:52 -05:00
}
2016-12-09 04:17:53 -05:00
id , err := s . d . GetIDByName ( "test" )
2016-02-28 05:47:37 -05:00
c . Assert ( err , check . IsNil )
2015-02-04 16:44:52 -05:00
2016-12-09 04:17:53 -05:00
logPath := filepath . Join ( s . d . Root , "containers" , id , id + "-json.log" )
2015-02-04 16:44:52 -05:00
if _ , err := os . Stat ( logPath ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
f , err := os . Open ( logPath )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
2016-06-24 23:57:21 -04:00
defer f . Close ( )
2015-02-04 16:44:52 -05:00
var res struct {
2015-03-25 23:18:42 -04:00
Log string ` json:"log" `
Stream string ` json:"stream" `
Time time . Time ` json:"time" `
2015-02-04 16:44:52 -05:00
}
if err := json . NewDecoder ( f ) . Decode ( & res ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-02-04 16:44:52 -05:00
}
if res . Log != "testline\n" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Unexpected log line: %q, expected: %q" , res . Log , "testline\n" )
2015-02-04 16:44:52 -05:00
}
if res . Stream != "stdout" {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Unexpected stream: %q, expected: %q" , res . Stream , "stdout" )
2015-02-04 16:44:52 -05:00
}
if ! time . Now ( ) . After ( res . Time ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Log time %v in future" , res . Time )
2015-02-04 16:44:52 -05:00
}
}
2015-02-05 19:24:47 -05:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverNoneLogsError ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--log-driver=none" )
2015-02-05 19:24:47 -05:00
2016-02-27 12:07:39 -05:00
out , err := s . d . Cmd ( "run" , "--name=test" , "busybox" , "echo" , "testline" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "logs" , "test" )
c . Assert ( err , check . NotNil , check . Commentf ( "Logs should fail with 'none' driver" ) )
2016-11-22 08:51:22 -05:00
expected := ` configured logging driver does not support reading `
2016-02-27 12:07:39 -05:00
c . Assert ( out , checker . Contains , expected )
2015-02-05 19:24:47 -05:00
}
2015-03-17 20:27:53 -04:00
2016-12-19 15:18:06 -05:00
func ( s * DockerDaemonSuite ) TestDaemonLoggingDriverShouldBeIgnoredForBuild ( c * check . C ) {
s . d . StartWithBusybox ( c , "--log-driver=splunk" )
out , err := s . d . Cmd ( "build" )
out , code , err := s . d . BuildImageWithOut ( "busyboxs" , `
FROM busybox
RUN echo foo ` , false )
comment := check . Commentf ( "Failed to build image. output %s, exitCode %d, err %v" , out , code , err )
c . Assert ( err , check . IsNil , comment )
c . Assert ( code , check . Equals , 0 , comment )
c . Assert ( out , checker . Contains , "foo" , comment )
}
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonUnixSockCleanedUp ( c * check . C ) {
2015-03-18 17:26:14 -04:00
dir , err := ioutil . TempDir ( "" , "socket-cleanup-test" )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-03-18 17:26:14 -04:00
}
defer os . RemoveAll ( dir )
sockPath := filepath . Join ( dir , "docker.sock" )
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--host" , "unix://" + sockPath )
2015-03-18 17:26:14 -04:00
if _ , err := os . Stat ( sockPath ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( "socket does not exist" )
2015-03-18 17:26:14 -04:00
}
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2015-03-18 17:26:14 -04:00
if _ , err := os . Stat ( sockPath ) ; err == nil || ! os . IsNotExist ( err ) {
2015-04-18 12:46:47 -04:00
c . Fatal ( "unix socket is not cleaned up" )
2015-03-18 17:26:14 -04:00
}
}
2015-04-05 20:57:19 -04:00
2015-04-29 07:56:45 -04:00
func ( s * DockerDaemonSuite ) TestDaemonWithWrongkey ( c * check . C ) {
2015-04-05 20:57:19 -04:00
type Config struct {
Crv string ` json:"crv" `
D string ` json:"d" `
Kid string ` json:"kid" `
Kty string ` json:"kty" `
X string ` json:"x" `
Y string ` json:"y" `
}
os . Remove ( "/etc/docker/key.json" )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
s . d . Stop ( c )
2015-04-05 20:57:19 -04:00
config := & Config { }
bytes , err := ioutil . ReadFile ( "/etc/docker/key.json" )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error reading key.json file: %s" , err )
2015-04-05 20:57:19 -04:00
}
// byte[] to Data-Struct
if err := json . Unmarshal ( bytes , & config ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error Unmarshal: %s" , err )
2015-04-05 20:57:19 -04:00
}
//replace config.Kid with the fake value
config . Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4"
// NEW Data-Struct to byte[]
newBytes , err := json . Marshal ( & config )
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error Marshal: %s" , err )
2015-04-05 20:57:19 -04:00
}
// write back
if err := ioutil . WriteFile ( "/etc/docker/key.json" , newBytes , 0400 ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error ioutil.WriteFile: %s" , err )
2015-04-05 20:57:19 -04:00
}
2015-04-13 19:31:20 -04:00
defer os . Remove ( "/etc/docker/key.json" )
2015-04-05 20:57:19 -04:00
2016-12-09 17:20:14 -05:00
if err := s . d . StartWithError ( ) ; err == nil {
2015-04-27 16:33:30 -04:00
c . Fatalf ( "It should not be successful to start daemon with wrong key: %v" , err )
2015-04-05 20:57:19 -04:00
}
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2015-04-05 20:57:19 -04:00
if ! strings . Contains ( string ( content ) , "Public Key ID does not match" ) {
2016-12-01 17:17:07 -05:00
c . Fatalf ( "Missing KeyID message from daemon logs: %s" , string ( content ) )
2015-04-05 20:57:19 -04:00
}
}
2015-04-09 17:11:11 -04:00
2015-04-25 22:47:42 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartKillWait ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-04-09 17:11:11 -04:00
2015-04-25 22:47:42 -04:00
out , err := s . d . Cmd ( "run" , "-id" , "busybox" , "/bin/cat" )
2015-04-09 17:11:11 -04:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not run /bin/cat: err=%v\n%s" , err , out )
2015-04-09 17:11:11 -04:00
}
containerID := strings . TrimSpace ( out )
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "kill" , containerID ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not kill %s: err=%v\n%s" , containerID , err , out )
2015-04-09 17:11:11 -04:00
}
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-04-09 17:11:11 -04:00
errchan := make ( chan error )
go func ( ) {
2015-04-25 22:47:42 -04:00
if out , err := s . d . Cmd ( "wait" , containerID ) ; err != nil {
2015-04-09 17:11:11 -04:00
errchan <- fmt . Errorf ( "%v:\n%s" , err , out )
}
close ( errchan )
} ( )
select {
case <- time . After ( 5 * time . Second ) :
2015-04-18 12:46:47 -04:00
c . Fatal ( "Waiting on a stopped (killed) container timed out" )
2015-04-09 17:11:11 -04:00
case err := <- errchan :
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( err )
2015-04-09 17:11:11 -04:00
}
}
}
2015-04-20 19:21:46 -04: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-27 21:50:12 -04:00
// TestHTTPSInfo connects via two-way authenticated HTTPS to the info endpoint
func ( s * DockerDaemonSuite ) TestHTTPSInfo ( c * check . C ) {
2015-04-20 19:21:46 -04:00
const (
2015-05-01 10:00:43 -04:00
testDaemonHTTPSAddr = "tcp://localhost:4271"
2015-04-20 19:21:46 -04:00
)
2016-12-09 17:20:14 -05: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 19:21:46 -04:00
2016-07-22 12:14:05 -04:00
args := [ ] string {
"--host" , testDaemonHTTPSAddr ,
2016-12-09 17:20:14 -05:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 12:14:05 -04:00
"--tlscert" , "fixtures/https/client-cert.pem" ,
"--tlskey" , "fixtures/https/client-key.pem" ,
"info" ,
}
out , err := s . d . Cmd ( args ... )
2015-04-20 19:21:46 -04: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-27 21:50:12 -04:00
// TestHTTPSRun connects via two-way authenticated HTTPS to the create, attach, start, and wait endpoints.
2016-01-13 20:18:06 -05: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-27 21:50:12 -04:00
func ( s * DockerDaemonSuite ) TestHTTPSRun ( c * check . C ) {
2016-01-13 20:18:06 -05:00
const (
testDaemonHTTPSAddr = "tcp://localhost:4271"
)
2016-12-09 17:20:14 -05: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-13 20:18:06 -05:00
2016-07-22 12:14:05 -04: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-13 20:18:06 -05: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-27 21:50:12 -04:00
// TestTLSVerify verifies that --tlsverify=false turns on tls
func ( s * DockerDaemonSuite ) TestTLSVerify ( c * check . C ) {
2016-05-26 07:14:35 -04:00
out , err := exec . Command ( dockerdBinary , "--tlsverify=false" ) . CombinedOutput ( )
2015-07-30 21:38:02 -04: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-27 21:50:12 -04:00
// TestHTTPSInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint
2015-04-20 19:21:46 -04: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-27 21:50:12 -04:00
func ( s * DockerDaemonSuite ) TestHTTPSInfoRogueCert ( c * check . C ) {
2015-04-20 19:21:46 -04:00
const (
2016-06-04 08:17:24 -04:00
errBadCertificate = "bad certificate"
2015-05-01 10:00:43 -04:00
testDaemonHTTPSAddr = "tcp://localhost:4271"
2015-04-20 19:21:46 -04:00
)
2015-05-01 10:00:43 -04:00
2016-12-09 17:20:14 -05: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 19:21:46 -04:00
2016-07-22 12:14:05 -04:00
args := [ ] string {
"--host" , testDaemonHTTPSAddr ,
2016-12-09 17:20:14 -05:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 12:14:05 -04: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 19:21:46 -04: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-27 21:50:12 -04:00
// TestHTTPSInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint
2015-04-20 19:21:46 -04: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-27 21:50:12 -04:00
func ( s * DockerDaemonSuite ) TestHTTPSInfoRogueServerCert ( c * check . C ) {
2015-04-20 19:21:46 -04:00
const (
errCaUnknown = "x509: certificate signed by unknown authority"
2015-05-01 10:00:43 -04:00
testDaemonRogueHTTPSAddr = "tcp://localhost:4272"
2015-04-20 19:21:46 -04:00
)
2016-12-09 17:20:14 -05: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 19:21:46 -04:00
2016-07-22 12:14:05 -04:00
args := [ ] string {
"--host" , testDaemonRogueHTTPSAddr ,
2016-12-09 17:20:14 -05:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
2016-07-22 12:14:05 -04: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 19:21:46 -04:00
if err == nil || ! strings . Contains ( out , errCaUnknown ) {
c . Fatalf ( "Expected err: %s, got instead: %s and output: %s" , errCaUnknown , err , out )
}
}
2015-04-27 23:36:40 -04:00
2016-12-09 04:17:53 -05:00
func pingContainers ( c * check . C , d * daemon . Daemon , expectFailure bool ) {
2015-04-28 19:17:00 -04:00
var dargs [ ] string
if d != nil {
2016-12-09 04:17:53 -05:00
dargs = [ ] string { "--host" , d . Sock ( ) }
2015-04-28 19:17:00 -04:00
}
args := append ( dargs , "run" , "-d" , "--name" , "container1" , "busybox" , "top" )
2015-07-20 02:55:40 -04:00
dockerCmd ( c , args ... )
2015-04-27 23:36:40 -04:00
2015-04-28 19:17:00 -04:00
args = append ( dargs , "run" , "--rm" , "--link" , "container1:alias1" , "busybox" , "sh" , "-c" )
2015-04-27 23:36:40 -04:00
pingCmd := "ping -c 1 %s -W 1"
2015-04-28 19:17:00 -04:00
args = append ( args , fmt . Sprintf ( pingCmd , "alias1" ) )
2015-07-27 14:13:25 -04:00
_ , _ , err := dockerCmdWithError ( args ... )
2015-04-28 19:17:00 -04:00
if expectFailure {
c . Assert ( err , check . NotNil )
} else {
c . Assert ( err , check . IsNil )
}
2015-04-27 23:36:40 -04:00
2015-04-28 19:17:00 -04:00
args = append ( dargs , "rm" , "-f" , "container1" )
2015-07-20 02:55:40 -04:00
dockerCmd ( c , args ... )
2015-04-27 23:36:40 -04:00
}
2015-05-07 18:35:12 -04:00
2015-05-19 12:32:19 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithSocketAsVolume ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-05-07 18:35:12 -04:00
2016-12-09 04:18:02 -05:00
socket := filepath . Join ( s . d . Folder , "docker.sock" )
2015-05-07 18:35:12 -04:00
2016-02-28 05:47:37 -05:00
out , err := s . d . Cmd ( "run" , "--restart=always" , "-v" , socket + ":/sock" , "busybox" )
2015-05-07 18:35:12 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-05-07 18:35:12 -04:00
}
2015-05-19 12:32:19 -04:00
2016-03-04 17:41:53 -05:00
// os.Kill should kill daemon ungracefully, leaving behind container mounts.
2017-05-21 19:24:07 -04:00
// A subsequent daemon restart should clean up said mounts.
2016-03-04 17:41:53 -05:00
func ( s * DockerDaemonSuite ) TestCleanupMountsAfterDaemonAndContainerKill ( c * check . C ) {
2016-12-09 17:20:14 -05:00
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config {
2017-01-13 11:23:28 -05:00
Experimental : testEnv . ExperimentalDaemon ( ) ,
2016-12-09 17:20:14 -05:00
} )
d . StartWithBusybox ( c )
2015-05-19 12:32:19 -04:00
2016-12-09 17:20:14 -05:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2015-05-19 12:32:19 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
id := strings . TrimSpace ( out )
2016-12-09 17:20:14 -05:00
c . Assert ( d . Signal ( os . Kill ) , check . IsNil )
2016-03-04 17:41:53 -05:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
// container mounts should exist even after daemon has crashed.
2016-12-09 17:20:14 -05:00
comment := check . Commentf ( "%s should stay mounted from older daemon start:\nDaemon root repository %s\n%s" , id , d . Root , mountOut )
2016-03-04 17:41:53 -05:00
c . Assert ( strings . Contains ( string ( mountOut ) , id ) , check . Equals , true , comment )
2016-03-18 14:50:19 -04:00
// kill the container
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( ctrBinary , "--address" , "unix:///var/run/docker/libcontainerd/docker-containerd.sock" , "containers" , "kill" , id ) . Assert ( c , icmd . Success )
2016-03-04 17:41:53 -05:00
// restart daemon.
2016-12-09 17:20:14 -05:00
d . Restart ( c )
2016-03-18 14:50:19 -04:00
2016-03-04 17:41:53 -05:00
// Now, container mounts should be gone.
mountOut , err = ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
2016-12-09 17:20:14 -05:00
comment = check . Commentf ( "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s" , id , d . Root , mountOut )
2016-03-04 17:41:53 -05:00
c . Assert ( strings . Contains ( string ( mountOut ) , id ) , check . Equals , false , comment )
2016-12-09 17:20:14 -05:00
d . Stop ( c )
2016-03-04 17:41:53 -05:00
}
// os.Interrupt should perform a graceful daemon shutdown and hence cleanup mounts.
func ( s * DockerDaemonSuite ) TestCleanupMountsAfterGracefulShutdown ( c * check . C ) {
2016-12-09 17:20:14 -05:00
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config {
2017-01-13 11:23:28 -05:00
Experimental : testEnv . ExperimentalDaemon ( ) ,
2016-12-09 17:20:14 -05:00
} )
d . StartWithBusybox ( c )
2016-03-04 17:41:53 -05:00
2016-12-09 17:20:14 -05:00
out , err := d . Cmd ( "run" , "-d" , "busybox" , "top" )
2016-03-04 17:41:53 -05:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
id := strings . TrimSpace ( out )
// Send SIGINT and daemon should clean up
2016-12-09 17:20:14 -05:00
c . Assert ( d . Signal ( os . Interrupt ) , check . IsNil )
2016-06-14 16:41:29 -04:00
// Wait for the daemon to stop.
2016-12-09 17:20:14 -05:00
c . Assert ( <- d . Wait , checker . IsNil )
2016-03-18 14:50:19 -04:00
2015-08-26 08:00:01 -04:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
2015-05-19 12:32:19 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
2015-08-26 08:00:01 -04:00
2016-12-09 17:20:14 -05:00
comment := check . Commentf ( "%s is still mounted from older daemon start:\nDaemon root repository %s\n%s" , id , d . Root , mountOut )
2015-08-26 08:00:01 -04:00
c . Assert ( strings . Contains ( string ( mountOut ) , id ) , check . Equals , false , comment )
2015-05-19 12:32:19 -04:00
}
2015-05-24 11:26:56 -04:00
func ( s * DockerDaemonSuite ) TestRunContainerWithBridgeNone ( c * check . C ) {
2015-11-04 19:40:58 -05:00
testRequires ( c , DaemonIsLinux , NotUserNamespace )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "-b" , "none" )
2015-05-24 11:26:56 -04:00
out , err := s . d . Cmd ( "run" , "--rm" , "busybox" , "ip" , "l" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( strings . Contains ( out , "eth0" ) , check . Equals , false ,
2015-06-30 13:34:15 -04:00
check . Commentf ( "There shouldn't be eth0 in container in default(bridge) mode when bridge network is disabled: %s" , out ) )
out , err = s . d . Cmd ( "run" , "--rm" , "--net=bridge" , "busybox" , "ip" , "l" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( strings . Contains ( out , "eth0" ) , check . Equals , false ,
check . Commentf ( "There shouldn't be eth0 in container in bridge mode when bridge network is disabled: %s" , out ) )
2015-10-13 12:39:05 -04:00
// the extra grep and awk clean up the output of `ip` to only list the number and name of
// interfaces, allowing for different versions of ip (e.g. inside and outside the container) to
// be used while still verifying that the interface list is the exact same
cmd := exec . Command ( "sh" , "-c" , "ip l | grep -E '^[0-9]+:' | awk -F: ' { print $1\":\"$2 } '" )
2015-09-18 20:49:36 -04:00
stdout := bytes . NewBuffer ( nil )
cmd . Stdout = stdout
if err := cmd . Run ( ) ; err != nil {
c . Fatal ( "Failed to get host network interface" )
}
2015-10-13 12:39:05 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--net=host" , "busybox" , "sh" , "-c" , "ip l | grep -E '^[0-9]+:' | awk -F: ' { print $1\":\"$2 } '" )
2015-06-30 13:34:15 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
2015-09-18 20:49:36 -04:00
c . Assert ( out , check . Equals , fmt . Sprintf ( "%s" , stdout ) ,
check . Commentf ( "The network interfaces in container should be the same with host when --net=host when bridge network is disabled: %s" , out ) )
2015-05-24 11:26:56 -04:00
}
2015-05-25 21:25:34 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithContainerRunning ( t * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( t )
2016-01-25 10:45:13 -05:00
if out , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" ) ; err != nil {
2015-05-25 21:25:34 -04:00
t . Fatal ( out , err )
}
2015-06-05 18:02:56 -04:00
2016-12-09 17:20:14 -05:00
s . d . Restart ( t )
2015-05-25 21:25:34 -04: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 18:02:56 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartCleanupNetns ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-06-05 18:02:56 -04:00
out , err := s . d . Cmd ( "run" , "--name" , "netns" , "-d" , "busybox" , "top" )
if err != nil {
c . Fatal ( out , err )
}
2015-09-02 19:43:28 -04: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 18:02:56 -04:00
if out , err := s . d . Cmd ( "stop" , "netns" ) ; err != nil {
c . Fatal ( out , err )
}
// Test if the file still exists
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "stat" , "-c" , "%n" , fileName ) . Assert ( c , icmd . Expected {
Out : fileName ,
} )
2015-06-05 18:02:56 -04: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 17:20:14 -05:00
s . d . Restart ( c )
2015-06-05 18:02:56 -04:00
// Test again and see now the netns file does not exist
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "stat" , "-c" , "%n" , fileName ) . Assert ( c , icmd . Expected {
Err : "No such file or directory" ,
ExitCode : 1 ,
} )
2015-06-05 18:02:56 -04:00
}
2015-06-16 11:00:54 -04: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-27 21:50:12 -04:00
func ( s * DockerDaemonSuite ) TestDaemonTLSVerifyIssue13964 ( c * check . C ) {
2015-06-16 11:00:54 -04:00
host := "tcp://localhost:4271"
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "-H" , host )
2017-01-05 06:38:34 -05: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 07:50:20 -04:00
}
2016-08-03 12:20:46 -04:00
func setupV6 ( c * check . C ) {
2015-04-28 07:50:20 -04:00
// Hack to get the right IPv6 address on docker0, which has already been created
2016-08-03 12:20:46 -04:00
result := icmd . RunCommand ( "ip" , "addr" , "add" , "fe80::1/64" , "dev" , "docker0" )
2017-01-05 06:38:34 -05:00
result . Assert ( c , icmd . Success )
2015-04-28 07:50:20 -04:00
}
2016-08-03 12:20:46 -04:00
func teardownV6 ( c * check . C ) {
result := icmd . RunCommand ( "ip" , "addr" , "del" , "fe80::1/64" , "dev" , "docker0" )
2017-01-05 06:38:34 -05:00
result . Assert ( c , icmd . Success )
2015-06-16 11:00:54 -04:00
}
2015-08-01 08:52:00 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithContainerWithRestartPolicyAlways ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-08-01 08:52:00 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--restart" , "always" , "busybox" , "top" )
c . Assert ( err , check . IsNil )
id := strings . TrimSpace ( out )
_ , err = s . d . Cmd ( "stop" , id )
c . Assert ( err , check . IsNil )
_ , err = s . d . Cmd ( "wait" , id )
c . Assert ( err , check . IsNil )
out , err = s . d . Cmd ( "ps" , "-q" )
c . Assert ( err , check . IsNil )
c . Assert ( out , check . Equals , "" )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-08-01 08:52:00 -04:00
out , err = s . d . Cmd ( "ps" , "-q" )
c . Assert ( err , check . IsNil )
c . Assert ( strings . TrimSpace ( out ) , check . Equals , id [ : 12 ] )
}
2015-08-17 14:38:37 -04:00
2015-08-17 18:27:44 -04:00
func ( s * DockerDaemonSuite ) TestDaemonWideLogConfig ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--log-opt=max-size=1k" )
2016-03-12 07:50:37 -05:00
name := "logtest"
out , err := s . d . Cmd ( "run" , "-d" , "--log-opt=max-file=5" , "--name" , name , "busybox" , "top" )
2015-08-17 18:27:44 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s, err: %v" , out , err ) )
2016-03-12 07:50:37 -05:00
out , err = s . d . Cmd ( "inspect" , "-f" , "{{ .HostConfig.LogConfig.Config }}" , name )
2015-08-17 18:27:44 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
2016-03-12 07:50:37 -05:00
c . Assert ( out , checker . Contains , "max-size:1k" )
c . Assert ( out , checker . Contains , "max-file:5" )
out , err = s . d . Cmd ( "inspect" , "-f" , "{{ .HostConfig.LogConfig.Type }}" , name )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( strings . TrimSpace ( out ) , checker . Equals , "json-file" )
2015-08-17 18:27:44 -04:00
}
2015-08-24 21:42:58 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithPausedContainer ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-08-24 21:42:58 -04: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 17:20:14 -05:00
s . d . Restart ( c )
2015-08-24 21:42:58 -04: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 09:25:32 -04:00
}
func ( s * DockerDaemonSuite ) TestDaemonRestartRmVolumeInUse ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-06-12 09:25:32 -04:00
out , err := s . d . Cmd ( "create" , "-v" , "test:/foo" , "busybox" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-08-24 21:42:58 -04:00
2015-06-12 09:25:32 -04:00
out , err = s . d . Cmd ( "volume" , "rm" , "test" )
2015-09-23 16:29:14 -04: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 09:25:32 -04:00
}
func ( s * DockerDaemonSuite ) TestDaemonRestartLocalVolumes ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
2015-06-12 09:25:32 -04:00
2016-06-14 18:42:30 -04:00
_ , err := s . d . Cmd ( "volume" , "create" , "test" )
2015-06-12 09:25:32 -04:00
c . Assert ( err , check . IsNil )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-06-12 09:25:32 -04:00
_ , err = s . d . Cmd ( "volume" , "inspect" , "test" )
c . Assert ( err , check . IsNil )
2015-08-24 21:42:58 -04:00
}
2015-09-20 07:03:09 -04:00
2016-12-09 17:20:14 -05:00
// FIXME(vdemeester) should be a unit test
2015-09-20 07:03:09 -04:00
func ( s * DockerDaemonSuite ) TestDaemonCorruptedLogDriverAddress ( c * check . C ) {
2016-12-09 17:20:14 -05:00
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config {
2017-01-13 11:23:28 -05:00
Experimental : testEnv . ExperimentalDaemon ( ) ,
2016-12-09 17:20:14 -05:00
} )
c . Assert ( d . StartWithError ( "--log-driver=syslog" , "--log-opt" , "syslog-address=corrupted:42" ) , check . NotNil )
2016-01-26 01:53:10 -05:00
expected := "Failed to set log opts: syslog-address should be in form proto://address"
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "grep" , expected , d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-09-20 07:03:09 -04:00
}
2016-12-09 17:20:14 -05:00
// FIXME(vdemeester) should be a unit test
2015-09-20 07:03:09 -04:00
func ( s * DockerDaemonSuite ) TestDaemonCorruptedFluentdAddress ( c * check . C ) {
2016-12-09 17:20:14 -05:00
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config {
2017-01-13 11:23:28 -05:00
Experimental : testEnv . ExperimentalDaemon ( ) ,
2016-12-09 17:20:14 -05:00
} )
c . Assert ( d . StartWithError ( "--log-driver=fluentd" , "--log-opt" , "fluentd-address=corrupted:c" ) , check . NotNil )
2015-09-20 07:03:09 -04:00
expected := "Failed to set log opts: invalid fluentd-address corrupted:c: "
2017-01-05 06:38:34 -05:00
icmd . RunCommand ( "grep" , expected , d . LogFileName ( ) ) . Assert ( c , icmd . Success )
2015-09-20 07:03:09 -04:00
}
2015-10-12 04:49:25 -04:00
2016-12-09 04:17:53 -05:00
// FIXME(vdemeester) Use a new daemon instance instead of the Suite one
2015-10-12 04:49:25 -04:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithoutHost ( c * check . C ) {
2016-12-09 04:17:53 -05:00
s . d . UseDefaultHost = true
2015-10-12 04:49:25 -04:00
defer func ( ) {
2016-12-09 04:17:53 -05:00
s . d . UseDefaultHost = false
2015-10-12 04:49:25 -04:00
} ( )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
2015-10-12 04:49:25 -04:00
}
2015-10-19 09:17:37 -04:00
2016-12-09 04:17:53 -05:00
// FIXME(vdemeester) Use a new daemon instance instead of the Suite one
2017-05-12 14:07:51 -04:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithDefaultTLSHost ( c * check . C ) {
2016-12-09 04:17:53 -05:00
s . d . UseDefaultTLSHost = true
2015-10-19 09:17:37 -04:00
defer func ( ) {
2016-12-09 04:17:53 -05:00
s . d . UseDefaultTLSHost = false
2015-10-19 09:17:37 -04:00
} ( )
2016-12-09 17:20:14 -05:00
s . d . Start ( c ,
2015-10-19 09:17:37 -04:00
"--tlsverify" ,
"--tlscacert" , "fixtures/https/ca.pem" ,
"--tlscert" , "fixtures/https/server-cert.pem" ,
2016-12-09 17:20:14 -05:00
"--tlskey" , "fixtures/https/server-key.pem" )
2015-10-19 09:17:37 -04: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 14:07:51 -04:00
// ensure when connecting to the server that only a single acceptable CA is requested
contents , err := ioutil . ReadFile ( "fixtures/https/ca.pem" )
c . Assert ( err , checker . IsNil )
rootCert , err := helpers . ParseCertificatePEM ( contents )
c . Assert ( err , checker . IsNil )
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
} ,
} )
c . Assert ( err , checker . IsNil )
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 09:17:37 -04:00
}
2015-10-25 04:36:18 -04:00
func ( s * DockerDaemonSuite ) TestBridgeIPIsExcludedFromAllocatorPool ( c * check . C ) {
defaultNetworkBridge := "docker0"
deleteInterface ( c , defaultNetworkBridge )
bridgeIP := "192.169.1.1"
bridgeRange := bridgeIP + "/30"
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--bip" , bridgeRange )
defer s . d . Restart ( c )
2015-10-25 04:36:18 -04:00
var cont int
for {
contName := fmt . Sprintf ( "container%d" , cont )
2016-12-09 17:20:14 -05:00
_ , err := s . d . Cmd ( "run" , "--name" , contName , "-d" , "busybox" , "/bin/sleep" , "2" )
2015-10-25 04:36:18 -04:00
if err != nil {
// pool exhausted
break
}
ip , err := s . d . Cmd ( "inspect" , "--format" , "'{{.NetworkSettings.IPAddress}}'" , contName )
c . Assert ( err , check . IsNil )
c . Assert ( ip , check . Not ( check . Equals ) , bridgeIP )
cont ++
}
}
2015-11-13 00:53:35 -05:00
// Test daemon for no space left on device error
2016-04-19 17:16:18 -04:00
func ( s * DockerDaemonSuite ) TestDaemonNoSpaceLeftOnDeviceError ( c * check . C ) {
2016-02-18 11:34:34 -05:00
testRequires ( c , SameHostDaemon , DaemonIsLinux , Network )
2015-11-18 08:20:49 -05:00
2016-04-19 17:16:18 -04:00
testDir , err := ioutil . TempDir ( "" , "no-space-left-on-device-test" )
c . Assert ( err , checker . IsNil )
defer os . RemoveAll ( testDir )
c . Assert ( mount . MakeRShared ( testDir ) , checker . IsNil )
defer mount . Unmount ( testDir )
2016-03-29 18:24:05 -04:00
2016-04-19 17:16:18 -04:00
// create a 2MiB image and mount it as graph root
// 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 17:54:27 -04: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 06:38:34 -05:00
icmd . RunCommand ( "mkfs.ext4" , "-F" , filepath . Join ( testDir , "testfs.img" ) ) . Assert ( c , icmd . Success )
2016-05-06 17:19:27 -04:00
2017-01-05 06:38:34 -05:00
result := icmd . RunCommand ( "losetup" , "-f" , "--show" , filepath . Join ( testDir , "testfs.img" ) )
result . Assert ( c , icmd . Success )
loopname := strings . TrimSpace ( string ( result . Combined ( ) ) )
2016-05-06 17:19:27 -04:00
defer exec . Command ( "losetup" , "-d" , loopname ) . Run ( )
dockerCmd ( c , "run" , "--privileged" , "--rm" , "-v" , testDir + ":/test:shared" , "busybox" , "sh" , "-c" , fmt . Sprintf ( "mkdir -p /test/test-mount && mount -t ext4 -no loop,rw %v /test/test-mount" , loopname ) )
defer mount . Unmount ( filepath . Join ( testDir , "test-mount" ) )
2016-03-29 18:24:05 -04:00
2016-11-22 01:17:24 -05:00
s . d . Start ( c , "--data-root" , filepath . Join ( testDir , "test-mount" ) )
2016-12-09 17:20:14 -05:00
defer s . d . Stop ( c )
2015-11-13 00:53:35 -05:00
// pull a repository large enough to fill the mount point
2016-03-29 18:24:05 -04:00
pullOut , err := s . d . Cmd ( "pull" , "registry:2" )
c . Assert ( err , checker . NotNil , check . Commentf ( pullOut ) )
c . Assert ( pullOut , checker . Contains , "no space left on device" )
2015-11-13 00:53:35 -05:00
}
2015-11-24 15:25:12 -05:00
// Test daemon restart with container links + auto restart
func ( s * DockerDaemonSuite ) TestDaemonRestartContainerLinksRestart ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-11-24 15:25:12 -05:00
parent1Args := [ ] string { }
parent2Args := [ ] string { }
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 17:20:14 -05:00
_ , err := s . d . Cmd ( "run" , "-d" , "--name" , name , "--restart=always" , "busybox" , "top" )
2015-11-24 15:25:12 -05:00
chErr <- err
wg . Done ( )
} ( )
}
wg . Wait ( )
close ( chErr )
for err := range chErr {
c . Assert ( err , check . IsNil )
}
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 17:20:14 -05:00
_ , err := s . d . Cmd ( parent1Args ... )
2015-11-24 15:25:12 -05:00
c . Assert ( err , check . IsNil )
2016-08-30 17:25:16 -04:00
_ , err = s . d . Cmd ( parent2Args ... )
2015-11-24 15:25:12 -05:00
c . Assert ( err , check . IsNil )
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2015-11-24 15:25:12 -05: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 17:25:16 -04:00
os . Truncate ( s . d . LogFileName ( ) , 0 )
2016-12-09 17:20:14 -05:00
s . d . Start ( c )
2015-11-24 15:25:12 -05:00
for _ , num := range [ ] string { "1" , "2" } {
2016-08-30 17:25:16 -04:00
out , err := s . d . Cmd ( "inspect" , "-f" , "{{ .State.Running }}" , "parent" + num )
2015-11-24 15:25:12 -05:00
c . Assert ( err , check . IsNil )
if strings . TrimSpace ( out ) != "true" {
2016-08-30 17:25:16 -04:00
log , _ := ioutil . ReadFile ( s . d . LogFileName ( ) )
2015-11-24 15:25:12 -05:00
c . Fatalf ( "parent container is not running\n%s" , string ( log ) )
}
}
}
2015-12-07 12:55:33 -05:00
func ( s * DockerDaemonSuite ) TestDaemonCgroupParent ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
cgroupParent := "test"
name := "cgroup-test"
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--cgroup-parent" , cgroupParent )
defer s . d . Restart ( c )
2015-12-07 12:55:33 -05:00
out , err := s . d . Cmd ( "run" , "--name" , name , "busybox" , "cat" , "/proc/self/cgroup" )
c . Assert ( err , checker . IsNil )
2017-08-21 19:03:58 -04:00
cgroupPaths := ParseCgroupPaths ( string ( out ) )
2015-12-07 12:55:33 -05: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 )
c . Assert ( err , checker . IsNil )
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-03 20:51:04 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithLinks ( c * check . C ) {
testRequires ( c , DaemonIsLinux ) // Windows does not support links
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-09-03 20:51:04 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "run" , "--name=test2" , "--link" , "test:abc" , "busybox" , "sh" , "-c" , "ping -c 1 -w 1 abc" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-09-03 20:51:04 -04:00
// should fail since test is not running yet
out , err = s . d . Cmd ( "start" , "test2" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "start" , "test" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
c . Assert ( strings . Contains ( out , "1 packets transmitted, 1 packets received" ) , check . Equals , true , check . Commentf ( out ) )
}
func ( s * DockerDaemonSuite ) TestDaemonRestartWithNames ( c * check . C ) {
testRequires ( c , DaemonIsLinux ) // Windows does not support links
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-09-03 20:51:04 -04:00
out , err := s . d . Cmd ( "create" , "--name=test" , "busybox" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "run" , "-d" , "--name=test2" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
test2ID := strings . TrimSpace ( out )
out , err = s . d . Cmd ( "run" , "-d" , "--name=test3" , "--link" , "test2:abc" , "busybox" , "top" )
test3ID := strings . TrimSpace ( out )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-09-03 20:51:04 -04:00
out , err = s . d . Cmd ( "create" , "--name=test" , "busybox" )
c . Assert ( err , check . NotNil , check . Commentf ( "expected error trying to create container with duplicate name" ) )
// this one is no longer needed, removing simplifies the remainder of the test
out , err = s . d . Cmd ( "rm" , "-f" , "test" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "ps" , "-a" , "--no-trunc" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
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 :
c . Assert ( names , check . Equals , "test2,test3/abc" )
test2validated = true
case test3ID :
c . Assert ( names , check . Equals , "test3" )
test3validated = true
}
}
c . Assert ( test2validated , check . Equals , true )
c . Assert ( test3validated , check . Equals , true )
}
2016-06-17 11:21:03 -04:00
// TestDaemonRestartWithKilledRunningContainer requires live restore of running containers
func ( s * DockerDaemonSuite ) TestDaemonRestartWithKilledRunningContainer ( t * check . C ) {
// TODO(mlaventure): Not sure what would the exit code be on windows
testRequires ( t , DaemonIsLinux )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( t )
2016-06-17 11:21:03 -04:00
cid , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2016-12-09 17:20:14 -05:00
defer s . d . Stop ( t )
2016-06-17 11:21:03 -04:00
if err != nil {
t . Fatal ( cid , err )
}
cid = strings . TrimSpace ( cid )
2016-06-27 23:32:03 -04:00
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , cid )
t . Assert ( err , check . IsNil )
pid = strings . TrimSpace ( pid )
2016-06-17 11:21:03 -04:00
// Kill the daemon
if err := s . d . Kill ( ) ; err != nil {
t . Fatal ( err )
}
// kill the container
2017-01-05 13:08:24 -05:00
icmd . RunCommand ( ctrBinary , "--address" , "unix:///var/run/docker/libcontainerd/docker-containerd.sock" , "containers" , "kill" , cid ) . Assert ( t , icmd . Success )
2016-06-17 11:21:03 -04: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 10:39:12 -05:00
result := icmd . RunCommand ( "kill" , "-0" , pid )
for result . ExitCode == 0 {
2016-06-27 23:32:03 -04:00
time . Sleep ( 1 * time . Second )
2017-01-16 10:39:12 -05:00
// FIXME(vdemeester) should we check it doesn't error out ?
result = icmd . RunCommand ( "kill" , "-0" , pid )
2016-06-17 11:21:03 -04:00
}
// restart the daemon
2016-12-09 17:20:14 -05:00
s . d . Start ( t )
2016-06-17 11:21:03 -04:00
// Check that we've got the correct exit code
out , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , cid )
t . Assert ( err , check . IsNil )
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 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--live-restore" )
2016-06-17 11:21:03 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
id := strings . TrimSpace ( out )
2016-12-09 04:17:53 -05:00
c . Assert ( s . d . Signal ( os . Kill ) , check . IsNil )
2016-06-17 11:21:03 -04:00
mountOut , err := ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
// container mounts should exist even after daemon has crashed.
2016-12-09 04:17:53 -05:00
comment := check . Commentf ( "%s should stay mounted from older daemon start:\nDaemon root repository %s\n%s" , id , s . d . Root , mountOut )
2016-06-17 11:21:03 -04:00
c . Assert ( strings . Contains ( string ( mountOut ) , id ) , check . Equals , true , comment )
// restart daemon.
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--live-restore" )
2016-06-17 11:21:03 -04:00
// container should be running.
2016-06-23 12:24:28 -04:00
out , err = s . d . Cmd ( "inspect" , "--format={{.State.Running}}" , id )
2016-06-17 11:21:03 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
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 )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
// Now, container mounts should be gone.
mountOut , err = ioutil . ReadFile ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , mountOut ) )
2016-12-09 04:17:53 -05: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 11:21:03 -04: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 ) {
// TODO(mlaventure): Not sure what would the exit code be on windows
testRequires ( t , DaemonIsLinux )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( t , "--live-restore" )
2016-06-17 11:21:03 -04:00
cid , err := s . d . Cmd ( "run" , "-d" , "--name" , "test" , "busybox" , "top" )
2016-12-09 17:20:14 -05:00
defer s . d . Stop ( t )
2016-06-17 11:21:03 -04:00
if err != nil {
t . Fatal ( cid , err )
}
cid = strings . TrimSpace ( cid )
2016-06-27 23:32:03 -04:00
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , cid )
t . Assert ( err , check . IsNil )
2016-06-17 11:21:03 -04: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 12:57:34 -04:00
result := icmd . RunCommand (
ctrBinary ,
"--address" , "unix:///var/run/docker/libcontainerd/docker-containerd.sock" ,
"containers" , "resume" , cid )
2017-08-23 17:01:29 -04:00
result . Assert ( t , icmd . Success )
2016-06-17 11:21:03 -04: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 12:57:34 -04: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 11:21:03 -04:00
// restart the daemon
2016-12-09 17:20:14 -05:00
s . d . Start ( t , "--live-restore" )
2016-06-17 11:21:03 -04:00
// Check that we've got the correct status
out , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Status}}" , cid )
t . Assert ( err , check . IsNil )
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-03 20:51:04 -04: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 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2015-09-03 20:51:04 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "run" , "--name=test2" , "--link=test:abc" , "busybox" , "sh" , "-c" , "ping -c 1 abc" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "1 packets transmitted, 1 packets received" )
out , err = s . d . Cmd ( "rm" , "-f" , "test" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "run" , "-d" , "--name=test" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , check . Not ( checker . Contains ) , "1 packets transmitted, 1 packets received" )
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2015-09-03 20:51:04 -04:00
out , err = s . d . Cmd ( "start" , "-a" , "test2" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , check . Not ( checker . Contains ) , "1 packets transmitted, 1 packets received" )
}
2016-01-28 13:33:35 -05:00
func ( s * DockerDaemonSuite ) TestDaemonStartWithoutColors ( c * check . C ) {
2016-02-09 18:02:18 -05:00
testRequires ( c , DaemonIsLinux , NotPpc64le )
2016-01-28 13:33:35 -05:00
infoLog := "\x1b[34mINFO\x1b"
2016-12-29 03:34:11 -05:00
b := bytes . NewBuffer ( nil )
done := make ( chan bool )
2016-01-28 13:33:35 -05:00
p , tty , err := pty . Open ( )
c . Assert ( err , checker . IsNil )
defer func ( ) {
tty . Close ( )
p . Close ( )
} ( )
2016-12-29 03:34:11 -05:00
go func ( ) {
io . Copy ( b , p )
done <- true
} ( )
2016-01-28 13:33:35 -05:00
// Enable coloring explicitly
2016-08-30 17:25:16 -04:00
s . d . StartWithLogFile ( tty , "--raw-logs=false" )
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2016-12-29 03:34:11 -05:00
// Wait for io.Copy() before checking output
<- done
2016-01-28 13:33:35 -05:00
c . Assert ( b . String ( ) , checker . Contains , infoLog )
b . Reset ( )
2016-12-29 03:34:11 -05: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 ( )
c . Assert ( err , checker . IsNil )
go func ( ) {
io . Copy ( b , p )
done <- true
} ( )
2016-01-28 13:33:35 -05:00
// Disable coloring explicitly
2016-08-30 17:25:16 -04:00
s . d . StartWithLogFile ( tty , "--raw-logs=true" )
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2016-12-29 03:34:11 -05:00
// Wait for io.Copy() before checking output
<- done
c . Assert ( b . String ( ) , check . Not ( check . Equals ) , "" )
2016-01-28 13:33:35 -05:00
c . Assert ( b . String ( ) , check . Not ( checker . Contains ) , infoLog )
}
2016-02-01 18:09:25 -05:00
func ( s * DockerDaemonSuite ) TestDaemonDebugLog ( c * check . C ) {
2016-02-09 18:02:18 -05:00
testRequires ( c , DaemonIsLinux , NotPpc64le )
2016-02-01 18:09:25 -05:00
debugLog := "\x1b[37mDEBU\x1b"
p , tty , err := pty . Open ( )
c . Assert ( err , checker . IsNil )
defer func ( ) {
tty . Close ( )
p . Close ( )
} ( )
b := bytes . NewBuffer ( nil )
go io . Copy ( b , p )
2016-08-30 17:25:16 -04:00
s . d . StartWithLogFile ( tty , "--debug" )
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
2016-02-01 18:09:25 -05:00
c . Assert ( b . String ( ) , checker . Contains , debugLog )
}
2016-02-18 14:00:26 -05:00
2016-08-30 17:25:16 -04:00
func ( s * DockerDaemonSuite ) TestDaemonDiscoveryBackendConfigReload ( c * check . C ) {
2016-02-18 14:00:26 -05:00
testRequires ( c , SameHostDaemon , DaemonIsLinux )
// daemon config file
2016-07-28 11:58:06 -04: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 ) )
c . Assert ( err , checker . IsNil )
2016-02-18 14:00:26 -05:00
2016-08-03 12:20:46 -04:00
// --log-level needs to be set so that d.Start() doesn't add --debug causing
// a conflict with the config
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--config-file" , configFilePath , "--log-level=info" )
2016-02-18 14:00:26 -05:00
// daemon config file
2016-07-28 11:58:06 -04:00
daemonConfig = ` {
2016-02-18 14:00:26 -05:00
"cluster-store" : "consul://consuladdr:consulport/some/path" ,
"cluster-advertise" : "192.168.56.100:0" ,
"debug" : false
} `
2016-07-28 11:58:06 -04:00
err = configFile . Truncate ( 0 )
c . Assert ( err , checker . IsNil )
_ , err = configFile . Seek ( 0 , os . SEEK_SET )
2016-02-18 14:00:26 -05:00
c . Assert ( err , checker . IsNil )
2016-07-28 11:58:06 -04:00
_ , err = configFile . Write ( [ ] byte ( daemonConfig ) )
c . Assert ( err , checker . IsNil )
2016-02-18 14:00:26 -05:00
2016-12-09 04:17:53 -05:00
err = s . d . ReloadConfig ( )
2016-07-28 11:58:06 -04:00
c . Assert ( err , checker . IsNil , check . Commentf ( "error reloading daemon config" ) )
2016-02-18 14:00:26 -05:00
2016-08-30 17:25:16 -04:00
out , err := s . d . Cmd ( "info" )
2016-02-18 14:00:26 -05:00
c . Assert ( err , checker . IsNil )
2016-08-03 12:20:46 -04:00
2016-03-28 03:46:53 -04: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 14:00:26 -05:00
}
2016-04-11 19:07:02 -04:00
// Test for #21956
func ( s * DockerDaemonSuite ) TestDaemonLogOptions ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--log-driver=syslog" , "--log-opt=syslog-address=udp://127.0.0.1:514" )
2016-04-11 19:07:02 -04:00
out , err := s . d . Cmd ( "run" , "-d" , "--log-driver=json-file" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
id := strings . TrimSpace ( out )
out , err = s . d . Cmd ( "inspect" , "--format='{{.HostConfig.LogConfig}}'" , id )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "{json-file map[]}" )
}
2016-05-06 00:45:55 -04:00
// Test case for #20936, #22443
func ( s * DockerDaemonSuite ) TestDaemonMaxConcurrency ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . Start ( c , "--max-concurrent-uploads=6" , "--max-concurrent-downloads=8" )
2016-05-06 00:45:55 -04:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 6" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 8" `
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04: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 ) {
testRequires ( c , SameHostDaemon , DaemonIsLinux )
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
defer os . Remove ( configFilePath )
daemonConfig := ` { "max-concurrent-downloads" : 8 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 17:20:14 -05:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-06 00:45:55 -04:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 5" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 8" `
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
daemonConfig = ` { "max-concurrent-uploads" : 7, "max-concurrent-downloads" : 9 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
// unix.Kill(s.d.cmd.Process.Pid, unix.SIGHUP)
2016-05-06 00:45:55 -04: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 04:17:53 -05:00
content , err = s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04: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 ) {
testRequires ( c , SameHostDaemon , DaemonIsLinux )
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
defer os . Remove ( configFilePath )
daemonConfig := ` { "max-concurrent-uploads" : null } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 17:20:14 -05:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-06 00:45:55 -04:00
expectedMaxConcurrentUploads := ` level=debug msg="Max Concurrent Uploads: 5" `
expectedMaxConcurrentDownloads := ` level=debug msg="Max Concurrent Downloads: 3" `
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
daemonConfig = ` { "max-concurrent-uploads" : 1, "max-concurrent-downloads" : null } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
// unix.Kill(s.d.cmd.Process.Pid, unix.SIGHUP)
2016-05-06 00:45:55 -04: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 04:17:53 -05:00
content , err = s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
configFile , err = os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
daemonConfig = ` { "labels":["foo=bar"] } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-06 00:45:55 -04: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 04:17:53 -05:00
content , err = s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-06 00:45:55 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentUploads )
c . Assert ( string ( content ) , checker . Contains , expectedMaxConcurrentDownloads )
}
2016-05-24 04:13:54 -04:00
func ( s * DockerDaemonSuite ) TestBuildOnDisabledBridgeNetworkDaemon ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "-b=none" , "--iptables=false" )
2016-12-09 04:17:53 -05:00
out , code , err := s . d . BuildImageWithOut ( "busyboxs" ,
2016-05-24 04:13:54 -04:00
` FROM busybox
RUN cat / etc / hosts ` , false )
comment := check . Commentf ( "Failed to build image. output %s, exitCode %d, err %v" , out , code , err )
c . Assert ( err , check . IsNil , comment )
c . Assert ( code , check . Equals , 0 , comment )
}
2016-04-29 01:46:57 -04:00
// Test case for #21976
2017-01-02 17:42:45 -05:00
func ( s * DockerDaemonSuite ) TestDaemonDNSFlagsInHostMode ( c * check . C ) {
2016-04-29 01:46:57 -04:00
testRequires ( c , SameHostDaemon , DaemonIsLinux )
2017-01-02 17:42:45 -05:00
s . d . StartWithBusybox ( c , "--dns" , "1.2.3.4" , "--dns-search" , "example.com" , "--dns-opt" , "timeout:3" )
2016-04-29 01:46:57 -04: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 17:42:45 -05:00
expectedOutput = "search example.com"
2016-04-29 01:46:57 -04:00
c . Assert ( out , checker . Contains , expectedOutput , check . Commentf ( "Expected '%s', but got %q" , expectedOutput , out ) )
2017-01-02 17:42:45 -05:00
expectedOutput = "options timeout:3"
2016-04-29 01:46:57 -04:00
c . Assert ( out , checker . Contains , expectedOutput , check . Commentf ( "Expected '%s', but got %q" , expectedOutput , out ) )
}
2016-05-23 17:49:50 -04:00
func ( s * DockerDaemonSuite ) TestRunWithRuntimeFromConfigFile ( c * check . C ) {
conf , err := ioutil . TempFile ( "" , "config-file-" )
c . Assert ( err , check . IsNil )
configName := conf . Name ( )
conf . Close ( )
defer os . Remove ( configName )
config := `
{
"runtimes" : {
"oci" : {
"path" : "docker-runc"
} ,
"vm" : {
"path" : "/usr/local/bin/vm-manager" ,
"runtimeArgs" : [
"--debug"
]
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--config-file" , configName )
2016-05-23 17:49:50 -04:00
// Run with default runtime
out , err := s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2016-06-19 12:53:31 -04:00
// Run with default runtime explicitly
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// 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" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// Run with "vm"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=vm" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
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 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 17:49:50 -04:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
// Run with default runtime
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// Run with "oci"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=oci" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Start previously created container with oci
out , err = s . d . Cmd ( "start" , "oci-runtime-ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Check that we can't override the default runtime
config = `
{
"runtimes" : {
2016-06-20 15:14:27 -04:00
"runc" : {
"path" : "my-runc"
2016-05-23 17:49:50 -04:00
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 17:49:50 -04:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-06-20 15:14:27 -04:00
c . Assert ( string ( content ) , checker . Contains , ` file configuration validation failed (runtime name 'runc' is reserved) ` )
2016-05-23 17:49:50 -04:00
// Check that we can select a default runtime
config = `
{
"default-runtime" : "vm" ,
"runtimes" : {
"oci" : {
"path" : "docker-runc"
} ,
"vm" : {
"path" : "/usr/local/bin/vm-manager" ,
"runtimeArgs" : [
"--debug"
]
}
}
}
`
ioutil . WriteFile ( configName , [ ] byte ( config ) , 0644 )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-23 17:49:50 -04:00
// Give daemon time to reload config
<- time . After ( 1 * time . Second )
out , err = s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
2016-06-19 12:53:31 -04:00
// Run with default runtime explicitly
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
}
func ( s * DockerDaemonSuite ) TestRunWithRuntimeFromCommandLine ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--add-runtime" , "oci=docker-runc" , "--add-runtime" , "vm=/usr/local/bin/vm-manager" )
2016-05-23 17:49:50 -04:00
// Run with default runtime
out , err := s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
2016-06-19 12:53:31 -04:00
// Run with default runtime explicitly
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// 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" )
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// Run with "vm"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=vm" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
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 17:20:14 -05:00
s . d . Stop ( c )
s . d . StartWithBusybox ( c )
2016-05-23 17:49:50 -04:00
// Run with default runtime
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
// Run with "oci"
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=oci" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Start previously created container with oci
out , err = s . d . Cmd ( "start" , "oci-runtime-ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "Unknown runtime specified oci" )
// Check that we can't override the default runtime
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
c . Assert ( s . d . StartWithError ( "--add-runtime" , "runc=my-runc" ) , checker . NotNil )
2016-05-23 17:49:50 -04:00
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-06-20 15:14:27 -04:00
c . Assert ( string ( content ) , checker . Contains , ` runtime name 'runc' is reserved ` )
2016-05-23 17:49:50 -04:00
// Check that we can select a default runtime
2016-12-09 17:20:14 -05:00
s . d . Stop ( c )
s . d . StartWithBusybox ( c , "--default-runtime=vm" , "--add-runtime" , "oci=docker-runc" , "--add-runtime" , "vm=/usr/local/bin/vm-manager" )
2016-05-23 17:49:50 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "busybox" , "ls" )
c . Assert ( err , check . NotNil , check . Commentf ( out ) )
c . Assert ( out , checker . Contains , "/usr/local/bin/vm-manager: no such file or directory" )
2016-06-19 12:53:31 -04:00
// Run with default runtime explicitly
2016-06-20 15:14:27 -04:00
out , err = s . d . Cmd ( "run" , "--rm" , "--runtime=runc" , "busybox" , "ls" )
2016-05-23 17:49:50 -04:00
c . Assert ( err , check . IsNil , check . Commentf ( out ) )
}
2016-03-01 11:30:27 -05:00
func ( s * DockerDaemonSuite ) TestDaemonRestartWithAutoRemoveContainer ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2016-03-01 11:30:27 -05: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" )
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 17:20:14 -05:00
s . d . Restart ( c )
2016-03-01 11:30:27 -05:00
out , err = s . d . Cmd ( "ps" , "-a" )
c . Assert ( err , checker . IsNil , check . Commentf ( "out: %v" , out ) )
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 15:00:27 -04:00
func ( s * DockerDaemonSuite ) TestDaemonRestartSaveContainerExitCode ( c * check . C ) {
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c )
2016-08-30 15:00:27 -04:00
containerName := "error-values"
// Make a container with both a non 0 exit code and an error message
2017-01-17 21:08:31 -05: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.
out , err := s . d . Cmd ( "run" , "--name" , containerName , "--init=false" , "busybox" , "toto" )
2016-08-30 15:00:27 -04:00
c . Assert ( err , checker . NotNil )
// Check that those values were saved on disk
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , containerName )
out = strings . TrimSpace ( out )
c . Assert ( err , checker . IsNil )
c . Assert ( out , checker . Equals , "127" )
2017-01-17 21:08:31 -05:00
errMsg1 , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Error}}" , containerName )
errMsg1 = strings . TrimSpace ( errMsg1 )
2016-08-30 15:00:27 -04:00
c . Assert ( err , checker . IsNil )
2017-01-17 21:08:31 -05:00
c . Assert ( errMsg1 , checker . Contains , "executable file not found" )
2016-08-30 15:00:27 -04:00
// now restart daemon
2016-12-09 17:20:14 -05:00
s . d . Restart ( c )
2016-08-30 15:00:27 -04:00
// Check that those values are still around
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.State.ExitCode}}" , containerName )
out = strings . TrimSpace ( out )
c . Assert ( err , checker . IsNil )
c . Assert ( out , checker . Equals , "127" )
out , err = s . d . Cmd ( "inspect" , "-f" , "{{.State.Error}}" , containerName )
out = strings . TrimSpace ( out )
c . Assert ( err , checker . IsNil )
2017-01-17 21:08:31 -05:00
c . Assert ( out , checker . Equals , errMsg1 )
2016-08-30 15:00:27 -04:00
}
2016-09-06 09:49:10 -04:00
func ( s * DockerDaemonSuite ) TestDaemonBackcompatPre17Volumes ( c * check . C ) {
testRequires ( c , SameHostDaemon )
d := s . d
2016-12-09 17:20:14 -05:00
d . StartWithBusybox ( c )
2016-09-06 09:49:10 -04:00
// hack to be able to side-load a container config
out , err := d . Cmd ( "create" , "busybox:latest" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
id := strings . TrimSpace ( out )
out , err = d . Cmd ( "inspect" , "--type=image" , "--format={{.ID}}" , "busybox:latest" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
2016-12-09 17:20:14 -05:00
d . Stop ( c )
2016-12-09 04:17:53 -05:00
<- d . Wait
2016-09-06 09:49:10 -04:00
imageID := strings . TrimSpace ( out )
volumeID := stringid . GenerateNonCryptoID ( )
2016-12-09 04:17:53 -05:00
vfsPath := filepath . Join ( d . Root , "vfs" , "dir" , volumeID )
2016-09-06 09:49:10 -04:00
c . Assert ( os . MkdirAll ( vfsPath , 0755 ) , checker . IsNil )
config := [ ] byte ( `
{
"ID" : "` + id + `" ,
"Name" : "hello" ,
2016-12-09 04:17:53 -05:00
"Driver" : "` + d.StorageDriver() + `" ,
2016-09-06 09:49:10 -04:00
"Image" : "` + imageID + `" ,
"Config" : { "Image" : "busybox:latest" } ,
"NetworkSettings" : { } ,
"Volumes" : {
"/bar" : "/foo" ,
"/foo" : "` + vfsPath + `" ,
"/quux" : "/quux"
} ,
"VolumesRW" : {
"/bar" : true ,
"/foo" : true ,
"/quux" : false
}
}
` )
2016-12-09 04:17:53 -05:00
configPath := filepath . Join ( d . Root , "containers" , id , "config.v2.json" )
2017-04-10 12:54:29 -04:00
c . Assert ( ioutil . WriteFile ( configPath , config , 600 ) , checker . IsNil )
2016-12-09 17:20:14 -05:00
d . Start ( c )
2016-09-06 09:49:10 -04:00
out , err = d . Cmd ( "inspect" , "--type=container" , "--format={{ json .Mounts }}" , id )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
type mount struct {
Name string
Source string
Destination string
Driver string
RW bool
}
ls := [ ] mount { }
err = json . NewDecoder ( strings . NewReader ( out ) ) . Decode ( & ls )
c . Assert ( err , checker . IsNil )
expected := [ ] mount {
{ Source : "/foo" , Destination : "/bar" , RW : true } ,
{ Name : volumeID , Destination : "/foo" , RW : true } ,
{ Source : "/quux" , Destination : "/quux" , RW : false } ,
}
c . Assert ( ls , checker . HasLen , len ( expected ) )
for _ , m := range ls {
var matched bool
for _ , x := range expected {
if m . Source == x . Source && m . Destination == x . Destination && m . RW == x . RW || m . Name != x . Name {
matched = true
break
}
}
c . Assert ( matched , checker . True , check . Commentf ( "did find match for %+v" , m ) )
}
}
2016-09-24 09:44:25 -04:00
func ( s * DockerDaemonSuite ) TestDaemonWithUserlandProxyPath ( c * check . C ) {
testRequires ( c , SameHostDaemon , DaemonIsLinux )
dockerProxyPath , err := exec . LookPath ( "docker-proxy" )
c . Assert ( err , checker . IsNil )
tmpDir , err := ioutil . TempDir ( "" , "test-docker-proxy" )
c . Assert ( err , checker . IsNil )
newProxyPath := filepath . Join ( tmpDir , "docker-proxy" )
cmd := exec . Command ( "cp" , dockerProxyPath , newProxyPath )
c . Assert ( cmd . Run ( ) , checker . IsNil )
// custom one
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--userland-proxy-path" , newProxyPath )
2016-09-24 09:44:25 -04:00
out , err := s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
// try with the original one
2016-12-09 17:20:14 -05:00
s . d . Restart ( c , "--userland-proxy-path" , dockerProxyPath )
2016-09-24 09:44:25 -04:00
out , err = s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
c . Assert ( err , checker . IsNil , check . Commentf ( out ) )
// not exist
2016-12-09 17:20:14 -05:00
s . d . Restart ( c , "--userland-proxy-path" , "/does/not/exist" )
2016-09-24 09:44:25 -04:00
out , err = s . d . Cmd ( "run" , "-p" , "5000:5000" , "busybox:latest" , "true" )
c . Assert ( err , checker . NotNil , check . Commentf ( out ) )
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 17:07:30 -04:00
// Test case for #22471
func ( s * DockerDaemonSuite ) TestDaemonShutdownTimeout ( c * check . C ) {
testRequires ( c , SameHostDaemon )
2016-12-09 17:20:14 -05:00
s . d . StartWithBusybox ( c , "--shutdown-timeout=3" )
2016-05-26 17:07:30 -04:00
_ , err := s . d . Cmd ( "run" , "-d" , "busybox" , "top" )
c . Assert ( err , check . IsNil )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGINT ) , checker . IsNil )
2016-05-26 17:07:30 -04:00
select {
2016-12-09 04:17:53 -05:00
case <- s . d . Wait :
2016-05-26 17:07:30 -04:00
case <- time . After ( 5 * time . Second ) :
}
expectedMessage := ` level=debug msg="start clean shutdown of all containers with a 3 seconds timeout..." `
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-26 17:07:30 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMessage )
}
// Test case for #22471
func ( s * DockerDaemonSuite ) TestDaemonShutdownTimeoutWithConfigFile ( c * check . C ) {
testRequires ( c , SameHostDaemon )
// daemon config file
configFilePath := "test.json"
configFile , err := os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
defer os . Remove ( configFilePath )
daemonConfig := ` { "shutdown-timeout" : 8 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2016-12-09 17:20:14 -05:00
s . d . Start ( c , fmt . Sprintf ( "--config-file=%s" , configFilePath ) )
2016-05-26 17:07:30 -04:00
configFile , err = os . Create ( configFilePath )
c . Assert ( err , checker . IsNil )
daemonConfig = ` { "shutdown-timeout" : 5 } `
fmt . Fprintf ( configFile , "%s" , daemonConfig )
configFile . Close ( )
2017-05-23 10:22:32 -04:00
c . Assert ( s . d . Signal ( unix . SIGHUP ) , checker . IsNil )
2016-05-26 17:07:30 -04:00
select {
2016-12-09 04:17:53 -05:00
case <- s . d . Wait :
2016-05-26 17:07:30 -04:00
case <- time . After ( 3 * time . Second ) :
}
expectedMessage := ` level=debug msg="Reset Shutdown Timeout: 5" `
2016-12-09 04:17:53 -05:00
content , err := s . d . ReadLogFile ( )
c . Assert ( err , checker . IsNil )
2016-05-26 17:07:30 -04:00
c . Assert ( string ( content ) , checker . Contains , expectedMessage )
}
2016-12-13 11:06:42 -05:00
// Test case for 29342
func ( s * DockerDaemonSuite ) TestExecWithUserAfterLiveRestore ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
s . d . StartWithBusybox ( c , "--live-restore" )
2017-04-06 04:33:49 -04: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" )
2016-12-13 11:06:42 -05:00
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
2016-12-28 20:08:03 -05:00
s . d . WaitRun ( "top" )
2016-12-13 11:06:42 -05:00
2017-04-06 04:33:49 -04: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 11:06:42 -05: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 05:38:13 -04:00
c . Assert ( out2 , check . Equals , out1 , check . Commentf ( "Output: before restart '%s', after restart '%s'" , out1 , out2 ) )
2016-12-13 11:06:42 -05:00
out , err = s . d . Cmd ( "stop" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
}
2016-12-28 20:08:03 -05:00
func ( s * DockerDaemonSuite ) TestRemoveContainerAfterLiveRestore ( c * check . C ) {
testRequires ( c , DaemonIsLinux , overlayFSSupported , SameHostDaemon )
s . d . StartWithBusybox ( c , "--live-restore" , "--storage-driver" , "overlay" )
out , err := s . d . Cmd ( "run" , "-d" , "--name=top" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
s . d . WaitRun ( "top" )
// restart daemon.
s . d . Restart ( c , "--live-restore" , "--storage-driver" , "overlay" )
out , err = s . d . Cmd ( "stop" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
// test if the rootfs mountpoint still exist
mountpoint , err := s . d . InspectField ( "top" , ".GraphDriver.Data.MergedDir" )
c . Assert ( err , check . IsNil )
f , err := os . Open ( "/proc/self/mountinfo" )
c . Assert ( err , check . IsNil )
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" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
2016-12-27 20:44:38 -05:00
}
// #29598
func ( s * DockerDaemonSuite ) TestRestartPolicyWithLiveRestore ( c * check . C ) {
testRequires ( c , DaemonIsLinux , SameHostDaemon )
s . d . StartWithBusybox ( c , "--live-restore" )
out , err := s . d . Cmd ( "run" , "-d" , "--restart" , "always" , "busybox" , "top" )
c . Assert ( err , check . IsNil , check . Commentf ( "output: %s" , out ) )
id := strings . TrimSpace ( out )
2016-12-28 20:08:03 -05:00
2016-12-27 20:44:38 -05: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 )
c . Assert ( err , checker . IsNil )
s . d . Restart ( c , "--live-restore" )
pid , err := s . d . Cmd ( "inspect" , "-f" , "{{.State.Pid}}" , id )
c . Assert ( err , check . IsNil )
pidint , err := strconv . Atoi ( strings . TrimSpace ( pid ) )
c . Assert ( err , check . IsNil )
c . Assert ( pidint , checker . GreaterThan , 0 )
2017-05-23 10:22:32 -04:00
c . Assert ( unix . Kill ( pidint , unix . SIGKILL ) , check . IsNil )
2016-12-27 20:44:38 -05: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 )
c . Assert ( err , checker . IsNil )
if ! newState . Running {
continue
}
if newState . StartedAt . After ( origState . StartedAt ) {
break
}
}
out , err = s . d . Cmd ( "stop" , id )
c . Assert ( err , check . IsNil , check . Commentf ( "output: %s" , out ) )
2016-12-28 20:08:03 -05:00
}
2016-12-25 04:11:12 -05: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" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
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" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
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" )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( pattern . MatchString ( out ) , checker . True )
out , err = s . d . Cmd ( "inspect" , "--format" , "{{.HostConfig.ShmSize}}" , name )
c . Assert ( err , check . IsNil , check . Commentf ( "Output: %s" , out ) )
c . Assert ( strings . TrimSpace ( out ) , check . Equals , fmt . Sprintf ( "%v" , size ) )
}
2017-06-26 14:54:14 -04:00
2017-07-19 14:24:54 -04:00
// this is used to test both "private" and "shareable" daemon default ipc modes
func testDaemonIpcPrivateShareable ( d * daemon . Daemon , c * check . C , mustExist bool ) {
name := "test-ipcmode"
_ , err := d . Cmd ( "run" , "-d" , "--name" , name , "busybox" , "top" )
c . Assert ( err , checker . IsNil )
// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
mm , err := d . Cmd ( "exec" , "-i" , name , "sh" , "-c" , cmd )
c . Assert ( err , checker . IsNil )
c . Assert ( mm , checker . Matches , "^[0-9]+:[0-9]+$" )
exists , err := testIpcCheckDevExists ( mm )
c . Assert ( err , checker . IsNil )
c . Logf ( "[testDaemonIpcPrivateShareable] ipcdev: %v, exists: %v, mustExist: %v\n" , mm , exists , mustExist )
c . Assert ( exists , checker . Equals , mustExist )
}
// TestDaemonIpcModeShareable checks that --default-ipc-mode shareable works as intended.
func ( s * DockerDaemonSuite ) TestDaemonIpcModeShareable ( c * check . C ) {
2017-08-24 09:46:41 -04:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2017-07-19 14:24:54 -04:00
s . d . StartWithBusybox ( c , "--default-ipc-mode" , "shareable" )
testDaemonIpcPrivateShareable ( s . d , c , true )
}
// TestDaemonIpcModePrivate checks that --default-ipc-mode private works as intended.
func ( s * DockerDaemonSuite ) TestDaemonIpcModePrivate ( c * check . C ) {
2017-08-24 09:46:41 -04:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2017-07-19 14:24:54 -04:00
s . d . StartWithBusybox ( c , "--default-ipc-mode" , "private" )
testDaemonIpcPrivateShareable ( s . d , c , false )
}
// used to check if an IpcMode given in config works as intended
func testDaemonIpcFromConfig ( s * DockerDaemonSuite , c * check . C , mode string , mustExist bool ) {
f , err := ioutil . TempFile ( "" , "test-daemon-ipc-config" )
c . Assert ( err , checker . IsNil )
defer os . Remove ( f . Name ( ) )
config := ` { "default-ipc-mode": " ` + mode + ` "} `
_ , err = f . WriteString ( config )
c . Assert ( f . Close ( ) , checker . IsNil )
c . Assert ( err , checker . IsNil )
s . d . StartWithBusybox ( c , "--config-file" , f . Name ( ) )
testDaemonIpcPrivateShareable ( s . d , c , mustExist )
}
// TestDaemonIpcModePrivateFromConfig checks that "default-ipc-mode: private" config works as intended.
func ( s * DockerDaemonSuite ) TestDaemonIpcModePrivateFromConfig ( c * check . C ) {
2017-08-24 09:46:41 -04:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2017-07-19 14:24:54 -04:00
testDaemonIpcFromConfig ( s , c , "private" , false )
}
// TestDaemonIpcModeShareableFromConfig checks that "default-ipc-mode: shareable" config works as intended.
func ( s * DockerDaemonSuite ) TestDaemonIpcModeShareableFromConfig ( c * check . C ) {
2017-08-24 09:46:41 -04:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2017-07-19 14:24:54 -04:00
testDaemonIpcFromConfig ( s , c , "shareable" , true )
}
func testDaemonStartIpcMode ( c * check . C , from , mode string , valid bool ) {
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config {
Experimental : testEnv . ExperimentalDaemon ( ) ,
} )
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" )
c . Assert ( err , checker . IsNil )
defer os . Remove ( f . Name ( ) )
config := ` { "default-ipc-mode": " ` + mode + ` "} `
_ , err = f . WriteString ( config )
c . Assert ( f . Close ( ) , checker . IsNil )
c . Assert ( err , checker . IsNil )
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 {
c . Assert ( serr , check . IsNil )
} else {
c . Assert ( serr , check . NotNil )
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 ) {
2017-08-24 09:46:41 -04:00
testRequires ( c , DaemonIsLinux , SameHostDaemon )
2017-07-19 14:24:54 -04: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 )
}
}
}
// TestDaemonRestartIpcMode makes sure a container keeps its ipc mode
// (derived from daemon default) even after the daemon is restarted
// with a different default ipc mode.
func ( s * DockerDaemonSuite ) TestDaemonRestartIpcMode ( c * check . C ) {
f , err := ioutil . TempFile ( "" , "test-daemon-ipc-config-restart" )
c . Assert ( err , checker . IsNil )
file := f . Name ( )
defer os . Remove ( file )
c . Assert ( f . Close ( ) , checker . IsNil )
config := [ ] byte ( ` { "default-ipc-mode": "private"} ` )
c . Assert ( ioutil . WriteFile ( file , config , 0644 ) , checker . IsNil )
s . d . StartWithBusybox ( c , "--config-file" , file )
// check the container is created with private ipc mode as per daemon default
name := "ipc1"
_ , err = s . d . Cmd ( "run" , "-d" , "--name" , name , "--restart=always" , "busybox" , "top" )
c . Assert ( err , checker . IsNil )
m , err := s . d . InspectField ( name , ".HostConfig.IpcMode" )
c . Assert ( err , check . IsNil )
c . Assert ( m , checker . Equals , "private" )
// restart the daemon with shareable default ipc mode
config = [ ] byte ( ` { "default-ipc-mode": "shareable"} ` )
c . Assert ( ioutil . WriteFile ( file , config , 0644 ) , checker . IsNil )
s . d . Restart ( c , "--config-file" , file )
// check the container is still having private ipc mode
m , err = s . d . InspectField ( name , ".HostConfig.IpcMode" )
c . Assert ( err , check . IsNil )
c . Assert ( m , checker . Equals , "private" )
// check a new container is created with shareable ipc mode as per new daemon default
name = "ipc2"
_ , err = s . d . Cmd ( "run" , "-d" , "--name" , name , "busybox" , "top" )
c . Assert ( err , checker . IsNil )
m , err = s . d . InspectField ( name , ".HostConfig.IpcMode" )
c . Assert ( err , check . IsNil )
c . Assert ( m , checker . Equals , "shareable" )
}
2017-06-26 14:54:14 -04:00
// TestFailedPluginRemove makes sure that a failed plugin remove does not block
// the daemon from starting
func ( s * DockerDaemonSuite ) TestFailedPluginRemove ( c * check . C ) {
testRequires ( c , DaemonIsLinux , IsAmd64 , SameHostDaemon )
d := daemon . New ( c , dockerBinary , dockerdBinary , daemon . Config { } )
d . Start ( c )
cli , err := client . NewClient ( d . Sock ( ) , api . DefaultVersion , nil , nil )
c . Assert ( err , checker . IsNil )
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" ,
} )
c . Assert ( err , checker . IsNil )
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 )
c . Assert ( err , checker . IsNil )
// simulate a bad/partial removal by removing the plugin config.
configPath := filepath . Join ( d . Root , "plugins" , p . ID , "config.json" )
c . Assert ( os . Remove ( configPath ) , checker . IsNil )
d . Restart ( c )
ctx , cancel = context . WithTimeout ( context . Background ( ) , 30 * time . Second )
defer cancel ( )
_ , err = cli . Ping ( ctx )
c . Assert ( err , checker . IsNil )
_ , _ , err = cli . PluginInspectWithRaw ( ctx , name )
// plugin should be gone since the config.json is gone
c . Assert ( err , checker . NotNil )
}