kitchen-ansible 0.49.0 → 0.49.1

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,1239 +1,1239 @@
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
- playbook_remote_path
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
- return File.join(sandbox_path, playbook).to_s if config[:keep_playbook_path]
577
- File.join(sandbox_path, File.basename(playbook)).to_s
578
- end
579
-
580
- def tmp_host_vars_dir
581
- File.join(sandbox_path, 'host_vars')
582
- end
583
-
584
- def tmp_roles_dir
585
- File.join(sandbox_path, 'roles')
586
- end
587
-
588
- def tmp_spec_dir
589
- File.join(sandbox_path, 'spec')
590
- end
591
-
592
- def tmp_library_plugins_dir
593
- File.join(sandbox_path, 'library')
594
- end
595
-
596
- def tmp_callback_plugins_dir
597
- File.join(sandbox_path, 'callback_plugins')
598
- end
599
-
600
- def tmp_filter_plugins_dir
601
- File.join(sandbox_path, 'filter_plugins')
602
- end
603
-
604
- def tmp_lookup_plugins_dir
605
- File.join(sandbox_path, 'lookup_plugins')
606
- end
607
-
608
- def tmp_additional_ssh_private_keys_dir
609
- File.join(sandbox_path, 'ssh_private_keys')
610
- end
611
-
612
- def tmp_ansible_vault_password_file_path(f)
613
- File.join(sandbox_path, File.basename(f).reverse.chomp('.').reverse)
614
- end
615
-
616
- def tmp_kerberos_conf_file_path
617
- File.join(sandbox_path, 'krb5.conf')
618
- end
619
-
620
- def tmp_inventory_path
621
- File.join(sandbox_path, File.basename(ansible_inventory))
622
- end
623
-
624
- def ansiblefile
625
- config[:ansiblefile_path] || ''
626
- end
627
-
628
- def galaxy_requirements
629
- config[:requirements_path] || nil
630
- end
631
-
632
- def env_vars
633
- return nil if config[:env_vars].none?
634
- config[:env_vars].map { |k, v| "#{k}=#{v}" }.join(' ')
635
- end
636
-
637
- def playbook
638
- config[:playbook]
639
- end
640
-
641
- def playbook_remote_path
642
- return File.join(config[:root_path], config[:playbook]).to_s if config[:keep_playbook_path]
643
- File.join(config[:root_path], File.basename(config[:playbook])).to_s
644
- end
645
-
646
- def hosts
647
- config[:hosts]
648
- end
649
-
650
- def roles
651
- config[:roles_path]
652
- end
653
-
654
- def role_name
655
- if config[:role_name]
656
- config[:role_name]
657
- elsif File.basename(roles) == 'roles'
658
- ''
659
- else
660
- File.basename(roles)
661
- end
662
- end
663
-
664
- def modules
665
- config[:modules_path]
666
- end
667
-
668
- def spec
669
- 'spec'
670
- end
671
-
672
- def group_vars
673
- config[:group_vars_path].to_s
674
- end
675
-
676
- def additional_copy
677
- config[:additional_copy_path]
678
- end
679
-
680
- def ansible_cfg_path
681
- config[:ansible_cfg_path]
682
- end
683
-
684
- def recursive_additional_copy
685
- config[:recursive_additional_copy_path]
686
- end
687
-
688
- def host_vars
689
- config[:host_vars_path].to_s
690
- end
691
-
692
- def library_plugins
693
- config[:library_plugins_path].to_s
694
- end
695
-
696
- def callback_plugins
697
- config[:callback_plugins_path].to_s
698
- end
699
-
700
- def filter_plugins
701
- config[:filter_plugins_path].to_s
702
- end
703
-
704
- def lookup_plugins
705
- config[:lookup_plugins_path].to_s
706
- end
707
-
708
- def ansible_vault_password_file
709
- password_files = []
710
- if config[:ansible_vault_password_file]
711
- password_files = config[:ansible_vault_password_file].is_a?(Array) ? config[:ansible_vault_password_file] : [config[:ansible_vault_password_file]]
712
- end
713
- password_files.map(&:to_s)
714
- end
715
-
716
- def ansible_inventory
717
- return nil if config[:ansible_inventory] == 'none'
718
- config[:ansible_inventory] = config[:ansible_inventory_file] if config[:ansible_inventory].nil?
719
- info('ansible_inventory_file parameter deprecated use ansible_inventory') if config[:ansible_inventory_file]
720
- config[:ansible_inventory]
721
- end
722
-
723
- def ansible_debian_version
724
- if @config[:ansible_version] == 'latest' || @config[:ansible_version] == nil
725
- ''
726
- else
727
- "=#{@config[:ansible_version]}"
728
- end
729
- end
730
-
731
- def ansible_connection_flag
732
- "-c #{config[:ansible_connection]}" if config[:ansible_connection] != 'none'
733
- end
734
-
735
- def ansible_verbose_flag
736
- config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
737
- end
738
-
739
- def ansible_check_flag
740
- config[:ansible_check] ? '--check' : nil
741
- end
742
-
743
- def ansible_diff_flag
744
- config[:ansible_diff] ? '--diff' : nil
745
- end
746
-
747
- def ansible_vault_flag
748
- debug(config[:ansible_vault_password_file])
749
- return nil if not ansible_vault_password_file
750
-
751
- files = []
752
-
753
- ansible_vault_password_file.each do |f|
754
- files << "--vault-password-file=#{File.join(config[:root_path], File.basename(f).reverse.chomp('.').reverse)}"
755
- end
756
-
757
- files.join(' ')
758
- end
759
-
760
- def ansible_inventory_flag
761
- return nil if config[:ansible_inventory] == 'none'
762
- ansible_inventory ? "-i #{File.join(config[:root_path], File.basename(ansible_inventory))}" : "-i #{File.join(config[:root_path], 'hosts')}"
763
- end
764
-
765
- def ansible_limit_flag
766
- config[:ansible_limit] ? "-l #{config[:ansible_limit]}" : ""
767
- end
768
-
769
- def ansible_extra_flags
770
- config[:ansible_extra_flags] || ''
771
- end
772
-
773
- def ansible_platform
774
- config[:ansible_platform].to_s.downcase
775
- end
776
-
777
- def ansible_host_key_checking
778
- config[:ansible_host_key_checking]
779
- end
780
-
781
- def private_key
782
- if config[:private_key]
783
- "--private-key #{private_key_file}"
784
- end
785
- end
786
-
787
- def copy_private_key_cmd
788
- if !config[:private_key].start_with?('/') && !config[:private_key].start_with?('~')
789
- ssh_private_key = File.join('~/.ssh', File.basename(config[:private_key]))
790
- tmp_private_key = File.join(config[:root_path], config[:private_key])
791
- "rm -rf #{ssh_private_key}; cp #{tmp_private_key} #{ssh_private_key}; chmod 400 #{ssh_private_key};"
792
- end
793
- end
794
-
795
- def private_key_file
796
- if config[:private_key].start_with?('/') || config[:private_key].start_with?('~')
797
- "#{config[:private_key]}"
798
- elsif config[:private_key]
799
- "#{File.join('~/.ssh', File.basename(config[:private_key]))}"
800
- end
801
- end
802
-
803
- def update_packages_debian_cmd
804
- Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).update_packages_command
805
- end
806
-
807
- def update_packages_suse_cmd
808
- Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).update_packages_command
809
- end
810
-
811
- def update_packages_redhat_cmd
812
- Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).update_packages_command
813
- end
814
-
815
- def update_packages_alpine_cmd
816
- Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).update_packages_command
817
- end
818
-
819
- def python_sles_repo
820
- config[:python_sles_repo]
821
- end
822
-
823
- def extra_vars
824
- bash_vars = config[:extra_vars]
825
- if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
826
- bash_vars = config[:attributes][:extra_vars]
827
- end
828
-
829
- return nil if bash_vars.none?
830
- bash_vars = JSON.dump(bash_vars)
831
- bash_vars = "-e '#{bash_vars}'"
832
- debug(bash_vars)
833
- bash_vars
834
- end
835
-
836
- def extra_vars_file
837
- return nil if config[:extra_vars_file].nil?
838
- bash_extra_vars = "-e '\@#{config[:extra_vars_file]}'"
839
- debug(bash_extra_vars)
840
- bash_extra_vars
841
- end
842
-
843
- def tags(idempotence = false)
844
- bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
845
- bash_skip_tags = []
846
- if idempotence and config[:idempotency_test]
847
- bash_tags += config[:idempotency_tags]
848
- bash_skip_tags += config[:idempotency_skip_tags]
849
- end
850
- return nil if (bash_tags.empty? and bash_skip_tags.empty?)
851
-
852
- result = ''
853
- if not bash_tags.empty?
854
- result += " --tags=#{bash_tags.join(',')}"
855
- end
856
- if not bash_skip_tags.empty?
857
- result += " --skip-tags=#{bash_skip_tags.join(',')}"
858
- end
859
- debug(result)
860
- result
861
- end
862
-
863
- def chef_url
864
- config[:chef_bootstrap_url]
865
- end
866
-
867
- def require_ruby_for_busser
868
- config[:require_ruby_for_busser]
869
- end
870
-
871
- def require_chef_for_busser
872
- config[:require_chef_for_busser]
873
- end
874
-
875
- def require_windows_support
876
- config[:require_windows_support]
877
- end
878
-
879
- def kerberos_conf_file
880
- config[:kerberos_conf_file]
881
- end
882
-
883
- def install_source_rev
884
- config[:ansible_source_rev] ? "--branch #{config[:ansible_source_rev]}" : nil
885
- end
886
-
887
- def http_proxy
888
- config[:http_proxy]
889
- end
890
-
891
- def https_proxy
892
- config[:https_proxy]
893
- end
894
-
895
- def no_proxy
896
- config[:no_proxy]
897
- end
898
-
899
- def sudo_env(pm,home=false)
900
- s = https_proxy ? "https_proxy=#{https_proxy}" : nil
901
- p = http_proxy ? "http_proxy=#{http_proxy}" : nil
902
- n = no_proxy ? "no_proxy=#{no_proxy}" : nil
903
- if home
904
- p || s || n ? "#{sudo_home('env')} #{p} #{s} #{n} #{pm}" : "#{sudo_home(pm)}"
905
- else
906
- p || s || n ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
907
- end
908
- end
909
-
910
- def export_http_proxy
911
- cmd = ''
912
- cmd = " HTTP_PROXY=#{http_proxy}" if http_proxy
913
- cmd = "#{cmd} HTTPS_PROXY=#{https_proxy}" if https_proxy
914
- cmd = "#{cmd} NO_PROXY=#{no_proxy}" if no_proxy
915
- cmd = "export #{cmd}" if cmd != ''
916
- cmd
917
- end
918
-
919
- def ansible_roles_path
920
- roles_paths = []
921
- roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
922
- if config[:additional_copy_role_path]
923
- if config[:additional_copy_role_path].is_a? String
924
- roles_paths << File.join(config[:root_path], File.basename(config[:additional_copy_role_path]))
925
- else
926
- config[:additional_copy_role_path].each do |path|
927
- roles_paths << File.join(config[:root_path], File.basename(File.expand_path(path)))
928
- end
929
- end
930
- end
931
- if roles_paths.empty?
932
- info('No roles have been set.')
933
- nil
934
- else
935
- debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
936
- roles_paths.join(':')
937
- end
938
- end
939
-
940
- def prepare_roles
941
- info('Preparing roles')
942
- debug("Using roles from #{File.expand_path(roles)}")
943
-
944
- resolve_with_librarian if File.exist?(ansiblefile)
945
-
946
- if galaxy_requirements
947
- dest = File.join(sandbox_path, galaxy_requirements)
948
- FileUtils.mkdir_p(File.dirname(dest))
949
- FileUtils.cp(File.expand_path(galaxy_requirements), dest)
950
- end
951
-
952
- if config[:additional_copy_role_path]
953
- if config[:additional_copy_role_path].is_a? String
954
- debug("Using additional roles copy from #{File.expand_path(config[:additional_copy_role_path])}")
955
- dest = File.join(sandbox_path, File.basename(File.expand_path(config[:additional_copy_role_path])))
956
- FileUtils.mkdir_p(File.dirname(dest))
957
- FileUtils.cp_r(File.expand_path(config[:additional_copy_role_path]), dest)
958
- else
959
- config[:additional_copy_role_path].each do |path|
960
- dest = File.join(sandbox_path, File.basename(File.expand_path(path)))
961
- FileUtils.mkdir_p(File.dirname(dest))
962
- FileUtils.cp_r(File.expand_path(path), dest)
963
- end
964
- end
965
- end
966
-
967
- FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
968
- Find.find(roles) do |source|
969
- # Detect whether we are running tests on a role
970
- # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
971
- role_path = source.sub(/#{roles}|\/roles/, '')
972
- unless roles =~ /\/roles$/
973
- role_path = "#{role_name}/#{role_path}"
974
- end
975
- target = File.join(tmp_roles_dir, role_path)
976
-
977
- Find.prune if config[:ignore_paths_from_root].include? File.basename(source)
978
- Find.prune if config[:ignore_extensions_from_root].include? File.extname(source)
979
- if File.directory?(source)
980
- FileUtils.mkdir_p(target)
981
- else
982
- FileUtils.cp(source, target)
983
- end
984
- end
985
- end
986
-
987
- # copy ansible.cfg if found
988
- def prepare_ansible_cfg
989
- info('Preparing ansible.cfg file')
990
- ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
991
- if !ansible_cfg_path.nil? && File.exist?(ansible_cfg_path) && !config[:ignore_ansible_cfg]
992
- info('Found existing ansible.cfg')
993
- FileUtils.cp_r(ansible_cfg_path, ansible_config_file)
994
- else
995
- info('Empty ansible.cfg generated')
996
- File.open(ansible_config_file, 'wb') do |file|
997
- file.write("#no config parameters\n")
998
- end
999
- end
1000
- end
1001
-
1002
- def prepare_inventory
1003
- info('Preparing inventory')
1004
- return unless ansible_inventory
1005
- if File.directory?(ansible_inventory)
1006
- debug("Copying inventory directory from #{ansible_inventory} to #{tmp_inventory_path}")
1007
- FileUtils.cp_r(ansible_inventory, sandbox_path)
1008
- else
1009
- debug("Copying inventory file from #{ansible_inventory} to #{tmp_inventory_path}")
1010
- FileUtils.cp_r(ansible_inventory, tmp_inventory_path)
1011
- end
1012
- end
1013
-
1014
- # localhost ansible_connection=local
1015
- # [example_servers]
1016
- # localhost
1017
- def prepare_hosts
1018
- return if ansible_inventory
1019
- info('Preparing hosts file')
1020
-
1021
- if config[:hosts].nil?
1022
- fail 'No hosts have been set. Please specify one in .kitchen.yml'
1023
- elsif config[:hosts].is_a?(Array)
1024
- debug("Using an array of hosts from #{hosts}")
1025
- File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1026
- hoststring="localhost ansible_connection=local\n"
1027
- config[:hosts].each do |h|
1028
- hoststring+="[#{h}]\nlocalhost\n\n"
1029
- end
1030
- file.write(hoststring)
1031
- end
1032
- else
1033
- debug("Using host from #{hosts}")
1034
- File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1035
- file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
1036
- end
1037
- end
1038
- end
1039
-
1040
- def prepare_playbook
1041
- info('Preparing playbook')
1042
- debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
1043
- FileUtils.mkdir_p(File.dirname(tmp_playbook_path)) if config[:keep_playbook_path]
1044
- FileUtils.cp_r(playbook, tmp_playbook_path)
1045
- end
1046
-
1047
- def prepare_group_vars
1048
- info('Preparing group_vars')
1049
- tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
1050
- FileUtils.mkdir_p(tmp_group_vars_dir)
1051
-
1052
- unless File.directory?(group_vars)
1053
- info('nothing to do for group_vars')
1054
- return
1055
- end
1056
-
1057
- debug("Using group_vars from #{group_vars}")
1058
- FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
1059
- end
1060
-
1061
- def prepare_additional_copy_path
1062
- info('Preparing additional_copy_path')
1063
- additional_files.each do |file|
1064
- info("Copy additional path: #{file}")
1065
- destination = File.join(sandbox_path, File.basename(File.expand_path(file)))
1066
- if File.directory?(File.expand_path(file)) && File.basename(File.expand_path(file))!= ?.
1067
- debug("Copy dir: #{File.expand_path(file)} #{destination}")
1068
- FileUtils.cp_r(File.expand_path(file), destination)
1069
- else
1070
- debug("Copy file: #{file} #{destination}")
1071
- FileUtils.cp(file, destination)
1072
- end
1073
- end
1074
- recursive_additional_files.each do |file|
1075
- info("Copy recursive additional path: #{file}")
1076
- Find.find(file) do |files|
1077
- destination = File.join(sandbox_path, files)
1078
- Find.prune if config[:ignore_paths_from_root].include? File.basename(files)
1079
- Find.prune if "?.".include? File.basename(files)
1080
- Find.prune if config[:ignore_extensions_from_root].include? File.extname(files)
1081
- debug File.basename(files)
1082
- if File.directory?(files)
1083
- FileUtils.mkdir_p(destination)
1084
- else
1085
- FileUtils.cp(files, destination)
1086
- end
1087
- end
1088
- end
1089
- end
1090
-
1091
- def additional_files
1092
- additional_files = []
1093
- if additional_copy
1094
- additional_files = additional_copy.is_a?(Array) ? additional_copy : [additional_copy]
1095
- end
1096
- additional_files.map(&:to_s)
1097
- end
1098
-
1099
- def recursive_additional_files
1100
- recursive_additional_files = []
1101
- if recursive_additional_copy
1102
- recursive_additional_files = recursive_additional_copy.is_a?(Array) ? recursive_additional_copy : [recursive_additional_copy]
1103
- end
1104
- recursive_additional_files.map(&:to_s)
1105
- end
1106
-
1107
- def prepare_host_vars
1108
- info('Preparing host_vars')
1109
- FileUtils.mkdir_p(tmp_host_vars_dir)
1110
-
1111
- unless File.directory?(host_vars)
1112
- info 'nothing to do for host_vars'
1113
- return
1114
- end
1115
-
1116
- debug("Using host_vars from #{host_vars}")
1117
- FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
1118
- end
1119
-
1120
- def prepare_modules
1121
- info('Preparing modules')
1122
-
1123
- FileUtils.mkdir_p(tmp_modules_dir)
1124
-
1125
- if modules && File.directory?(modules)
1126
- debug("Using modules from #{modules}")
1127
- FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
1128
- else
1129
- info 'nothing to do for modules'
1130
- end
1131
- end
1132
-
1133
- def prepare_spec
1134
- info('Preparing spec')
1135
-
1136
- FileUtils.mkdir_p(tmp_spec_dir)
1137
-
1138
- if spec && File.directory?(spec)
1139
- debug("Using spec from #{spec}")
1140
- FileUtils.cp_r(Dir.glob("#{spec}/*"), tmp_spec_dir, remove_destination: true)
1141
- else
1142
- info 'nothing to do for spec'
1143
- end
1144
- end
1145
-
1146
- def prepare_library_plugins
1147
- info('Preparing library plugins')
1148
- FileUtils.mkdir_p(tmp_library_plugins_dir)
1149
-
1150
- if library_plugins && File.directory?(library_plugins)
1151
- debug("Using library plugins from #{library_plugins}")
1152
- FileUtils.cp_r(Dir.glob("#{library_plugins}/{*,!*.pyc}"), tmp_library_plugins_dir, remove_destination: true)
1153
- else
1154
- info 'nothing to do for library plugins'
1155
- end
1156
- end
1157
-
1158
- def prepare_callback_plugins
1159
- info('Preparing callback plugins')
1160
- FileUtils.mkdir_p(tmp_callback_plugins_dir)
1161
-
1162
- if callback_plugins && File.directory?(callback_plugins)
1163
- debug("Using callback plugins from #{callback_plugins}")
1164
- FileUtils.cp_r(Dir.glob("#{callback_plugins}/{*,!*.pyc}"), tmp_callback_plugins_dir, remove_destination: true)
1165
- else
1166
- info 'nothing to do for callback plugins'
1167
- end
1168
- end
1169
-
1170
- def prepare_filter_plugins
1171
- info('Preparing filter_plugins')
1172
- FileUtils.mkdir_p(tmp_filter_plugins_dir)
1173
-
1174
- if filter_plugins && File.directory?(filter_plugins)
1175
- debug("Using filter_plugins from #{filter_plugins}")
1176
- FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
1177
- else
1178
- info 'nothing to do for filter_plugins'
1179
- end
1180
- end
1181
-
1182
- def prepare_lookup_plugins
1183
- info('Preparing lookup_plugins')
1184
- FileUtils.mkdir_p(tmp_lookup_plugins_dir)
1185
-
1186
- if lookup_plugins && File.directory?(lookup_plugins)
1187
- debug("Using lookup_plugins from #{lookup_plugins}")
1188
- FileUtils.cp_r(Dir.glob("#{lookup_plugins}/*.py"), tmp_lookup_plugins_dir, remove_destination: true)
1189
- else
1190
- info 'nothing to do for lookup_plugins'
1191
- end
1192
- end
1193
-
1194
- def prepare_additional_ssh_private_keys
1195
- info('Preparing additional_ssh_private_keys')
1196
- FileUtils.mkdir_p(tmp_additional_ssh_private_keys_dir)
1197
- if config[:additional_ssh_private_keys]
1198
- config[:additional_ssh_private_keys].each do |key|
1199
- debug("Adding additional_ssh_private_key file #{key}")
1200
- FileUtils.cp_r(File.expand_path(key), tmp_additional_ssh_private_keys_dir, remove_destination: true)
1201
- end
1202
- else
1203
- info 'nothing to do for additional_ssh_private_keys'
1204
- end
1205
- end
1206
-
1207
- def prepare_ansible_vault_password_file
1208
- return unless ansible_vault_password_file
1209
-
1210
- info('Preparing ansible vault password')
1211
- ansible_vault_password_file.each do |f|
1212
- debug("Copying ansible vault password file from #{f} to #{tmp_ansible_vault_password_file_path(f)}")
1213
-
1214
- FileUtils.cp(File.expand_path(f), tmp_ansible_vault_password_file_path(f))
1215
- end
1216
- end
1217
-
1218
- def prepare_kerberos_conf_file
1219
- return unless kerberos_conf_file
1220
-
1221
- info('Preparing kerberos configuration file')
1222
- debug("Copying kerberos configuration file from #{kerberos_conf_file} to #{tmp_kerberos_conf_file_path}")
1223
-
1224
- FileUtils.cp(File.expand_path(kerberos_conf_file), tmp_kerberos_conf_file_path)
1225
- end
1226
-
1227
- def resolve_with_librarian
1228
- Kitchen.mutex.synchronize do
1229
- Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
1230
- end
1231
- end
1232
-
1233
- def galaxy_cert_ignore
1234
- config[:galaxy_ignore_certs] ? '--ignore-certs' : nil
1235
- end
1236
-
1237
- end
1238
- end
1239
- 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
+ playbook_remote_path
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
+ return File.join(sandbox_path, playbook).to_s if config[:keep_playbook_path]
577
+ File.join(sandbox_path, File.basename(playbook)).to_s
578
+ end
579
+
580
+ def tmp_host_vars_dir
581
+ File.join(sandbox_path, 'host_vars')
582
+ end
583
+
584
+ def tmp_roles_dir
585
+ File.join(sandbox_path, 'roles')
586
+ end
587
+
588
+ def tmp_spec_dir
589
+ File.join(sandbox_path, 'spec')
590
+ end
591
+
592
+ def tmp_library_plugins_dir
593
+ File.join(sandbox_path, 'library')
594
+ end
595
+
596
+ def tmp_callback_plugins_dir
597
+ File.join(sandbox_path, 'callback_plugins')
598
+ end
599
+
600
+ def tmp_filter_plugins_dir
601
+ File.join(sandbox_path, 'filter_plugins')
602
+ end
603
+
604
+ def tmp_lookup_plugins_dir
605
+ File.join(sandbox_path, 'lookup_plugins')
606
+ end
607
+
608
+ def tmp_additional_ssh_private_keys_dir
609
+ File.join(sandbox_path, 'ssh_private_keys')
610
+ end
611
+
612
+ def tmp_ansible_vault_password_file_path(f)
613
+ File.join(sandbox_path, File.basename(f).reverse.chomp('.').reverse)
614
+ end
615
+
616
+ def tmp_kerberos_conf_file_path
617
+ File.join(sandbox_path, 'krb5.conf')
618
+ end
619
+
620
+ def tmp_inventory_path
621
+ File.join(sandbox_path, File.basename(ansible_inventory))
622
+ end
623
+
624
+ def ansiblefile
625
+ config[:ansiblefile_path] || ''
626
+ end
627
+
628
+ def galaxy_requirements
629
+ config[:requirements_path] || nil
630
+ end
631
+
632
+ def env_vars
633
+ return nil if config[:env_vars].none?
634
+ config[:env_vars].map { |k, v| "#{k}=#{v}" }.join(' ')
635
+ end
636
+
637
+ def playbook
638
+ config[:playbook]
639
+ end
640
+
641
+ def playbook_remote_path
642
+ return File.join(config[:root_path], config[:playbook]).to_s if config[:keep_playbook_path]
643
+ File.join(config[:root_path], File.basename(config[:playbook])).to_s
644
+ end
645
+
646
+ def hosts
647
+ config[:hosts]
648
+ end
649
+
650
+ def roles
651
+ config[:roles_path]
652
+ end
653
+
654
+ def role_name
655
+ if config[:role_name]
656
+ config[:role_name]
657
+ elsif File.basename(roles) == 'roles'
658
+ ''
659
+ else
660
+ File.basename(roles)
661
+ end
662
+ end
663
+
664
+ def modules
665
+ config[:modules_path]
666
+ end
667
+
668
+ def spec
669
+ 'spec'
670
+ end
671
+
672
+ def group_vars
673
+ config[:group_vars_path].to_s
674
+ end
675
+
676
+ def additional_copy
677
+ config[:additional_copy_path]
678
+ end
679
+
680
+ def ansible_cfg_path
681
+ config[:ansible_cfg_path]
682
+ end
683
+
684
+ def recursive_additional_copy
685
+ config[:recursive_additional_copy_path]
686
+ end
687
+
688
+ def host_vars
689
+ config[:host_vars_path].to_s
690
+ end
691
+
692
+ def library_plugins
693
+ config[:library_plugins_path].to_s
694
+ end
695
+
696
+ def callback_plugins
697
+ config[:callback_plugins_path].to_s
698
+ end
699
+
700
+ def filter_plugins
701
+ config[:filter_plugins_path].to_s
702
+ end
703
+
704
+ def lookup_plugins
705
+ config[:lookup_plugins_path].to_s
706
+ end
707
+
708
+ def ansible_vault_password_file
709
+ password_files = []
710
+ if config[:ansible_vault_password_file]
711
+ password_files = config[:ansible_vault_password_file].is_a?(Array) ? config[:ansible_vault_password_file] : [config[:ansible_vault_password_file]]
712
+ end
713
+ password_files.map(&:to_s)
714
+ end
715
+
716
+ def ansible_inventory
717
+ return nil if config[:ansible_inventory] == 'none'
718
+ config[:ansible_inventory] = config[:ansible_inventory_file] if config[:ansible_inventory].nil?
719
+ info('ansible_inventory_file parameter deprecated use ansible_inventory') if config[:ansible_inventory_file]
720
+ config[:ansible_inventory]
721
+ end
722
+
723
+ def ansible_debian_version
724
+ if @config[:ansible_version] == 'latest' || @config[:ansible_version] == nil
725
+ ''
726
+ else
727
+ "=#{@config[:ansible_version]}"
728
+ end
729
+ end
730
+
731
+ def ansible_connection_flag
732
+ "-c #{config[:ansible_connection]}" if config[:ansible_connection] != 'none'
733
+ end
734
+
735
+ def ansible_verbose_flag
736
+ config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
737
+ end
738
+
739
+ def ansible_check_flag
740
+ config[:ansible_check] ? '--check' : nil
741
+ end
742
+
743
+ def ansible_diff_flag
744
+ config[:ansible_diff] ? '--diff' : nil
745
+ end
746
+
747
+ def ansible_vault_flag
748
+ debug(config[:ansible_vault_password_file])
749
+ return nil if not ansible_vault_password_file
750
+
751
+ files = []
752
+
753
+ ansible_vault_password_file.each do |f|
754
+ files << "--vault-password-file=#{File.join(config[:root_path], File.basename(f).reverse.chomp('.').reverse)}"
755
+ end
756
+
757
+ files.join(' ')
758
+ end
759
+
760
+ def ansible_inventory_flag
761
+ return nil if config[:ansible_inventory] == 'none'
762
+ ansible_inventory ? "-i #{File.join(config[:root_path], File.basename(ansible_inventory))}" : "-i #{File.join(config[:root_path], 'hosts')}"
763
+ end
764
+
765
+ def ansible_limit_flag
766
+ config[:ansible_limit] ? "-l #{config[:ansible_limit]}" : ""
767
+ end
768
+
769
+ def ansible_extra_flags
770
+ config[:ansible_extra_flags] || ''
771
+ end
772
+
773
+ def ansible_platform
774
+ config[:ansible_platform].to_s.downcase
775
+ end
776
+
777
+ def ansible_host_key_checking
778
+ config[:ansible_host_key_checking]
779
+ end
780
+
781
+ def private_key
782
+ if config[:private_key]
783
+ "--private-key #{private_key_file}"
784
+ end
785
+ end
786
+
787
+ def copy_private_key_cmd
788
+ if !config[:private_key].start_with?('/') && !config[:private_key].start_with?('~')
789
+ ssh_private_key = File.join('~/.ssh', File.basename(config[:private_key]))
790
+ tmp_private_key = File.join(config[:root_path], config[:private_key])
791
+ "rm -rf #{ssh_private_key}; cp #{tmp_private_key} #{ssh_private_key}; chmod 400 #{ssh_private_key};"
792
+ end
793
+ end
794
+
795
+ def private_key_file
796
+ if config[:private_key].start_with?('/') || config[:private_key].start_with?('~')
797
+ "#{config[:private_key]}"
798
+ elsif config[:private_key]
799
+ "#{File.join('~/.ssh', File.basename(config[:private_key]))}"
800
+ end
801
+ end
802
+
803
+ def update_packages_debian_cmd
804
+ Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).update_packages_command
805
+ end
806
+
807
+ def update_packages_suse_cmd
808
+ Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).update_packages_command
809
+ end
810
+
811
+ def update_packages_redhat_cmd
812
+ Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).update_packages_command
813
+ end
814
+
815
+ def update_packages_alpine_cmd
816
+ Kitchen::Provisioner::Ansible::Os::Alpine.new('alpine', config).update_packages_command
817
+ end
818
+
819
+ def python_sles_repo
820
+ config[:python_sles_repo]
821
+ end
822
+
823
+ def extra_vars
824
+ bash_vars = config[:extra_vars]
825
+ if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
826
+ bash_vars = config[:attributes][:extra_vars]
827
+ end
828
+
829
+ return nil if bash_vars.none?
830
+ bash_vars = JSON.dump(bash_vars)
831
+ bash_vars = "-e '#{bash_vars}'"
832
+ debug(bash_vars)
833
+ bash_vars
834
+ end
835
+
836
+ def extra_vars_file
837
+ return nil if config[:extra_vars_file].nil?
838
+ bash_extra_vars = "-e '\@#{config[:extra_vars_file]}'"
839
+ debug(bash_extra_vars)
840
+ bash_extra_vars
841
+ end
842
+
843
+ def tags(idempotence = false)
844
+ bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
845
+ bash_skip_tags = []
846
+ if idempotence and config[:idempotency_test]
847
+ bash_tags += config[:idempotency_tags]
848
+ bash_skip_tags += config[:idempotency_skip_tags]
849
+ end
850
+ return nil if (bash_tags.empty? and bash_skip_tags.empty?)
851
+
852
+ result = ''
853
+ if not bash_tags.empty?
854
+ result += " --tags=#{bash_tags.join(',')}"
855
+ end
856
+ if not bash_skip_tags.empty?
857
+ result += " --skip-tags=#{bash_skip_tags.join(',')}"
858
+ end
859
+ debug(result)
860
+ result
861
+ end
862
+
863
+ def chef_url
864
+ config[:chef_bootstrap_url]
865
+ end
866
+
867
+ def require_ruby_for_busser
868
+ config[:require_ruby_for_busser]
869
+ end
870
+
871
+ def require_chef_for_busser
872
+ config[:require_chef_for_busser]
873
+ end
874
+
875
+ def require_windows_support
876
+ config[:require_windows_support]
877
+ end
878
+
879
+ def kerberos_conf_file
880
+ config[:kerberos_conf_file]
881
+ end
882
+
883
+ def install_source_rev
884
+ config[:ansible_source_rev] ? "--branch #{config[:ansible_source_rev]}" : nil
885
+ end
886
+
887
+ def http_proxy
888
+ config[:http_proxy]
889
+ end
890
+
891
+ def https_proxy
892
+ config[:https_proxy]
893
+ end
894
+
895
+ def no_proxy
896
+ config[:no_proxy]
897
+ end
898
+
899
+ def sudo_env(pm,home=false)
900
+ s = https_proxy ? "https_proxy=#{https_proxy}" : nil
901
+ p = http_proxy ? "http_proxy=#{http_proxy}" : nil
902
+ n = no_proxy ? "no_proxy=#{no_proxy}" : nil
903
+ if home
904
+ p || s || n ? "#{sudo_home('env')} #{p} #{s} #{n} #{pm}" : "#{sudo_home(pm)}"
905
+ else
906
+ p || s || n ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
907
+ end
908
+ end
909
+
910
+ def export_http_proxy
911
+ cmd = ''
912
+ cmd = " HTTP_PROXY=#{http_proxy}" if http_proxy
913
+ cmd = "#{cmd} HTTPS_PROXY=#{https_proxy}" if https_proxy
914
+ cmd = "#{cmd} NO_PROXY=#{no_proxy}" if no_proxy
915
+ cmd = "export #{cmd}" if cmd != ''
916
+ cmd
917
+ end
918
+
919
+ def ansible_roles_path
920
+ roles_paths = []
921
+ roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
922
+ if config[:additional_copy_role_path]
923
+ if config[:additional_copy_role_path].is_a? String
924
+ roles_paths << File.join(config[:root_path], File.basename(config[:additional_copy_role_path]))
925
+ else
926
+ config[:additional_copy_role_path].each do |path|
927
+ roles_paths << File.join(config[:root_path], File.basename(File.expand_path(path)))
928
+ end
929
+ end
930
+ end
931
+ if roles_paths.empty?
932
+ info('No roles have been set.')
933
+ nil
934
+ else
935
+ debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
936
+ roles_paths.join(':')
937
+ end
938
+ end
939
+
940
+ def prepare_roles
941
+ info('Preparing roles')
942
+ debug("Using roles from #{File.expand_path(roles)}")
943
+
944
+ resolve_with_librarian if File.exist?(ansiblefile)
945
+
946
+ if galaxy_requirements
947
+ dest = File.join(sandbox_path, galaxy_requirements)
948
+ FileUtils.mkdir_p(File.dirname(dest))
949
+ FileUtils.cp(File.expand_path(galaxy_requirements), dest)
950
+ end
951
+
952
+ if config[:additional_copy_role_path]
953
+ if config[:additional_copy_role_path].is_a? String
954
+ debug("Using additional roles copy from #{File.expand_path(config[:additional_copy_role_path])}")
955
+ dest = File.join(sandbox_path, File.basename(File.expand_path(config[:additional_copy_role_path])))
956
+ FileUtils.mkdir_p(File.dirname(dest))
957
+ FileUtils.cp_r(File.expand_path(config[:additional_copy_role_path]), dest)
958
+ else
959
+ config[:additional_copy_role_path].each do |path|
960
+ dest = File.join(sandbox_path, File.basename(File.expand_path(path)))
961
+ FileUtils.mkdir_p(File.dirname(dest))
962
+ FileUtils.cp_r(File.expand_path(path), dest)
963
+ end
964
+ end
965
+ end
966
+
967
+ FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
968
+ Find.find(roles) do |source|
969
+ # Detect whether we are running tests on a role
970
+ # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
971
+ role_path = source.sub(/#{roles}|\/roles/, '')
972
+ unless roles =~ /\/roles$/
973
+ role_path = "#{role_name}/#{role_path}"
974
+ end
975
+ target = File.join(tmp_roles_dir, role_path)
976
+
977
+ Find.prune if config[:ignore_paths_from_root].include? File.basename(source)
978
+ Find.prune if config[:ignore_extensions_from_root].include? File.extname(source)
979
+ if File.directory?(source)
980
+ FileUtils.mkdir_p(target)
981
+ else
982
+ FileUtils.cp(source, target)
983
+ end
984
+ end
985
+ end
986
+
987
+ # copy ansible.cfg if found and ansible_cfg_overwrite is set to true
988
+ def prepare_ansible_cfg
989
+ info('Preparing ansible.cfg file')
990
+ ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
991
+ if !ansible_cfg_path.nil? && File.exist?(ansible_cfg_path) && !config[:ignore_ansible_cfg]
992
+ info('Found existing ansible.cfg')
993
+ FileUtils.cp_r(ansible_cfg_path, ansible_config_file)
994
+ elsif config[:ansible_cfg_overwrite]
995
+ info('Empty ansible.cfg generated')
996
+ File.open(ansible_config_file, 'wb') do |file|
997
+ file.write("#no config parameters\n")
998
+ end
999
+ end
1000
+ end
1001
+
1002
+ def prepare_inventory
1003
+ info('Preparing inventory')
1004
+ return unless ansible_inventory
1005
+ if File.directory?(ansible_inventory)
1006
+ debug("Copying inventory directory from #{ansible_inventory} to #{tmp_inventory_path}")
1007
+ FileUtils.cp_r(ansible_inventory, sandbox_path)
1008
+ else
1009
+ debug("Copying inventory file from #{ansible_inventory} to #{tmp_inventory_path}")
1010
+ FileUtils.cp_r(ansible_inventory, tmp_inventory_path)
1011
+ end
1012
+ end
1013
+
1014
+ # localhost ansible_connection=local
1015
+ # [example_servers]
1016
+ # localhost
1017
+ def prepare_hosts
1018
+ return if ansible_inventory
1019
+ info('Preparing hosts file')
1020
+
1021
+ if config[:hosts].nil?
1022
+ fail 'No hosts have been set. Please specify one in .kitchen.yml'
1023
+ elsif config[:hosts].is_a?(Array)
1024
+ debug("Using an array of hosts from #{hosts}")
1025
+ File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1026
+ hoststring="localhost ansible_connection=local\n"
1027
+ config[:hosts].each do |h|
1028
+ hoststring+="[#{h}]\nlocalhost\n\n"
1029
+ end
1030
+ file.write(hoststring)
1031
+ end
1032
+ else
1033
+ debug("Using host from #{hosts}")
1034
+ File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
1035
+ file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
1036
+ end
1037
+ end
1038
+ end
1039
+
1040
+ def prepare_playbook
1041
+ info('Preparing playbook')
1042
+ debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
1043
+ FileUtils.mkdir_p(File.dirname(tmp_playbook_path)) if config[:keep_playbook_path]
1044
+ FileUtils.cp_r(playbook, tmp_playbook_path)
1045
+ end
1046
+
1047
+ def prepare_group_vars
1048
+ info('Preparing group_vars')
1049
+ tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
1050
+ FileUtils.mkdir_p(tmp_group_vars_dir)
1051
+
1052
+ unless File.directory?(group_vars)
1053
+ info('nothing to do for group_vars')
1054
+ return
1055
+ end
1056
+
1057
+ debug("Using group_vars from #{group_vars}")
1058
+ FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
1059
+ end
1060
+
1061
+ def prepare_additional_copy_path
1062
+ info('Preparing additional_copy_path')
1063
+ additional_files.each do |file|
1064
+ info("Copy additional path: #{file}")
1065
+ destination = File.join(sandbox_path, File.basename(File.expand_path(file)))
1066
+ if File.directory?(File.expand_path(file)) && File.basename(File.expand_path(file))!= ?.
1067
+ debug("Copy dir: #{File.expand_path(file)} #{destination}")
1068
+ FileUtils.cp_r(File.expand_path(file), destination)
1069
+ else
1070
+ debug("Copy file: #{file} #{destination}")
1071
+ FileUtils.cp(file, destination)
1072
+ end
1073
+ end
1074
+ recursive_additional_files.each do |file|
1075
+ info("Copy recursive additional path: #{file}")
1076
+ Find.find(file) do |files|
1077
+ destination = File.join(sandbox_path, files)
1078
+ Find.prune if config[:ignore_paths_from_root].include? File.basename(files)
1079
+ Find.prune if "?.".include? File.basename(files)
1080
+ Find.prune if config[:ignore_extensions_from_root].include? File.extname(files)
1081
+ debug File.basename(files)
1082
+ if File.directory?(files)
1083
+ FileUtils.mkdir_p(destination)
1084
+ else
1085
+ FileUtils.cp(files, destination)
1086
+ end
1087
+ end
1088
+ end
1089
+ end
1090
+
1091
+ def additional_files
1092
+ additional_files = []
1093
+ if additional_copy
1094
+ additional_files = additional_copy.is_a?(Array) ? additional_copy : [additional_copy]
1095
+ end
1096
+ additional_files.map(&:to_s)
1097
+ end
1098
+
1099
+ def recursive_additional_files
1100
+ recursive_additional_files = []
1101
+ if recursive_additional_copy
1102
+ recursive_additional_files = recursive_additional_copy.is_a?(Array) ? recursive_additional_copy : [recursive_additional_copy]
1103
+ end
1104
+ recursive_additional_files.map(&:to_s)
1105
+ end
1106
+
1107
+ def prepare_host_vars
1108
+ info('Preparing host_vars')
1109
+ FileUtils.mkdir_p(tmp_host_vars_dir)
1110
+
1111
+ unless File.directory?(host_vars)
1112
+ info 'nothing to do for host_vars'
1113
+ return
1114
+ end
1115
+
1116
+ debug("Using host_vars from #{host_vars}")
1117
+ FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
1118
+ end
1119
+
1120
+ def prepare_modules
1121
+ info('Preparing modules')
1122
+
1123
+ FileUtils.mkdir_p(tmp_modules_dir)
1124
+
1125
+ if modules && File.directory?(modules)
1126
+ debug("Using modules from #{modules}")
1127
+ FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
1128
+ else
1129
+ info 'nothing to do for modules'
1130
+ end
1131
+ end
1132
+
1133
+ def prepare_spec
1134
+ info('Preparing spec')
1135
+
1136
+ FileUtils.mkdir_p(tmp_spec_dir)
1137
+
1138
+ if spec && File.directory?(spec)
1139
+ debug("Using spec from #{spec}")
1140
+ FileUtils.cp_r(Dir.glob("#{spec}/*"), tmp_spec_dir, remove_destination: true)
1141
+ else
1142
+ info 'nothing to do for spec'
1143
+ end
1144
+ end
1145
+
1146
+ def prepare_library_plugins
1147
+ info('Preparing library plugins')
1148
+ FileUtils.mkdir_p(tmp_library_plugins_dir)
1149
+
1150
+ if library_plugins && File.directory?(library_plugins)
1151
+ debug("Using library plugins from #{library_plugins}")
1152
+ FileUtils.cp_r(Dir.glob("#{library_plugins}/{*,!*.pyc}"), tmp_library_plugins_dir, remove_destination: true)
1153
+ else
1154
+ info 'nothing to do for library plugins'
1155
+ end
1156
+ end
1157
+
1158
+ def prepare_callback_plugins
1159
+ info('Preparing callback plugins')
1160
+ FileUtils.mkdir_p(tmp_callback_plugins_dir)
1161
+
1162
+ if callback_plugins && File.directory?(callback_plugins)
1163
+ debug("Using callback plugins from #{callback_plugins}")
1164
+ FileUtils.cp_r(Dir.glob("#{callback_plugins}/{*,!*.pyc}"), tmp_callback_plugins_dir, remove_destination: true)
1165
+ else
1166
+ info 'nothing to do for callback plugins'
1167
+ end
1168
+ end
1169
+
1170
+ def prepare_filter_plugins
1171
+ info('Preparing filter_plugins')
1172
+ FileUtils.mkdir_p(tmp_filter_plugins_dir)
1173
+
1174
+ if filter_plugins && File.directory?(filter_plugins)
1175
+ debug("Using filter_plugins from #{filter_plugins}")
1176
+ FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
1177
+ else
1178
+ info 'nothing to do for filter_plugins'
1179
+ end
1180
+ end
1181
+
1182
+ def prepare_lookup_plugins
1183
+ info('Preparing lookup_plugins')
1184
+ FileUtils.mkdir_p(tmp_lookup_plugins_dir)
1185
+
1186
+ if lookup_plugins && File.directory?(lookup_plugins)
1187
+ debug("Using lookup_plugins from #{lookup_plugins}")
1188
+ FileUtils.cp_r(Dir.glob("#{lookup_plugins}/*.py"), tmp_lookup_plugins_dir, remove_destination: true)
1189
+ else
1190
+ info 'nothing to do for lookup_plugins'
1191
+ end
1192
+ end
1193
+
1194
+ def prepare_additional_ssh_private_keys
1195
+ info('Preparing additional_ssh_private_keys')
1196
+ FileUtils.mkdir_p(tmp_additional_ssh_private_keys_dir)
1197
+ if config[:additional_ssh_private_keys]
1198
+ config[:additional_ssh_private_keys].each do |key|
1199
+ debug("Adding additional_ssh_private_key file #{key}")
1200
+ FileUtils.cp_r(File.expand_path(key), tmp_additional_ssh_private_keys_dir, remove_destination: true)
1201
+ end
1202
+ else
1203
+ info 'nothing to do for additional_ssh_private_keys'
1204
+ end
1205
+ end
1206
+
1207
+ def prepare_ansible_vault_password_file
1208
+ return unless ansible_vault_password_file
1209
+
1210
+ info('Preparing ansible vault password')
1211
+ ansible_vault_password_file.each do |f|
1212
+ debug("Copying ansible vault password file from #{f} to #{tmp_ansible_vault_password_file_path(f)}")
1213
+
1214
+ FileUtils.cp(File.expand_path(f), tmp_ansible_vault_password_file_path(f))
1215
+ end
1216
+ end
1217
+
1218
+ def prepare_kerberos_conf_file
1219
+ return unless kerberos_conf_file
1220
+
1221
+ info('Preparing kerberos configuration file')
1222
+ debug("Copying kerberos configuration file from #{kerberos_conf_file} to #{tmp_kerberos_conf_file_path}")
1223
+
1224
+ FileUtils.cp(File.expand_path(kerberos_conf_file), tmp_kerberos_conf_file_path)
1225
+ end
1226
+
1227
+ def resolve_with_librarian
1228
+ Kitchen.mutex.synchronize do
1229
+ Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
1230
+ end
1231
+ end
1232
+
1233
+ def galaxy_cert_ignore
1234
+ config[:galaxy_ignore_certs] ? '--ignore-certs' : nil
1235
+ end
1236
+
1237
+ end
1238
+ end
1239
+ end