kitchen-ansible 0.48.7 → 0.48.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,80 +1,80 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Michael Heap (<m@michaelheap.com>)
4
- #
5
- # Copyright (C) 2015 Michael Heap
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- module Kitchen
21
- module Provisioner
22
- module Ansible
23
- class Os
24
- class Redhat < Os
25
- def install_command
26
- <<-INSTALL
27
-
28
- if [ ! $(which ansible) ]; then
29
- #{install_epel_repo}
30
- #{redhat_yum_repo}
31
- #{update_packages_command}
32
- #{sudo_env('yum')} -y install #{ansible_package_name} libselinux-python git
33
- fi
34
- INSTALL
35
- end
36
-
37
- def update_packages_command
38
- @config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
39
- end
40
-
41
- def install_epel_repo
42
- @config[:enable_yum_epel] ? sudo_env('yum install epel-release -y') : nil
43
- end
44
-
45
- def ansible_package_version_suffix
46
- return unless @config[:ansible_version] && @config[:ansible_version] != 'latest'
47
-
48
- if @config[:ansible_package_name]
49
- "-#{@config[:ansible_version]}"
50
- else
51
- "#{@config[:ansible_version][0..2]}-#{@config[:ansible_version]}"
52
- end
53
- end
54
-
55
- def ansible_package_name
56
- if @config[:ansible_package_name]
57
- "#{@config[:ansible_package_name]}#{ansible_package_version_suffix}"
58
- else
59
- "ansible#{ansible_package_version_suffix}"
60
- end
61
- end
62
-
63
- def redhat_yum_repo
64
- if @config[:ansible_yum_repo]
65
- <<-INSTALL
66
- #{sudo_env('rpm')} -ivh #{@config[:ansible_yum_repo]}
67
- INSTALL
68
- else
69
- <<-INSTALL
70
- if ! yum repolist epel | grep -q epel; then
71
- #{sudo_env('rpm')} -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-`rpm -E %dist | sed -n 's/.*el\\([0-9]\\).*/\\1/p'`.noarch.rpm
72
- fi
73
- INSTALL
74
- end
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Michael Heap (<m@michaelheap.com>)
4
+ #
5
+ # Copyright (C) 2015 Michael Heap
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Kitchen
21
+ module Provisioner
22
+ module Ansible
23
+ class Os
24
+ class Redhat < Os
25
+ def install_command
26
+ <<-INSTALL
27
+
28
+ if [ ! $(which ansible) ]; then
29
+ #{install_epel_repo}
30
+ #{redhat_yum_repo}
31
+ #{update_packages_command}
32
+ #{sudo_env('yum')} -y install #{ansible_package_name} libselinux-python git
33
+ fi
34
+ INSTALL
35
+ end
36
+
37
+ def update_packages_command
38
+ @config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
39
+ end
40
+
41
+ def install_epel_repo
42
+ @config[:enable_yum_epel] ? sudo_env('yum install epel-release -y') : nil
43
+ end
44
+
45
+ def ansible_package_version_suffix
46
+ return unless @config[:ansible_version] && @config[:ansible_version] != 'latest'
47
+
48
+ if @config[:ansible_package_name]
49
+ "-#{@config[:ansible_version]}"
50
+ else
51
+ "#{@config[:ansible_version][0..2]}-#{@config[:ansible_version]}"
52
+ end
53
+ end
54
+
55
+ def ansible_package_name
56
+ if @config[:ansible_package_name]
57
+ "#{@config[:ansible_package_name]}#{ansible_package_version_suffix}"
58
+ else
59
+ "ansible#{ansible_package_version_suffix}"
60
+ end
61
+ end
62
+
63
+ def redhat_yum_repo
64
+ if @config[:ansible_yum_repo]
65
+ <<-INSTALL
66
+ #{sudo_env('rpm')} -ivh #{@config[:ansible_yum_repo]}
67
+ INSTALL
68
+ else
69
+ <<-INSTALL
70
+ if ! yum repolist epel | grep -q epel; then
71
+ #{sudo_env('rpm')} -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-`rpm -E %dist | sed -n 's/.*el\\([0-9]\\).*/\\1/p'`.noarch.rpm
72
+ fi
73
+ INSTALL
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,44 +1,44 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Michael Heap (<m@michaelheap.com>)
4
- #
5
- # Copyright (C) 2015 Michael Heap
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- module Kitchen
21
- module Provisioner
22
- module Ansible
23
- class Os
24
- class Suse < Os
25
- def install_command
26
- <<-INSTALL
27
-
28
- if [ ! $(which ansible) ]; then
29
- #{sudo_env('zypper')} ar #{@config[:python_sles_repo]}
30
- #{sudo_env('zypper')} ar #{@config[:ansible_sles_repo]}
31
- #{update_packages_command}
32
- #{sudo_env('zypper')} --non-interactive install ansible
33
- fi
34
- INSTALL
35
- end
36
-
37
- def update_packages_command
38
- @config[:update_package_repos] ? "#{sudo_env('zypper')} --gpg-auto-import-keys ref" : nil
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Michael Heap (<m@michaelheap.com>)
4
+ #
5
+ # Copyright (C) 2015 Michael Heap
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Kitchen
21
+ module Provisioner
22
+ module Ansible
23
+ class Os
24
+ class Suse < Os
25
+ def install_command
26
+ <<-INSTALL
27
+
28
+ if [ ! $(which ansible) ]; then
29
+ #{sudo_env('zypper')} ar #{@config[:python_sles_repo]}
30
+ #{sudo_env('zypper')} ar #{@config[:ansible_sles_repo]}
31
+ #{update_packages_command}
32
+ #{sudo_env('zypper')} --non-interactive install ansible
33
+ fi
34
+ INSTALL
35
+ end
36
+
37
+ def update_packages_command
38
+ @config[:update_package_repos] ? "#{sudo_env('zypper')} --gpg-auto-import-keys ref" : nil
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,1227 +1,1232 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Neill Turner (<neillwturner@gmail.com>)
4
- #
5
- # Copyright (C) 2013,2014 Neill Turner
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
- # See https://github.com/neillturner/kitchen-ansible/blob/master/provisioner_options.md
20
- # for documentation configuration parameters with ansible_playbook provisioner.
21
- #
22
-
23
- require 'json'
24
- require 'find'
25
- require 'kitchen/provisioner/base'
26
- require 'kitchen/provisioner/ansible/config'
27
- require 'kitchen/provisioner/ansible/os'
28
- require 'kitchen/provisioner/ansible/librarian'
29
-
30
- module Kitchen
31
- class Busser
32
- def non_suite_dirs
33
- %w(data)
34
- end
35
- end
36
-
37
- module Provisioner
38
- #
39
- # Ansible Playbook provisioner.
40
- #
41
- class AnsiblePlaybook < Base
42
- attr_accessor :tmp_dir
43
-
44
- def initialize(provisioner_config)
45
- config = Kitchen::Provisioner::Ansible::Config.new(provisioner_config)
46
- super(config)
47
-
48
- @os = Kitchen::Provisioner::Ansible::Os.make(ansible_platform, config)
49
- end
50
-
51
- def finalize_config!(instance)
52
- config.instance = instance
53
- super(instance)
54
- end
55
-
56
- def verbosity_level(level = 1)
57
- level = level.to_sym if level.is_a? String
58
- log_levels = { info: 1, warn: 2, debug: 3, trace: 4 }
59
- if level.is_a?(Symbol) && log_levels.include?(level)
60
- # puts "Log Level is: #{log_levels[level]}"
61
- log_levels[level]
62
- elsif level.is_a?(Integer) && level > 0
63
- # puts "Log Level is: #{level}"
64
- level
65
- else
66
- fail 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
67
- end
68
- end
69
-
70
- def install_command
71
- if config[:require_ansible_omnibus]
72
- cmd = install_omnibus_command
73
- elsif config[:require_ansible_source]
74
- info('Installing ansible from source')
75
- cmd = install_ansible_from_source_command
76
- elsif config[:require_pip]
77
- info('Installing ansible through pip')
78
- cmd = install_ansible_from_pip_command
79
- elsif config[:require_ansible_repo]
80
- if !@os.nil?
81
- info("Installing ansible on #{@os.name}")
82
- cmd = @os.install_command
83
- else
84
- info('Installing ansible, will try to determine platform os')
85
- cmd = <<-INSTALL
86
-
87
- if [ ! $(which ansible) ]; then
88
- if [ -f /etc/fedora-release ]; then
89
- #{Kitchen::Provisioner::Ansible::Os::Fedora.new('fedora', config).install_command}
90
- elif [ -f /etc/system-release ] && [ `grep -q 'Amazon Linux' /etc/system-release` ]; then
91
- #{Kitchen::Provisioner::Ansible::Os::Amazon.new('amazon', config).install_command}
92
- elif [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
93
- #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_command}
94
- elif [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
95
- #{Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).install_command}
96
- elif [[ "$OSTYPE" == "darwin"* ]]; then
97
- #{Kitchen::Provisioner::Ansible::Os::Darwin.new('darwin', config).install_command}
98
- elif [ -f /etc/alpine-release ] || [ -d /etc/apk ]; then
99
- #{Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).install_command}
100
- elif [ $(uname -s) = "OpenBSD" ]; then
101
- #{Kitchen::Provisioner::Ansible::Os::Openbsd.new('openbsd', config).install_command}
102
- else
103
- #{Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).install_command}
104
- fi
105
- fi
106
- INSTALL
107
- end
108
- else
109
- return
110
- end
111
-
112
- result = custom_pre_install_command + cmd + install_windows_support + install_busser_prereqs + custom_post_install_command
113
- debug("Going to install ansible with: #{result}")
114
- result
115
- end
116
-
117
- def detect_debug
118
- if ARGV.include? 'debug' or config[:show_command_output]
119
- result = "/dev/stdout"
120
- else
121
- result = "/dev/null"
122
- end
123
- return result
124
- end
125
-
126
- def install_windows_support
127
- install = ''
128
- if require_windows_support
129
- info ("Installing Windows Support")
130
- info ("Installing pip")
131
- install << <<-INSTALL
132
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
133
- #{sudo_env('yum')} -y install python-devel krb5-devel krb5-libs krb5-workstation gcc > #{detect_debug}
134
- else
135
- if [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
136
- #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
137
- #{sudo_env('zypper')} --non-interactive install python python-devel krb5-client pam_krb5 > #{detect_debug}
138
- else
139
- #{sudo_env('apt-get')} -y install python-dev libkrb5-dev build-essential > #{detect_debug}
140
- fi
141
- fi
142
- #{export_http_proxy}
143
- #{sudo_env('easy_install')} pip > #{detect_debug}
144
- #{sudo_env('pip')} install pywinrm kerberos > #{detect_debug}
145
- INSTALL
146
- end
147
- install
148
- end
149
-
150
- def install_busser_prereqs
151
- install = ''
152
- install << <<-INSTALL
153
- #{Util.shell_helpers}
154
- # Fix for https://github.com/test-kitchen/busser/issues/12
155
- if [ -h /usr/bin/ruby ]; then
156
- L=$(readlink -f /usr/bin/ruby)
157
- #{sudo_env('rm')} /usr/bin/ruby
158
- #{sudo_env('ln')} -s $L /usr/bin/ruby
159
- fi
160
- INSTALL
161
-
162
- if require_ruby_for_busser
163
- install << <<-INSTALL
164
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
165
- if [ -z `grep -q 'Amazon Linux' /etc/system-release` ]; then
166
- rhelversion6=$(cat /etc/redhat-release | grep 'release 6')
167
- rhelversion7=$(cat /etc/redhat-release | grep 'release 7')
168
- # For CentOS6/CentOS7/RHEL6/RHEL7 install ruby from SCL
169
- if [ -n "$rhelversion6" ] || [ -n "$rhelversion7" ]; then
170
- if [ ! -d "/opt/rh/ruby200" ]; then
171
- echo "-----> Installing ruby200 SCL in CentOS6/CentOS7/RHEL6/RHEL7 to install busser to run tests"
172
- #{sudo_env('yum')} install -y centos-release-scl > #{detect_debug}
173
- #{sudo_env('yum')} install -y ruby200 > #{detect_debug}
174
- #{sudo_env('yum')} install -y ruby200-ruby-devel > #{detect_debug}
175
- echo "-----> Enabling ruby200"
176
- source /opt/rh/ruby200/enable
177
- echo "/opt/rh/ruby200/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
178
- #{sudo_env('ldconfig')}
179
- #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/ruby /usr/bin/ruby
180
- #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/gem /usr/bin/gem
181
- fi
182
- else
183
- if [ ! $(which ruby) ]; then
184
- #{update_packages_redhat_cmd} > #{detect_debug}
185
- #{sudo_env('yum')} -y install ruby ruby-devel > #{detect_debug}
186
- fi
187
- fi
188
- else
189
- #{update_packages_redhat_cmd} > #{detect_debug}
190
- #{sudo_env('yum')} -y install ruby ruby-devel gcc > #{detect_debug}
191
- fi
192
- elif [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
193
- #{update_packages_suse_cmd} > #{detect_debug}
194
- #{sudo_env('zypper')} --non-interactive install ruby ruby-devel ca-certificates ca-certificates-cacert ca-certificates-mozilla > #{detect_debug}
195
- #{sudo_env('gem')} sources --add https://rubygems.org/
196
- elif [ -f /etc/alpine-release ] || [ -d /etc/apk ]; then
197
- #{update_packages_alpine_cmd}
198
- #{sudo_env('apk')} add ruby ruby-dev ruby-io-console ca-certificates > #{detect_debug}
199
- else
200
- if [ ! $(which ruby) ]; then
201
- #{update_packages_debian_cmd}
202
- # default package selection for Debian/Ubuntu machines
203
- PACKAGES="ruby1.9.1 ruby1.9.1-dev"
204
- if [ "$(lsb_release -si)" = "Debian" ]; then
205
- debvers=$(sed 's/\\..*//' /etc/debian_version)
206
- if [ $debvers -ge 8 ]; then
207
- # this is jessie or better, where ruby1.9.1 is
208
- # no longer in the repositories
209
- PACKAGES="ruby ruby-dev ruby2.1 ruby2.1-dev"
210
- fi
211
- fi
212
- if [ "$(lsb_release -si)" = "Ubuntu" ]; then
213
- ubuntuvers=$(lsb_release -sr | tr -d .)
214
- if [ $ubuntuvers -ge 1410 ]; then
215
- # Default ruby is 2.x in utopic and newer
216
- PACKAGES="ruby ruby-dev"
217
- fi
218
- fi
219
- #{sudo_env('apt-get')} -y install $PACKAGES > #{detect_debug}
220
- if [ $debvers -eq 6 ]; then
221
- # in squeeze we need to update alternatives
222
- # for enable ruby1.9.1
223
- ALTERNATIVES_STRING="--install /usr/bin/ruby ruby /usr/bin/ruby1.9.1 10 --slave /usr/share/man/man1/ruby.1.gz ruby.1.gz /usr/share/man/man1/ruby1.9.1.1.gz --slave /usr/bin/erb erb /usr/bin/erb1.9.1 --slave /usr/bin/gem gem /usr/bin/gem1.9.1 --slave /usr/bin/irb irb /usr/bin/irb1.9.1 --slave /usr/bin/rake rake /usr/bin/rake1.9.1 --slave /usr/bin/rdoc rdoc /usr/bin/rdoc1.9.1 --slave /usr/bin/testrb testrb /usr/bin/testrb1.9.1 --slave /usr/share/man/man1/erb.1.gz erb.1.gz /usr/share/man/man1/erb1.9.1.1.gz --slave /usr/share/man/man1/gem.1.gz gem.1.gz /usr/share/man/man1/gem1.9.1.1.gz --slave /usr/share/man/man1/irb.1.gz irb.1.gz /usr/share/man/man1/irb1.9.1.1.gz --slave /usr/share/man/man1/rake.1.gz rake.1.gz /usr/share/man/man1/rake1.9.1.1.gz --slave /usr/share/man/man1/rdoc.1.gz rdoc.1.gz /usr/share/man/man1/rdoc1.9.1.1.gz --slave /usr/share/man/man1/testrb.1.gz testrb.1.gz /usr/share/man/man1/testrb1.9.1.1.gz"
224
- #{sudo_env('update-alternatives')} $ALTERNATIVES_STRING
225
- # need to update gem tool because gem 1.3.7 from ruby 1.9.1 is broken
226
- #{sudo_env('gem')} install rubygems-update > #{detect_debug}
227
- #{sudo_env('/var/lib/gems/1.9.1/bin/update_rubygems')}
228
- # clear local gem cache
229
- #{sudo_env('rm')} -r /home/vagrant/.gem
230
- fi
231
- fi
232
- fi
233
- INSTALL
234
-
235
- elsif require_chef_for_busser && chef_url
236
- install << <<-INSTALL
237
- # install chef omnibus so that busser works as this is needed to run tests :(
238
- if [ ! -d "/opt/chef" ]
239
- then
240
- echo "-----> Installing Chef Omnibus to install busser to run tests"
241
- #{export_http_proxy}
242
- do_download #{chef_url} /tmp/install.sh
243
- #{sudo_env('sh')} /tmp/install.sh > #{detect_debug}
244
- fi
245
- INSTALL
246
- end
247
-
248
- install
249
- end
250
-
251
- def custom_pre_install_command
252
- <<-INSTALL
253
-
254
- #{config[:custom_pre_install_command]}
255
- INSTALL
256
- end
257
-
258
- def custom_post_install_command
259
- <<-INSTALL
260
- #{config[:custom_post_install_command]}
261
- INSTALL
262
- end
263
-
264
- def init_command
265
- dirs = %w(modules roles group_vars host_vars)
266
- .map { |dir| File.join(config[:root_path], dir) }.join(' ')
267
- cmd = "#{sudo_env('rm')} -rf #{dirs};"
268
- cmd += " mkdir -p #{config[:root_path]}"
269
- debug(cmd)
270
- cmd
271
- end
272
-
273
- def create_sandbox
274
- super
275
- debug("Creating local sandbox in #{sandbox_path}")
276
-
277
- yield if block_given?
278
-
279
- prepare_playbook
280
- prepare_inventory
281
- prepare_modules
282
- prepare_roles
283
- prepare_ansible_cfg
284
- prepare_group_vars
285
- prepare_additional_copy_path
286
- prepare_host_vars
287
- prepare_hosts
288
- prepare_spec
289
- prepare_library_plugins
290
- prepare_callback_plugins
291
- prepare_filter_plugins
292
- prepare_lookup_plugins
293
- prepare_ansible_vault_password_file
294
- prepare_kerberos_conf_file
295
- prepare_additional_ssh_private_keys
296
- info('Finished Preparing files for transfer')
297
- end
298
-
299
- def cleanup_sandbox
300
- return if sandbox_path.nil?
301
- debug("Cleaning up local sandbox in #{sandbox_path}")
302
- FileUtils.rmtree(sandbox_path)
303
- end
304
-
305
- def prepare_command
306
- commands = []
307
-
308
- # Prevent failure when ansible package installation doesn't contain /etc/ansible
309
- commands << [
310
- sudo_env("#{config[:shell_command]} -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
311
- ]
312
-
313
- commands << [
314
- sudo_env('cp'), File.join(config[:root_path], 'ansible.cfg'), '/etc/ansible'
315
- ].join(' ')
316
-
317
- commands << [
318
- sudo_env('cp -r'), File.join(config[:root_path], 'group_vars'), '/etc/ansible/.'
319
- ].join(' ')
320
-
321
- commands << [
322
- sudo_env('cp -r'), File.join(config[:root_path], 'host_vars'), '/etc/ansible/.'
323
- ].join(' ')
324
-
325
- if config[:ssh_known_hosts]
326
- config[:ssh_known_hosts].each do |host|
327
- info("Add #{host} to ~/.ssh/known_hosts")
328
- if host.include? ':'
329
- stripped_host, port = host.split(':')
330
- commands << "ssh-keyscan -p #{port} #{stripped_host} >> ~/.ssh/known_hosts 2> /dev/null"
331
- else
332
- commands << "ssh-keyscan #{host} >> ~/.ssh/known_hosts 2> /dev/null"
333
- end
334
- end
335
- end
336
-
337
- if config[:additional_ssh_private_keys]
338
- commands << [
339
- sudo_env('cp -r'), File.join(config[:root_path], 'ssh_private_keys'), '~/.ssh'
340
- ].join(' ')
341
- end
342
-
343
- if ansible_inventory
344
- if File.directory?(ansible_inventory)
345
- Dir.foreach(ansible_inventory) do |f|
346
- next if File.directory?("#{ansible_inventory}/#{f}")
347
- contents = File.open("#{ansible_inventory}/#{f}", 'rb') { |g| g.read }
348
- if contents.start_with?('#!')
349
- commands << [
350
- sudo_env('chmod +x'), File.join("#{config[:root_path]}/#{File.basename(ansible_inventory)}", File.basename(f))
351
- ].join(' ')
352
- end
353
- end
354
- else
355
- contents = File.open(ansible_inventory, 'rb') { |f| f.read }
356
- if contents.start_with?('#!')
357
- commands << [
358
- sudo_env('chmod +x'), File.join(config[:root_path], File.basename(ansible_inventory))
359
- ].join(' ')
360
- end
361
- end
362
- end
363
-
364
- if galaxy_requirements
365
- if config[:require_ansible_source]
366
- commands << setup_ansible_env_from_source
367
- end
368
- commands << ansible_galaxy_command
369
- end
370
-
371
- if kerberos_conf_file
372
- commands << [
373
- sudo_env('cp -f'), File.join(config[:root_path], 'krb5.conf'), '/etc'
374
- ].join(' ')
375
- end
376
-
377
- command = commands.join(' && ')
378
- debug("*** COMMAND TO RUN:")
379
- debug(command)
380
- command
381
- end
382
-
383
- def run_command
384
- return config[:ansible_playbook_command] unless config[:ansible_playbook_command].nil?
385
- if config[:require_ansible_source] && !config[:ansible_binary_path]
386
- # this is an ugly hack to get around the fact that extra vars uses ' and "
387
- cmd = ansible_command("PATH=#{config[:root_path]}/ansible/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games PYTHONPATH=#{config[:root_path]}/ansible/lib MANPATH=#{config[:root_path]}/ansible/docs/man ansible-playbook")
388
- elsif config[:ansible_binary_path]
389
- cmd = ansible_command("#{config[:ansible_binary_path]}/ansible-playbook")
390
- else
391
- cmd = ansible_command('ansible-playbook')
392
- end
393
-
394
- cmd = "#{env_vars} #{cmd}" if !config[:env_vars].none?
395
- cmd = "HTTPS_PROXY=#{https_proxy} #{cmd}" if https_proxy
396
- cmd = "HTTP_PROXY=#{http_proxy} #{cmd}" if http_proxy
397
- cmd = "NO_PROXY=#{no_proxy} #{cmd}" if no_proxy
398
- cmd = "ANSIBLE_ROLES_PATH=#{ansible_roles_path} #{cmd}" if ansible_roles_path
399
- cmd = "ANSIBLE_HOST_KEY_CHECKING=false #{cmd}" if !ansible_host_key_checking
400
-
401
- cmd = "#{cd_ansible} #{cmd}" if !config[:ansible_sudo].nil? && !config[:ansible_sudo]
402
- cmd = "#{copy_private_key_cmd} #{cmd}" if config[:private_key]
403
-
404
- def _run(cmd, idempotence = false)
405
- [
406
- cmd,
407
- ansible_inventory_flag,
408
- ansible_limit_flag,
409
- ansible_connection_flag,
410
- "-M #{File.join(config[:root_path], 'modules')}",
411
- ansible_verbose_flag,
412
- ansible_check_flag,
413
- ansible_diff_flag,
414
- ansible_vault_flag,
415
- private_key,
416
- extra_vars,
417
- extra_vars_file,
418
- tags(idempotence),
419
- ansible_extra_flags,
420
- "#{File.join(config[:root_path], File.basename(config[:playbook]))}"
421
- ].join(' ')
422
- end
423
- result = _run(cmd)
424
- if config[:idempotency_test]
425
- idempotency_result = _run(cmd, true)
426
- result = "#{result} && (echo 'Going to invoke ansible-playbook second time:'; #{idempotency_result} | tee /tmp/idempotency_test.txt; if grep -qE 'changed=[1-9].*failed=|changed=.*failed=[1-9]' /tmp/idempotency_test.txt; then echo 'Idempotence test: FAIL' && exit 1; else echo 'Idempotence test: PASS' && exit 0; fi)"
427
- end
428
- if config[:custom_post_play_command]
429
- custom_post_play_trap = <<-TRAP
430
- function custom_post_play_command {
431
- #{config[:custom_post_play_command]}
432
- }
433
- trap custom_post_play_command EXIT
434
- TRAP
435
- end
436
- result = <<-RUN
437
- #{config[:custom_pre_play_command]}
438
- #{custom_post_play_trap}
439
- #{result}
440
- RUN
441
-
442
- debug("Going to invoke ansible-playbook with: #{result}")
443
- result
444
-
445
- end
446
-
447
- def ansible_command(script)
448
- if config[:ansible_sudo].nil? || config[:ansible_sudo] == true
449
- s = https_proxy ? "https_proxy=#{https_proxy}" : nil
450
- p = http_proxy ? "http_proxy=#{http_proxy}" : nil
451
- n = no_proxy ? "no_proxy=#{no_proxy}" : nil
452
- p || s || n ? " #{p} #{s} #{n} #{config[:sudo_command]} -s #{cd_ansible} #{script}" : "#{config[:sudo_command]} -s #{cd_ansible} #{script}"
453
- else
454
- return script
455
- end
456
- end
457
-
458
- def ansible_galaxy_command
459
- cmd = [
460
- 'ansible-galaxy', 'install', '--force',
461
- galaxy_cert_ignore,
462
- '-p', File.join(config[:root_path], 'roles'),
463
- '-r', File.join(config[:root_path], galaxy_requirements)
464
- ].join(' ')
465
- cmd = "https_proxy=#{https_proxy} #{cmd}" if https_proxy
466
- cmd = "http_proxy=#{http_proxy} #{cmd}" if http_proxy
467
- cmd = "no_proxy=#{no_proxy} #{cmd}" if no_proxy
468
- cmd
469
- end
470
-
471
- def cd_ansible
472
- # this is not working so just return nil for now
473
- # File.exist?('ansible.cfg') ? "cd #{config[:root_path]};" : nil
474
- nil
475
- end
476
-
477
- protected
478
-
479
- def load_needed_dependencies!
480
- return unless File.exist?(ansiblefile)
481
-
482
- debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
483
- Ansible::Librarian.load!(logger)
484
- end
485
-
486
- def install_ansible_from_source_command
487
- <<-INSTALL
488
- if [ ! -d #{config[:root_path]}/ansible ]; then
489
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
490
- #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_epel_repo}
491
- #{update_packages_redhat_cmd} > #{detect_debug}
492
- #{sudo_env('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev libffi-devel libssl-devel > #{detect_debug}
493
- else
494
- if [ -f /etc/SUSE-brand ] || [ -f /etc/SuSE-release ]; then
495
- #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
496
- #{update_packages_suse_cmd} > #{detect_debug}
497
- #{sudo_env('zypper')} --non-interactive install python python-devel git python-setuptools python-pip python-six libyaml-devel libffi-devel libopenssl-devel > #{detect_debug}
498
- else
499
- #{update_packages_debian_cmd} > #{detect_debug}
500
- #{sudo_env('apt-get')} -y install git python python-setuptools build-essential python-dev libffi-dev libssl-dev > #{detect_debug}
501
- fi
502
- fi
503
-
504
- #{export_http_proxy}
505
- git clone #{config[:ansible_source_url]} --recursive #{config[:root_path]}/ansible #{install_source_rev}
506
- #{sudo_env('easy_install')} pip > #{detect_debug}
507
- #{sudo_env('pip')} install -U setuptools > #{detect_debug}
508
- #{sudo_env('pip')} install six paramiko PyYAML Jinja2 httplib2 > #{detect_debug}
509
- fi
510
- INSTALL
511
- end
512
-
513
- def install_ansible_from_pip_command
514
- if config[:ansible_version]=='latest' or config[:ansible_version].nil?
515
- ansible_version = ''
516
- else
517
- ansible_version = "==#{config[:ansible_version]}"
518
- end
519
- <<-INSTALL
520
- if [ ! $(which ansible) ]; then
521
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
522
- #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_epel_repo}
523
- #{update_packages_redhat_cmd} > #{detect_debug}
524
- #{sudo_env('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev libffi-devel openssl-devel gcc > #{detect_debug}
525
- else
526
- if [ -f /etc/SUSE-brand ] || [ -f /etc/SuSE-release ]; then
527
- #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
528
- #{update_packages_suse_cmd} > #{detect_debug}
529
- #{sudo_env('zypper')} --non-interactive install python python-devel git python-setuptools python-pip python-six libyaml-devel libffi-devel libopenssl-devel > #{detect_debug}
530
- else
531
- #{update_packages_debian_cmd} > #{detect_debug}
532
- #{sudo_env('apt-get')} -y install git python python-pip python-setuptools build-essential python-dev libffi-dev libssl-dev > #{detect_debug}
533
- fi
534
- fi
535
-
536
- #{export_http_proxy}
537
- #{sudo_env('easy_install')} pip > #{detect_debug}
538
- #{sudo_env('pip')} install -U setuptools > #{detect_debug}
539
- #{sudo_env('pip')} install ansible#{ansible_version} > #{detect_debug}
540
- fi
541
- INSTALL
542
- end
543
-
544
- def install_omnibus_command
545
- info('Installing ansible using ansible omnibus')
546
-
547
- version = ''
548
- version = "-v #{config[:ansible_version]}" unless config[:ansible_version].nil?
549
-
550
- <<-INSTALL
551
- #{Util.shell_helpers}
552
-
553
- if [ ! -d "#{config[:ansible_omnibus_remote_path]}" ]; then
554
- echo "-----> Installing Ansible Omnibus"
555
- #{export_http_proxy}
556
- do_download #{config[:ansible_omnibus_url]} /tmp/ansible_install.sh
557
- #{sudo_env(config[:shell_command])} /tmp/ansible_install.sh #{version} > #{detect_debug}
558
- fi
559
- INSTALL
560
- end
561
-
562
- def setup_ansible_env_from_source
563
- "cd #{config[:root_path]}/ansible && source hacking/env-setup && cd ../"
564
- end
565
-
566
- def tmp_modules_dir
567
- File.join(sandbox_path, 'modules')
568
- end
569
-
570
- def tmp_playbook_path
571
- File.join(sandbox_path, File.basename(playbook))
572
- end
573
-
574
- def tmp_host_vars_dir
575
- File.join(sandbox_path, 'host_vars')
576
- end
577
-
578
- def tmp_roles_dir
579
- File.join(sandbox_path, 'roles')
580
- end
581
-
582
- def tmp_spec_dir
583
- File.join(sandbox_path, 'spec')
584
- end
585
-
586
- def tmp_library_plugins_dir
587
- File.join(sandbox_path, 'library')
588
- end
589
-
590
- def tmp_callback_plugins_dir
591
- File.join(sandbox_path, 'callback_plugins')
592
- end
593
-
594
- def tmp_filter_plugins_dir
595
- File.join(sandbox_path, 'filter_plugins')
596
- end
597
-
598
- def tmp_lookup_plugins_dir
599
- File.join(sandbox_path, 'lookup_plugins')
600
- end
601
-
602
- def tmp_additional_ssh_private_keys_dir
603
- File.join(sandbox_path, 'ssh_private_keys')
604
- end
605
-
606
- def tmp_ansible_vault_password_file_path(f)
607
- File.join(sandbox_path, File.basename(f).reverse.chomp('.').reverse)
608
- end
609
-
610
- def tmp_kerberos_conf_file_path
611
- File.join(sandbox_path, 'krb5.conf')
612
- end
613
-
614
- def tmp_inventory_path
615
- File.join(sandbox_path, File.basename(ansible_inventory))
616
- end
617
-
618
- def ansiblefile
619
- config[:ansiblefile_path] || ''
620
- end
621
-
622
- def galaxy_requirements
623
- config[:requirements_path] || nil
624
- end
625
-
626
- def env_vars
627
- return nil if config[:env_vars].none?
628
- config[:env_vars].map { |k, v| "#{k}=#{v}" }.join(' ')
629
- end
630
-
631
- def playbook
632
- config[:playbook]
633
- end
634
-
635
- def hosts
636
- config[:hosts]
637
- end
638
-
639
- def roles
640
- config[:roles_path]
641
- end
642
-
643
- def role_name
644
- if config[:role_name]
645
- config[:role_name]
646
- elsif File.basename(roles) == 'roles'
647
- ''
648
- else
649
- File.basename(roles)
650
- end
651
- end
652
-
653
- def modules
654
- config[:modules_path]
655
- end
656
-
657
- def spec
658
- 'spec'
659
- end
660
-
661
- def group_vars
662
- config[:group_vars_path].to_s
663
- end
664
-
665
- def additional_copy
666
- config[:additional_copy_path]
667
- end
668
-
669
- def ansible_cfg_path
670
- config[:ansible_cfg_path]
671
- end
672
-
673
- def recursive_additional_copy
674
- config[:recursive_additional_copy_path]
675
- end
676
-
677
- def host_vars
678
- config[:host_vars_path].to_s
679
- end
680
-
681
- def library_plugins
682
- config[:library_plugins_path].to_s
683
- end
684
-
685
- def callback_plugins
686
- config[:callback_plugins_path].to_s
687
- end
688
-
689
- def filter_plugins
690
- config[:filter_plugins_path].to_s
691
- end
692
-
693
- def lookup_plugins
694
- config[:lookup_plugins_path].to_s
695
- end
696
-
697
- def ansible_vault_password_file
698
- password_files = []
699
- if config[:ansible_vault_password_file]
700
- password_files = config[:ansible_vault_password_file].is_a?(Array) ? config[:ansible_vault_password_file] : [config[:ansible_vault_password_file]]
701
- end
702
- password_files.map(&:to_s)
703
- end
704
-
705
- def ansible_inventory
706
- return nil if config[:ansible_inventory] == 'none'
707
- config[:ansible_inventory] = config[:ansible_inventory_file] if config[:ansible_inventory].nil?
708
- info('ansible_inventory_file parameter deprecated use ansible_inventory') if config[:ansible_inventory_file]
709
- config[:ansible_inventory]
710
- end
711
-
712
- def ansible_debian_version
713
- if @config[:ansible_version] == 'latest' || @config[:ansible_version] == nil
714
- ''
715
- else
716
- "=#{@config[:ansible_version]}"
717
- end
718
- end
719
-
720
- def ansible_connection_flag
721
- "-c #{config[:ansible_connection]}" if config[:ansible_connection] != 'none'
722
- end
723
-
724
- def ansible_verbose_flag
725
- config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
726
- end
727
-
728
- def ansible_check_flag
729
- config[:ansible_check] ? '--check' : nil
730
- end
731
-
732
- def ansible_diff_flag
733
- config[:ansible_diff] ? '--diff' : nil
734
- end
735
-
736
- def ansible_vault_flag
737
- debug(config[:ansible_vault_password_file])
738
- return nil if not ansible_vault_password_file
739
-
740
- files = []
741
-
742
- ansible_vault_password_file.each do |f|
743
- files << "--vault-password-file=#{File.join(config[:root_path], File.basename(f).reverse.chomp('.').reverse)}"
744
- end
745
-
746
- files.join(' ')
747
- end
748
-
749
- def ansible_inventory_flag
750
- return nil if config[:ansible_inventory] == 'none'
751
- ansible_inventory ? "-i #{File.join(config[:root_path], File.basename(ansible_inventory))}" : "-i #{File.join(config[:root_path], 'hosts')}"
752
- end
753
-
754
- def ansible_limit_flag
755
- config[:ansible_limit] ? "-l #{config[:ansible_limit]}" : ""
756
- end
757
-
758
- def ansible_extra_flags
759
- config[:ansible_extra_flags] || ''
760
- end
761
-
762
- def ansible_platform
763
- config[:ansible_platform].to_s.downcase
764
- end
765
-
766
- def ansible_host_key_checking
767
- config[:ansible_host_key_checking]
768
- end
769
-
770
- def private_key
771
- if config[:private_key]
772
- "--private-key #{private_key_file}"
773
- end
774
- end
775
-
776
- def copy_private_key_cmd
777
- if !config[:private_key].start_with?('/') && !config[:private_key].start_with?('~')
778
- ssh_private_key = File.join('~/.ssh', File.basename(config[:private_key]))
779
- tmp_private_key = File.join(config[:root_path], config[:private_key])
780
- "rm -rf #{ssh_private_key}; cp #{tmp_private_key} #{ssh_private_key}; chmod 400 #{ssh_private_key};"
781
- end
782
- end
783
-
784
- def private_key_file
785
- if config[:private_key].start_with?('/') || config[:private_key].start_with?('~')
786
- "#{config[:private_key]}"
787
- elsif config[:private_key]
788
- "#{File.join('~/.ssh', File.basename(config[:private_key]))}"
789
- end
790
- end
791
-
792
- def update_packages_debian_cmd
793
- Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).update_packages_command
794
- end
795
-
796
- def update_packages_suse_cmd
797
- Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).update_packages_command
798
- end
799
-
800
- def update_packages_redhat_cmd
801
- Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).update_packages_command
802
- end
803
-
804
- def update_packages_alpine_cmd
805
- Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).update_packages_command
806
- end
807
-
808
- def python_sles_repo
809
- config[:python_sles_repo]
810
- end
811
-
812
- def extra_vars
813
- bash_vars = config[:extra_vars]
814
- if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
815
- bash_vars = config[:attributes][:extra_vars]
816
- end
817
-
818
- return nil if bash_vars.none?
819
- bash_vars = JSON.dump(bash_vars)
820
- bash_vars = "-e '#{bash_vars}'"
821
- debug(bash_vars)
822
- bash_vars
823
- end
824
-
825
- def extra_vars_file
826
- return nil if config[:extra_vars_file].nil?
827
- bash_extra_vars = "-e '\@#{config[:extra_vars_file]}'"
828
- debug(bash_extra_vars)
829
- bash_extra_vars
830
- end
831
-
832
- def tags(idempotence = false)
833
- bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
834
- bash_skip_tags = []
835
- if idempotence and config[:idempotency_test]
836
- bash_tags += config[:idempotency_tags]
837
- bash_skip_tags += config[:idempotency_skip_tags]
838
- end
839
- return nil if (bash_tags.empty? and bash_skip_tags.empty?)
840
-
841
- result = ''
842
- if not bash_tags.empty?
843
- result += " --tags=#{bash_tags.join(',')}"
844
- end
845
- if not bash_skip_tags.empty?
846
- result += " --skip-tags=#{bash_skip_tags.join(',')}"
847
- end
848
- debug(result)
849
- result
850
- end
851
-
852
- def chef_url
853
- config[:chef_bootstrap_url]
854
- end
855
-
856
- def require_ruby_for_busser
857
- config[:require_ruby_for_busser]
858
- end
859
-
860
- def require_chef_for_busser
861
- config[:require_chef_for_busser]
862
- end
863
-
864
- def require_windows_support
865
- config[:require_windows_support]
866
- end
867
-
868
- def kerberos_conf_file
869
- config[:kerberos_conf_file]
870
- end
871
-
872
- def install_source_rev
873
- config[:ansible_source_rev] ? "--branch #{config[:ansible_source_rev]}" : nil
874
- end
875
-
876
- def http_proxy
877
- config[:http_proxy]
878
- end
879
-
880
- def https_proxy
881
- config[:https_proxy]
882
- end
883
-
884
- def no_proxy
885
- config[:no_proxy]
886
- end
887
-
888
- def sudo_env(pm,home=false)
889
- s = https_proxy ? "https_proxy=#{https_proxy}" : nil
890
- p = http_proxy ? "http_proxy=#{http_proxy}" : nil
891
- n = no_proxy ? "no_proxy=#{no_proxy}" : nil
892
- if home
893
- p || s || n ? "#{sudo_home('env')} #{p} #{s} #{n} #{pm}" : "#{sudo_home(pm)}"
894
- else
895
- p || s || n ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
896
- end
897
- end
898
-
899
- def export_http_proxy
900
- cmd = ''
901
- cmd = " HTTP_PROXY=#{http_proxy}" if http_proxy
902
- cmd = "#{cmd} HTTPS_PROXY=#{https_proxy}" if https_proxy
903
- cmd = "#{cmd} NO_PROXY=#{no_proxy}" if no_proxy
904
- cmd = "export #{cmd}" if cmd != ''
905
- cmd
906
- end
907
-
908
- def ansible_roles_path
909
- roles_paths = []
910
- roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
911
- if config[:additional_copy_role_path]
912
- if config[:additional_copy_role_path].is_a? String
913
- roles_paths << File.join(config[:root_path], File.basename(config[:additional_copy_role_path]))
914
- else
915
- config[:additional_copy_role_path].each do |path|
916
- roles_paths << File.join(config[:root_path], File.basename(File.expand_path(path)))
917
- end
918
- end
919
- end
920
- if roles_paths.empty?
921
- info('No roles have been set.')
922
- nil
923
- else
924
- debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
925
- roles_paths.join(':')
926
- end
927
- end
928
-
929
- def prepare_roles
930
- info('Preparing roles')
931
- debug("Using roles from #{File.expand_path(roles)}")
932
-
933
- resolve_with_librarian if File.exist?(ansiblefile)
934
-
935
- if galaxy_requirements
936
- dest = File.join(sandbox_path, galaxy_requirements)
937
- FileUtils.mkdir_p(File.dirname(dest))
938
- FileUtils.cp(File.expand_path(galaxy_requirements), dest)
939
- end
940
-
941
- if config[:additional_copy_role_path]
942
- if config[:additional_copy_role_path].is_a? String
943
- debug("Using additional roles copy from #{File.expand_path(config[:additional_copy_role_path])}")
944
- dest = File.join(sandbox_path, File.basename(File.expand_path(config[:additional_copy_role_path])))
945
- FileUtils.mkdir_p(File.dirname(dest))
946
- FileUtils.cp_r(File.expand_path(config[:additional_copy_role_path]), dest)
947
- else
948
- config[:additional_copy_role_path].each do |path|
949
- dest = File.join(sandbox_path, File.basename(File.expand_path(path)))
950
- FileUtils.mkdir_p(File.dirname(dest))
951
- FileUtils.cp_r(File.expand_path(path), dest)
952
- end
953
- end
954
- end
955
-
956
- FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
957
- Find.find(roles) do |source|
958
- # Detect whether we are running tests on a role
959
- # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
960
- role_path = source.sub(/#{roles}|\/roles/, '')
961
- unless roles =~ /\/roles$/
962
- role_path = "#{role_name}/#{role_path}"
963
- end
964
- target = File.join(tmp_roles_dir, role_path)
965
-
966
- Find.prune if config[:ignore_paths_from_root].include? File.basename(source)
967
- Find.prune if config[:ignore_extensions_from_root].include? File.extname(source)
968
- if File.directory?(source)
969
- FileUtils.mkdir_p(target)
970
- else
971
- FileUtils.cp(source, target)
972
- end
973
- end
974
- end
975
-
976
- # copy ansible.cfg if found
977
- def prepare_ansible_cfg
978
- info('Preparing ansible.cfg file')
979
- ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
980
- if !ansible_cfg_path.nil? && File.exist?(ansible_cfg_path) && !config[:ignore_ansible_cfg]
981
- info('Found existing ansible.cfg')
982
- FileUtils.cp_r(ansible_cfg_path, ansible_config_file)
983
- else
984
- info('Empty ansible.cfg generated')
985
- File.open(ansible_config_file, 'wb') do |file|
986
- file.write("#no config parameters\n")
987
- end
988
- end
989
- end
990
-
991
- def prepare_inventory
992
- info('Preparing inventory')
993
- return unless ansible_inventory
994
- if File.directory?(ansible_inventory)
995
- debug("Copying inventory directory from #{ansible_inventory} to #{tmp_inventory_path}")
996
- FileUtils.cp_r(ansible_inventory, sandbox_path)
997
- else
998
- debug("Copying inventory file from #{ansible_inventory} to #{tmp_inventory_path}")
999
- FileUtils.cp_r(ansible_inventory, tmp_inventory_path)
1000
- end
1001
- end
1002
-
1003
- # localhost ansible_connection=local
1004
- # [example_servers]
1005
- # localhost
1006
- def prepare_hosts
1007
- return if ansible_inventory
1008
- info('Preparing hosts file')
1009
-
1010
- if config[:hosts].nil?
1011
- fail 'No hosts have been set. Please specify one in .kitchen.yml'
1012
- elsif config[:hosts].is_a?(Array)
1013
- debug("Using an array of hosts from #{hosts}")
1014
- File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1015
- hoststring="localhost ansible_connection=local\n"
1016
- config[:hosts].each do |h|
1017
- hoststring+="[#{h}]\nlocalhost\n\n"
1018
- end
1019
- file.write(hoststring)
1020
- end
1021
- else
1022
- debug("Using host from #{hosts}")
1023
- File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1024
- file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
1025
- end
1026
- end
1027
- end
1028
-
1029
- def prepare_playbook
1030
- info('Preparing playbook')
1031
- debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
1032
- FileUtils.cp_r(playbook, tmp_playbook_path)
1033
- end
1034
-
1035
- def prepare_group_vars
1036
- info('Preparing group_vars')
1037
- tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
1038
- FileUtils.mkdir_p(tmp_group_vars_dir)
1039
-
1040
- unless File.directory?(group_vars)
1041
- info('nothing to do for group_vars')
1042
- return
1043
- end
1044
-
1045
- debug("Using group_vars from #{group_vars}")
1046
- FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
1047
- end
1048
-
1049
- def prepare_additional_copy_path
1050
- info('Preparing additional_copy_path')
1051
- additional_files.each do |file|
1052
- info("Copy additional path: #{file}")
1053
- destination = File.join(sandbox_path, File.basename(File.expand_path(file)))
1054
- if File.directory?(File.expand_path(file)) && File.basename(File.expand_path(file))!= ?.
1055
- debug("Copy dir: #{File.expand_path(file)} #{destination}")
1056
- FileUtils.cp_r(File.expand_path(file), destination)
1057
- else
1058
- debug("Copy file: #{file} #{destination}")
1059
- FileUtils.cp(file, destination)
1060
- end
1061
- end
1062
- recursive_additional_files.each do |file|
1063
- info("Copy recursive additional path: #{file}")
1064
- Find.find(file) do |files|
1065
- destination = File.join(sandbox_path, files)
1066
- Find.prune if config[:ignore_paths_from_root].include? File.basename(files)
1067
- Find.prune if "?.".include? File.basename(files)
1068
- Find.prune if config[:ignore_extensions_from_root].include? File.extname(files)
1069
- debug File.basename(files)
1070
- if File.directory?(files)
1071
- FileUtils.mkdir_p(destination)
1072
- else
1073
- FileUtils.cp(files, destination)
1074
- end
1075
- end
1076
- end
1077
- end
1078
-
1079
- def additional_files
1080
- additional_files = []
1081
- if additional_copy
1082
- additional_files = additional_copy.is_a?(Array) ? additional_copy : [additional_copy]
1083
- end
1084
- additional_files.map(&:to_s)
1085
- end
1086
-
1087
- def recursive_additional_files
1088
- recursive_additional_files = []
1089
- if recursive_additional_copy
1090
- recursive_additional_files = recursive_additional_copy.is_a?(Array) ? recursive_additional_copy : [recursive_additional_copy]
1091
- end
1092
- recursive_additional_files.map(&:to_s)
1093
- end
1094
-
1095
- def prepare_host_vars
1096
- info('Preparing host_vars')
1097
- FileUtils.mkdir_p(tmp_host_vars_dir)
1098
-
1099
- unless File.directory?(host_vars)
1100
- info 'nothing to do for host_vars'
1101
- return
1102
- end
1103
-
1104
- debug("Using host_vars from #{host_vars}")
1105
- FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
1106
- end
1107
-
1108
- def prepare_modules
1109
- info('Preparing modules')
1110
-
1111
- FileUtils.mkdir_p(tmp_modules_dir)
1112
-
1113
- if modules && File.directory?(modules)
1114
- debug("Using modules from #{modules}")
1115
- FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
1116
- else
1117
- info 'nothing to do for modules'
1118
- end
1119
- end
1120
-
1121
- def prepare_spec
1122
- info('Preparing spec')
1123
-
1124
- FileUtils.mkdir_p(tmp_spec_dir)
1125
-
1126
- if spec && File.directory?(spec)
1127
- debug("Using spec from #{spec}")
1128
- FileUtils.cp_r(Dir.glob("#{spec}/*"), tmp_spec_dir, remove_destination: true)
1129
- else
1130
- info 'nothing to do for spec'
1131
- end
1132
- end
1133
-
1134
- def prepare_library_plugins
1135
- info('Preparing library plugins')
1136
- FileUtils.mkdir_p(tmp_library_plugins_dir)
1137
-
1138
- if library_plugins && File.directory?(library_plugins)
1139
- debug("Using library plugins from #{library_plugins}")
1140
- FileUtils.cp_r(Dir.glob("#{library_plugins}/{*,!*.pyc}"), tmp_library_plugins_dir, remove_destination: true)
1141
- else
1142
- info 'nothing to do for library plugins'
1143
- end
1144
- end
1145
-
1146
- def prepare_callback_plugins
1147
- info('Preparing callback plugins')
1148
- FileUtils.mkdir_p(tmp_callback_plugins_dir)
1149
-
1150
- if callback_plugins && File.directory?(callback_plugins)
1151
- debug("Using callback plugins from #{callback_plugins}")
1152
- FileUtils.cp_r(Dir.glob("#{callback_plugins}/{*,!*.pyc}"), tmp_callback_plugins_dir, remove_destination: true)
1153
- else
1154
- info 'nothing to do for callback plugins'
1155
- end
1156
- end
1157
-
1158
- def prepare_filter_plugins
1159
- info('Preparing filter_plugins')
1160
- FileUtils.mkdir_p(tmp_filter_plugins_dir)
1161
-
1162
- if filter_plugins && File.directory?(filter_plugins)
1163
- debug("Using filter_plugins from #{filter_plugins}")
1164
- FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
1165
- else
1166
- info 'nothing to do for filter_plugins'
1167
- end
1168
- end
1169
-
1170
- def prepare_lookup_plugins
1171
- info('Preparing lookup_plugins')
1172
- FileUtils.mkdir_p(tmp_lookup_plugins_dir)
1173
-
1174
- if lookup_plugins && File.directory?(lookup_plugins)
1175
- debug("Using lookup_plugins from #{lookup_plugins}")
1176
- FileUtils.cp_r(Dir.glob("#{lookup_plugins}/*.py"), tmp_lookup_plugins_dir, remove_destination: true)
1177
- else
1178
- info 'nothing to do for lookup_plugins'
1179
- end
1180
- end
1181
-
1182
- def prepare_additional_ssh_private_keys
1183
- info('Preparing additional_ssh_private_keys')
1184
- FileUtils.mkdir_p(tmp_additional_ssh_private_keys_dir)
1185
- if config[:additional_ssh_private_keys]
1186
- config[:additional_ssh_private_keys].each do |key|
1187
- debug("Adding additional_ssh_private_key file #{key}")
1188
- FileUtils.cp_r(File.expand_path(key), tmp_additional_ssh_private_keys_dir, remove_destination: true)
1189
- end
1190
- else
1191
- info 'nothing to do for additional_ssh_private_keys'
1192
- end
1193
- end
1194
-
1195
- def prepare_ansible_vault_password_file
1196
- return unless ansible_vault_password_file
1197
-
1198
- info('Preparing ansible vault password')
1199
- ansible_vault_password_file.each do |f|
1200
- debug("Copying ansible vault password file from #{f} to #{tmp_ansible_vault_password_file_path(f)}")
1201
-
1202
- FileUtils.cp(File.expand_path(f), tmp_ansible_vault_password_file_path(f))
1203
- end
1204
- end
1205
-
1206
- def prepare_kerberos_conf_file
1207
- return unless kerberos_conf_file
1208
-
1209
- info('Preparing kerberos configuration file')
1210
- debug("Copying kerberos configuration file from #{kerberos_conf_file} to #{tmp_kerberos_conf_file_path}")
1211
-
1212
- FileUtils.cp(File.expand_path(kerberos_conf_file), tmp_kerberos_conf_file_path)
1213
- end
1214
-
1215
- def resolve_with_librarian
1216
- Kitchen.mutex.synchronize do
1217
- Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
1218
- end
1219
- end
1220
-
1221
- def galaxy_cert_ignore
1222
- config[:galaxy_ignore_certs] ? '--ignore-certs' : nil
1223
- end
1224
-
1225
- end
1226
- end
1227
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Neill Turner (<neillwturner@gmail.com>)
4
+ #
5
+ # Copyright (C) 2013,2014 Neill Turner
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ # See https://github.com/neillturner/kitchen-ansible/blob/master/provisioner_options.md
20
+ # for documentation configuration parameters with ansible_playbook provisioner.
21
+ #
22
+
23
+ require 'json'
24
+ require 'find'
25
+ require 'kitchen/provisioner/base'
26
+ require 'kitchen/provisioner/ansible/config'
27
+ require 'kitchen/provisioner/ansible/os'
28
+ require 'kitchen/provisioner/ansible/librarian'
29
+
30
+ module Kitchen
31
+ class Busser
32
+ def non_suite_dirs
33
+ %w(data)
34
+ end
35
+ end
36
+
37
+ module Provisioner
38
+ #
39
+ # Ansible Playbook provisioner.
40
+ #
41
+ class AnsiblePlaybook < Base
42
+ attr_accessor :tmp_dir
43
+
44
+ def initialize(provisioner_config)
45
+ config = Kitchen::Provisioner::Ansible::Config.new(provisioner_config)
46
+ super(config)
47
+
48
+ @os = Kitchen::Provisioner::Ansible::Os.make(ansible_platform, config)
49
+ end
50
+
51
+ def finalize_config!(instance)
52
+ config.instance = instance
53
+ super(instance)
54
+ end
55
+
56
+ def verbosity_level(level = 1)
57
+ level = level.to_sym if level.is_a? String
58
+ log_levels = { info: 1, warn: 2, debug: 3, trace: 4 }
59
+ if level.is_a?(Symbol) && log_levels.include?(level)
60
+ # puts "Log Level is: #{log_levels[level]}"
61
+ log_levels[level]
62
+ elsif level.is_a?(Integer) && level > 0
63
+ # puts "Log Level is: #{level}"
64
+ level
65
+ else
66
+ fail 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
67
+ end
68
+ end
69
+
70
+ def install_command
71
+ if config[:require_ansible_omnibus]
72
+ cmd = install_omnibus_command
73
+ elsif config[:require_ansible_source]
74
+ info('Installing ansible from source')
75
+ cmd = install_ansible_from_source_command
76
+ elsif config[:require_pip]
77
+ info('Installing ansible through pip')
78
+ cmd = install_ansible_from_pip_command
79
+ elsif config[:require_ansible_repo]
80
+ if !@os.nil?
81
+ info("Installing ansible on #{@os.name}")
82
+ cmd = @os.install_command
83
+ else
84
+ info('Installing ansible, will try to determine platform os')
85
+ cmd = <<-INSTALL
86
+
87
+ if [ ! $(which ansible) ]; then
88
+ if [ -f /etc/fedora-release ]; then
89
+ #{Kitchen::Provisioner::Ansible::Os::Fedora.new('fedora', config).install_command}
90
+ elif [ -f /etc/system-release ] && [ `grep -q 'Amazon Linux' /etc/system-release` ]; then
91
+ #{Kitchen::Provisioner::Ansible::Os::Amazon.new('amazon', config).install_command}
92
+ elif [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
93
+ #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_command}
94
+ elif [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
95
+ #{Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).install_command}
96
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
97
+ #{Kitchen::Provisioner::Ansible::Os::Darwin.new('darwin', config).install_command}
98
+ elif [ -f /etc/alpine-release ] || [ -d /etc/apk ]; then
99
+ #{Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).install_command}
100
+ elif [ $(uname -s) = "OpenBSD" ]; then
101
+ #{Kitchen::Provisioner::Ansible::Os::Openbsd.new('openbsd', config).install_command}
102
+ elif [ $(uname -s) = "FreeBSD" ]; then
103
+ #{Kitchen::Provisioner::Ansible::Os::Freebsd.new('freebsd', config).install_command}
104
+ else
105
+ #{Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).install_command}
106
+ fi
107
+ fi
108
+ INSTALL
109
+ end
110
+ else
111
+ return
112
+ end
113
+
114
+ result = custom_pre_install_command + cmd + install_windows_support + install_busser_prereqs + custom_post_install_command
115
+ debug("Going to install ansible with: #{result}")
116
+ result
117
+ end
118
+
119
+ def detect_debug
120
+ if ARGV.include? 'debug' or config[:show_command_output]
121
+ result = "/dev/stdout"
122
+ else
123
+ result = "/dev/null"
124
+ end
125
+ return result
126
+ end
127
+
128
+ def install_windows_support
129
+ install = ''
130
+ if require_windows_support
131
+ info ("Installing Windows Support")
132
+ info ("Installing pip")
133
+ install << <<-INSTALL
134
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
135
+ #{sudo_env('yum')} -y install python-devel krb5-devel krb5-libs krb5-workstation gcc > #{detect_debug}
136
+ else
137
+ if [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
138
+ #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
139
+ #{sudo_env('zypper')} --non-interactive install python python-devel krb5-client pam_krb5 > #{detect_debug}
140
+ else
141
+ #{sudo_env('apt-get')} -y install python-dev libkrb5-dev build-essential > #{detect_debug}
142
+ fi
143
+ fi
144
+ #{export_http_proxy}
145
+ #{sudo_env('easy_install')} pip > #{detect_debug}
146
+ #{sudo_env('pip')} install pywinrm kerberos > #{detect_debug}
147
+ INSTALL
148
+ end
149
+ install
150
+ end
151
+
152
+ def install_busser_prereqs
153
+ install = ''
154
+ install << <<-INSTALL
155
+ #{Util.shell_helpers}
156
+ # Fix for https://github.com/test-kitchen/busser/issues/12
157
+ if [ -h /usr/bin/ruby ]; then
158
+ L=$(readlink -f /usr/bin/ruby)
159
+ #{sudo_env('rm')} /usr/bin/ruby
160
+ #{sudo_env('ln')} -s $L /usr/bin/ruby
161
+ fi
162
+ INSTALL
163
+
164
+ if require_ruby_for_busser
165
+ install << <<-INSTALL
166
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
167
+ if [ -z `grep -q 'Amazon Linux' /etc/system-release` ]; then
168
+ rhelversion6=$(cat /etc/redhat-release | grep 'release 6')
169
+ rhelversion7=$(cat /etc/redhat-release | grep 'release 7')
170
+ # For CentOS6/CentOS7/RHEL6/RHEL7 install ruby from SCL
171
+ if [ -n "$rhelversion6" ] || [ -n "$rhelversion7" ]; then
172
+ if [ ! -d "/opt/rh/ruby200" ]; then
173
+ echo "-----> Installing ruby200 SCL in CentOS6/CentOS7/RHEL6/RHEL7 to install busser to run tests"
174
+ #{sudo_env('yum')} install -y centos-release-scl > #{detect_debug}
175
+ #{sudo_env('yum')} install -y ruby200 > #{detect_debug}
176
+ #{sudo_env('yum')} install -y ruby200-ruby-devel > #{detect_debug}
177
+ echo "-----> Enabling ruby200"
178
+ source /opt/rh/ruby200/enable
179
+ echo "/opt/rh/ruby200/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
180
+ #{sudo_env('ldconfig')}
181
+ #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/ruby /usr/bin/ruby
182
+ #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/gem /usr/bin/gem
183
+ fi
184
+ else
185
+ if [ ! $(which ruby) ]; then
186
+ #{update_packages_redhat_cmd} > #{detect_debug}
187
+ #{sudo_env('yum')} -y install ruby ruby-devel > #{detect_debug}
188
+ fi
189
+ fi
190
+ else
191
+ #{update_packages_redhat_cmd} > #{detect_debug}
192
+ #{sudo_env('yum')} -y install ruby ruby-devel gcc > #{detect_debug}
193
+ fi
194
+ elif [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
195
+ #{update_packages_suse_cmd} > #{detect_debug}
196
+ #{sudo_env('zypper')} --non-interactive install ruby ruby-devel ca-certificates ca-certificates-cacert ca-certificates-mozilla > #{detect_debug}
197
+ #{sudo_env('gem')} sources --add https://rubygems.org/
198
+ elif [ -f /etc/alpine-release ] || [ -d /etc/apk ]; then
199
+ #{update_packages_alpine_cmd}
200
+ #{sudo_env('apk')} add ruby ruby-dev ruby-io-console ca-certificates > #{detect_debug}
201
+ else
202
+ if [ ! $(which ruby) ]; then
203
+ #{update_packages_debian_cmd}
204
+ # default package selection for Debian/Ubuntu machines
205
+ PACKAGES="ruby1.9.1 ruby1.9.1-dev"
206
+ if [ "$(lsb_release -si)" = "Debian" ]; then
207
+ debvers=$(sed 's/\\..*//' /etc/debian_version)
208
+ if [ $debvers -ge 8 ]; then
209
+ # this is jessie or better, where ruby1.9.1 is
210
+ # no longer in the repositories
211
+ PACKAGES="ruby ruby-dev ruby2.1 ruby2.1-dev"
212
+ fi
213
+ fi
214
+ if [ "$(lsb_release -si)" = "Ubuntu" ]; then
215
+ ubuntuvers=$(lsb_release -sr | tr -d .)
216
+ if [ $ubuntuvers -ge 1410 ]; then
217
+ # Default ruby is 2.x in utopic and newer
218
+ PACKAGES="ruby ruby-dev"
219
+ fi
220
+ fi
221
+ #{sudo_env('apt-get')} -y install $PACKAGES > #{detect_debug}
222
+ if [ $debvers -eq 6 ]; then
223
+ # in squeeze we need to update alternatives
224
+ # for enable ruby1.9.1
225
+ ALTERNATIVES_STRING="--install /usr/bin/ruby ruby /usr/bin/ruby1.9.1 10 --slave /usr/share/man/man1/ruby.1.gz ruby.1.gz /usr/share/man/man1/ruby1.9.1.1.gz --slave /usr/bin/erb erb /usr/bin/erb1.9.1 --slave /usr/bin/gem gem /usr/bin/gem1.9.1 --slave /usr/bin/irb irb /usr/bin/irb1.9.1 --slave /usr/bin/rake rake /usr/bin/rake1.9.1 --slave /usr/bin/rdoc rdoc /usr/bin/rdoc1.9.1 --slave /usr/bin/testrb testrb /usr/bin/testrb1.9.1 --slave /usr/share/man/man1/erb.1.gz erb.1.gz /usr/share/man/man1/erb1.9.1.1.gz --slave /usr/share/man/man1/gem.1.gz gem.1.gz /usr/share/man/man1/gem1.9.1.1.gz --slave /usr/share/man/man1/irb.1.gz irb.1.gz /usr/share/man/man1/irb1.9.1.1.gz --slave /usr/share/man/man1/rake.1.gz rake.1.gz /usr/share/man/man1/rake1.9.1.1.gz --slave /usr/share/man/man1/rdoc.1.gz rdoc.1.gz /usr/share/man/man1/rdoc1.9.1.1.gz --slave /usr/share/man/man1/testrb.1.gz testrb.1.gz /usr/share/man/man1/testrb1.9.1.1.gz"
226
+ #{sudo_env('update-alternatives')} $ALTERNATIVES_STRING
227
+ # need to update gem tool because gem 1.3.7 from ruby 1.9.1 is broken
228
+ #{sudo_env('gem')} install rubygems-update > #{detect_debug}
229
+ #{sudo_env('/var/lib/gems/1.9.1/bin/update_rubygems')}
230
+ # clear local gem cache
231
+ #{sudo_env('rm')} -r /home/vagrant/.gem
232
+ fi
233
+ fi
234
+ fi
235
+ INSTALL
236
+
237
+ elsif require_chef_for_busser && chef_url
238
+ install << <<-INSTALL
239
+ # install chef omnibus so that busser works as this is needed to run tests :(
240
+ if [ ! -d "/opt/chef" ]
241
+ then
242
+ echo "-----> Installing Chef Omnibus to install busser to run tests"
243
+ #{export_http_proxy}
244
+ do_download #{chef_url} /tmp/install.sh
245
+ #{sudo_env('sh')} /tmp/install.sh > #{detect_debug}
246
+ fi
247
+ INSTALL
248
+ end
249
+
250
+ install
251
+ end
252
+
253
+ def custom_pre_install_command
254
+ <<-INSTALL
255
+
256
+ #{config[:custom_pre_install_command]}
257
+ INSTALL
258
+ end
259
+
260
+ def custom_post_install_command
261
+ <<-INSTALL
262
+ #{config[:custom_post_install_command]}
263
+ INSTALL
264
+ end
265
+
266
+ def init_command
267
+ dirs = %w(modules roles group_vars host_vars)
268
+ .map { |dir| File.join(config[:root_path], dir) }.join(' ')
269
+ cmd = "#{sudo_env('rm')} -rf #{dirs};"
270
+ cmd += " mkdir -p #{config[:root_path]}"
271
+ debug(cmd)
272
+ cmd
273
+ end
274
+
275
+ def create_sandbox
276
+ super
277
+ debug("Creating local sandbox in #{sandbox_path}")
278
+
279
+ yield if block_given?
280
+
281
+ prepare_playbook
282
+ prepare_inventory
283
+ prepare_modules
284
+ prepare_roles
285
+ prepare_ansible_cfg
286
+ prepare_group_vars
287
+ prepare_additional_copy_path
288
+ prepare_host_vars
289
+ prepare_hosts
290
+ prepare_spec
291
+ prepare_library_plugins
292
+ prepare_callback_plugins
293
+ prepare_filter_plugins
294
+ prepare_lookup_plugins
295
+ prepare_ansible_vault_password_file
296
+ prepare_kerberos_conf_file
297
+ prepare_additional_ssh_private_keys
298
+ info('Finished Preparing files for transfer')
299
+ end
300
+
301
+ def cleanup_sandbox
302
+ return if sandbox_path.nil?
303
+ debug("Cleaning up local sandbox in #{sandbox_path}")
304
+ FileUtils.rmtree(sandbox_path)
305
+ end
306
+
307
+ def prepare_command
308
+ commands = []
309
+
310
+ commands << [
311
+ "if [ $(uname -s) == 'FreeBSD' ]; then ETC_ANSIBLE='/usr/local/etc/ansible'; else ETC_ANSIBLE='/etc/ansible'; fi"
312
+ ]
313
+ # Prevent failure when ansible package installation doesn't contain /etc/ansible
314
+ commands << [
315
+ sudo_env("#{config[:shell_command]} -c \"[ -d $ETC_ANSIBLE ] || mkdir $ETC_ANSIBLE\"")
316
+ ]
317
+
318
+ commands << [
319
+ sudo_env('cp'), File.join(config[:root_path], 'ansible.cfg'), '$ETC_ANSIBLE/.'
320
+ ].join(' ')
321
+
322
+ commands << [
323
+ sudo_env('cp -r'), File.join(config[:root_path], 'group_vars'), '$ETC_ANSIBLE/.'
324
+ ].join(' ')
325
+
326
+ commands << [
327
+ sudo_env('cp -r'), File.join(config[:root_path], 'host_vars'), '$ETC_ANSIBLE/.'
328
+ ].join(' ')
329
+
330
+ if config[:ssh_known_hosts]
331
+ config[:ssh_known_hosts].each do |host|
332
+ info("Add #{host} to ~/.ssh/known_hosts")
333
+ if host.include? ':'
334
+ stripped_host, port = host.split(':')
335
+ commands << "ssh-keyscan -p #{port} #{stripped_host} >> ~/.ssh/known_hosts 2> /dev/null"
336
+ else
337
+ commands << "ssh-keyscan #{host} >> ~/.ssh/known_hosts 2> /dev/null"
338
+ end
339
+ end
340
+ end
341
+
342
+ if config[:additional_ssh_private_keys]
343
+ commands << [
344
+ sudo_env('cp -r'), File.join(config[:root_path], 'ssh_private_keys'), '~/.ssh'
345
+ ].join(' ')
346
+ end
347
+
348
+ if ansible_inventory
349
+ if File.directory?(ansible_inventory)
350
+ Dir.foreach(ansible_inventory) do |f|
351
+ next if File.directory?("#{ansible_inventory}/#{f}")
352
+ contents = File.open("#{ansible_inventory}/#{f}", 'rb') { |g| g.read }
353
+ if contents.start_with?('#!')
354
+ commands << [
355
+ sudo_env('chmod +x'), File.join("#{config[:root_path]}/#{File.basename(ansible_inventory)}", File.basename(f))
356
+ ].join(' ')
357
+ end
358
+ end
359
+ else
360
+ contents = File.open(ansible_inventory, 'rb') { |f| f.read }
361
+ if contents.start_with?('#!')
362
+ commands << [
363
+ sudo_env('chmod +x'), File.join(config[:root_path], File.basename(ansible_inventory))
364
+ ].join(' ')
365
+ end
366
+ end
367
+ end
368
+
369
+ if galaxy_requirements
370
+ if config[:require_ansible_source]
371
+ commands << setup_ansible_env_from_source
372
+ end
373
+ commands << ansible_galaxy_command
374
+ end
375
+
376
+ if kerberos_conf_file
377
+ commands << [
378
+ sudo_env('cp -f'), File.join(config[:root_path], 'krb5.conf'), '/etc'
379
+ ].join(' ')
380
+ end
381
+
382
+ command = commands.join(' && ')
383
+ debug("*** COMMAND TO RUN:")
384
+ debug(command)
385
+ command
386
+ end
387
+
388
+ def run_command
389
+ return config[:ansible_playbook_command] unless config[:ansible_playbook_command].nil?
390
+ if config[:require_ansible_source] && !config[:ansible_binary_path]
391
+ # this is an ugly hack to get around the fact that extra vars uses ' and "
392
+ cmd = ansible_command("PATH=#{config[:root_path]}/ansible/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games PYTHONPATH=#{config[:root_path]}/ansible/lib MANPATH=#{config[:root_path]}/ansible/docs/man ansible-playbook")
393
+ elsif config[:ansible_binary_path]
394
+ cmd = ansible_command("#{config[:ansible_binary_path]}/ansible-playbook")
395
+ else
396
+ cmd = ansible_command('ansible-playbook')
397
+ end
398
+
399
+ cmd = "#{env_vars} #{cmd}" if !config[:env_vars].none?
400
+ cmd = "HTTPS_PROXY=#{https_proxy} #{cmd}" if https_proxy
401
+ cmd = "HTTP_PROXY=#{http_proxy} #{cmd}" if http_proxy
402
+ cmd = "NO_PROXY=#{no_proxy} #{cmd}" if no_proxy
403
+ cmd = "ANSIBLE_ROLES_PATH=#{ansible_roles_path} #{cmd}" if ansible_roles_path
404
+ cmd = "ANSIBLE_HOST_KEY_CHECKING=false #{cmd}" if !ansible_host_key_checking
405
+
406
+ cmd = "#{cd_ansible} #{cmd}" if !config[:ansible_sudo].nil? && !config[:ansible_sudo]
407
+ cmd = "#{copy_private_key_cmd} #{cmd}" if config[:private_key]
408
+
409
+ def _run(cmd, idempotence = false)
410
+ [
411
+ cmd,
412
+ ansible_inventory_flag,
413
+ ansible_limit_flag,
414
+ ansible_connection_flag,
415
+ "-M #{File.join(config[:root_path], 'modules')}",
416
+ ansible_verbose_flag,
417
+ ansible_check_flag,
418
+ ansible_diff_flag,
419
+ ansible_vault_flag,
420
+ private_key,
421
+ extra_vars,
422
+ extra_vars_file,
423
+ tags(idempotence),
424
+ ansible_extra_flags,
425
+ "#{File.join(config[:root_path], File.basename(config[:playbook]))}"
426
+ ].join(' ')
427
+ end
428
+ result = _run(cmd)
429
+ if config[:idempotency_test]
430
+ idempotency_result = _run(cmd, true)
431
+ result = "#{result} && (echo 'Going to invoke ansible-playbook second time:'; #{idempotency_result} | tee /tmp/idempotency_test.txt; if grep -qE 'changed=[1-9].*failed=|changed=.*failed=[1-9]' /tmp/idempotency_test.txt; then echo 'Idempotence test: FAIL' && exit 1; else echo 'Idempotence test: PASS' && exit 0; fi)"
432
+ end
433
+ if config[:custom_post_play_command]
434
+ custom_post_play_trap = <<-TRAP
435
+ function custom_post_play_command {
436
+ #{config[:custom_post_play_command]}
437
+ }
438
+ trap custom_post_play_command EXIT
439
+ TRAP
440
+ end
441
+ result = <<-RUN
442
+ #{config[:custom_pre_play_command]}
443
+ #{custom_post_play_trap}
444
+ #{result}
445
+ RUN
446
+
447
+ debug("Going to invoke ansible-playbook with: #{result}")
448
+ result
449
+
450
+ end
451
+
452
+ def ansible_command(script)
453
+ if config[:ansible_sudo].nil? || config[:ansible_sudo] == true
454
+ s = https_proxy ? "https_proxy=#{https_proxy}" : nil
455
+ p = http_proxy ? "http_proxy=#{http_proxy}" : nil
456
+ n = no_proxy ? "no_proxy=#{no_proxy}" : nil
457
+ p || s || n ? " #{p} #{s} #{n} #{config[:sudo_command]} -s #{cd_ansible} #{script}" : "#{config[:sudo_command]} -s #{cd_ansible} #{script}"
458
+ else
459
+ return script
460
+ end
461
+ end
462
+
463
+ def ansible_galaxy_command
464
+ cmd = [
465
+ 'ansible-galaxy', 'install', '--force',
466
+ galaxy_cert_ignore,
467
+ '-p', File.join(config[:root_path], 'roles'),
468
+ '-r', File.join(config[:root_path], galaxy_requirements)
469
+ ].join(' ')
470
+ cmd = "https_proxy=#{https_proxy} #{cmd}" if https_proxy
471
+ cmd = "http_proxy=#{http_proxy} #{cmd}" if http_proxy
472
+ cmd = "no_proxy=#{no_proxy} #{cmd}" if no_proxy
473
+ cmd
474
+ end
475
+
476
+ def cd_ansible
477
+ # this is not working so just return nil for now
478
+ # File.exist?('ansible.cfg') ? "cd #{config[:root_path]};" : nil
479
+ nil
480
+ end
481
+
482
+ protected
483
+
484
+ def load_needed_dependencies!
485
+ return unless File.exist?(ansiblefile)
486
+
487
+ debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
488
+ Ansible::Librarian.load!(logger)
489
+ end
490
+
491
+ def install_ansible_from_source_command
492
+ <<-INSTALL
493
+ if [ ! -d #{config[:root_path]}/ansible ]; then
494
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
495
+ #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_epel_repo}
496
+ #{update_packages_redhat_cmd} > #{detect_debug}
497
+ #{sudo_env('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev libffi-devel libssl-devel > #{detect_debug}
498
+ else
499
+ if [ -f /etc/SUSE-brand ] || [ -f /etc/SuSE-release ]; then
500
+ #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
501
+ #{update_packages_suse_cmd} > #{detect_debug}
502
+ #{sudo_env('zypper')} --non-interactive install python python-devel git python-setuptools python-pip python-six libyaml-devel libffi-devel libopenssl-devel > #{detect_debug}
503
+ else
504
+ #{update_packages_debian_cmd} > #{detect_debug}
505
+ #{sudo_env('apt-get')} -y install git python python-setuptools build-essential python-dev libffi-dev libssl-dev > #{detect_debug}
506
+ fi
507
+ fi
508
+
509
+ #{export_http_proxy}
510
+ git clone #{config[:ansible_source_url]} --recursive #{config[:root_path]}/ansible #{install_source_rev}
511
+ #{sudo_env('easy_install')} pip > #{detect_debug}
512
+ #{sudo_env('pip')} install -U setuptools > #{detect_debug}
513
+ #{sudo_env('pip')} install six paramiko PyYAML Jinja2 httplib2 > #{detect_debug}
514
+ fi
515
+ INSTALL
516
+ end
517
+
518
+ def install_ansible_from_pip_command
519
+ if config[:ansible_version]=='latest' or config[:ansible_version].nil?
520
+ ansible_version = ''
521
+ else
522
+ ansible_version = "==#{config[:ansible_version]}"
523
+ end
524
+ <<-INSTALL
525
+ if [ ! $(which ansible) ]; then
526
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
527
+ #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_epel_repo}
528
+ #{update_packages_redhat_cmd} > #{detect_debug}
529
+ #{sudo_env('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev libffi-devel openssl-devel gcc > #{detect_debug}
530
+ else
531
+ if [ -f /etc/SUSE-brand ] || [ -f /etc/SuSE-release ]; then
532
+ #{sudo_env('zypper')} ar #{python_sles_repo} > #{detect_debug}
533
+ #{update_packages_suse_cmd} > #{detect_debug}
534
+ #{sudo_env('zypper')} --non-interactive install python python-devel git python-setuptools python-pip python-six libyaml-devel libffi-devel libopenssl-devel > #{detect_debug}
535
+ else
536
+ #{update_packages_debian_cmd} > #{detect_debug}
537
+ #{sudo_env('apt-get')} -y install git python python-pip python-setuptools build-essential python-dev libffi-dev libssl-dev > #{detect_debug}
538
+ fi
539
+ fi
540
+
541
+ #{export_http_proxy}
542
+ #{sudo_env('easy_install')} pip > #{detect_debug}
543
+ #{sudo_env('pip')} install -U setuptools > #{detect_debug}
544
+ #{sudo_env('pip')} install ansible#{ansible_version} > #{detect_debug}
545
+ fi
546
+ INSTALL
547
+ end
548
+
549
+ def install_omnibus_command
550
+ info('Installing ansible using ansible omnibus')
551
+
552
+ version = ''
553
+ version = "-v #{config[:ansible_version]}" unless config[:ansible_version].nil?
554
+
555
+ <<-INSTALL
556
+ #{Util.shell_helpers}
557
+
558
+ if [ ! -d "#{config[:ansible_omnibus_remote_path]}" ]; then
559
+ echo "-----> Installing Ansible Omnibus"
560
+ #{export_http_proxy}
561
+ do_download #{config[:ansible_omnibus_url]} /tmp/ansible_install.sh
562
+ #{sudo_env(config[:shell_command])} /tmp/ansible_install.sh #{version} > #{detect_debug}
563
+ fi
564
+ INSTALL
565
+ end
566
+
567
+ def setup_ansible_env_from_source
568
+ "cd #{config[:root_path]}/ansible && source hacking/env-setup && cd ../"
569
+ end
570
+
571
+ def tmp_modules_dir
572
+ File.join(sandbox_path, 'modules')
573
+ end
574
+
575
+ def tmp_playbook_path
576
+ File.join(sandbox_path, File.basename(playbook))
577
+ end
578
+
579
+ def tmp_host_vars_dir
580
+ File.join(sandbox_path, 'host_vars')
581
+ end
582
+
583
+ def tmp_roles_dir
584
+ File.join(sandbox_path, 'roles')
585
+ end
586
+
587
+ def tmp_spec_dir
588
+ File.join(sandbox_path, 'spec')
589
+ end
590
+
591
+ def tmp_library_plugins_dir
592
+ File.join(sandbox_path, 'library')
593
+ end
594
+
595
+ def tmp_callback_plugins_dir
596
+ File.join(sandbox_path, 'callback_plugins')
597
+ end
598
+
599
+ def tmp_filter_plugins_dir
600
+ File.join(sandbox_path, 'filter_plugins')
601
+ end
602
+
603
+ def tmp_lookup_plugins_dir
604
+ File.join(sandbox_path, 'lookup_plugins')
605
+ end
606
+
607
+ def tmp_additional_ssh_private_keys_dir
608
+ File.join(sandbox_path, 'ssh_private_keys')
609
+ end
610
+
611
+ def tmp_ansible_vault_password_file_path(f)
612
+ File.join(sandbox_path, File.basename(f).reverse.chomp('.').reverse)
613
+ end
614
+
615
+ def tmp_kerberos_conf_file_path
616
+ File.join(sandbox_path, 'krb5.conf')
617
+ end
618
+
619
+ def tmp_inventory_path
620
+ File.join(sandbox_path, File.basename(ansible_inventory))
621
+ end
622
+
623
+ def ansiblefile
624
+ config[:ansiblefile_path] || ''
625
+ end
626
+
627
+ def galaxy_requirements
628
+ config[:requirements_path] || nil
629
+ end
630
+
631
+ def env_vars
632
+ return nil if config[:env_vars].none?
633
+ config[:env_vars].map { |k, v| "#{k}=#{v}" }.join(' ')
634
+ end
635
+
636
+ def playbook
637
+ config[:playbook]
638
+ end
639
+
640
+ def hosts
641
+ config[:hosts]
642
+ end
643
+
644
+ def roles
645
+ config[:roles_path]
646
+ end
647
+
648
+ def role_name
649
+ if config[:role_name]
650
+ config[:role_name]
651
+ elsif File.basename(roles) == 'roles'
652
+ ''
653
+ else
654
+ File.basename(roles)
655
+ end
656
+ end
657
+
658
+ def modules
659
+ config[:modules_path]
660
+ end
661
+
662
+ def spec
663
+ 'spec'
664
+ end
665
+
666
+ def group_vars
667
+ config[:group_vars_path].to_s
668
+ end
669
+
670
+ def additional_copy
671
+ config[:additional_copy_path]
672
+ end
673
+
674
+ def ansible_cfg_path
675
+ config[:ansible_cfg_path]
676
+ end
677
+
678
+ def recursive_additional_copy
679
+ config[:recursive_additional_copy_path]
680
+ end
681
+
682
+ def host_vars
683
+ config[:host_vars_path].to_s
684
+ end
685
+
686
+ def library_plugins
687
+ config[:library_plugins_path].to_s
688
+ end
689
+
690
+ def callback_plugins
691
+ config[:callback_plugins_path].to_s
692
+ end
693
+
694
+ def filter_plugins
695
+ config[:filter_plugins_path].to_s
696
+ end
697
+
698
+ def lookup_plugins
699
+ config[:lookup_plugins_path].to_s
700
+ end
701
+
702
+ def ansible_vault_password_file
703
+ password_files = []
704
+ if config[:ansible_vault_password_file]
705
+ password_files = config[:ansible_vault_password_file].is_a?(Array) ? config[:ansible_vault_password_file] : [config[:ansible_vault_password_file]]
706
+ end
707
+ password_files.map(&:to_s)
708
+ end
709
+
710
+ def ansible_inventory
711
+ return nil if config[:ansible_inventory] == 'none'
712
+ config[:ansible_inventory] = config[:ansible_inventory_file] if config[:ansible_inventory].nil?
713
+ info('ansible_inventory_file parameter deprecated use ansible_inventory') if config[:ansible_inventory_file]
714
+ config[:ansible_inventory]
715
+ end
716
+
717
+ def ansible_debian_version
718
+ if @config[:ansible_version] == 'latest' || @config[:ansible_version] == nil
719
+ ''
720
+ else
721
+ "=#{@config[:ansible_version]}"
722
+ end
723
+ end
724
+
725
+ def ansible_connection_flag
726
+ "-c #{config[:ansible_connection]}" if config[:ansible_connection] != 'none'
727
+ end
728
+
729
+ def ansible_verbose_flag
730
+ config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
731
+ end
732
+
733
+ def ansible_check_flag
734
+ config[:ansible_check] ? '--check' : nil
735
+ end
736
+
737
+ def ansible_diff_flag
738
+ config[:ansible_diff] ? '--diff' : nil
739
+ end
740
+
741
+ def ansible_vault_flag
742
+ debug(config[:ansible_vault_password_file])
743
+ return nil if not ansible_vault_password_file
744
+
745
+ files = []
746
+
747
+ ansible_vault_password_file.each do |f|
748
+ files << "--vault-password-file=#{File.join(config[:root_path], File.basename(f).reverse.chomp('.').reverse)}"
749
+ end
750
+
751
+ files.join(' ')
752
+ end
753
+
754
+ def ansible_inventory_flag
755
+ return nil if config[:ansible_inventory] == 'none'
756
+ ansible_inventory ? "-i #{File.join(config[:root_path], File.basename(ansible_inventory))}" : "-i #{File.join(config[:root_path], 'hosts')}"
757
+ end
758
+
759
+ def ansible_limit_flag
760
+ config[:ansible_limit] ? "-l #{config[:ansible_limit]}" : ""
761
+ end
762
+
763
+ def ansible_extra_flags
764
+ config[:ansible_extra_flags] || ''
765
+ end
766
+
767
+ def ansible_platform
768
+ config[:ansible_platform].to_s.downcase
769
+ end
770
+
771
+ def ansible_host_key_checking
772
+ config[:ansible_host_key_checking]
773
+ end
774
+
775
+ def private_key
776
+ if config[:private_key]
777
+ "--private-key #{private_key_file}"
778
+ end
779
+ end
780
+
781
+ def copy_private_key_cmd
782
+ if !config[:private_key].start_with?('/') && !config[:private_key].start_with?('~')
783
+ ssh_private_key = File.join('~/.ssh', File.basename(config[:private_key]))
784
+ tmp_private_key = File.join(config[:root_path], config[:private_key])
785
+ "rm -rf #{ssh_private_key}; cp #{tmp_private_key} #{ssh_private_key}; chmod 400 #{ssh_private_key};"
786
+ end
787
+ end
788
+
789
+ def private_key_file
790
+ if config[:private_key].start_with?('/') || config[:private_key].start_with?('~')
791
+ "#{config[:private_key]}"
792
+ elsif config[:private_key]
793
+ "#{File.join('~/.ssh', File.basename(config[:private_key]))}"
794
+ end
795
+ end
796
+
797
+ def update_packages_debian_cmd
798
+ Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).update_packages_command
799
+ end
800
+
801
+ def update_packages_suse_cmd
802
+ Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).update_packages_command
803
+ end
804
+
805
+ def update_packages_redhat_cmd
806
+ Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).update_packages_command
807
+ end
808
+
809
+ def update_packages_alpine_cmd
810
+ Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).update_packages_command
811
+ end
812
+
813
+ def python_sles_repo
814
+ config[:python_sles_repo]
815
+ end
816
+
817
+ def extra_vars
818
+ bash_vars = config[:extra_vars]
819
+ if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
820
+ bash_vars = config[:attributes][:extra_vars]
821
+ end
822
+
823
+ return nil if bash_vars.none?
824
+ bash_vars = JSON.dump(bash_vars)
825
+ bash_vars = "-e '#{bash_vars}'"
826
+ debug(bash_vars)
827
+ bash_vars
828
+ end
829
+
830
+ def extra_vars_file
831
+ return nil if config[:extra_vars_file].nil?
832
+ bash_extra_vars = "-e '\@#{config[:extra_vars_file]}'"
833
+ debug(bash_extra_vars)
834
+ bash_extra_vars
835
+ end
836
+
837
+ def tags(idempotence = false)
838
+ bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
839
+ bash_skip_tags = []
840
+ if idempotence and config[:idempotency_test]
841
+ bash_tags += config[:idempotency_tags]
842
+ bash_skip_tags += config[:idempotency_skip_tags]
843
+ end
844
+ return nil if (bash_tags.empty? and bash_skip_tags.empty?)
845
+
846
+ result = ''
847
+ if not bash_tags.empty?
848
+ result += " --tags=#{bash_tags.join(',')}"
849
+ end
850
+ if not bash_skip_tags.empty?
851
+ result += " --skip-tags=#{bash_skip_tags.join(',')}"
852
+ end
853
+ debug(result)
854
+ result
855
+ end
856
+
857
+ def chef_url
858
+ config[:chef_bootstrap_url]
859
+ end
860
+
861
+ def require_ruby_for_busser
862
+ config[:require_ruby_for_busser]
863
+ end
864
+
865
+ def require_chef_for_busser
866
+ config[:require_chef_for_busser]
867
+ end
868
+
869
+ def require_windows_support
870
+ config[:require_windows_support]
871
+ end
872
+
873
+ def kerberos_conf_file
874
+ config[:kerberos_conf_file]
875
+ end
876
+
877
+ def install_source_rev
878
+ config[:ansible_source_rev] ? "--branch #{config[:ansible_source_rev]}" : nil
879
+ end
880
+
881
+ def http_proxy
882
+ config[:http_proxy]
883
+ end
884
+
885
+ def https_proxy
886
+ config[:https_proxy]
887
+ end
888
+
889
+ def no_proxy
890
+ config[:no_proxy]
891
+ end
892
+
893
+ def sudo_env(pm,home=false)
894
+ s = https_proxy ? "https_proxy=#{https_proxy}" : nil
895
+ p = http_proxy ? "http_proxy=#{http_proxy}" : nil
896
+ n = no_proxy ? "no_proxy=#{no_proxy}" : nil
897
+ if home
898
+ p || s || n ? "#{sudo_home('env')} #{p} #{s} #{n} #{pm}" : "#{sudo_home(pm)}"
899
+ else
900
+ p || s || n ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
901
+ end
902
+ end
903
+
904
+ def export_http_proxy
905
+ cmd = ''
906
+ cmd = " HTTP_PROXY=#{http_proxy}" if http_proxy
907
+ cmd = "#{cmd} HTTPS_PROXY=#{https_proxy}" if https_proxy
908
+ cmd = "#{cmd} NO_PROXY=#{no_proxy}" if no_proxy
909
+ cmd = "export #{cmd}" if cmd != ''
910
+ cmd
911
+ end
912
+
913
+ def ansible_roles_path
914
+ roles_paths = []
915
+ roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
916
+ if config[:additional_copy_role_path]
917
+ if config[:additional_copy_role_path].is_a? String
918
+ roles_paths << File.join(config[:root_path], File.basename(config[:additional_copy_role_path]))
919
+ else
920
+ config[:additional_copy_role_path].each do |path|
921
+ roles_paths << File.join(config[:root_path], File.basename(File.expand_path(path)))
922
+ end
923
+ end
924
+ end
925
+ if roles_paths.empty?
926
+ info('No roles have been set.')
927
+ nil
928
+ else
929
+ debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
930
+ roles_paths.join(':')
931
+ end
932
+ end
933
+
934
+ def prepare_roles
935
+ info('Preparing roles')
936
+ debug("Using roles from #{File.expand_path(roles)}")
937
+
938
+ resolve_with_librarian if File.exist?(ansiblefile)
939
+
940
+ if galaxy_requirements
941
+ dest = File.join(sandbox_path, galaxy_requirements)
942
+ FileUtils.mkdir_p(File.dirname(dest))
943
+ FileUtils.cp(File.expand_path(galaxy_requirements), dest)
944
+ end
945
+
946
+ if config[:additional_copy_role_path]
947
+ if config[:additional_copy_role_path].is_a? String
948
+ debug("Using additional roles copy from #{File.expand_path(config[:additional_copy_role_path])}")
949
+ dest = File.join(sandbox_path, File.basename(File.expand_path(config[:additional_copy_role_path])))
950
+ FileUtils.mkdir_p(File.dirname(dest))
951
+ FileUtils.cp_r(File.expand_path(config[:additional_copy_role_path]), dest)
952
+ else
953
+ config[:additional_copy_role_path].each do |path|
954
+ dest = File.join(sandbox_path, File.basename(File.expand_path(path)))
955
+ FileUtils.mkdir_p(File.dirname(dest))
956
+ FileUtils.cp_r(File.expand_path(path), dest)
957
+ end
958
+ end
959
+ end
960
+
961
+ FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
962
+ Find.find(roles) do |source|
963
+ # Detect whether we are running tests on a role
964
+ # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
965
+ role_path = source.sub(/#{roles}|\/roles/, '')
966
+ unless roles =~ /\/roles$/
967
+ role_path = "#{role_name}/#{role_path}"
968
+ end
969
+ target = File.join(tmp_roles_dir, role_path)
970
+
971
+ Find.prune if config[:ignore_paths_from_root].include? File.basename(source)
972
+ Find.prune if config[:ignore_extensions_from_root].include? File.extname(source)
973
+ if File.directory?(source)
974
+ FileUtils.mkdir_p(target)
975
+ else
976
+ FileUtils.cp(source, target)
977
+ end
978
+ end
979
+ end
980
+
981
+ # copy ansible.cfg if found
982
+ def prepare_ansible_cfg
983
+ info('Preparing ansible.cfg file')
984
+ ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
985
+ if !ansible_cfg_path.nil? && File.exist?(ansible_cfg_path) && !config[:ignore_ansible_cfg]
986
+ info('Found existing ansible.cfg')
987
+ FileUtils.cp_r(ansible_cfg_path, ansible_config_file)
988
+ else
989
+ info('Empty ansible.cfg generated')
990
+ File.open(ansible_config_file, 'wb') do |file|
991
+ file.write("#no config parameters\n")
992
+ end
993
+ end
994
+ end
995
+
996
+ def prepare_inventory
997
+ info('Preparing inventory')
998
+ return unless ansible_inventory
999
+ if File.directory?(ansible_inventory)
1000
+ debug("Copying inventory directory from #{ansible_inventory} to #{tmp_inventory_path}")
1001
+ FileUtils.cp_r(ansible_inventory, sandbox_path)
1002
+ else
1003
+ debug("Copying inventory file from #{ansible_inventory} to #{tmp_inventory_path}")
1004
+ FileUtils.cp_r(ansible_inventory, tmp_inventory_path)
1005
+ end
1006
+ end
1007
+
1008
+ # localhost ansible_connection=local
1009
+ # [example_servers]
1010
+ # localhost
1011
+ def prepare_hosts
1012
+ return if ansible_inventory
1013
+ info('Preparing hosts file')
1014
+
1015
+ if config[:hosts].nil?
1016
+ fail 'No hosts have been set. Please specify one in .kitchen.yml'
1017
+ elsif config[:hosts].is_a?(Array)
1018
+ debug("Using an array of hosts from #{hosts}")
1019
+ File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1020
+ hoststring="localhost ansible_connection=local\n"
1021
+ config[:hosts].each do |h|
1022
+ hoststring+="[#{h}]\nlocalhost\n\n"
1023
+ end
1024
+ file.write(hoststring)
1025
+ end
1026
+ else
1027
+ debug("Using host from #{hosts}")
1028
+ File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1029
+ file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
1030
+ end
1031
+ end
1032
+ end
1033
+
1034
+ def prepare_playbook
1035
+ info('Preparing playbook')
1036
+ debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
1037
+ FileUtils.cp_r(playbook, tmp_playbook_path)
1038
+ end
1039
+
1040
+ def prepare_group_vars
1041
+ info('Preparing group_vars')
1042
+ tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
1043
+ FileUtils.mkdir_p(tmp_group_vars_dir)
1044
+
1045
+ unless File.directory?(group_vars)
1046
+ info('nothing to do for group_vars')
1047
+ return
1048
+ end
1049
+
1050
+ debug("Using group_vars from #{group_vars}")
1051
+ FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
1052
+ end
1053
+
1054
+ def prepare_additional_copy_path
1055
+ info('Preparing additional_copy_path')
1056
+ additional_files.each do |file|
1057
+ info("Copy additional path: #{file}")
1058
+ destination = File.join(sandbox_path, File.basename(File.expand_path(file)))
1059
+ if File.directory?(File.expand_path(file)) && File.basename(File.expand_path(file))!= ?.
1060
+ debug("Copy dir: #{File.expand_path(file)} #{destination}")
1061
+ FileUtils.cp_r(File.expand_path(file), destination)
1062
+ else
1063
+ debug("Copy file: #{file} #{destination}")
1064
+ FileUtils.cp(file, destination)
1065
+ end
1066
+ end
1067
+ recursive_additional_files.each do |file|
1068
+ info("Copy recursive additional path: #{file}")
1069
+ Find.find(file) do |files|
1070
+ destination = File.join(sandbox_path, files)
1071
+ Find.prune if config[:ignore_paths_from_root].include? File.basename(files)
1072
+ Find.prune if "?.".include? File.basename(files)
1073
+ Find.prune if config[:ignore_extensions_from_root].include? File.extname(files)
1074
+ debug File.basename(files)
1075
+ if File.directory?(files)
1076
+ FileUtils.mkdir_p(destination)
1077
+ else
1078
+ FileUtils.cp(files, destination)
1079
+ end
1080
+ end
1081
+ end
1082
+ end
1083
+
1084
+ def additional_files
1085
+ additional_files = []
1086
+ if additional_copy
1087
+ additional_files = additional_copy.is_a?(Array) ? additional_copy : [additional_copy]
1088
+ end
1089
+ additional_files.map(&:to_s)
1090
+ end
1091
+
1092
+ def recursive_additional_files
1093
+ recursive_additional_files = []
1094
+ if recursive_additional_copy
1095
+ recursive_additional_files = recursive_additional_copy.is_a?(Array) ? recursive_additional_copy : [recursive_additional_copy]
1096
+ end
1097
+ recursive_additional_files.map(&:to_s)
1098
+ end
1099
+
1100
+ def prepare_host_vars
1101
+ info('Preparing host_vars')
1102
+ FileUtils.mkdir_p(tmp_host_vars_dir)
1103
+
1104
+ unless File.directory?(host_vars)
1105
+ info 'nothing to do for host_vars'
1106
+ return
1107
+ end
1108
+
1109
+ debug("Using host_vars from #{host_vars}")
1110
+ FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
1111
+ end
1112
+
1113
+ def prepare_modules
1114
+ info('Preparing modules')
1115
+
1116
+ FileUtils.mkdir_p(tmp_modules_dir)
1117
+
1118
+ if modules && File.directory?(modules)
1119
+ debug("Using modules from #{modules}")
1120
+ FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
1121
+ else
1122
+ info 'nothing to do for modules'
1123
+ end
1124
+ end
1125
+
1126
+ def prepare_spec
1127
+ info('Preparing spec')
1128
+
1129
+ FileUtils.mkdir_p(tmp_spec_dir)
1130
+
1131
+ if spec && File.directory?(spec)
1132
+ debug("Using spec from #{spec}")
1133
+ FileUtils.cp_r(Dir.glob("#{spec}/*"), tmp_spec_dir, remove_destination: true)
1134
+ else
1135
+ info 'nothing to do for spec'
1136
+ end
1137
+ end
1138
+
1139
+ def prepare_library_plugins
1140
+ info('Preparing library plugins')
1141
+ FileUtils.mkdir_p(tmp_library_plugins_dir)
1142
+
1143
+ if library_plugins && File.directory?(library_plugins)
1144
+ debug("Using library plugins from #{library_plugins}")
1145
+ FileUtils.cp_r(Dir.glob("#{library_plugins}/{*,!*.pyc}"), tmp_library_plugins_dir, remove_destination: true)
1146
+ else
1147
+ info 'nothing to do for library plugins'
1148
+ end
1149
+ end
1150
+
1151
+ def prepare_callback_plugins
1152
+ info('Preparing callback plugins')
1153
+ FileUtils.mkdir_p(tmp_callback_plugins_dir)
1154
+
1155
+ if callback_plugins && File.directory?(callback_plugins)
1156
+ debug("Using callback plugins from #{callback_plugins}")
1157
+ FileUtils.cp_r(Dir.glob("#{callback_plugins}/{*,!*.pyc}"), tmp_callback_plugins_dir, remove_destination: true)
1158
+ else
1159
+ info 'nothing to do for callback plugins'
1160
+ end
1161
+ end
1162
+
1163
+ def prepare_filter_plugins
1164
+ info('Preparing filter_plugins')
1165
+ FileUtils.mkdir_p(tmp_filter_plugins_dir)
1166
+
1167
+ if filter_plugins && File.directory?(filter_plugins)
1168
+ debug("Using filter_plugins from #{filter_plugins}")
1169
+ FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
1170
+ else
1171
+ info 'nothing to do for filter_plugins'
1172
+ end
1173
+ end
1174
+
1175
+ def prepare_lookup_plugins
1176
+ info('Preparing lookup_plugins')
1177
+ FileUtils.mkdir_p(tmp_lookup_plugins_dir)
1178
+
1179
+ if lookup_plugins && File.directory?(lookup_plugins)
1180
+ debug("Using lookup_plugins from #{lookup_plugins}")
1181
+ FileUtils.cp_r(Dir.glob("#{lookup_plugins}/*.py"), tmp_lookup_plugins_dir, remove_destination: true)
1182
+ else
1183
+ info 'nothing to do for lookup_plugins'
1184
+ end
1185
+ end
1186
+
1187
+ def prepare_additional_ssh_private_keys
1188
+ info('Preparing additional_ssh_private_keys')
1189
+ FileUtils.mkdir_p(tmp_additional_ssh_private_keys_dir)
1190
+ if config[:additional_ssh_private_keys]
1191
+ config[:additional_ssh_private_keys].each do |key|
1192
+ debug("Adding additional_ssh_private_key file #{key}")
1193
+ FileUtils.cp_r(File.expand_path(key), tmp_additional_ssh_private_keys_dir, remove_destination: true)
1194
+ end
1195
+ else
1196
+ info 'nothing to do for additional_ssh_private_keys'
1197
+ end
1198
+ end
1199
+
1200
+ def prepare_ansible_vault_password_file
1201
+ return unless ansible_vault_password_file
1202
+
1203
+ info('Preparing ansible vault password')
1204
+ ansible_vault_password_file.each do |f|
1205
+ debug("Copying ansible vault password file from #{f} to #{tmp_ansible_vault_password_file_path(f)}")
1206
+
1207
+ FileUtils.cp(File.expand_path(f), tmp_ansible_vault_password_file_path(f))
1208
+ end
1209
+ end
1210
+
1211
+ def prepare_kerberos_conf_file
1212
+ return unless kerberos_conf_file
1213
+
1214
+ info('Preparing kerberos configuration file')
1215
+ debug("Copying kerberos configuration file from #{kerberos_conf_file} to #{tmp_kerberos_conf_file_path}")
1216
+
1217
+ FileUtils.cp(File.expand_path(kerberos_conf_file), tmp_kerberos_conf_file_path)
1218
+ end
1219
+
1220
+ def resolve_with_librarian
1221
+ Kitchen.mutex.synchronize do
1222
+ Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
1223
+ end
1224
+ end
1225
+
1226
+ def galaxy_cert_ignore
1227
+ config[:galaxy_ignore_certs] ? '--ignore-certs' : nil
1228
+ end
1229
+
1230
+ end
1231
+ end
1232
+ end