kitchen-ansible 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,695 +1,709 @@
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 'kitchen/provisioner/base'
25
- require 'kitchen/provisioner/ansible/config'
26
- require 'kitchen/provisioner/ansible/librarian'
27
-
28
- module Kitchen
29
-
30
- class Busser
31
-
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
- end
48
-
49
- def finalize_config!(instance)
50
- config.set_instance(instance)
51
- super(instance)
52
- end
53
-
54
- def verbosity_level(level = 1)
55
- level = level.to_sym if level.is_a? String
56
- log_levels = { :info => 1, :warn => 2, :debug => 3, :trace => 4 }
57
- if level.is_a? Symbol and log_levels.include? level
58
- # puts "Log Level is: #{log_levels[level]}"
59
- log_levels[level]
60
- elsif level.is_a? Integer and level > 0
61
- # puts "Log Level is: #{level}"
62
- level
63
- else
64
- raise 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
65
- end
66
- end
67
-
68
- def install_command
69
- if config[:require_ansible_omnibus]
70
- cmd = install_omnibus_command
71
- elsif config[:require_ansible_source]
72
- info("Installing ansible from source")
73
- cmd = install_ansible_from_source_command
74
- elsif config[:require_ansible_repo]
75
- case ansible_platform
76
- when "debian", "ubuntu"
77
- info("Installing ansible on #{ansible_platform}")
78
- cmd = install_debian_command
79
- when "redhat", "centos", "fedora"
80
- info("Installing ansible on #{ansible_platform}")
81
- cmd = install_redhat_command
82
- when "amazon"
83
- info("Installing ansible on #{ansible_platform}")
84
- cmd = install_amazon_linux_command
85
- else
86
- info("Installing ansible, will try to determine platform os")
87
- cmd = <<-INSTALL
88
- if [ ! $(which ansible) ]; then
89
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
90
- if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
91
- #{install_redhat_command}
92
- else
93
- #{install_amazon_linux_command}
94
- fi
95
- else
96
- #{install_debian_command}
97
- fi
98
- fi
99
- INSTALL
100
- end
101
- else
102
- return
103
- end
104
- cmd + install_busser_prereqs
105
- end
106
-
107
- def install_busser_prereqs
108
- install = ''
109
- install << <<-INSTALL
110
- #{Util.shell_helpers}
111
- # Fix for https://github.com/test-kitchen/busser/issues/12
112
- if [ -h /usr/bin/ruby ]; then
113
- L=$(readlink -f /usr/bin/ruby)
114
- #{sudo('rm')} /usr/bin/ruby
115
- #{sudo('ln')} -s $L /usr/bin/ruby
116
- fi
117
- INSTALL
118
-
119
- if require_ruby_for_busser
120
- install << <<-INSTALL
121
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
122
- if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
123
- rhelversion=$(cat /etc/redhat-release | grep 'release 6')
124
- # For CentOS6/RHEL6 install ruby from SCL
125
- if [ -n "$rhelversion" ]; then
126
- if [ ! -d "/opt/rh/ruby193" ]; then
127
- echo "-----> Installing ruby SCL in CentOS6/RHEL6 to install busser to run tests"
128
- #{sudo('yum')} install -y centos-release-SCL
129
- #{sudo('yum')} install -y ruby193
130
- #{sudo('yum')} install -y ruby193-ruby-devel
131
- echo "-----> Enabling ruby193"
132
- source /opt/rh/ruby193/enable
133
- echo "/opt/rh/ruby193/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
134
- #{sudo('ldconfig')}
135
- #{sudo('ln')} -s /opt/rh/ruby193/root/usr/bin/ruby /usr/bin/ruby
136
- #{sudo('ln')} -s /opt/rh/ruby193/root/usr/bin/gem /usr/bin/gem
137
- fi
138
- else
139
- if [ ! $(which ruby) ]; then
140
- #{update_packages_redhat_cmd}
141
- #{sudo('yum')} -y install ruby ruby-devel
142
- fi
143
- fi
144
- else
145
- #{update_packages_redhat_cmd}
146
- #{sudo('yum')} -y install ruby ruby-devel gcc
147
- fi
148
- else
149
- if [ ! $(which ruby) ]; then
150
- #{update_packages_debian_cmd}
151
- #{sudo('apt-get')} -y install ruby1.9.1 ruby1.9.1-dev
152
- fi
153
- fi
154
- INSTALL
155
-
156
- elsif require_chef_for_busser && chef_url then
157
- install << <<-INSTALL
158
- # install chef omnibus so that busser works as this is needed to run tests :(
159
- if [ ! -d "/opt/chef" ]
160
- then
161
- echo "-----> Installing Chef Omnibus to install busser to run tests"
162
- do_download #{chef_url} /tmp/install.sh
163
- #{sudo('sh')} /tmp/install.sh
164
- fi
165
- INSTALL
166
- end
167
-
168
- install
169
- end
170
-
171
- def init_command
172
- dirs = %w{modules roles group_vars host_vars}.
173
- map { |dir| File.join(config[:root_path], dir) }.join(" ")
174
- cmd = "#{sudo('rm')} -rf #{dirs};"
175
- cmd = cmd+" mkdir -p #{config[:root_path]}"
176
- debug(cmd)
177
- cmd
178
- end
179
-
180
- def create_sandbox
181
- super
182
- debug("Creating local sandbox in #{sandbox_path}")
183
-
184
- yield if block_given?
185
-
186
- prepare_playbook
187
- prepare_inventory_file
188
- prepare_modules
189
- prepare_roles
190
- prepare_ansible_cfg
191
- prepare_group_vars
192
- prepare_additional_copy_path
193
- prepare_host_vars
194
- prepare_hosts
195
- prepare_filter_plugins
196
- prepare_ansible_vault_password_file
197
- info('Finished Preparing files for transfer')
198
-
199
- end
200
-
201
- def cleanup_sandbox
202
- return if sandbox_path.nil?
203
- debug("Cleaning up local sandbox in #{sandbox_path}")
204
- FileUtils.rmtree(sandbox_path)
205
- end
206
-
207
- def prepare_command
208
- commands = []
209
-
210
- # Prevent failure when ansible package installation doesn't contain /etc/ansible
211
- commands << [
212
- sudo("bash -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
213
- ]
214
-
215
- commands << [
216
- sudo('cp'),File.join(config[:root_path], 'ansible.cfg'),'/etc/ansible',
217
- ].join(' ')
218
-
219
- commands << [
220
- sudo('cp -r'), File.join(config[:root_path],'group_vars'), '/etc/ansible/.',
221
- ].join(' ')
222
-
223
- commands << [
224
- sudo('cp -r'), File.join(config[:root_path],'host_vars'), '/etc/ansible/.',
225
- ].join(' ')
226
-
227
- if galaxy_requirements
228
- if config[:require_ansible_source]
229
- commands << setup_ansible_env_from_source
230
- end
231
- commands << [
232
- 'ansible-galaxy', 'install', '--force',
233
- '-p', File.join(config[:root_path], 'roles'),
234
- '-r', File.join(config[:root_path], galaxy_requirements),
235
- ].join(' ')
236
- end
237
-
238
- command = commands.join(' && ')
239
- debug(command)
240
- command
241
- end
242
-
243
- def run_command
244
- if config[:require_ansible_source]
245
- # this is an ugly hack to get around the fact that extra vars uses ' and "
246
- cmd = sudo("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 #{config[:root_path]}/ansible/bin/ansible-playbook")
247
- else
248
- cmd = sudo("ansible-playbook")
249
- end
250
- [
251
- cmd,
252
- ansible_inventory_flag,
253
- "-c #{config[:ansible_connection]}",
254
- "-M #{File.join(config[:root_path], 'modules')}",
255
- ansible_verbose_flag,
256
- ansible_check_flag,
257
- ansible_diff_flag,
258
- ansible_vault_flag,
259
- extra_vars,
260
- tags,
261
- "#{File.join(config[:root_path], File.basename(config[:playbook]))}",
262
- ].join(" ")
263
- end
264
-
265
- protected
266
-
267
- def load_needed_dependencies!
268
- if File.exists?(ansiblefile)
269
- debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
270
- Ansible::Librarian.load!(logger)
271
- end
272
- end
273
-
274
- def install_ansible_from_source_command
275
- <<-INSTALL
276
- if [ ! -d #{config[:root_path]}/ansible ]; then
277
- if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
278
- #{update_packages_redhat_cmd}
279
- #{sudo('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev
280
- else
281
- #{update_packages_debian_cmd}
282
- #{sudo('apt-get')} -y install git python python-setuptools build-essential python-dev
283
- fi
284
-
285
- git clone git://github.com/ansible/ansible.git --recursive #{config[:root_path]}/ansible
286
- #{sudo('easy_install')} pip
287
- #{sudo('pip')} install paramiko PyYAML Jinja2 httplib2
288
- fi
289
- INSTALL
290
- end
291
-
292
- def install_omnibus_command
293
- info("Installing ansible using ansible omnibus")
294
- version = if !config[:ansible_version].nil?
295
- "-v #{config[:ansible_version]}"
296
- else
297
- ""
298
- end
299
- <<-INSTALL
300
- #{Util.shell_helpers}
301
-
302
- if [ ! -d "#{config[:ansible_omnibus_remote_path]}" ]; then
303
- echo "-----> Installing Ansible Omnibus"
304
- do_download #{config[:ansible_omnibus_url]} /tmp/ansible_install.sh
305
- #{sudo('sh')} /tmp/ansible_install.sh #{version}
306
- fi
307
- INSTALL
308
- end
309
-
310
- def install_debian_command
311
- <<-INSTALL
312
- if [ ! $(which ansible) ]; then
313
- #{update_packages_debian_cmd}
314
-
315
- ## Install apt-utils to silence debconf warning: http://serverfault.com/q/358943/77156
316
- #{sudo('apt-get')} -y install apt-utils git
317
-
318
- ## Fix debconf tty warning messages
319
- export DEBIAN_FRONTEND=noninteractive
320
-
321
- ## 13.10, 14.04 include add-apt-repository in software-properties-common
322
- #{sudo('apt-get')} -y install software-properties-common
323
-
324
- ## 10.04, 12.04 include add-apt-repository in
325
- #{sudo('apt-get')} -y install python-software-properties
326
-
327
- ## 10.04 version of add-apt-repository doesn't accept --yes
328
- ## later versions require interaction from user, so we must specify --yes
329
- ## First try with -y flag, else if it fails, try without.
330
- ## "add-apt-repository: error: no such option: -y" is returned but is ok to ignore, we just retry
331
- #{sudo('add-apt-repository')} -y #{ansible_apt_repo} || #{sudo('add-apt-repository')} #{ansible_apt_repo}
332
- #{sudo('apt-get')} update
333
- #{sudo('apt-get')} -y install ansible
334
- fi
335
- INSTALL
336
- end
337
-
338
- def install_redhat_command
339
- <<-INSTALL
340
- if [ ! $(which ansible) ]; then
341
- #{sudo('rpm')} -ivh #{ansible_yum_repo}
342
- #{update_packages_redhat_cmd}
343
- #{sudo('yum')} -y install ansible#{ansible_redhat_version} libselinux-python git
344
- fi
345
- INSTALL
346
- end
347
-
348
- def install_amazon_linux_command
349
- <<-INSTALL
350
- if [ ! $(which ansible) ]; then
351
- #{sudo('yum-config-manager')} --enable epel/x86_64
352
- #{sudo('yum')} -y install ansible#{ansible_redhat_version} git
353
- #{sudo('alternatives')} --set python /usr/bin/python2.6
354
- #{sudo('yum')} clean all
355
- #{sudo('yum')} install yum-python26 -y
356
- fi
357
- INSTALL
358
- end
359
-
360
- def setup_ansible_env_from_source
361
- "cd #{config[:root_path]}/ansible && source hacking/env-setup && cd ../"
362
- end
363
-
364
- def tmp_modules_dir
365
- File.join(sandbox_path, 'modules')
366
- end
367
-
368
- def tmp_playbook_path
369
- File.join(sandbox_path, File.basename(playbook))
370
- end
371
-
372
- def tmp_host_vars_dir
373
- File.join(sandbox_path, 'host_vars')
374
- end
375
-
376
- def tmp_roles_dir
377
- File.join(sandbox_path, 'roles')
378
- end
379
-
380
- def tmp_filter_plugins_dir
381
- File.join(sandbox_path, 'filter_plugins')
382
- end
383
-
384
- def tmp_ansible_vault_password_file_path
385
- File.join(sandbox_path, File.basename(ansible_vault_password_file))
386
- end
387
-
388
- def tmp_inventory_file_path
389
- File.join(sandbox_path, File.basename(ansible_inventory_file))
390
- end
391
-
392
- def ansiblefile
393
- config[:ansiblefile_path] || ''
394
- end
395
-
396
- def galaxy_requirements
397
- config[:requirements_path] || nil
398
- end
399
-
400
- def playbook
401
- config[:playbook]
402
- end
403
-
404
- def hosts
405
- config[:hosts]
406
- end
407
-
408
- def roles
409
- config[:roles_path]
410
- end
411
-
412
- def role_name
413
- File.basename(roles) == 'roles' ? '' : File.basename(roles)
414
- end
415
-
416
- def modules
417
- config[:modules_path]
418
- end
419
-
420
- def group_vars
421
- config[:group_vars_path].to_s
422
- end
423
-
424
- def additional_copy
425
- config[:additional_copy_path]
426
- end
427
-
428
- def host_vars
429
- config[:host_vars_path].to_s
430
- end
431
-
432
- def filter_plugins
433
- config[:filter_plugins_path].to_s
434
- end
435
-
436
- def ansible_vault_password_file
437
- config[:ansible_vault_password_file]
438
- end
439
-
440
- def ansible_inventory_file
441
- config[:ansible_inventory_file]
442
- end
443
-
444
- def ansible_debian_version
445
- config[:ansible_version] ? "=#{config[:ansible_version]}" : nil
446
- end
447
-
448
- def ansible_redhat_version
449
- config[:ansible_version] ? "-#{config[:ansible_version]}" : nil
450
- end
451
-
452
- def ansible_verbose_flag
453
- config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
454
- end
455
-
456
- def ansible_check_flag
457
- config[:ansible_check] ? '--check' : nil
458
- end
459
-
460
- def ansible_diff_flag
461
- config[:ansible_diff] ? '--diff' : nil
462
- end
463
-
464
- def ansible_vault_flag
465
- debug(config[:ansible_vault_password_file])
466
- config[:ansible_vault_password_file] ? "--vault-password-file=#{File.join(config[:root_path], File.basename(config[:ansible_vault_password_file]))}" : nil
467
- end
468
-
469
- def ansible_inventory_flag
470
- config[:ansible_inventory_file] ? "--inventory-file=#{File.join(config[:root_path], File.basename(config[:ansible_inventory_file]))}" : "--inventory-file=#{File.join(config[:root_path], 'hosts')}"
471
- end
472
-
473
- def ansible_platform
474
- config[:ansible_platform].to_s.downcase
475
- end
476
-
477
- def update_packages_debian_cmd
478
- config[:update_package_repos] ? "#{sudo('apt-get')} update" : nil
479
- end
480
-
481
- def update_packages_redhat_cmd
482
- config[:update_package_repos] ? "#{sudo('yum')} makecache" : nil
483
- end
484
-
485
- def extra_vars
486
- bash_vars = config[:extra_vars]
487
- if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
488
- bash_vars = config[:attributes][:extra_vars]
489
- end
490
-
491
- return nil if bash_vars.none?
492
- bash_vars = JSON.dump(bash_vars)
493
- bash_vars = "-e '#{bash_vars}'"
494
- debug(bash_vars)
495
- bash_vars
496
- end
497
-
498
- def tags
499
- bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
500
- return nil if bash_tags.empty?
501
-
502
- bash_tags = bash_tags.join(",")
503
- bash_tags = "-t '#{bash_tags}'"
504
- debug(bash_tags)
505
- bash_tags
506
- end
507
-
508
- def ansible_apt_repo
509
- config[:ansible_apt_repo]
510
- end
511
-
512
- def ansible_apt_repo_file
513
- config[:ansible_apt_repo].split('/').last
514
- end
515
-
516
- def ansible_yum_repo
517
- config[:ansible_yum_repo]
518
- end
519
-
520
- def chef_url
521
- config[:chef_bootstrap_url]
522
- end
523
-
524
- def require_ruby_for_busser
525
- config[:require_ruby_for_busser]
526
- end
527
-
528
- def require_chef_for_busser
529
- config[:require_chef_for_busser]
530
- end
531
-
532
- def prepare_roles
533
- info('Preparing roles')
534
- debug("Using roles from #{roles}")
535
-
536
- resolve_with_librarian if File.exists?(ansiblefile)
537
-
538
- if galaxy_requirements
539
- FileUtils.cp(galaxy_requirements, File.join(sandbox_path, galaxy_requirements))
540
- end
541
-
542
- # Detect whether we are running tests on a role
543
- # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
544
-
545
- FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
546
- FileUtils.cp_r(Dir.glob("#{roles}/*"), File.join(tmp_roles_dir, role_name))
547
- end
548
-
549
- # /etc/ansible/ansible.cfg should contain
550
- # roles_path = /tmp/kitchen/roles
551
- def prepare_ansible_cfg
552
- info('Preparing ansible.cfg file')
553
- ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
554
-
555
- roles_paths = []
556
- roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
557
- additional_files.each do |additional_file|
558
- roles_paths << File.join(config[:root_path], File.basename(additional_file))
559
- end
560
-
561
- if roles_paths.empty?
562
- info('No roles have been set. empty ansible.cfg generated')
563
- File.open(ansible_config_file, "wb") do |file|
564
- file.write("#no roles path specified\n")
565
- end
566
- else
567
- debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
568
- File.open( ansible_config_file, "wb") do |file|
569
- file.write("[defaults]\nroles_path = #{ roles_paths.join(':') }\n")
570
- end
571
- end
572
- end
573
-
574
- def prepare_inventory_file
575
- info('Preparing inventory file')
576
-
577
- if ansible_inventory_file
578
- debug("Copying inventory file from #{ansible_inventory_file} to #{tmp_inventory_file_path}")
579
- FileUtils.cp_r(ansible_inventory_file, tmp_inventory_file_path)
580
- end
581
- end
582
-
583
- # localhost ansible_connection=local
584
- # [example_servers]
585
- # localhost
586
- def prepare_hosts
587
- info('Preparing hosts file')
588
-
589
- if config[:hosts].nil?
590
- raise 'No hosts have been set. Please specify one in .kitchen.yml'
591
- else
592
- debug("Using host from #{hosts}")
593
- File.open(File.join(sandbox_path, "hosts"), "wb") do |file|
594
- file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
595
- end
596
- end
597
- end
598
-
599
- def prepare_playbook
600
- info('Preparing playbook')
601
- debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
602
- FileUtils.cp_r(playbook, tmp_playbook_path)
603
- end
604
-
605
- def prepare_group_vars
606
- info('Preparing group_vars')
607
- tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
608
- FileUtils.mkdir_p(tmp_group_vars_dir)
609
-
610
- unless File.directory?(group_vars)
611
- info 'nothing to do for group_vars'
612
- return
613
- end
614
-
615
- debug("Using group_vars from #{group_vars}")
616
- FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
617
- end
618
-
619
- def prepare_additional_copy_path
620
- info('Preparing additional_copy_path')
621
- additional_files.each do |file|
622
- destination = File.join(sandbox_path, File.basename(file))
623
- if File.directory?(file)
624
- info("Copy dir: #{file} #{destination}")
625
- FileUtils.cp_r(file, destination)
626
- else
627
- info("Copy file: #{file} #{destination}")
628
- FileUtils.cp file, destination
629
- end
630
- end
631
- end
632
-
633
- def additional_files
634
- additional_files = []
635
- if ( additional_copy )
636
- additional_files = additional_copy.kind_of?(Array) ? additional_copy : [additional_copy]
637
- end
638
- additional_files.map { |additional_dir | additional_dir.to_s }
639
- end
640
-
641
- def prepare_host_vars
642
- info('Preparing host_vars')
643
- FileUtils.mkdir_p(tmp_host_vars_dir)
644
-
645
- unless File.directory?(host_vars)
646
- info 'nothing to do for host_vars'
647
- return
648
- end
649
-
650
- debug("Using host_vars from #{host_vars}")
651
- FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
652
- end
653
-
654
- def prepare_modules
655
- info('Preparing modules')
656
-
657
- FileUtils.mkdir_p(tmp_modules_dir)
658
-
659
- if modules && File.directory?(modules)
660
- debug("Using modules from #{modules}")
661
- FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
662
- else
663
- info 'nothing to do for modules'
664
- end
665
- end
666
-
667
- def prepare_filter_plugins
668
- info('Preparing filter_plugins')
669
- FileUtils.mkdir_p(tmp_filter_plugins_dir)
670
-
671
- if filter_plugins && File.directory?(filter_plugins)
672
- debug("Using filter_plugins from #{filter_plugins}")
673
- FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
674
- else
675
- info 'nothing to do for filter_plugins'
676
- end
677
- end
678
-
679
- def prepare_ansible_vault_password_file
680
- if ansible_vault_password_file
681
- info('Preparing ansible vault password')
682
- debug("Copying ansible vault password file from #{ansible_vault_password_file} to #{tmp_ansible_vault_password_file_path}")
683
-
684
- FileUtils.cp(ansible_vault_password_file, tmp_ansible_vault_password_file_path)
685
- end
686
- end
687
-
688
- def resolve_with_librarian
689
- Kitchen.mutex.synchronize do
690
- Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
691
- end
692
- end
693
- end
694
- end
695
- 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 'kitchen/provisioner/base'
25
+ require 'kitchen/provisioner/ansible/config'
26
+ require 'kitchen/provisioner/ansible/librarian'
27
+
28
+ module Kitchen
29
+
30
+ class Busser
31
+
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
+ end
48
+
49
+ def finalize_config!(instance)
50
+ config.set_instance(instance)
51
+ super(instance)
52
+ end
53
+
54
+ def verbosity_level(level = 1)
55
+ level = level.to_sym if level.is_a? String
56
+ log_levels = { :info => 1, :warn => 2, :debug => 3, :trace => 4 }
57
+ if level.is_a? Symbol and log_levels.include? level
58
+ # puts "Log Level is: #{log_levels[level]}"
59
+ log_levels[level]
60
+ elsif level.is_a? Integer and level > 0
61
+ # puts "Log Level is: #{level}"
62
+ level
63
+ else
64
+ raise 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
65
+ end
66
+ end
67
+
68
+ def install_command
69
+ if config[:require_ansible_omnibus]
70
+ cmd = install_omnibus_command
71
+ elsif config[:require_ansible_source]
72
+ info("Installing ansible from source")
73
+ cmd = install_ansible_from_source_command
74
+ elsif config[:require_ansible_repo]
75
+ case ansible_platform
76
+ when "debian", "ubuntu"
77
+ info("Installing ansible on #{ansible_platform}")
78
+ cmd = install_debian_command
79
+ when "redhat", "centos", "fedora"
80
+ info("Installing ansible on #{ansible_platform}")
81
+ cmd = install_redhat_command
82
+ when "amazon"
83
+ info("Installing ansible on #{ansible_platform}")
84
+ cmd = install_amazon_linux_command
85
+ else
86
+ info("Installing ansible, will try to determine platform os")
87
+ cmd = <<-INSTALL
88
+ if [ ! $(which ansible) ]; then
89
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
90
+ if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
91
+ #{install_redhat_command}
92
+ else
93
+ #{install_amazon_linux_command}
94
+ fi
95
+ else
96
+ #{install_debian_command}
97
+ fi
98
+ fi
99
+ INSTALL
100
+ end
101
+ else
102
+ return
103
+ end
104
+ cmd + install_busser_prereqs
105
+ end
106
+
107
+ def install_busser_prereqs
108
+ install = ''
109
+ install << <<-INSTALL
110
+ #{Util.shell_helpers}
111
+ # Fix for https://github.com/test-kitchen/busser/issues/12
112
+ if [ -h /usr/bin/ruby ]; then
113
+ L=$(readlink -f /usr/bin/ruby)
114
+ #{sudo('rm')} /usr/bin/ruby
115
+ #{sudo('ln')} -s $L /usr/bin/ruby
116
+ fi
117
+ INSTALL
118
+
119
+ if require_ruby_for_busser
120
+ install << <<-INSTALL
121
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
122
+ if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
123
+ rhelversion=$(cat /etc/redhat-release | grep 'release 6')
124
+ # For CentOS6/RHEL6 install ruby from SCL
125
+ if [ -n "$rhelversion" ]; then
126
+ if [ ! -d "/opt/rh/ruby193" ]; then
127
+ echo "-----> Installing ruby SCL in CentOS6/RHEL6 to install busser to run tests"
128
+ #{sudo('yum')} install -y centos-release-SCL
129
+ #{sudo('yum')} install -y ruby193
130
+ #{sudo('yum')} install -y ruby193-ruby-devel
131
+ echo "-----> Enabling ruby193"
132
+ source /opt/rh/ruby193/enable
133
+ echo "/opt/rh/ruby193/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
134
+ #{sudo('ldconfig')}
135
+ #{sudo('ln')} -s /opt/rh/ruby193/root/usr/bin/ruby /usr/bin/ruby
136
+ #{sudo('ln')} -s /opt/rh/ruby193/root/usr/bin/gem /usr/bin/gem
137
+ fi
138
+ else
139
+ if [ ! $(which ruby) ]; then
140
+ #{update_packages_redhat_cmd}
141
+ #{sudo('yum')} -y install ruby ruby-devel
142
+ fi
143
+ fi
144
+ else
145
+ #{update_packages_redhat_cmd}
146
+ #{sudo('yum')} -y install ruby ruby-devel gcc
147
+ fi
148
+ else
149
+ if [ ! $(which ruby) ]; then
150
+ #{update_packages_debian_cmd}
151
+ # default package selection for Debian/Ubuntu machines
152
+ PACKAGES="ruby1.9.1 ruby1.9.1-dev"
153
+ if [ "$(lsb_release -si)" = "Debian" ]; then
154
+ debvers=$(sed 's/\\..*//' /etc/debian_version)
155
+ if [ $debvers -ge 8 ]; then
156
+ # this is jessie or better, where ruby1.9.1 is
157
+ # no longer in the repositories
158
+ PACKAGES="ruby ruby-dev ruby2.1 ruby2.1-dev"
159
+ fi
160
+ fi
161
+ #{sudo('apt-get')} -y install $PACKAGES
162
+ fi
163
+ fi
164
+ INSTALL
165
+
166
+ elsif require_chef_for_busser && chef_url then
167
+ install << <<-INSTALL
168
+ # install chef omnibus so that busser works as this is needed to run tests :(
169
+ if [ ! -d "/opt/chef" ]
170
+ then
171
+ echo "-----> Installing Chef Omnibus to install busser to run tests"
172
+ do_download #{chef_url} /tmp/install.sh
173
+ #{sudo('sh')} /tmp/install.sh
174
+ fi
175
+ INSTALL
176
+ end
177
+
178
+ install
179
+ end
180
+
181
+ def init_command
182
+ dirs = %w{modules roles group_vars host_vars}.
183
+ map { |dir| File.join(config[:root_path], dir) }.join(" ")
184
+ cmd = "#{sudo('rm')} -rf #{dirs};"
185
+ cmd = cmd+" mkdir -p #{config[:root_path]}"
186
+ debug(cmd)
187
+ cmd
188
+ end
189
+
190
+ def create_sandbox
191
+ super
192
+ debug("Creating local sandbox in #{sandbox_path}")
193
+
194
+ yield if block_given?
195
+
196
+ prepare_playbook
197
+ prepare_inventory_file
198
+ prepare_modules
199
+ prepare_roles
200
+ prepare_ansible_cfg
201
+ prepare_group_vars
202
+ prepare_additional_copy_path
203
+ prepare_host_vars
204
+ prepare_hosts
205
+ prepare_filter_plugins
206
+ prepare_ansible_vault_password_file
207
+ info('Finished Preparing files for transfer')
208
+
209
+ end
210
+
211
+ def cleanup_sandbox
212
+ return if sandbox_path.nil?
213
+ debug("Cleaning up local sandbox in #{sandbox_path}")
214
+ FileUtils.rmtree(sandbox_path)
215
+ end
216
+
217
+ def prepare_command
218
+ commands = []
219
+
220
+ # Prevent failure when ansible package installation doesn't contain /etc/ansible
221
+ commands << [
222
+ sudo("bash -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
223
+ ]
224
+
225
+ commands << [
226
+ sudo('cp'),File.join(config[:root_path], 'ansible.cfg'),'/etc/ansible',
227
+ ].join(' ')
228
+
229
+ commands << [
230
+ sudo('cp -r'), File.join(config[:root_path],'group_vars'), '/etc/ansible/.',
231
+ ].join(' ')
232
+
233
+ commands << [
234
+ sudo('cp -r'), File.join(config[:root_path],'host_vars'), '/etc/ansible/.',
235
+ ].join(' ')
236
+
237
+ if galaxy_requirements
238
+ if config[:require_ansible_source]
239
+ commands << setup_ansible_env_from_source
240
+ end
241
+ commands << [
242
+ 'ansible-galaxy', 'install', '--force',
243
+ '-p', File.join(config[:root_path], 'roles'),
244
+ '-r', File.join(config[:root_path], galaxy_requirements),
245
+ ].join(' ')
246
+ end
247
+
248
+ command = commands.join(' && ')
249
+ debug(command)
250
+ command
251
+ end
252
+
253
+ def run_command
254
+ if config[:require_ansible_source]
255
+ # this is an ugly hack to get around the fact that extra vars uses ' and "
256
+ 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 #{config[:root_path]}/ansible/bin/ansible-playbook")
257
+ else
258
+ cmd = ansible_command("ansible-playbook")
259
+ end
260
+ [
261
+ cmd,
262
+ ansible_inventory_flag,
263
+ "-c #{config[:ansible_connection]}",
264
+ "-M #{File.join(config[:root_path], 'modules')}",
265
+ ansible_verbose_flag,
266
+ ansible_check_flag,
267
+ ansible_diff_flag,
268
+ ansible_vault_flag,
269
+ extra_vars,
270
+ tags,
271
+ "#{File.join(config[:root_path], File.basename(config[:playbook]))}",
272
+ ].join(" ")
273
+ end
274
+
275
+ def ansible_command(script)
276
+ config[:ansible_sudo].nil? || config[:ansible_sudo] == true ? sudo(script) : script
277
+ end
278
+
279
+ protected
280
+
281
+ def load_needed_dependencies!
282
+ if File.exists?(ansiblefile)
283
+ debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
284
+ Ansible::Librarian.load!(logger)
285
+ end
286
+ end
287
+
288
+ def install_ansible_from_source_command
289
+ <<-INSTALL
290
+ if [ ! -d #{config[:root_path]}/ansible ]; then
291
+ if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
292
+ #{update_packages_redhat_cmd}
293
+ #{sudo('yum')} -y install libselinux-python python2-devel git python-setuptools python-setuptools-dev
294
+ else
295
+ #{update_packages_debian_cmd}
296
+ #{sudo('apt-get')} -y install git python python-setuptools build-essential python-dev
297
+ fi
298
+
299
+ git clone git://github.com/ansible/ansible.git --recursive #{config[:root_path]}/ansible
300
+ #{sudo('easy_install')} pip
301
+ #{sudo('pip')} install paramiko PyYAML Jinja2 httplib2
302
+ fi
303
+ INSTALL
304
+ end
305
+
306
+ def install_omnibus_command
307
+ info("Installing ansible using ansible omnibus")
308
+ version = if !config[:ansible_version].nil?
309
+ "-v #{config[:ansible_version]}"
310
+ else
311
+ ""
312
+ end
313
+ <<-INSTALL
314
+ #{Util.shell_helpers}
315
+
316
+ if [ ! -d "#{config[:ansible_omnibus_remote_path]}" ]; then
317
+ echo "-----> Installing Ansible Omnibus"
318
+ do_download #{config[:ansible_omnibus_url]} /tmp/ansible_install.sh
319
+ #{sudo('sh')} /tmp/ansible_install.sh #{version}
320
+ fi
321
+ INSTALL
322
+ end
323
+
324
+ def install_debian_command
325
+ <<-INSTALL
326
+ if [ ! $(which ansible) ]; then
327
+ #{update_packages_debian_cmd}
328
+
329
+ ## Install apt-utils to silence debconf warning: http://serverfault.com/q/358943/77156
330
+ #{sudo('apt-get')} -y install apt-utils git
331
+
332
+ ## Fix debconf tty warning messages
333
+ export DEBIAN_FRONTEND=noninteractive
334
+
335
+ ## 13.10, 14.04 include add-apt-repository in software-properties-common
336
+ #{sudo('apt-get')} -y install software-properties-common
337
+
338
+ ## 10.04, 12.04 include add-apt-repository in
339
+ #{sudo('apt-get')} -y install python-software-properties
340
+
341
+ ## 10.04 version of add-apt-repository doesn't accept --yes
342
+ ## later versions require interaction from user, so we must specify --yes
343
+ ## First try with -y flag, else if it fails, try without.
344
+ ## "add-apt-repository: error: no such option: -y" is returned but is ok to ignore, we just retry
345
+ #{sudo('add-apt-repository')} -y #{ansible_apt_repo} || #{sudo('add-apt-repository')} #{ansible_apt_repo}
346
+ #{sudo('apt-get')} update
347
+ #{sudo('apt-get')} -y install ansible
348
+ fi
349
+ INSTALL
350
+ end
351
+
352
+ def install_redhat_command
353
+ <<-INSTALL
354
+ if [ ! $(which ansible) ]; then
355
+ #{sudo('rpm')} -ivh #{ansible_yum_repo}
356
+ #{update_packages_redhat_cmd}
357
+ #{sudo('yum')} -y install ansible#{ansible_redhat_version} libselinux-python git
358
+ fi
359
+ INSTALL
360
+ end
361
+
362
+ def install_amazon_linux_command
363
+ <<-INSTALL
364
+ if [ ! $(which ansible) ]; then
365
+ #{sudo('yum-config-manager')} --enable epel/x86_64
366
+ #{sudo('yum')} -y install ansible#{ansible_redhat_version} git
367
+ #{sudo('alternatives')} --set python /usr/bin/python2.6
368
+ #{sudo('yum')} clean all
369
+ #{sudo('yum')} install yum-python26 -y
370
+ fi
371
+ INSTALL
372
+ end
373
+
374
+ def setup_ansible_env_from_source
375
+ "cd #{config[:root_path]}/ansible && source hacking/env-setup && cd ../"
376
+ end
377
+
378
+ def tmp_modules_dir
379
+ File.join(sandbox_path, 'modules')
380
+ end
381
+
382
+ def tmp_playbook_path
383
+ File.join(sandbox_path, File.basename(playbook))
384
+ end
385
+
386
+ def tmp_host_vars_dir
387
+ File.join(sandbox_path, 'host_vars')
388
+ end
389
+
390
+ def tmp_roles_dir
391
+ File.join(sandbox_path, 'roles')
392
+ end
393
+
394
+ def tmp_filter_plugins_dir
395
+ File.join(sandbox_path, 'filter_plugins')
396
+ end
397
+
398
+ def tmp_ansible_vault_password_file_path
399
+ File.join(sandbox_path, File.basename(ansible_vault_password_file))
400
+ end
401
+
402
+ def tmp_inventory_file_path
403
+ File.join(sandbox_path, File.basename(ansible_inventory_file))
404
+ end
405
+
406
+ def ansiblefile
407
+ config[:ansiblefile_path] || ''
408
+ end
409
+
410
+ def galaxy_requirements
411
+ config[:requirements_path] || nil
412
+ end
413
+
414
+ def playbook
415
+ config[:playbook]
416
+ end
417
+
418
+ def hosts
419
+ config[:hosts]
420
+ end
421
+
422
+ def roles
423
+ config[:roles_path]
424
+ end
425
+
426
+ def role_name
427
+ File.basename(roles) == 'roles' ? '' : File.basename(roles)
428
+ end
429
+
430
+ def modules
431
+ config[:modules_path]
432
+ end
433
+
434
+ def group_vars
435
+ config[:group_vars_path].to_s
436
+ end
437
+
438
+ def additional_copy
439
+ config[:additional_copy_path]
440
+ end
441
+
442
+ def host_vars
443
+ config[:host_vars_path].to_s
444
+ end
445
+
446
+ def filter_plugins
447
+ config[:filter_plugins_path].to_s
448
+ end
449
+
450
+ def ansible_vault_password_file
451
+ config[:ansible_vault_password_file]
452
+ end
453
+
454
+ def ansible_inventory_file
455
+ config[:ansible_inventory_file]
456
+ end
457
+
458
+ def ansible_debian_version
459
+ config[:ansible_version] ? "=#{config[:ansible_version]}" : nil
460
+ end
461
+
462
+ def ansible_redhat_version
463
+ config[:ansible_version] ? "-#{config[:ansible_version]}" : nil
464
+ end
465
+
466
+ def ansible_verbose_flag
467
+ config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
468
+ end
469
+
470
+ def ansible_check_flag
471
+ config[:ansible_check] ? '--check' : nil
472
+ end
473
+
474
+ def ansible_diff_flag
475
+ config[:ansible_diff] ? '--diff' : nil
476
+ end
477
+
478
+ def ansible_vault_flag
479
+ debug(config[:ansible_vault_password_file])
480
+ config[:ansible_vault_password_file] ? "--vault-password-file=#{File.join(config[:root_path], File.basename(config[:ansible_vault_password_file]))}" : nil
481
+ end
482
+
483
+ def ansible_inventory_flag
484
+ config[:ansible_inventory_file] ? "--inventory-file=#{File.join(config[:root_path], File.basename(config[:ansible_inventory_file]))}" : "--inventory-file=#{File.join(config[:root_path], 'hosts')}"
485
+ end
486
+
487
+ def ansible_platform
488
+ config[:ansible_platform].to_s.downcase
489
+ end
490
+
491
+ def update_packages_debian_cmd
492
+ config[:update_package_repos] ? "#{sudo('apt-get')} update" : nil
493
+ end
494
+
495
+ def update_packages_redhat_cmd
496
+ config[:update_package_repos] ? "#{sudo('yum')} makecache" : nil
497
+ end
498
+
499
+ def extra_vars
500
+ bash_vars = config[:extra_vars]
501
+ if config.key?(:attributes) && config[:attributes].key?(:extra_vars) && config[:attributes][:extra_vars].is_a?(Hash)
502
+ bash_vars = config[:attributes][:extra_vars]
503
+ end
504
+
505
+ return nil if bash_vars.none?
506
+ bash_vars = JSON.dump(bash_vars)
507
+ bash_vars = "-e '#{bash_vars}'"
508
+ debug(bash_vars)
509
+ bash_vars
510
+ end
511
+
512
+ def tags
513
+ bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
514
+ return nil if bash_tags.empty?
515
+
516
+ bash_tags = bash_tags.join(",")
517
+ bash_tags = "-t '#{bash_tags}'"
518
+ debug(bash_tags)
519
+ bash_tags
520
+ end
521
+
522
+ def ansible_apt_repo
523
+ config[:ansible_apt_repo]
524
+ end
525
+
526
+ def ansible_apt_repo_file
527
+ config[:ansible_apt_repo].split('/').last
528
+ end
529
+
530
+ def ansible_yum_repo
531
+ config[:ansible_yum_repo]
532
+ end
533
+
534
+ def chef_url
535
+ config[:chef_bootstrap_url]
536
+ end
537
+
538
+ def require_ruby_for_busser
539
+ config[:require_ruby_for_busser]
540
+ end
541
+
542
+ def require_chef_for_busser
543
+ config[:require_chef_for_busser]
544
+ end
545
+
546
+ def prepare_roles
547
+ info('Preparing roles')
548
+ debug("Using roles from #{roles}")
549
+
550
+ resolve_with_librarian if File.exists?(ansiblefile)
551
+
552
+ if galaxy_requirements
553
+ FileUtils.cp(galaxy_requirements, File.join(sandbox_path, galaxy_requirements))
554
+ end
555
+
556
+ # Detect whether we are running tests on a role
557
+ # If so, make sure to copy into VM so dir structure is like: /tmp/kitchen/roles/role_name
558
+
559
+ FileUtils.mkdir_p(File.join(tmp_roles_dir, role_name))
560
+ FileUtils.cp_r(Dir.glob("#{roles}/*"), File.join(tmp_roles_dir, role_name))
561
+ end
562
+
563
+ # /etc/ansible/ansible.cfg should contain
564
+ # roles_path = /tmp/kitchen/roles
565
+ def prepare_ansible_cfg
566
+ info('Preparing ansible.cfg file')
567
+ ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
568
+
569
+ roles_paths = []
570
+ roles_paths << File.join(config[:root_path], 'roles') unless config[:roles_path].nil?
571
+ additional_files.each do |additional_file|
572
+ roles_paths << File.join(config[:root_path], File.basename(additional_file))
573
+ end
574
+
575
+ if roles_paths.empty?
576
+ info('No roles have been set. empty ansible.cfg generated')
577
+ File.open(ansible_config_file, "wb") do |file|
578
+ file.write("#no roles path specified\n")
579
+ end
580
+ else
581
+ debug("Setting roles_path inside VM to #{ roles_paths.join(':') }")
582
+ File.open( ansible_config_file, "wb") do |file|
583
+ file.write("[defaults]\nroles_path = #{ roles_paths.join(':') }\n")
584
+ end
585
+ end
586
+ end
587
+
588
+ def prepare_inventory_file
589
+ info('Preparing inventory file')
590
+
591
+ if ansible_inventory_file
592
+ debug("Copying inventory file from #{ansible_inventory_file} to #{tmp_inventory_file_path}")
593
+ FileUtils.cp_r(ansible_inventory_file, tmp_inventory_file_path)
594
+ end
595
+ end
596
+
597
+ # localhost ansible_connection=local
598
+ # [example_servers]
599
+ # localhost
600
+ def prepare_hosts
601
+ info('Preparing hosts file')
602
+
603
+ if config[:hosts].nil?
604
+ raise 'No hosts have been set. Please specify one in .kitchen.yml'
605
+ else
606
+ debug("Using host from #{hosts}")
607
+ File.open(File.join(sandbox_path, "hosts"), "wb") do |file|
608
+ file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
609
+ end
610
+ end
611
+ end
612
+
613
+ def prepare_playbook
614
+ info('Preparing playbook')
615
+ debug("Copying playbook from #{playbook} to #{tmp_playbook_path}")
616
+ FileUtils.cp_r(playbook, tmp_playbook_path)
617
+ end
618
+
619
+ def prepare_group_vars
620
+ info('Preparing group_vars')
621
+ tmp_group_vars_dir = File.join(sandbox_path, 'group_vars')
622
+ FileUtils.mkdir_p(tmp_group_vars_dir)
623
+
624
+ unless File.directory?(group_vars)
625
+ info 'nothing to do for group_vars'
626
+ return
627
+ end
628
+
629
+ debug("Using group_vars from #{group_vars}")
630
+ FileUtils.cp_r(Dir.glob("#{group_vars}/*"), tmp_group_vars_dir)
631
+ end
632
+
633
+ def prepare_additional_copy_path
634
+ info('Preparing additional_copy_path')
635
+ additional_files.each do |file|
636
+ destination = File.join(sandbox_path, File.basename(file))
637
+ if File.directory?(file)
638
+ info("Copy dir: #{file} #{destination}")
639
+ FileUtils.cp_r(file, destination)
640
+ else
641
+ info("Copy file: #{file} #{destination}")
642
+ FileUtils.cp file, destination
643
+ end
644
+ end
645
+ end
646
+
647
+ def additional_files
648
+ additional_files = []
649
+ if ( additional_copy )
650
+ additional_files = additional_copy.kind_of?(Array) ? additional_copy : [additional_copy]
651
+ end
652
+ additional_files.map { |additional_dir | additional_dir.to_s }
653
+ end
654
+
655
+ def prepare_host_vars
656
+ info('Preparing host_vars')
657
+ FileUtils.mkdir_p(tmp_host_vars_dir)
658
+
659
+ unless File.directory?(host_vars)
660
+ info 'nothing to do for host_vars'
661
+ return
662
+ end
663
+
664
+ debug("Using host_vars from #{host_vars}")
665
+ FileUtils.cp_r(Dir.glob("#{host_vars}/*"), tmp_host_vars_dir)
666
+ end
667
+
668
+ def prepare_modules
669
+ info('Preparing modules')
670
+
671
+ FileUtils.mkdir_p(tmp_modules_dir)
672
+
673
+ if modules && File.directory?(modules)
674
+ debug("Using modules from #{modules}")
675
+ FileUtils.cp_r(Dir.glob("#{modules}/*"), tmp_modules_dir, remove_destination: true)
676
+ else
677
+ info 'nothing to do for modules'
678
+ end
679
+ end
680
+
681
+ def prepare_filter_plugins
682
+ info('Preparing filter_plugins')
683
+ FileUtils.mkdir_p(tmp_filter_plugins_dir)
684
+
685
+ if filter_plugins && File.directory?(filter_plugins)
686
+ debug("Using filter_plugins from #{filter_plugins}")
687
+ FileUtils.cp_r(Dir.glob("#{filter_plugins}/*.py"), tmp_filter_plugins_dir, remove_destination: true)
688
+ else
689
+ info 'nothing to do for filter_plugins'
690
+ end
691
+ end
692
+
693
+ def prepare_ansible_vault_password_file
694
+ if ansible_vault_password_file
695
+ info('Preparing ansible vault password')
696
+ debug("Copying ansible vault password file from #{ansible_vault_password_file} to #{tmp_ansible_vault_password_file_path}")
697
+
698
+ FileUtils.cp(ansible_vault_password_file, tmp_ansible_vault_password_file_path)
699
+ end
700
+ end
701
+
702
+ def resolve_with_librarian
703
+ Kitchen.mutex.synchronize do
704
+ Ansible::Librarian.new(ansiblefile, tmp_roles_dir, logger).resolve
705
+ end
706
+ end
707
+ end
708
+ end
709
+ end