Skip to content

Commit 690bd52

Browse files
authored
Merge pull request #262 from florindragos/docker_swarm_tests
Configure Docker Swarm on Windows
2 parents f116841 + a138c19 commit 690bd52

File tree

11 files changed

+337
-53
lines changed

11 files changed

+337
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ doc
1111
log
1212
Gemfile.lock
1313
coverage/*
14+
/vendor/

.rubocop.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ RSpec/BeforeAfterAll:
2323
A necessary evil in acceptance testing.
2424
Exclude:
2525
- spec/acceptance/**/*.rb
26+
- spec/acceptance_swarm/**/*.rb
2627
RSpec/HookArgument:
2728
Description: Prefer explicit :each argument, matching existing module's style
2829
EnforcedStyle: each

Guardfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ group :acceptance do
1515
watch(%r{^spec\/acceptance\/.+\.rb$})
1616
end
1717
end
18+
19+
group :acceptance_swarm do
20+
guard :rake, :task => 'acceptance_swarm' do
21+
watch(%r{^spec\/acceptance_swarm\/.+\.rb$})
22+
end
23+
end

lib/puppet/parser/functions/docker_swarm_join_flags.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module Puppet::Parser::Functions
1717
end
1818

1919
if opts['listen_addr'].to_s != 'undef'
20-
flags << "--listen-addr '#{opts['listen_addr']}'"
20+
flags << "--listen-addr \"#{opts['listen_addr']}\""
2121
end
2222

2323
if opts['token'].to_s != 'undef'

manifests/swarm.pp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,27 @@
9090

9191
include docker::params
9292

93+
if $::osfamily == 'windows' {
94+
$exec_environment = 'PATH=C:/Program Files/Docker/'
95+
$exec_path = ['c:/Windows/Temp/', 'C:/Program Files/Docker/']
96+
$exec_timeout = 3000
97+
$exec_provider = 'powershell'
98+
$unless_init = '$info = docker info | select-string -pattern "Swarm: active"
99+
if ($info -eq $null) { Exit 1 } else { Exit 0 }'
100+
$unless_join = '$info = docker info | select-string -pattern "Swarm: active"
101+
if ($info -eq $null) { Exit 1 } else { Exit 0 }'
102+
$onlyif_leave = '$info = docker info | select-string -pattern "Swarm: active"
103+
if ($info -eq $null) { Exit 1 } else { Exit 0 }'
104+
} else {
105+
$exec_environment = 'HOME=/root'
106+
$exec_path = ['/bin', '/usr/bin']
107+
$exec_timeout = 0
108+
$exec_provider = undef
109+
$unless_init = 'docker info | grep -w "Swarm: active"'
110+
$unless_join = 'docker info | grep -w "Swarm: active"'
111+
$onlyif_leave = 'docker info | grep -w "Swarm: active"'
112+
}
113+
93114
$docker_command = "${docker::params::docker_command} swarm"
94115

95116
if $init {
@@ -107,13 +128,13 @@
107128
})
108129

109130
$exec_init = "${docker_command} ${docker_swarm_init_flags}"
110-
$unless_init = 'docker info | grep -w "Swarm: active"'
111131

112132
exec { 'Swarm init':
113133
command => $exec_init,
114-
environment => 'HOME=/root',
115-
path => ['/bin', '/usr/bin'],
116-
timeout => 0,
134+
environment => $exec_environment,
135+
path => $exec_path,
136+
provider => $exec_provider,
137+
timeout => $exec_timeout,
117138
unless => $unless_init,
118139
}
119140
}
@@ -127,22 +148,23 @@
127148
})
128149

129150
$exec_join = "${docker_command} ${docker_swarm_join_flags} ${manager_ip}"
130-
$unless_join = 'docker info | grep -w "Swarm: active"'
131151

132152
exec { 'Swarm join':
133153
command => $exec_join,
134-
environment => 'HOME=/root',
135-
path => ['/bin', '/usr/bin'],
136-
timeout => 0,
154+
environment => $exec_environment,
155+
path => $exec_path,
156+
provider => $exec_provider,
157+
timeout => $exec_timeout,
137158
unless => $unless_join,
138159
}
139160
}
140161

141162
if $ensure == 'absent' {
142163
exec { 'Leave swarm':
143-
command => 'docker swarm leave --force',
144-
onlyif => 'docker info | grep -w "Swarm: active"',
145-
path => ['/bin', '/usr/bin'],
164+
command => 'docker swarm leave --force',
165+
onlyif => $onlyif_leave,
166+
path => $exec_path,
167+
provider => $exec_provider,
146168
}
147169
}
148170
}

rakelib/acceptance_swarm.rake

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require 'rake'
2+
require 'parallel_tests'
3+
4+
# We clear the Beaker rake tasks from spec_helper as they assume
5+
# rspec-puppet and a certain filesystem layout
6+
Rake::Task[:beaker_nodes].clear
7+
Rake::Task[:beaker].clear
8+
9+
desc "Run acceptance tests"
10+
RSpec::Core::RakeTask.new(:acceptance_swarm => [:spec_prep]) do |t|
11+
t.pattern = 'spec/acceptance_swarm'
12+
end
13+
14+
namespace :acceptance_swarm do
15+
{
16+
:pooler => [
17+
'ubuntu-1604',
18+
'win-2016',
19+
]
20+
}.each do |ns, configs|
21+
namespace ns.to_sym do
22+
configs.each do |config|
23+
desc "Run acceptance tests for #{ns}:#{config}"
24+
RSpec::Core::RakeTask.new("#{config}".to_sym => [:spec_prep]) do |t|
25+
ENV['BEAKER_keyfile'] = '~/.ssh/id_rsa-acceptance' if ns == :pooler
26+
ENV['BEAKER_setdir'] = 'spec/acceptance_swarm/nodesets'
27+
ENV['BEAKER_set'] = "#{ns}/#{config}"
28+
t.pattern = 'spec/acceptance_swarm'
29+
end
30+
end
31+
end
32+
end
33+
end

spec/acceptance_swarm/default.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
HOSTS:
2+
ubuntu-1604:
3+
roles:
4+
- default
5+
- swarm-manager
6+
platform: ubuntu-16.04-amd64
7+
hypervisor: vmpooler
8+
template: Delivery/Quality Assurance/Templates/vCloud/ubuntu-1604-x86_64
9+
ubuntu-1604-a:
10+
roles:
11+
- swarm-worker
12+
platform: ubuntu-16.04-amd64
13+
hypervisor: vmpooler
14+
template: Delivery/Quality Assurance/Templates/vCloud/ubuntu-1604-x86_64
15+
CONFIG:
16+
nfs_server: none
17+
consoleport: 443
18+
datastore: instance0
19+
folder: Delivery/Quality Assurance/Enterprise/Dynamic
20+
resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
21+
pooling_api: http://vcloud.delivery.puppetlabs.net/
22+
type: foss
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
HOSTS:
2+
ubuntu-1604:
3+
roles:
4+
- default
5+
- swarm-manager
6+
platform: ubuntu-16.04-amd64
7+
hypervisor: vmpooler
8+
template: Delivery/Quality Assurance/Templates/vCloud/ubuntu-1604-x86_64
9+
ubuntu-1604-a:
10+
roles:
11+
- swarm-worker
12+
platform: ubuntu-16.04-amd64
13+
hypervisor: vmpooler
14+
template: Delivery/Quality Assurance/Templates/vCloud/ubuntu-1604-x86_64
15+
CONFIG:
16+
nfs_server: none
17+
consoleport: 443
18+
datastore: instance0
19+
folder: Delivery/Quality Assurance/Enterprise/Dynamic
20+
resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
21+
pooling_api: http://vcloud.delivery.puppetlabs.net/
22+
type: foss
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
HOSTS:
2+
ubuntu-1604:
3+
roles:
4+
- master
5+
- database
6+
- dashboard
7+
platform: ubuntu-16.04-amd64
8+
hypervisor: vmpooler
9+
template: Delivery/Quality Assurance/Templates/vCloud/ubuntu-1604-x86_64
10+
win-2016:
11+
roles:
12+
- default
13+
- agent
14+
- swarm-manager
15+
platform: windows-2016-x86_64
16+
hypervisor: vmpooler
17+
template: Delivery/Quality Assurance/Templates/vCloud/win-2016-x86_64
18+
win-2016-a:
19+
roles:
20+
- agent
21+
- swarm-worker
22+
platform: windows-2016-x86_64
23+
hypervisor: vmpooler
24+
template: Delivery/Quality Assurance/Templates/vCloud/win-2016-x86_64
25+
CONFIG:
26+
nfs_server: none
27+
consoleport: 443
28+
datastore: instance0
29+
folder: Delivery/Quality Assurance/Enterprise/Dynamic
30+
resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
31+
pooling_api: http://vcloud.delivery.puppetlabs.net/
32+
type: foss
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
require 'spec_helper_acceptance'
2+
3+
if fact('osfamily') == 'windows'
4+
install_dir = '/cygdrive/c/Program Files/Docker'
5+
file_extension = '.exe'
6+
docker_args = 'docker_ee => true'
7+
tmp_path = 'C:/cygwin64/tmp'
8+
test_docker_image = 'hello-world:nanoserver'
9+
test_docker_command = 'cmd.exe /C "ping /t 8.8.8.8"'
10+
else
11+
install_dir = '/usr/local/bin'
12+
file_extension = ''
13+
docker_args = ''
14+
tmp_path = '/tmp'
15+
test_docker_image = 'ubuntu:16.04'
16+
test_docker_command = '/bin/sh -c "while true; do echo hello world; sleep 1; done"'
17+
end
18+
19+
skip_tests = false
20+
21+
begin
22+
swarm_manager = only_host_with_role(hosts, 'swarm-manager')
23+
swarm_worker = only_host_with_role(hosts, 'swarm-worker')
24+
manager_ip = swarm_manager.ip
25+
rescue ArgumentError
26+
skip_tests = true
27+
end
28+
29+
describe 'docker swarm', :skip => skip_tests do
30+
before(:all) do
31+
retry_on_error_matching(60, 5, /connection failure running/) do
32+
@install_code = <<-code
33+
class { 'docker': #{docker_args} }
34+
code
35+
apply_manifest_on(swarm_manager, @install_code, :catch_failures=>true)
36+
end
37+
retry_on_error_matching(60, 5, /connection failure running/) do
38+
apply_manifest_on(swarm_worker, @install_code, :catch_failures=>true)
39+
end
40+
end
41+
42+
context 'Creating a swarm master' do
43+
before(:all) do
44+
@setup_manager = <<-code
45+
docker::swarm {'cluster_manager':
46+
init => true,
47+
advertise_addr => '#{manager_ip}',
48+
listen_addr => '#{manager_ip}',
49+
ensure => 'present',
50+
}
51+
code
52+
53+
retry_on_error_matching(60, 5, /connection failure running/) do
54+
apply_manifest_on(swarm_manager, @setup_manager, :catch_failures=>true)
55+
end
56+
57+
if fact('osfamily') == 'windows'
58+
on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', :acceptable_exit_codes => [0]
59+
on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', :acceptable_exit_codes => [0]
60+
on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', :acceptable_exit_codes => [0]
61+
on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', :acceptable_exit_codes => [0]
62+
end
63+
end
64+
65+
it 'should be idempotent' do
66+
apply_manifest_on(swarm_manager, @setup_manager, :catch_failures=>true)
67+
end
68+
69+
it 'should display nodes' do
70+
on swarm_manager, 'docker node ls', :acceptable_exit_codes => [0] do |result|
71+
expect(result.stdout).to match(/Leader/)
72+
end
73+
end
74+
75+
it 'should join a node' do
76+
token = shell('docker swarm join-token -q worker').stdout.strip
77+
@setup_slave = <<-code
78+
docker::swarm {'cluster_worker':
79+
join => true,
80+
advertise_addr => '#{swarm_worker.ip}',
81+
listen_addr => '#{swarm_worker.ip}',
82+
manager_ip => '#{manager_ip}',
83+
token => '#{token}',
84+
}
85+
code
86+
retry_on_error_matching(60, 5, /connection failure running/) do
87+
apply_manifest_on(swarm_worker, @setup_slave, :catch_failures=>true)
88+
end
89+
90+
retry_on_error_matching(60, 5, /connection failure running/) do
91+
on swarm_worker, 'docker info' do |result|
92+
expect(result.stdout).to match(/Swarm: active/)
93+
end
94+
end
95+
96+
if fact('osfamily') == 'windows'
97+
on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', :acceptable_exit_codes => [0]
98+
on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', :acceptable_exit_codes => [0]
99+
on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', :acceptable_exit_codes => [0]
100+
on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', :acceptable_exit_codes => [0]
101+
end
102+
103+
on swarm_manager, 'docker network create --driver=overlay swarmnet', :acceptable_exit_codes => [0]
104+
end
105+
106+
it 'should start a container' do
107+
on swarm_manager, "docker service create --name=helloworld --endpoint-mode dnsrr --network=swarmnet #{test_docker_image} #{test_docker_command}", :acceptable_exit_codes => [0]
108+
on swarm_manager, 'docker service ps helloworld', :acceptable_exit_codes => [0] do |result|
109+
expect(result.stdout).to match(/Running/)
110+
end
111+
end
112+
113+
after(:all) do
114+
remove_worker = <<-code
115+
docker::swarm {'cluster_worker':
116+
ensure => 'absent',
117+
}
118+
code
119+
retry_on_error_matching(60, 5, /connection failure running/) do
120+
apply_manifest_on(swarm_worker, remove_worker, :catch_failures=>true)
121+
end
122+
remove_mgr = <<-code
123+
docker::swarm {'cluster_manager':
124+
ensure => 'absent',
125+
}
126+
code
127+
retry_on_error_matching(60, 5, /connection failure running/) do
128+
apply_manifest_on(swarm_manager, remove_mgr, :catch_failures=>true)
129+
end
130+
end
131+
end
132+
end

0 commit comments

Comments
 (0)