kitchen-ansible 0.49.0 → 0.52.0

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