2016-12-15 16:56:32 -05:00
// +build !windows
package main
import (
"encoding/json"
"strings"
2019-09-09 17:06:12 -04:00
"testing"
2017-02-17 16:59:19 -05:00
"time"
2016-12-15 16:56:32 -05:00
"github.com/docker/docker/api/types/swarm"
2016-12-30 12:23:00 -05:00
"github.com/docker/docker/integration-cli/checker"
2019-04-04 09:23:19 -04:00
"gotest.tools/assert"
2019-08-26 11:51:40 -04:00
"gotest.tools/poll"
2016-12-15 16:56:32 -05:00
)
2019-09-09 17:05:55 -04:00
func ( s * DockerSwarmSuite ) TestSwarmVolumePlugin ( c * testing . T ) {
2016-12-15 16:56:32 -05:00
d := s . AddDaemon ( c , true , true )
2017-09-27 19:17:55 -04:00
out , err := d . Cmd ( "service" , "create" , "--detach" , "--no-resolve-image" , "--mount" , "type=volume,source=my-volume,destination=/foo,volume-driver=customvolumedriver" , "--name" , "top" , "busybox" , "top" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err , out )
2016-12-15 16:56:32 -05:00
// Make sure task stays pending before plugin is available
2019-08-26 11:51:40 -04:00
poll . WaitOn ( c , pollCheck ( c , d . CheckServiceTasksInStateWithError ( "top" , swarm . TaskStatePending , "missing plugin on 1 node" ) , checker . Equals ( 1 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2016-12-15 16:56:32 -05:00
plugin := newVolumePlugin ( c , "customvolumedriver" )
defer plugin . Close ( )
// create a dummy volume to trigger lazy loading of the plugin
out , err = d . Cmd ( "volume" , "create" , "-d" , "customvolumedriver" , "hello" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err , out )
2016-12-15 16:56:32 -05:00
// TODO(aaronl): It will take about 15 seconds for swarm to realize the
// plugin was loaded. Switching the test over to plugin v2 would avoid
// this long delay.
// make sure task has been deployed.
2019-08-26 11:51:40 -04:00
poll . WaitOn ( c , pollCheck ( c , d . CheckActiveContainerCount , checker . Equals ( 1 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2016-12-15 16:56:32 -05:00
out , err = d . Cmd ( "ps" , "-q" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2016-12-15 16:56:32 -05:00
containerID := strings . TrimSpace ( out )
out , err = d . Cmd ( "inspect" , "-f" , "{{json .Mounts}}" , containerID )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2016-12-15 16:56:32 -05:00
var mounts [ ] struct {
Name string
Driver string
}
2019-04-04 09:23:19 -04:00
assert . NilError ( c , json . NewDecoder ( strings . NewReader ( out ) ) . Decode ( & mounts ) )
2019-08-05 11:54:15 -04:00
assert . Equal ( c , len ( mounts ) , 1 , out )
2019-04-04 09:23:19 -04:00
assert . Equal ( c , mounts [ 0 ] . Name , "my-volume" )
assert . Equal ( c , mounts [ 0 ] . Driver , "customvolumedriver" )
2016-12-15 16:56:32 -05:00
}
2017-02-17 16:59:19 -05:00
// Test network plugin filter in swarm
2019-09-09 17:05:55 -04:00
func ( s * DockerSwarmSuite ) TestSwarmNetworkPluginV2 ( c * testing . T ) {
2017-03-07 09:17:28 -05:00
testRequires ( c , IsAmd64 )
2017-02-17 16:59:19 -05:00
d1 := s . AddDaemon ( c , true , true )
d2 := s . AddDaemon ( c , true , false )
// install plugin on d1 and d2
pluginName := "aragunathan/global-net-plugin:latest"
_ , err := d1 . Cmd ( "plugin" , "install" , pluginName , "--grant-all-permissions" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
_ , err = d2 . Cmd ( "plugin" , "install" , pluginName , "--grant-all-permissions" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
// create network
networkName := "globalnet"
_ , err = d1 . Cmd ( "network" , "create" , "--driver" , pluginName , networkName )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
// create a global service to ensure that both nodes will have an instance
serviceName := "my-service"
2017-09-27 19:17:55 -04:00
_ , err = d1 . Cmd ( "service" , "create" , "--detach" , "--no-resolve-image" , "--name" , serviceName , "--mode=global" , "--network" , networkName , "busybox" , "top" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
// wait for tasks ready
2019-08-26 11:51:40 -04:00
poll . WaitOn ( c , pollCheck ( c , reducedCheck ( sumAsIntegers , d1 . CheckActiveContainerCount , d2 . CheckActiveContainerCount ) , checker . Equals ( 2 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 16:59:19 -05:00
// remove service
_ , err = d1 . Cmd ( "service" , "rm" , serviceName )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
// wait to ensure all containers have exited before removing the plugin. Else there's a
// possibility of container exits erroring out due to plugins being unavailable.
2019-08-26 11:51:40 -04:00
poll . WaitOn ( c , pollCheck ( c , reducedCheck ( sumAsIntegers , d1 . CheckActiveContainerCount , d2 . CheckActiveContainerCount ) , checker . Equals ( 0 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 16:59:19 -05:00
// disable plugin on worker
_ , err = d2 . Cmd ( "plugin" , "disable" , "-f" , pluginName )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
time . Sleep ( 20 * time . Second )
2017-08-17 17:27:41 -04:00
image := "busybox:latest"
2017-02-17 16:59:19 -05:00
// create a new global service again.
2017-09-27 19:17:55 -04:00
_ , err = d1 . Cmd ( "service" , "create" , "--detach" , "--no-resolve-image" , "--name" , serviceName , "--mode=global" , "--network" , networkName , image , "top" )
2019-04-04 09:23:19 -04:00
assert . NilError ( c , err )
2017-02-17 16:59:19 -05:00
2019-08-26 11:51:40 -04:00
poll . WaitOn ( c , pollCheck ( c , d1 . CheckRunningTaskImages , checker . DeepEquals ( map [ string ] int { image : 1 } ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 16:59:19 -05:00
}