2014-05-09 06:32:19 -04:00
package main
import (
"encoding/json"
2015-05-22 19:15:14 -04:00
"fmt"
2014-11-11 11:17:33 -05:00
"os"
2015-01-06 19:04:10 -05:00
"reflect"
2015-04-06 09:21:18 -04:00
"strings"
2014-05-09 06:32:19 -04:00
"time"
2015-02-25 23:16:44 -05:00
2015-07-22 14:39:35 -04:00
"os/exec"
2015-07-22 21:46:59 -04:00
"io/ioutil"
2015-11-02 23:24:12 -05:00
"github.com/docker/docker/pkg/integration/checker"
2015-06-30 12:41:01 -04:00
"github.com/docker/docker/pkg/nat"
2015-04-18 12:46:47 -04:00
"github.com/go-check/check"
2014-05-09 06:32:19 -04:00
)
// Make sure we can create a simple container with some args
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateArgs ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "busybox" , "command" , "arg1" , "arg2" , "arg with space" )
2014-05-09 06:32:19 -04:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-05-09 06:32:19 -04:00
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "inspect" , cleanedContainerID )
2014-05-09 06:32:19 -04:00
containers := [ ] struct {
ID string
Created time . Time
Path string
Args [ ] string
Image string
} { }
2015-11-02 23:24:12 -05:00
err := json . Unmarshal ( [ ] byte ( out ) , & containers )
c . Assert ( err , check . IsNil , check . Commentf ( "Error inspecting the container: %s" , err ) )
c . Assert ( containers , checker . HasLen , 1 )
2014-05-09 06:32:19 -04:00
2015-04-18 12:46:47 -04:00
cont := containers [ 0 ]
2015-11-02 23:24:12 -05:00
c . Assert ( string ( cont . Path ) , checker . Equals , "command" , check . Commentf ( "Unexpected container path. Expected command, received: %s" , cont . Path ) )
2014-05-09 06:32:19 -04:00
b := false
expected := [ ] string { "arg1" , "arg2" , "arg with space" }
for i , arg := range expected {
2015-04-18 12:46:47 -04:00
if arg != cont . Args [ i ] {
2014-05-09 06:32:19 -04:00
b = true
break
}
}
2015-04-18 12:46:47 -04:00
if len ( cont . Args ) != len ( expected ) || b {
c . Fatalf ( "Unexpected args. Expected %v, received: %v" , expected , cont . Args )
2014-05-09 06:32:19 -04:00
}
}
// Make sure we can set hostconfig options too
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateHostConfig ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "-P" , "busybox" , "echo" )
2014-05-09 06:32:19 -04:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-05-09 06:32:19 -04:00
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "inspect" , cleanedContainerID )
2014-05-09 06:32:19 -04:00
containers := [ ] struct {
HostConfig * struct {
PublishAllPorts bool
}
} { }
2015-11-02 23:24:12 -05:00
err := json . Unmarshal ( [ ] byte ( out ) , & containers )
c . Assert ( err , check . IsNil , check . Commentf ( "Error inspecting the container: %s" , err ) )
c . Assert ( containers , checker . HasLen , 1 )
2014-05-09 06:32:19 -04:00
2015-11-02 23:24:12 -05:00
cont := containers [ 0 ]
c . Assert ( cont . HostConfig , check . NotNil , check . Commentf ( "Expected HostConfig, got none" ) )
c . Assert ( cont . HostConfig . PublishAllPorts , check . NotNil , check . Commentf ( "Expected PublishAllPorts, got false" ) )
2014-05-09 06:32:19 -04:00
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateWithPortRange ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "-p" , "3300-3303:3300-3303/tcp" , "busybox" , "echo" )
2014-11-03 13:15:55 -05:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-11-03 13:15:55 -05:00
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "inspect" , cleanedContainerID )
2014-11-03 13:15:55 -05:00
containers := [ ] struct {
HostConfig * struct {
PortBindings map [ nat . Port ] [ ] nat . PortBinding
}
} { }
2015-11-02 23:24:12 -05:00
err := json . Unmarshal ( [ ] byte ( out ) , & containers )
c . Assert ( err , check . IsNil , check . Commentf ( "Error inspecting the container: %s" , err ) )
c . Assert ( containers , checker . HasLen , 1 )
2014-11-03 13:15:55 -05:00
2015-04-18 12:46:47 -04:00
cont := containers [ 0 ]
2014-11-03 13:15:55 -05:00
2015-11-02 23:24:12 -05:00
c . Assert ( cont . HostConfig , check . NotNil , check . Commentf ( "Expected HostConfig, got none" ) )
c . Assert ( cont . HostConfig . PortBindings , checker . HasLen , 4 , check . Commentf ( "Expected 4 ports bindings, got %d" , len ( cont . HostConfig . PortBindings ) ) )
2015-04-18 12:46:47 -04:00
for k , v := range cont . HostConfig . PortBindings {
2015-11-02 23:24:12 -05:00
c . Assert ( v , checker . HasLen , 1 , check . Commentf ( "Expected 1 ports binding, for the port %s but found %s" , k , v ) )
c . Assert ( k . Port ( ) , checker . Equals , v [ 0 ] . HostPort , check . Commentf ( "Expected host port %s to match published port %s" , k . Port ( ) , v [ 0 ] . HostPort ) )
2014-11-03 13:15:55 -05:00
}
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateWithiLargePortRange ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "-p" , "1-65535:1-65535/tcp" , "busybox" , "echo" )
2014-11-03 13:15:55 -05:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-11-03 13:15:55 -05:00
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "inspect" , cleanedContainerID )
2014-11-03 13:15:55 -05:00
containers := [ ] struct {
HostConfig * struct {
PortBindings map [ nat . Port ] [ ] nat . PortBinding
}
} { }
2015-11-02 23:24:12 -05:00
err := json . Unmarshal ( [ ] byte ( out ) , & containers )
c . Assert ( err , check . IsNil , check . Commentf ( "Error inspecting the container: %s" , err ) )
c . Assert ( containers , checker . HasLen , 1 )
2014-11-03 13:15:55 -05:00
2015-04-18 12:46:47 -04:00
cont := containers [ 0 ]
2015-11-02 23:24:12 -05:00
c . Assert ( cont . HostConfig , check . NotNil , check . Commentf ( "Expected HostConfig, got none" ) )
c . Assert ( cont . HostConfig . PortBindings , checker . HasLen , 65535 )
2014-11-03 13:15:55 -05:00
2015-04-18 12:46:47 -04:00
for k , v := range cont . HostConfig . PortBindings {
2015-11-02 23:24:12 -05:00
c . Assert ( v , checker . HasLen , 1 )
c . Assert ( k . Port ( ) , checker . Equals , v [ 0 ] . HostPort , check . Commentf ( "Expected host port %s to match published port %s" , k . Port ( ) , v [ 0 ] . HostPort ) )
2014-11-03 13:15:55 -05:00
}
}
2014-05-09 06:32:19 -04:00
// "test123" should be printed by docker create + start
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateEchoStdout ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-02-20 01:56:02 -05:00
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "busybox" , "echo" , "test123" )
2014-05-09 06:32:19 -04:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-05-09 06:32:19 -04:00
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "start" , "-ai" , cleanedContainerID )
2015-11-02 23:24:12 -05:00
c . Assert ( out , checker . Equals , "test123\n" , check . Commentf ( "container should've printed 'test123', got %q" , out ) )
2014-05-09 06:32:19 -04:00
}
2014-11-11 11:17:33 -05:00
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateVolumesCreated ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-04-18 12:46:47 -04:00
testRequires ( c , SameHostDaemon )
2015-02-20 01:56:02 -05:00
2014-11-11 11:17:33 -05:00
name := "test_create_volume"
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "create" , "--name" , name , "-v" , "/foo" , "busybox" )
2015-06-03 15:21:38 -04:00
dir , err := inspectMountSourceField ( name , "/foo" )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil , check . Commentf ( "Error getting volume host path: %q" , err ) )
2014-11-11 11:17:33 -05:00
if _ , err := os . Stat ( dir ) ; err != nil && os . IsNotExist ( err ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Volume was not created" )
2014-11-11 11:17:33 -05:00
}
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Error statting volume host path: %q" , err )
2014-11-11 11:17:33 -05:00
}
}
2015-01-06 19:04:10 -05:00
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateLabels ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-01-06 19:04:10 -05:00
name := "test_create_labels"
expected := map [ string ] string { "k1" : "v1" , "k2" : "v2" }
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "create" , "--name" , name , "-l" , "k1=v1" , "--label" , "k2=v2" , "busybox" )
2015-01-06 19:04:10 -05:00
actual := make ( map [ string ] string )
err := inspectFieldAndMarshall ( name , "Config.Labels" , & actual )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
2015-01-06 19:04:10 -05:00
if ! reflect . DeepEqual ( expected , actual ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Expected %s got %s" , expected , actual )
2015-01-06 19:04:10 -05:00
}
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateLabelFromImage ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-01-06 19:04:10 -05:00
imageName := "testcreatebuildlabel"
_ , err := buildImage ( imageName ,
` FROM busybox
LABEL k1 = v1 k2 = v2 ` ,
true )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
2015-01-06 19:04:10 -05:00
name := "test_create_labels_from_image"
2015-08-11 19:48:41 -04:00
expected := map [ string ] string { "k2" : "x" , "k3" : "v3" , "k1" : "v1" }
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "create" , "--name" , name , "-l" , "k2=x" , "--label" , "k3=v3" , imageName )
2015-01-06 19:04:10 -05:00
actual := make ( map [ string ] string )
err = inspectFieldAndMarshall ( name , "Config.Labels" , & actual )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
2015-01-06 19:04:10 -05:00
if ! reflect . DeepEqual ( expected , actual ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Expected %s got %s" , expected , actual )
2015-01-06 19:04:10 -05:00
}
}
2015-04-10 17:06:43 -04:00
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestCreateHostnameWithNumber ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-04-18 12:46:47 -04:00
out , _ := dockerCmd ( c , "run" , "-h" , "web.0" , "busybox" , "hostname" )
2015-11-02 23:24:12 -05:00
c . Assert ( strings . TrimSpace ( out ) , checker . Equals , "web.0" , check . Commentf ( "hostname not set, expected `web.0`, got: %s" , out ) )
2015-04-10 17:06:43 -04:00
}
2015-05-21 10:30:51 -04:00
func ( s * DockerSuite ) TestCreateRM ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-05-21 10:30:51 -04:00
// Test to make sure we can 'rm' a new container that is in
// "Created" state, and has ever been run. Test "rm -f" too.
// create a container
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "busybox" )
2015-05-21 10:30:51 -04:00
cID := strings . TrimSpace ( out )
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "rm" , cID )
2015-05-21 10:30:51 -04:00
// Now do it again so we can "rm -f" this time
2015-07-14 02:35:36 -04:00
out , _ = dockerCmd ( c , "create" , "busybox" )
2015-05-21 10:30:51 -04:00
cID = strings . TrimSpace ( out )
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "rm" , "-f" , cID )
2015-05-21 10:30:51 -04:00
}
2015-05-22 19:15:14 -04:00
func ( s * DockerSuite ) TestCreateModeIpcContainer ( c * check . C ) {
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-09-18 13:41:12 -04:00
testRequires ( c , SameHostDaemon , NotUserNamespace )
2015-05-22 19:15:14 -04:00
2015-07-14 02:35:36 -04:00
out , _ := dockerCmd ( c , "create" , "busybox" )
2015-05-22 19:15:14 -04:00
id := strings . TrimSpace ( out )
2015-07-14 02:35:36 -04:00
dockerCmd ( c , "create" , fmt . Sprintf ( "--ipc=container:%s" , id ) , "busybox" )
2015-05-22 19:15:14 -04:00
}
2015-07-22 12:14:48 -04:00
func ( s * DockerTrustSuite ) TestTrustedCreate ( c * check . C ) {
2015-07-23 08:12:36 -04:00
repoName := s . setupTrustedImage ( c , "trusted-create" )
2015-07-22 12:14:48 -04:00
// Try create
createCmd := exec . Command ( dockerBinary , "create" , repoName )
s . trustedCmd ( createCmd )
2015-07-23 08:12:36 -04:00
out , _ , err := runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Tagging" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
dockerCmd ( c , "rmi" , repoName )
// Try untrusted create to ensure we pushed the tag to the registry
2015-07-24 04:59:42 -04:00
createCmd = exec . Command ( dockerBinary , "create" , "--disable-content-trust=true" , repoName )
2015-07-22 12:14:48 -04:00
s . trustedCmd ( createCmd )
out , _ , err = runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Status: Downloaded" , check . Commentf ( "Missing expected output on trusted create with --disable-content-trust:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
}
func ( s * DockerTrustSuite ) TestUntrustedCreate ( c * check . C ) {
repoName := fmt . Sprintf ( "%v/dockercli/trusted:latest" , privateRegistryURL )
// tag the image and upload it to the private registry
dockerCmd ( c , "tag" , "busybox" , repoName )
dockerCmd ( c , "push" , repoName )
dockerCmd ( c , "rmi" , repoName )
// Try trusted create on untrusted tag
createCmd := exec . Command ( dockerBinary , "create" , repoName )
s . trustedCmd ( createCmd )
out , _ , err := runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . Not ( check . IsNil ) )
c . Assert ( string ( out ) , checker . Contains , "no trust data available" , check . Commentf ( "Missing expected output on trusted create:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
}
2015-07-23 08:12:36 -04:00
func ( s * DockerTrustSuite ) TestTrustedIsolatedCreate ( c * check . C ) {
repoName := s . setupTrustedImage ( c , "trusted-isolated-create" )
2015-07-22 12:14:48 -04:00
2015-07-23 08:12:36 -04:00
// Try create
createCmd := exec . Command ( dockerBinary , "--config" , "/tmp/docker-isolated-create" , "create" , repoName )
s . trustedCmd ( createCmd )
out , _ , err := runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Tagging" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
dockerCmd ( c , "rmi" , repoName )
2015-07-23 08:12:36 -04:00
}
func ( s * DockerTrustSuite ) TestCreateWhenCertExpired ( c * check . C ) {
2015-07-29 15:09:40 -04:00
c . Skip ( "Currently changes system time, causing instability" )
2015-07-23 08:12:36 -04:00
repoName := s . setupTrustedImage ( c , "trusted-create-expired" )
2015-07-22 12:14:48 -04:00
// Certificates have 10 years of expiration
elevenYearsFromNow := time . Now ( ) . Add ( time . Hour * 24 * 365 * 11 )
runAtDifferentDate ( elevenYearsFromNow , func ( ) {
// Try create
createCmd := exec . Command ( dockerBinary , "create" , repoName )
s . trustedCmd ( createCmd )
2015-07-23 08:12:36 -04:00
out , _ , err := runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . Not ( check . IsNil ) )
c . Assert ( string ( out ) , checker . Contains , "could not validate the path to a trusted root" , check . Commentf ( "Missing expected output on trusted create in the distant future:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
} )
runAtDifferentDate ( elevenYearsFromNow , func ( ) {
// Try create
2015-07-24 04:59:42 -04:00
createCmd := exec . Command ( dockerBinary , "create" , "--disable-content-trust" , repoName )
2015-07-22 12:14:48 -04:00
s . trustedCmd ( createCmd )
2015-07-23 08:12:36 -04:00
out , _ , err := runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . Not ( check . IsNil ) )
c . Assert ( string ( out ) , checker . Contains , "Status: Downloaded" , check . Commentf ( "Missing expected output on trusted create in the distant future:\n%s" , out ) )
2015-07-22 12:14:48 -04:00
} )
}
2015-07-22 19:10:25 -04:00
func ( s * DockerTrustSuite ) TestTrustedCreateFromBadTrustServer ( c * check . C ) {
repoName := fmt . Sprintf ( "%v/dockerclievilcreate/trusted:latest" , privateRegistryURL )
evilLocalConfigDir , err := ioutil . TempDir ( "" , "evil-local-config-dir" )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
2015-07-22 19:10:25 -04:00
// tag the image and upload it to the private registry
dockerCmd ( c , "tag" , "busybox" , repoName )
pushCmd := exec . Command ( dockerBinary , "push" , repoName )
s . trustedCmd ( pushCmd )
out , _ , err := runCommandWithOutput ( pushCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Signing and pushing trust metadata" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 19:10:25 -04:00
dockerCmd ( c , "rmi" , repoName )
// Try create
createCmd := exec . Command ( dockerBinary , "create" , repoName )
s . trustedCmd ( createCmd )
out , _ , err = runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Tagging" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 19:10:25 -04:00
dockerCmd ( c , "rmi" , repoName )
// Kill the notary server, start a new "evil" one.
s . not . Close ( )
s . not , err = newTestNotary ( c )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
2015-07-22 19:10:25 -04:00
// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
// tag an image and upload it to the private registry
dockerCmd ( c , "--config" , evilLocalConfigDir , "tag" , "busybox" , repoName )
// Push up to the new server
pushCmd = exec . Command ( dockerBinary , "--config" , evilLocalConfigDir , "push" , repoName )
s . trustedCmd ( pushCmd )
out , _ , err = runCommandWithOutput ( pushCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . IsNil )
c . Assert ( string ( out ) , checker . Contains , "Signing and pushing trust metadata" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 19:10:25 -04:00
// Now, try creating with the original client from this new trust server. This should fail.
createCmd = exec . Command ( dockerBinary , "create" , repoName )
s . trustedCmd ( createCmd )
out , _ , err = runCommandWithOutput ( createCmd )
2015-11-02 23:24:12 -05:00
c . Assert ( err , check . Not ( check . IsNil ) )
c . Assert ( string ( out ) , checker . Contains , "failed to validate data with current trusted certificates" , check . Commentf ( "Missing expected output on trusted push:\n%s" , out ) )
2015-07-22 19:10:25 -04:00
}
2015-08-18 13:30:44 -04:00
func ( s * DockerSuite ) TestCreateStopSignal ( c * check . C ) {
name := "test_create_stop_signal"
dockerCmd ( c , "create" , "--name" , name , "--stop-signal" , "9" , "busybox" )
res , err := inspectFieldJSON ( name , "Config.StopSignal" )
c . Assert ( err , check . IsNil )
2015-11-02 23:24:12 -05:00
c . Assert ( res , checker . Contains , "9" )
2015-08-18 13:30:44 -04:00
}