2015-06-12 13:25:32 +00:00
package main
import (
2018-04-19 22:30:59 +00:00
"context"
2016-09-17 19:32:31 +00:00
"fmt"
2016-08-04 12:59:55 +00:00
"io/ioutil"
"os"
2015-06-12 13:25:32 +00:00
"os/exec"
2016-08-04 12:59:55 +00:00
"path/filepath"
2015-06-12 13:25:32 +00:00
"strings"
2017-05-24 03:56:26 +00:00
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
2016-12-30 17:23:00 +00:00
"github.com/docker/docker/integration-cli/checker"
2017-03-23 17:35:22 +00:00
"github.com/docker/docker/integration-cli/cli/build"
2015-06-12 13:25:32 +00:00
"github.com/go-check/check"
2019-04-04 13:23:19 +00:00
"gotest.tools/assert"
2018-06-11 13:32:11 +00:00
"gotest.tools/icmd"
2015-06-12 13:25:32 +00:00
)
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLICreate ( c * testing . T ) {
2015-06-12 13:25:32 +00:00
dockerCmd ( c , "volume" , "create" )
2016-12-13 20:21:51 +00:00
_ , _ , err := dockerCmdWithError ( "volume" , "create" , "-d" , "nosuchdriver" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2015-06-12 13:25:32 +00:00
2016-06-14 22:42:30 +00:00
// test using hidden --name option
2015-06-12 13:25:32 +00:00
out , _ := dockerCmd ( c , "volume" , "create" , "--name=test" )
name := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , name , checker . Equals , "test" )
2016-06-14 22:42:30 +00:00
out , _ = dockerCmd ( c , "volume" , "create" , "test2" )
name = strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , name , checker . Equals , "test2" )
2015-06-12 13:25:32 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIInspect ( c * testing . T ) {
2019-09-09 21:05:56 +00:00
assert . Assert ( c , exec . Command ( dockerBinary , "volume" , "inspect" , "doesnotexist" ) . Run ( ) != nil , check . Commentf ( "volume inspect should error on non-existent volume" ) )
2015-06-12 13:25:32 +00:00
out , _ := dockerCmd ( c , "volume" , "create" )
name := strings . TrimSpace ( out )
2016-05-16 21:20:29 +00:00
out , _ = dockerCmd ( c , "volume" , "inspect" , "--format={{ .Name }}" , name )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , name )
2015-06-12 13:25:32 +00:00
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "test" )
2016-05-16 21:20:29 +00:00
out , _ = dockerCmd ( c , "volume" , "inspect" , "--format={{ .Name }}" , "test" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , "test" )
2015-06-12 13:25:32 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIInspectMulti ( c * testing . T ) {
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "test1" )
dockerCmd ( c , "volume" , "create" , "test2" )
2017-02-01 20:03:58 +00:00
dockerCmd ( c , "volume" , "create" , "test3" )
2015-11-07 17:11:37 +00:00
2017-05-21 23:24:07 +00:00
result := dockerCmdWithResult ( "volume" , "inspect" , "--format={{ .Name }}" , "test1" , "test2" , "doesnotexist" , "test3" )
2017-08-23 21:01:29 +00:00
result . Assert ( c , icmd . Expected {
2016-08-04 16:57:34 +00:00
ExitCode : 1 ,
2017-05-21 23:24:07 +00:00
Err : "No such volume: doesnotexist" ,
2016-08-04 16:57:34 +00:00
} )
out := result . Stdout ( )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "test1" )
assert . Assert ( c , out , checker . Contains , "test2" )
assert . Assert ( c , out , checker . Contains , "test3" )
2015-11-07 17:11:37 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILs ( c * testing . T ) {
2016-02-03 14:16:00 +00:00
prefix , _ := getPrefixAndSlashFromDaemonPlatform ( )
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "aaa" )
2015-06-12 13:25:32 +00:00
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "test" )
2016-02-17 08:59:53 +00:00
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "soo" )
2016-02-17 08:59:53 +00:00
dockerCmd ( c , "run" , "-v" , "soo:" + prefix + "/foo" , "busybox" , "ls" , "/" )
2015-06-12 13:25:32 +00:00
2017-09-15 13:16:38 +00:00
out , _ := dockerCmd ( c , "volume" , "ls" , "-q" )
assertVolumesInList ( c , out , [ ] string { "aaa" , "soo" , "test" } )
2016-02-17 08:59:53 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeLsFormat ( c * testing . T ) {
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "aaa" )
dockerCmd ( c , "volume" , "create" , "test" )
dockerCmd ( c , "volume" , "create" , "soo" )
2016-08-04 12:59:55 +00:00
out , _ := dockerCmd ( c , "volume" , "ls" , "--format" , "{{.Name}}" )
2017-09-15 13:16:38 +00:00
assertVolumesInList ( c , out , [ ] string { "aaa" , "soo" , "test" } )
2016-08-04 12:59:55 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeLsFormatDefaultFormat ( c * testing . T ) {
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "aaa" )
dockerCmd ( c , "volume" , "create" , "test" )
dockerCmd ( c , "volume" , "create" , "soo" )
2016-08-04 12:59:55 +00:00
config := ` {
"volumesFormat" : "{{ .Name }} default"
} `
d , err := ioutil . TempDir ( "" , "integration-cli-" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-08-04 12:59:55 +00:00
defer os . RemoveAll ( d )
err = ioutil . WriteFile ( filepath . Join ( d , "config.json" ) , [ ] byte ( config ) , 0644 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-08-04 12:59:55 +00:00
out , _ := dockerCmd ( c , "--config" , d , "volume" , "ls" )
2017-09-15 13:16:38 +00:00
assertVolumesInList ( c , out , [ ] string { "aaa default" , "soo default" , "test default" } )
2016-08-04 12:59:55 +00:00
}
2019-09-09 21:05:55 +00:00
func assertVolumesInList ( c * testing . T , out string , expected [ ] string ) {
2017-09-15 13:16:38 +00:00
lines := strings . Split ( strings . TrimSpace ( string ( out ) ) , "\n" )
for _ , expect := range expected {
found := false
for _ , v := range lines {
found = v == expect
if found {
break
}
}
2019-04-04 13:23:19 +00:00
assert . Assert ( c , found , "Expected volume not found: %v, got: %v" , expect , lines )
2017-09-15 13:16:38 +00:00
}
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILsFilterDangling ( c * testing . T ) {
2016-02-03 14:16:00 +00:00
prefix , _ := getPrefixAndSlashFromDaemonPlatform ( )
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "testnotinuse1" )
dockerCmd ( c , "volume" , "create" , "testisinuse1" )
dockerCmd ( c , "volume" , "create" , "testisinuse2" )
2015-09-05 22:44:29 +00:00
// Make sure both "created" (but not started), and started
// containers are included in reference counting
2015-09-23 23:04:51 +00:00
dockerCmd ( c , "run" , "--name" , "volume-test1" , "-v" , "testisinuse1:" + prefix + "/foo" , "busybox" , "true" )
dockerCmd ( c , "create" , "--name" , "volume-test2" , "-v" , "testisinuse2:" + prefix + "/foo" , "busybox" , "true" )
2015-09-05 22:44:29 +00:00
out , _ := dockerCmd ( c , "volume" , "ls" )
// No filter, all volumes should show
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testisinuse1\n" , check . Commentf ( "expected volume 'testisinuse1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testisinuse2\n" , check . Commentf ( "expected volume 'testisinuse2' in output" ) )
2015-09-05 22:44:29 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "dangling=false" )
2016-01-25 19:39:41 +00:00
// Explicitly disabling dangling
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testisinuse1\n" , check . Commentf ( "expected volume 'testisinuse1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testisinuse2\n" , check . Commentf ( "expected volume 'testisinuse2' in output" ) )
2015-09-05 22:44:29 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "dangling=true" )
2015-12-13 16:00:39 +00:00
// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testisinuse1\n" , check . Commentf ( "volume 'testisinuse1' in output, but not expected" ) )
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testisinuse2\n" , check . Commentf ( "volume 'testisinuse2' in output, but not expected" ) )
2016-01-04 08:37:01 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "dangling=1" )
// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output, dangling also accept 1
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testisinuse1\n" , check . Commentf ( "volume 'testisinuse1' in output, but not expected" ) )
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testisinuse2\n" , check . Commentf ( "volume 'testisinuse2' in output, but not expected" ) )
2016-01-04 08:37:01 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "dangling=0" )
// dangling=0 is same as dangling=false case
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testisinuse1\n" , check . Commentf ( "expected volume 'testisinuse1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testisinuse2\n" , check . Commentf ( "expected volume 'testisinuse2' in output" ) )
2016-03-21 07:39:48 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "name=testisin" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testnotinuse1\n" , check . Commentf ( "expected volume 'testnotinuse1' in output" ) )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testisinuse1\n" , check . Commentf ( "expected volume 'testisinuse1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testisinuse2\n" , check . Commentf ( "expected volume 'testisinuse2' in output" ) )
2016-01-04 08:37:01 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILsErrorWithInvalidFilterName ( c * testing . T ) {
2016-01-04 08:37:01 +00:00
out , _ , err := dockerCmdWithError ( "volume" , "ls" , "-f" , "FOO=123" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "Invalid filter" )
2016-01-04 08:37:01 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILsWithIncorrectFilterValue ( c * testing . T ) {
2016-01-04 08:37:01 +00:00
out , _ , err := dockerCmdWithError ( "volume" , "ls" , "-f" , "dangling=invalid" )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "Invalid filter" )
2015-09-05 22:44:29 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIRm ( c * testing . T ) {
2016-02-03 14:16:00 +00:00
prefix , _ := getPrefixAndSlashFromDaemonPlatform ( )
2015-06-12 13:25:32 +00:00
out , _ := dockerCmd ( c , "volume" , "create" )
id := strings . TrimSpace ( out )
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "test" )
2015-06-12 13:25:32 +00:00
dockerCmd ( c , "volume" , "rm" , id )
dockerCmd ( c , "volume" , "rm" , "test" )
volumeID := "testing"
2015-09-23 23:04:51 +00:00
dockerCmd ( c , "run" , "-v" , volumeID + ":" + prefix + "/foo" , "--name=test" , "busybox" , "sh" , "-c" , "echo hello > /foo/bar" )
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( dockerBinary , "volume" , "rm" , "testing" ) . Assert ( c , icmd . Expected {
ExitCode : 1 ,
2017-01-05 18:08:24 +00:00
Error : "exit status 1" ,
2017-01-05 11:38:34 +00:00
} )
2015-06-12 13:25:32 +00:00
out , _ = dockerCmd ( c , "run" , "--volumes-from=test" , "--name=test2" , "busybox" , "sh" , "-c" , "cat /foo/bar" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , "hello" )
2015-06-12 13:25:32 +00:00
dockerCmd ( c , "rm" , "-fv" , "test2" )
dockerCmd ( c , "volume" , "inspect" , volumeID )
dockerCmd ( c , "rm" , "-f" , "test" )
2015-09-23 23:04:51 +00:00
out , _ = dockerCmd ( c , "run" , "--name=test2" , "-v" , volumeID + ":" + prefix + "/foo" , "busybox" , "sh" , "-c" , "cat /foo/bar" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , "hello" , check . Commentf ( "volume data was removed" ) )
2015-06-12 13:25:32 +00:00
dockerCmd ( c , "rm" , "test2" )
dockerCmd ( c , "volume" , "rm" , volumeID )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , exec . Command ( "volume" , "rm" , "doesnotexist" ) . Run ( ) != nil , check . Commentf ( "volume rm should fail with non-existent volume" ) )
2015-06-12 13:25:32 +00:00
}
2015-08-27 00:31:31 +00:00
2016-12-13 20:21:51 +00:00
// FIXME(vdemeester) should be a unit test in cli/command/volume package
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLINoArgs ( c * testing . T ) {
2015-08-27 00:31:31 +00:00
out , _ := dockerCmd ( c , "volume" )
2015-10-07 16:22:08 +00:00
// no args should produce the cmd usage output
2016-05-16 21:20:29 +00:00
usage := "Usage: docker volume COMMAND"
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , usage )
2015-08-27 00:31:31 +00:00
// invalid arg should error and show the command usage on stderr
2016-12-13 20:21:51 +00:00
icmd . RunCommand ( dockerBinary , "volume" , "somearg" ) . Assert ( c , icmd . Expected {
ExitCode : 1 ,
Error : "exit status 1" ,
Err : usage ,
} )
2015-10-07 16:22:08 +00:00
// invalid flag should error and show the flag error and cmd usage
2016-12-13 20:21:51 +00:00
result := icmd . RunCommand ( dockerBinary , "volume" , "--no-such-flag" )
result . Assert ( c , icmd . Expected {
ExitCode : 125 ,
Error : "exit status 125" ,
Err : usage ,
} )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , result . Stderr ( ) , checker . Contains , "unknown flag: --no-such-flag" )
2015-08-27 00:31:31 +00:00
}
2015-12-02 20:24:30 +00:00
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIInspectTmplError ( c * testing . T ) {
2015-12-02 20:24:30 +00:00
out , _ := dockerCmd ( c , "volume" , "create" )
name := strings . TrimSpace ( out )
out , exitCode , err := dockerCmdWithError ( "volume" , "inspect" , "--format='{{ .FooBar }}'" , name )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , err , checker . NotNil , check . Commentf ( "Output: %s" , out ) )
assert . Assert ( c , exitCode , checker . Equals , 1 , check . Commentf ( "Output: %s" , out ) )
assert . Assert ( c , out , checker . Contains , "Template parsing error" )
2015-12-02 20:24:30 +00:00
}
2016-02-12 02:48:16 +00:00
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLICreateWithOpts ( c * testing . T ) {
2016-02-12 02:48:16 +00:00
testRequires ( c , DaemonIsLinux )
2016-06-14 22:42:30 +00:00
dockerCmd ( c , "volume" , "create" , "-d" , "local" , "test" , "--opt=type=tmpfs" , "--opt=device=tmpfs" , "--opt=o=size=1m,uid=1000" )
2016-02-12 02:48:16 +00:00
out , _ := dockerCmd ( c , "run" , "-v" , "test:/foo" , "busybox" , "mount" )
mounts := strings . Split ( out , "\n" )
var found bool
for _ , m := range mounts {
if strings . Contains ( m , "/foo" ) {
found = true
info := strings . Fields ( m )
// tmpfs on <path> type tmpfs (rw,relatime,size=1024k,uid=1000)
2019-09-09 21:05:55 +00:00
assert . Assert ( c , info [ 0 ] , checker . Equals , "tmpfs" )
assert . Assert ( c , info [ 2 ] , checker . Equals , "/foo" )
assert . Assert ( c , info [ 4 ] , checker . Equals , "tmpfs" )
assert . Assert ( c , info [ 5 ] , checker . Contains , "uid=1000" )
assert . Assert ( c , info [ 5 ] , checker . Contains , "size=1024k" )
2016-12-08 07:59:52 +00:00
break
2016-02-12 02:48:16 +00:00
}
}
2019-09-09 21:05:55 +00:00
assert . Assert ( c , found , checker . Equals , true )
2016-02-12 02:48:16 +00:00
}
2016-03-16 21:52:34 +00:00
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLICreateLabel ( c * testing . T ) {
2016-03-16 21:52:34 +00:00
testVol := "testvolcreatelabel"
testLabel := "foo"
testValue := "bar"
2018-07-09 17:40:34 +00:00
_ , _ , err := dockerCmdWithError ( "volume" , "create" , "--label" , testLabel + "=" + testValue , testVol )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-03-16 21:52:34 +00:00
2018-07-09 17:40:34 +00:00
out , _ := dockerCmd ( c , "volume" , "inspect" , "--format={{ .Labels." + testLabel + " }}" , testVol )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , testValue )
2016-03-16 21:52:34 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLICreateLabelMultiple ( c * testing . T ) {
2016-03-16 21:52:34 +00:00
testVol := "testvolcreatelabel"
testLabels := map [ string ] string {
"foo" : "bar" ,
"baz" : "foo" ,
}
args := [ ] string {
"volume" ,
"create" ,
testVol ,
}
for k , v := range testLabels {
args = append ( args , "--label" , k + "=" + v )
}
2018-07-09 17:40:34 +00:00
_ , _ , err := dockerCmdWithError ( args ... )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-03-16 21:52:34 +00:00
for k , v := range testLabels {
2018-07-09 17:40:34 +00:00
out , _ := dockerCmd ( c , "volume" , "inspect" , "--format={{ .Labels." + k + " }}" , testVol )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Equals , v )
2016-03-16 21:52:34 +00:00
}
}
2016-03-28 08:43:41 +00:00
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILsFilterLabels ( c * testing . T ) {
2016-03-28 08:43:41 +00:00
testVol1 := "testvolcreatelabel-1"
2018-07-09 17:40:34 +00:00
_ , _ , err := dockerCmdWithError ( "volume" , "create" , "--label" , "foo=bar1" , testVol1 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-03-28 08:43:41 +00:00
testVol2 := "testvolcreatelabel-2"
2018-07-09 17:40:34 +00:00
_ , _ , err = dockerCmdWithError ( "volume" , "create" , "--label" , "foo=bar2" , testVol2 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-03-28 08:43:41 +00:00
2018-07-09 17:40:34 +00:00
out , _ := dockerCmd ( c , "volume" , "ls" , "--filter" , "label=foo" )
2016-03-28 08:43:41 +00:00
// filter with label=key
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testvolcreatelabel-1\n" , check . Commentf ( "expected volume 'testvolcreatelabel-1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testvolcreatelabel-2\n" , check . Commentf ( "expected volume 'testvolcreatelabel-2' in output" ) )
2016-03-28 08:43:41 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "label=foo=bar1" )
// filter with label=key=value
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testvolcreatelabel-1\n" , check . Commentf ( "expected volume 'testvolcreatelabel-1' in output" ) )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , "testvolcreatelabel-2\n" , check . Commentf ( "expected volume 'testvolcreatelabel-2 in output" ) )
2016-03-28 08:43:41 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "label=non-exist" )
outArr := strings . Split ( strings . TrimSpace ( out ) , "\n" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , len ( outArr ) , checker . Equals , 1 , check . Commentf ( "\n%s" , out ) )
2016-03-28 08:43:41 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "label=foo=non-exist" )
outArr = strings . Split ( strings . TrimSpace ( out ) , "\n" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , len ( outArr ) , checker . Equals , 1 , check . Commentf ( "\n%s" , out ) )
2016-03-28 08:43:41 +00:00
}
2016-06-10 14:40:09 +00:00
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLILsFilterDrivers ( c * testing . T ) {
2017-01-04 06:43:29 +00:00
// using default volume driver local to create volumes
testVol1 := "testvol-1"
2018-07-09 17:40:34 +00:00
_ , _ , err := dockerCmdWithError ( "volume" , "create" , testVol1 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-01-04 06:43:29 +00:00
testVol2 := "testvol-2"
2018-07-09 17:40:34 +00:00
_ , _ , err = dockerCmdWithError ( "volume" , "create" , testVol2 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-01-04 06:43:29 +00:00
// filter with driver=local
2018-07-09 17:40:34 +00:00
out , _ := dockerCmd ( c , "volume" , "ls" , "--filter" , "driver=local" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , "testvol-1\n" , check . Commentf ( "expected volume 'testvol-1' in output" ) )
assert . Assert ( c , out , checker . Contains , "testvol-2\n" , check . Commentf ( "expected volume 'testvol-2' in output" ) )
2017-01-04 06:43:29 +00:00
// filter with driver=invaliddriver
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "driver=invaliddriver" )
outArr := strings . Split ( strings . TrimSpace ( out ) , "\n" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , len ( outArr ) , checker . Equals , 1 , check . Commentf ( "\n%s" , out ) )
2017-01-04 06:43:29 +00:00
// filter with driver=loca
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "driver=loca" )
outArr = strings . Split ( strings . TrimSpace ( out ) , "\n" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , len ( outArr ) , checker . Equals , 1 , check . Commentf ( "\n%s" , out ) )
2017-01-04 06:43:29 +00:00
// filter with driver=
out , _ = dockerCmd ( c , "volume" , "ls" , "--filter" , "driver=" )
outArr = strings . Split ( strings . TrimSpace ( out ) , "\n" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , len ( outArr ) , checker . Equals , 1 , check . Commentf ( "\n%s" , out ) )
2017-01-04 06:43:29 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIRmForceUsage ( c * testing . T ) {
2016-06-10 14:40:09 +00:00
out , _ := dockerCmd ( c , "volume" , "create" )
id := strings . TrimSpace ( out )
dockerCmd ( c , "volume" , "rm" , "-f" , id )
dockerCmd ( c , "volume" , "rm" , "--force" , "nonexist" )
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIRmForce ( c * testing . T ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2016-06-10 14:40:09 +00:00
name := "test"
2016-06-14 22:42:30 +00:00
out , _ := dockerCmd ( c , "volume" , "create" , name )
2016-06-10 14:40:09 +00:00
id := strings . TrimSpace ( out )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , id , checker . Equals , name )
2016-06-10 14:40:09 +00:00
out , _ = dockerCmd ( c , "volume" , "inspect" , "--format" , "{{.Mountpoint}}" , name )
2019-04-04 13:23:19 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) != "" )
2016-06-10 14:40:09 +00:00
// Mountpoint is in the form of "/var/lib/docker/volumes/.../_data", removing `/_data`
path := strings . TrimSuffix ( strings . TrimSpace ( out ) , "/_data" )
2017-01-05 11:38:34 +00:00
icmd . RunCommand ( "rm" , "-rf" , path ) . Assert ( c , icmd . Success )
2016-06-10 14:40:09 +00:00
2017-03-01 13:36:09 +00:00
dockerCmd ( c , "volume" , "rm" , "-f" , name )
2016-06-10 14:40:09 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , name )
2017-03-01 13:36:09 +00:00
dockerCmd ( c , "volume" , "create" , name )
2016-06-10 14:40:09 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , name )
2016-06-10 14:40:09 +00:00
}
2016-09-17 19:32:31 +00:00
2017-03-01 13:36:09 +00:00
// TestVolumeCLIRmForceInUse verifies that repeated `docker volume rm -f` calls does not remove a volume
// if it is in use. Test case for https://github.com/docker/docker/issues/31446
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCLIRmForceInUse ( c * testing . T ) {
2017-03-01 13:36:09 +00:00
name := "testvolume"
out , _ := dockerCmd ( c , "volume" , "create" , name )
id := strings . TrimSpace ( out )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , id , checker . Equals , name )
2017-03-01 13:36:09 +00:00
prefix , slash := getPrefixAndSlashFromDaemonPlatform ( )
2018-07-09 17:40:34 +00:00
out , _ = dockerCmd ( c , "create" , "-v" , "testvolume:" + prefix + slash + "foo" , "busybox" )
2017-03-01 13:36:09 +00:00
cid := strings . TrimSpace ( out )
_ , _ , err := dockerCmdWithError ( "volume" , "rm" , "-f" , name )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
assert . ErrorContains ( c , err , "volume is in use" )
2017-03-01 13:36:09 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , name )
2017-03-01 13:36:09 +00:00
// The original issue did not _remove_ the volume from the list
// the first time. But a second call to `volume rm` removed it.
// Calling `volume rm` a second time to confirm it's not removed
// when calling twice.
_ , _ , err = dockerCmdWithError ( "volume" , "rm" , "-f" , name )
2019-04-04 13:23:19 +00:00
assert . ErrorContains ( c , err , "" )
assert . ErrorContains ( c , err , "volume is in use" )
2017-03-01 13:36:09 +00:00
out , _ = dockerCmd ( c , "volume" , "ls" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Contains , name )
2017-03-01 13:36:09 +00:00
// Verify removing the volume after the container is removed works
2018-07-09 17:40:34 +00:00
_ , e := dockerCmd ( c , "rm" , cid )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , e , checker . Equals , 0 )
2017-03-01 13:36:09 +00:00
_ , e = dockerCmd ( c , "volume" , "rm" , "-f" , name )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , e , checker . Equals , 0 )
2017-03-01 13:36:09 +00:00
out , e = dockerCmd ( c , "volume" , "ls" )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , e , checker . Equals , 0 )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , out , checker . Not ( checker . Contains ) , name )
2017-03-01 13:36:09 +00:00
}
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestVolumeCliInspectWithVolumeOpts ( c * testing . T ) {
2016-09-17 19:32:31 +00:00
testRequires ( c , DaemonIsLinux )
// Without options
name := "test1"
dockerCmd ( c , "volume" , "create" , "-d" , "local" , name )
out , _ := dockerCmd ( c , "volume" , "inspect" , "--format={{ .Options }}" , name )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , "map[]" )
2016-09-17 19:32:31 +00:00
// With options
name = "test2"
k1 , v1 := "type" , "tmpfs"
k2 , v2 := "device" , "tmpfs"
k3 , v3 := "o" , "size=1m,uid=1000"
dockerCmd ( c , "volume" , "create" , "-d" , "local" , name , "--opt" , fmt . Sprintf ( "%s=%s" , k1 , v1 ) , "--opt" , fmt . Sprintf ( "%s=%s" , k2 , v2 ) , "--opt" , fmt . Sprintf ( "%s=%s" , k3 , v3 ) )
out , _ = dockerCmd ( c , "volume" , "inspect" , "--format={{ .Options }}" , name )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , fmt . Sprintf ( "%s:%s" , k1 , v1 ) )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , fmt . Sprintf ( "%s:%s" , k2 , v2 ) )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , fmt . Sprintf ( "%s:%s" , k3 , v3 ) )
2016-09-17 19:32:31 +00:00
}
2017-01-27 22:12:45 +00:00
// Test case (1) for 21845: duplicate targets for --volumes-from
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestDuplicateMountpointsForVolumesFrom ( c * testing . T ) {
2017-01-27 22:12:45 +00:00
testRequires ( c , DaemonIsLinux )
image := "vimage"
2017-03-23 17:35:22 +00:00
buildImageSuccessfully ( c , image , build . WithDockerfile ( `
2017-01-27 22:12:45 +00:00
FROM busybox
VOLUME [ "/tmp/data" ] ` ) )
dockerCmd ( c , "run" , "--name=data1" , image , "true" )
dockerCmd ( c , "run" , "--name=data2" , image , "true" )
out , _ := dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data1" )
data1 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data1 != "" )
2017-01-27 22:12:45 +00:00
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data2" )
data2 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data2 != "" )
2017-01-27 22:12:45 +00:00
// Both volume should exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data2 )
2017-01-27 22:12:45 +00:00
out , _ , err := dockerCmdWithError ( "run" , "--name=app" , "--volumes-from=data1" , "--volumes-from=data2" , "-d" , "busybox" , "top" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , err , checker . IsNil , check . Commentf ( "Out: %s" , out ) )
2017-01-27 22:12:45 +00:00
// Only the second volume will be referenced, this is backward compatible
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "app" )
2019-04-04 13:23:19 +00:00
assert . Equal ( c , strings . TrimSpace ( out ) , data2 )
2017-01-27 22:12:45 +00:00
dockerCmd ( c , "rm" , "-f" , "-v" , "app" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data1" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data2" )
// Both volume should not exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data2 )
2017-01-27 22:12:45 +00:00
}
// Test case (2) for 21845: duplicate targets for --volumes-from and -v (bind)
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestDuplicateMountpointsForVolumesFromAndBind ( c * testing . T ) {
2017-01-27 22:12:45 +00:00
testRequires ( c , DaemonIsLinux )
image := "vimage"
2017-03-23 17:35:22 +00:00
buildImageSuccessfully ( c , image , build . WithDockerfile ( `
2017-01-27 22:12:45 +00:00
FROM busybox
VOLUME [ "/tmp/data" ] ` ) )
dockerCmd ( c , "run" , "--name=data1" , image , "true" )
dockerCmd ( c , "run" , "--name=data2" , image , "true" )
out , _ := dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data1" )
data1 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data1 != "" )
2017-01-27 22:12:45 +00:00
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data2" )
data2 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data2 != "" )
2017-01-27 22:12:45 +00:00
// Both volume should exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data2 )
2017-01-27 22:12:45 +00:00
2017-03-09 09:32:04 +00:00
// /tmp/data is automatically created, because we are not using the modern mount API here
2017-01-27 22:12:45 +00:00
out , _ , err := dockerCmdWithError ( "run" , "--name=app" , "--volumes-from=data1" , "--volumes-from=data2" , "-v" , "/tmp/data:/tmp/data" , "-d" , "busybox" , "top" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , err , checker . IsNil , check . Commentf ( "Out: %s" , out ) )
2017-01-27 22:12:45 +00:00
// No volume will be referenced (mount is /tmp/data), this is backward compatible
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "app" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data2 )
2017-01-27 22:12:45 +00:00
dockerCmd ( c , "rm" , "-f" , "-v" , "app" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data1" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data2" )
// Both volume should not exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data2 )
2017-01-27 22:12:45 +00:00
}
// Test case (3) for 21845: duplicate targets for --volumes-from and `Mounts` (API only)
2019-09-09 21:05:55 +00:00
func ( s * DockerSuite ) TestDuplicateMountpointsForVolumesFromAndMounts ( c * testing . T ) {
2018-12-24 12:25:53 +00:00
testRequires ( c , testEnv . IsLocalDaemon , DaemonIsLinux )
2017-01-27 22:12:45 +00:00
image := "vimage"
2017-03-23 17:35:22 +00:00
buildImageSuccessfully ( c , image , build . WithDockerfile ( `
2017-01-27 22:12:45 +00:00
FROM busybox
VOLUME [ "/tmp/data" ] ` ) )
dockerCmd ( c , "run" , "--name=data1" , image , "true" )
dockerCmd ( c , "run" , "--name=data2" , image , "true" )
out , _ := dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data1" )
data1 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data1 != "" )
2017-01-27 22:12:45 +00:00
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "data2" )
data2 := strings . TrimSpace ( out )
2019-09-09 21:05:56 +00:00
assert . Assert ( c , data2 != "" )
2017-01-27 22:12:45 +00:00
// Both volume should exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Contains , data2 )
2017-01-27 22:12:45 +00:00
2017-03-09 09:32:04 +00:00
err := os . MkdirAll ( "/tmp/data" , 0755 )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-01-27 22:12:45 +00:00
// Mounts is available in API
2019-01-03 21:49:00 +00:00
cli , err := client . NewClientWithOpts ( client . FromEnv )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-05-24 03:56:26 +00:00
defer cli . Close ( )
config := container . Config {
Cmd : [ ] string { "top" } ,
Image : "busybox" ,
}
hostConfig := container . HostConfig {
VolumesFrom : [ ] string { "data1" , "data2" } ,
Mounts : [ ] mount . Mount {
{
Type : "bind" ,
Source : "/tmp/data" ,
Target : "/tmp/data" ,
2017-01-27 22:12:45 +00:00
} ,
2017-05-24 03:56:26 +00:00
} ,
}
_ , err = cli . ContainerCreate ( context . Background ( ) , & config , & hostConfig , & network . NetworkingConfig { } , "app" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-01-27 22:12:45 +00:00
// No volume will be referenced (mount is /tmp/data), this is backward compatible
out , _ = dockerCmd ( c , "inspect" , "--format" , "{{(index .Mounts 0).Name}}" , "app" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data2 )
2017-01-27 22:12:45 +00:00
dockerCmd ( c , "rm" , "-f" , "-v" , "app" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data1" )
dockerCmd ( c , "rm" , "-f" , "-v" , "data2" )
// Both volume should not exist
out , _ = dockerCmd ( c , "volume" , "ls" , "-q" )
2019-09-09 21:05:55 +00:00
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data1 )
assert . Assert ( c , strings . TrimSpace ( out ) , checker . Not ( checker . Contains ) , data2 )
2017-01-27 22:12:45 +00:00
}