2021-08-23 13:14:53 +00:00
//go:build !windows
2016-12-15 21:56:32 +00:00
package main
import (
"encoding/json"
"strings"
2019-09-09 21:06:12 +00:00
"testing"
2017-02-17 21:59:19 +00:00
"time"
2016-12-15 21:56:32 +00:00
"github.com/docker/docker/api/types/swarm"
2016-12-30 17:23:00 +00:00
"github.com/docker/docker/integration-cli/checker"
2023-07-14 18:02:38 +00:00
"github.com/docker/docker/testutil"
2020-02-07 13:39:24 +00:00
"gotest.tools/v3/assert"
"gotest.tools/v3/poll"
2016-12-15 21:56:32 +00:00
)
2019-09-09 21:05:55 +00:00
func ( s * DockerSwarmSuite ) TestSwarmVolumePlugin ( c * testing . T ) {
2023-07-14 18:02:38 +00:00
ctx := testutil . GetContext ( c )
d := s . AddDaemon ( ctx , c , true , true )
2016-12-15 21:56:32 +00:00
2017-09-27 23:17:55 +00: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 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-12-15 21:56:32 +00:00
// Make sure task stays pending before plugin is available
2023-07-14 18:02:38 +00:00
poll . WaitOn ( c , pollCheck ( c , d . CheckServiceTasksInStateWithError ( ctx , "top" , swarm . TaskStatePending , "missing plugin on 1 node" ) , checker . Equals ( 1 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2016-12-15 21:56:32 +00: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 13:23:19 +00:00
assert . NilError ( c , err , out )
2016-12-15 21:56:32 +00: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.
2023-07-14 18:02:38 +00:00
poll . WaitOn ( c , pollCheck ( c , d . CheckActiveContainerCount ( ctx ) , checker . Equals ( 1 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2016-12-15 21:56:32 +00:00
out , err = d . Cmd ( "ps" , "-q" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-15 21:56:32 +00:00
containerID := strings . TrimSpace ( out )
out , err = d . Cmd ( "inspect" , "-f" , "{{json .Mounts}}" , containerID )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2016-12-15 21:56:32 +00:00
var mounts [ ] struct {
Name string
Driver string
}
2019-04-04 13:23:19 +00:00
assert . NilError ( c , json . NewDecoder ( strings . NewReader ( out ) ) . Decode ( & mounts ) )
2019-08-05 15:54:15 +00:00
assert . Equal ( c , len ( mounts ) , 1 , out )
2019-04-04 13:23:19 +00:00
assert . Equal ( c , mounts [ 0 ] . Name , "my-volume" )
assert . Equal ( c , mounts [ 0 ] . Driver , "customvolumedriver" )
2016-12-15 21:56:32 +00:00
}
2017-02-17 21:59:19 +00:00
// Test network plugin filter in swarm
2019-09-09 21:05:55 +00:00
func ( s * DockerSwarmSuite ) TestSwarmNetworkPluginV2 ( c * testing . T ) {
2017-03-07 14:17:28 +00:00
testRequires ( c , IsAmd64 )
2023-07-14 18:02:38 +00:00
ctx := testutil . GetContext ( c )
d1 := s . AddDaemon ( ctx , c , true , true )
d2 := s . AddDaemon ( ctx , c , true , false )
2017-02-17 21:59:19 +00:00
// install plugin on d1 and d2
pluginName := "aragunathan/global-net-plugin:latest"
_ , err := d1 . Cmd ( "plugin" , "install" , pluginName , "--grant-all-permissions" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
_ , err = d2 . Cmd ( "plugin" , "install" , pluginName , "--grant-all-permissions" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
// create network
networkName := "globalnet"
_ , err = d1 . Cmd ( "network" , "create" , "--driver" , pluginName , networkName )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
// create a global service to ensure that both nodes will have an instance
serviceName := "my-service"
2017-09-27 23:17:55 +00:00
_ , err = d1 . Cmd ( "service" , "create" , "--detach" , "--no-resolve-image" , "--name" , serviceName , "--mode=global" , "--network" , networkName , "busybox" , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
// wait for tasks ready
2023-07-14 18:02:38 +00:00
poll . WaitOn ( c , pollCheck ( c , reducedCheck ( sumAsIntegers , d1 . CheckActiveContainerCount ( ctx ) , d2 . CheckActiveContainerCount ( ctx ) ) , checker . Equals ( 2 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 21:59:19 +00:00
// remove service
_ , err = d1 . Cmd ( "service" , "rm" , serviceName )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00: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.
2023-07-14 18:02:38 +00:00
poll . WaitOn ( c , pollCheck ( c , reducedCheck ( sumAsIntegers , d1 . CheckActiveContainerCount ( ctx ) , d2 . CheckActiveContainerCount ( ctx ) ) , checker . Equals ( 0 ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 21:59:19 +00:00
// disable plugin on worker
_ , err = d2 . Cmd ( "plugin" , "disable" , "-f" , pluginName )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
time . Sleep ( 20 * time . Second )
2017-08-17 21:27:41 +00:00
image := "busybox:latest"
2017-02-17 21:59:19 +00:00
// create a new global service again.
2017-09-27 23:17:55 +00:00
_ , err = d1 . Cmd ( "service" , "create" , "--detach" , "--no-resolve-image" , "--name" , serviceName , "--mode=global" , "--network" , networkName , image , "top" )
2019-04-04 13:23:19 +00:00
assert . NilError ( c , err )
2017-02-17 21:59:19 +00:00
2023-07-14 18:02:38 +00:00
poll . WaitOn ( c , pollCheck ( c , d1 . CheckRunningTaskImages ( ctx ) , checker . DeepEquals ( map [ string ] int { image : 1 } ) ) , poll . WithTimeout ( defaultReconciliationTimeout ) )
2017-02-17 21:59:19 +00:00
}