kitchen-ansible 0.0.33 → 0.0.34

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,19 +20,14 @@ require 'kitchen/errors'
20
20
  require 'kitchen/logging'
21
21
 
22
22
  module Kitchen
23
-
24
23
  module Provisioner
25
-
26
24
  module Ansible
27
-
28
25
  # Ansible module resolver that uses Librarian-Ansible and a Ansiblefile to
29
26
  # calculate # dependencies.
30
27
  #
31
- class Librarian
32
-
28
+ class Librarian
33
29
  include Logging
34
30
 
35
-
36
31
  def initialize(ansiblefile, path, logger = Kitchen.logger)
37
32
  @ansiblefile = ansiblefile
38
33
  @path = path
@@ -49,8 +44,8 @@ module Kitchen
49
44
  debug("Using Ansiblefile from #{ansiblefile}")
50
45
 
51
46
  env = ::Librarian::Ansible::Environment.new(
52
- :project_path => File.dirname(ansiblefile))
53
- env.config_db.local["path"] = path
47
+ project_path: File.dirname(ansiblefile))
48
+ env.config_db.local['path'] = path
54
49
  ::Librarian::Action::Resolve.new(env).run
55
50
  ::Librarian::Action::Install.new(env).run
56
51
  end
@@ -70,12 +65,12 @@ module Kitchen
70
65
  logger.debug("Librarian-Ansible #{version} previously loaded")
71
66
  end
72
67
  rescue LoadError => e
73
- logger.fatal("The `librarian-ansible' gem is missing and must be installed" +
74
- " or cannot be properly activated. Run" +
75
- " `gem install librarian-ansible` or add the following to your" +
68
+ logger.fatal("The `librarian-ansible' gem is missing and must be installed" \
69
+ ' or cannot be properly activated. Run' \
70
+ ' `gem install librarian-ansible` or add the following to your' \
76
71
  " Gemfile if you are using Bundler: `gem 'librarian-ansible'`.")
77
72
  raise UserError,
78
- "Could not load or activate Librarian-Ansible (#{e.message})"
73
+ "Could not load or activate Librarian-Ansible (#{e.message})"
79
74
  end
80
75
  end
81
76
  end
@@ -0,0 +1,69 @@
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
+ require 'json'
21
+ require 'kitchen/provisioner/ansible/os/debian'
22
+ require 'kitchen/provisioner/ansible/os/redhat'
23
+ require 'kitchen/provisioner/ansible/os/amazon'
24
+ require 'kitchen/provisioner/ansible/os/suse'
25
+
26
+ module Kitchen
27
+ module Provisioner
28
+ module Ansible
29
+ class Os
30
+ attr_accessor :name
31
+
32
+ def initialize(name, config)
33
+ @config = config
34
+ @name = name
35
+ end
36
+
37
+ def self.make(platform, config)
38
+ return nil if platform == ''
39
+
40
+ case platform
41
+ when 'debian', 'ubuntu'
42
+ return Debian.new(platform, config)
43
+ when 'redhat', 'centos', 'fedora'
44
+ return Redhat.new(platform, config)
45
+ when 'amazon'
46
+ return Amazon.new(platform, config)
47
+ when 'suse', 'opensuse', 'sles'
48
+ return Suse.new(platform, config)
49
+ end
50
+
51
+ nil
52
+ end
53
+
54
+ # Helpers
55
+ def sudo_env(pm)
56
+ s = @config[:https_proxy] ? "https_proxy=#{@config[:https_proxy]}" : nil
57
+ p = @config[:http_proxy] ? "http_proxy=#{@config[:http_proxy]}" : nil
58
+ n = @config[:no_proxy] ? "no_proxy=#{@config[:no_proxy]}" : nil
59
+ p || s ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
60
+ end
61
+
62
+ # Taken from https://github.com/test-kitchen/test-kitchen/blob/master/lib/kitchen/provisioner/base.rb
63
+ def sudo(script)
64
+ @config[:sudo] ? "#{@config[:sudo_command]} #{script}" : script
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,41 @@
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 Amazon < Redhat
25
+ def install_command
26
+ <<-INSTALL
27
+ if [ ! $(which ansible) ]; then
28
+ #{install_epel_repo}
29
+ #{sudo_env('yum-config-manager')} --enable epel/x86_64
30
+ #{sudo_env('yum')} -y install ansible#{ansible_redhat_version} git
31
+ #{sudo_env('alternatives')} --set python /usr/bin/python2.6
32
+ #{sudo_env('yum')} clean all
33
+ #{sudo_env('yum')} install yum-python26 -y
34
+ fi
35
+ INSTALL
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,60 @@
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 Debian < Os
25
+ def update_packages_command
26
+ @config[:update_package_repos] ? "#{sudo_env('apt-get')} update" : nil
27
+ end
28
+
29
+ def install_command
30
+ <<-INSTALL
31
+ if [ ! $(which ansible) ]; then
32
+ #{update_packages_command}
33
+
34
+ ## Install apt-utils to silence debconf warning: http://serverfault.com/q/358943/77156
35
+ #{sudo_env('apt-get')} -y install apt-utils git
36
+
37
+ ## Fix debconf tty warning messages
38
+ export DEBIAN_FRONTEND=noninteractive
39
+
40
+ ## 13.10, 14.04 include add-apt-repository in software-properties-common
41
+ #{sudo_env('apt-get')} -y install software-properties-common
42
+
43
+ ## 10.04, 12.04 include add-apt-repository in
44
+ #{sudo_env('apt-get')} -y install python-software-properties
45
+
46
+ ## 10.04 version of add-apt-repository doesn't accept --yes
47
+ ## later versions require interaction from user, so we must specify --yes
48
+ ## First try with -y flag, else if it fails, try without.
49
+ ## "add-apt-repository: error: no such option: -y" is returned but is ok to ignore, we just retry
50
+ #{sudo_env('add-apt-repository')} -y #{@config[:ansible_apt_repo]} || #{sudo_env('add-apt-repository')} #{@config[:ansible_apt_repo]}
51
+ #{sudo_env('apt-get')} update
52
+ #{sudo_env('apt-get')} -y install ansible
53
+ fi
54
+ INSTALL
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,68 @@
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
+ if [ ! $(which ansible) ]; then
28
+ #{install_epel_repo}
29
+ #{redhat_yum_repo}
30
+ #{update_packages_command}
31
+ #{sudo_env('yum')} -y install ansible#{ansible_redhat_version} libselinux-python git
32
+ fi
33
+ INSTALL
34
+ end
35
+
36
+ def update_packages_command
37
+ @config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
38
+ end
39
+
40
+ def install_epel_repo
41
+ @config[:enable_yum_epel] ? sudo_env('yum install epel-release -y') : nil
42
+ end
43
+
44
+ def ansible_redhat_version
45
+ @config[:ansible_version] ? "-#{@config[:ansible_version]}" : nil
46
+ end
47
+
48
+ def redhat_yum_repo
49
+ if @config[:ansible_yum_repo] == 'https://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm'
50
+ <<-INSTALL
51
+ rhelversion6=$(cat /etc/redhat-release | grep 'release 6')
52
+ if [ -n "$rhelversion6" ]; then
53
+ #{sudo_env('rpm')} -ivh 'https://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm'
54
+ else
55
+ #{sudo_env('rpm')} -ivh 'http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm'
56
+ fi
57
+ INSTALL
58
+ else
59
+ <<-INSTALL
60
+ #{sudo_env('rpm')} -ivh #{@config[:ansible_yum_repo]}
61
+ INSTALL
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,43 @@
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
+ if [ ! $(which ansible) ]; then
28
+ #{sudo_env('zypper')} ar #{@config[:python_sles_repo]}
29
+ #{sudo_env('zypper')} ar #{@config[:ansible_sles_repo]}
30
+ #{update_packages_command}
31
+ #{sudo_env('zypper')} --non-interactive install ansible
32
+ fi
33
+ INSTALL
34
+ end
35
+
36
+ def update_packages_command
37
+ @config[:update_package_repos] ? "#{sudo_env('zypper')} --gpg-auto-import-keys ref" : nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -23,14 +23,13 @@
23
23
  require 'json'
24
24
  require 'kitchen/provisioner/base'
25
25
  require 'kitchen/provisioner/ansible/config'
26
+ require 'kitchen/provisioner/ansible/os'
26
27
  require 'kitchen/provisioner/ansible/librarian'
27
28
 
28
29
  module Kitchen
29
-
30
30
  class Busser
31
-
32
31
  def non_suite_dirs
33
- %w{data}
32
+ %w(data)
34
33
  end
35
34
  end
36
35
 
@@ -44,24 +43,26 @@ module Kitchen
44
43
  def initialize(provisioner_config)
45
44
  config = Kitchen::Provisioner::Ansible::Config.new(provisioner_config)
46
45
  super(config)
46
+
47
+ @os = Kitchen::Provisioner::Ansible::Os.make(ansible_platform, config)
47
48
  end
48
49
 
49
50
  def finalize_config!(instance)
50
- config.set_instance(instance)
51
+ config.instance = instance
51
52
  super(instance)
52
53
  end
53
54
 
54
55
  def verbosity_level(level = 1)
55
56
  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
57
+ log_levels = { info: 1, warn: 2, debug: 3, trace: 4 }
58
+ if level.is_a?(Symbol) && log_levels.include?(level)
58
59
  # puts "Log Level is: #{log_levels[level]}"
59
60
  log_levels[level]
60
- elsif level.is_a? Integer and level > 0
61
+ elsif level.is_a?(Integer) && level > 0
61
62
  # puts "Log Level is: #{level}"
62
63
  level
63
64
  else
64
- raise 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
65
+ fail 'Invalid ansible_verbosity setting. Valid values are: 1, 2, 3, 4 OR :info, :warn, :debug, :trace'
65
66
  end
66
67
  end
67
68
 
@@ -69,36 +70,26 @@ module Kitchen
69
70
  if config[:require_ansible_omnibus]
70
71
  cmd = install_omnibus_command
71
72
  elsif config[:require_ansible_source]
72
- info("Installing ansible from source")
73
+ info('Installing ansible from source')
73
74
  cmd = install_ansible_from_source_command
74
75
  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
- when "suse", "opensuse", "sles"
86
- info("Installing ansible on #{ansible_platform}")
87
- cmd = install_suse_command
76
+ if !@os.nil?
77
+ info("Installing ansible on #{@os.name}")
78
+ cmd = @os.install_command
88
79
  else
89
- info("Installing ansible, will try to determine platform os")
80
+ info('Installing ansible, will try to determine platform os')
90
81
  cmd = <<-INSTALL
91
82
  if [ ! $(which ansible) ]; then
92
83
  if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
93
84
  if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
94
- #{install_redhat_command}
85
+ #{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_command}
95
86
  else
96
- #{install_amazon_linux_command}
87
+ #{Kitchen::Provisioner::Ansible::Os::Amazon.new('amazon', config).install_command}
97
88
  fi
98
89
  elif [ -f /etc/SuSE-release ] || [ -f /etc/SUSE-brand ]; then
99
- #{install_suse_command}
90
+ #{Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).install_command}
100
91
  else
101
- #{install_debian_command}
92
+ #{Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).install_command}
102
93
  fi
103
94
  fi
104
95
  INSTALL
@@ -125,20 +116,21 @@ module Kitchen
125
116
  install << <<-INSTALL
126
117
  if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ]; then
127
118
  if ! [ grep -q 'Amazon Linux' /etc/system-release ]; then
128
- rhelversion=$(cat /etc/redhat-release | grep 'release 6')
129
- # For CentOS6/RHEL6 install ruby from SCL
130
- if [ -n "$rhelversion" ]; then
131
- if [ ! -d "/opt/rh/ruby193" ]; then
132
- echo "-----> Installing ruby SCL in CentOS6/RHEL6 to install busser to run tests"
133
- #{sudo_env('yum')} install -y centos-release-SCL
134
- #{sudo_env('yum')} install -y ruby193
135
- #{sudo_env('yum')} install -y ruby193-ruby-devel
136
- echo "-----> Enabling ruby193"
137
- source /opt/rh/ruby193/enable
138
- echo "/opt/rh/ruby193/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
119
+ rhelversion6=$(cat /etc/redhat-release | grep 'release 6')
120
+ rhelversion7=$(cat /etc/redhat-release | grep 'release 7')
121
+ # For CentOS6/CentOS7/RHEL6/RHEL7 install ruby from SCL
122
+ if [ -n "$rhelversion6" ] || [ -n "$rhelversion7" ]; then
123
+ if [ ! -d "/opt/rh/ruby200" ]; then
124
+ echo "-----> Installing ruby200 SCL in CentOS6/CentOS7/RHEL6/RHEL7 to install busser to run tests"
125
+ #{sudo_env('yum')} install -y centos-release-scl
126
+ #{sudo_env('yum')} install -y ruby200
127
+ #{sudo_env('yum')} install -y ruby200-ruby-devel
128
+ echo "-----> Enabling ruby200"
129
+ source /opt/rh/ruby200/enable
130
+ echo "/opt/rh/ruby200/root/usr/lib64" | sudo tee -a /etc/ld.so.conf
139
131
  #{sudo_env('ldconfig')}
140
- #{sudo_env('ln')} -s /opt/rh/ruby193/root/usr/bin/ruby /usr/bin/ruby
141
- #{sudo_env('ln')} -s /opt/rh/ruby193/root/usr/bin/gem /usr/bin/gem
132
+ #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/ruby /usr/bin/ruby
133
+ #{sudo_env('ln')} -sf /opt/rh/ruby200/root/usr/bin/gem /usr/bin/gem
142
134
  fi
143
135
  else
144
136
  if [ ! $(which ruby) ]; then
@@ -183,7 +175,7 @@ module Kitchen
183
175
  fi
184
176
  INSTALL
185
177
 
186
- elsif require_chef_for_busser && chef_url then
178
+ elsif require_chef_for_busser && chef_url
187
179
  install << <<-INSTALL
188
180
  # install chef omnibus so that busser works as this is needed to run tests :(
189
181
  if [ ! -d "/opt/chef" ]
@@ -200,10 +192,10 @@ module Kitchen
200
192
  end
201
193
 
202
194
  def init_command
203
- dirs = %w{modules roles group_vars host_vars}.
204
- map { |dir| File.join(config[:root_path], dir) }.join(" ")
195
+ dirs = %w(modules roles group_vars host_vars)
196
+ .map { |dir| File.join(config[:root_path], dir) }.join(' ')
205
197
  cmd = "#{sudo_env('rm')} -rf #{dirs};"
206
- cmd = cmd+" mkdir -p #{config[:root_path]}"
198
+ cmd += " mkdir -p #{config[:root_path]}"
207
199
  debug(cmd)
208
200
  cmd
209
201
  end
@@ -230,7 +222,6 @@ module Kitchen
230
222
  prepare_lookup_plugins
231
223
  prepare_ansible_vault_password_file
232
224
  info('Finished Preparing files for transfer')
233
-
234
225
  end
235
226
 
236
227
  def cleanup_sandbox
@@ -244,19 +235,19 @@ module Kitchen
244
235
 
245
236
  # Prevent failure when ansible package installation doesn't contain /etc/ansible
246
237
  commands << [
247
- sudo_env("bash -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
238
+ sudo_env("bash -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
248
239
  ]
249
240
 
250
241
  commands << [
251
- sudo_env('cp'),File.join(config[:root_path], 'ansible.cfg'),'/etc/ansible',
242
+ sudo_env('cp'), File.join(config[:root_path], 'ansible.cfg'), '/etc/ansible'
252
243
  ].join(' ')
253
244
 
254
245
  commands << [
255
- sudo_env('cp -r'), File.join(config[:root_path],'group_vars'), '/etc/ansible/.',
246
+ sudo_env('cp -r'), File.join(config[:root_path], 'group_vars'), '/etc/ansible/.'
256
247
  ].join(' ')
257
248
 
258
249
  commands << [
259
- sudo_env('cp -r'), File.join(config[:root_path],'host_vars'), '/etc/ansible/.',
250
+ sudo_env('cp -r'), File.join(config[:root_path], 'host_vars'), '/etc/ansible/.'
260
251
  ].join(' ')
261
252
 
262
253
  if galaxy_requirements
@@ -264,9 +255,9 @@ module Kitchen
264
255
  commands << setup_ansible_env_from_source
265
256
  end
266
257
  commands << [
267
- 'ansible-galaxy', 'install', '--force',
268
- '-p', File.join(config[:root_path], 'roles'),
269
- '-r', File.join(config[:root_path], galaxy_requirements),
258
+ 'ansible-galaxy', 'install', '--force',
259
+ '-p', File.join(config[:root_path], 'roles'),
260
+ '-r', File.join(config[:root_path], galaxy_requirements)
270
261
  ].join(' ')
271
262
  end
272
263
 
@@ -279,24 +270,25 @@ module Kitchen
279
270
  if !config[:ansible_playbook_command].nil?
280
271
  return config[:ansible_playbook_command]
281
272
  else
273
+
274
+ cmd = ansible_command('ansible-playbook')
282
275
  if config[:require_ansible_source]
283
276
  # this is an ugly hack to get around the fact that extra vars uses ' and "
284
277
  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")
285
- else
286
- cmd = ansible_command("ansible-playbook")
287
278
  end
279
+
288
280
  if config[:ansible_binary_path]
289
281
  cmd = ansible_command("#{config[:ansible_binary_path]}/ansible-playbook")
290
282
  end
291
- if https_proxy
292
- cmd = "HTTPS_PROXY=#{https_proxy} #{cmd}"
293
- end
294
- if http_proxy
295
- cmd = "HTTP_PROXY=#{http_proxy} #{cmd}"
296
- end
297
- if ansible_roles_path
298
- cmd = "ANSIBLE_ROLES_PATH=#{ansible_roles_path} #{cmd}"
299
- end
283
+
284
+ cmd = "HTTPS_PROXY=#{https_proxy} #{cmd}" if https_proxy
285
+ cmd = "HTTP_PROXY=#{http_proxy} #{cmd}" if http_proxy
286
+ cmd = "NO_PROXY=#{no_proxy} #{cmd}" if no_proxy
287
+ cmd = "ANSIBLE_ROLES_PATH=#{ansible_roles_path} #{cmd}" if ansible_roles_path
288
+ cmd = "ANSIBLE_HOST_KEY_CHECKING=false #{cmd}" if !ansible_host_key_checking
289
+
290
+ cmd = "#{cd_ansible} #{cmd}" if !config[:ansible_sudo].nil? && !config[:ansible_sudo]
291
+ cmd = "chmod 400 #{private_key_file}; #{cmd}" if config[:private_key] && config[:set_private_key_permissions]
300
292
 
301
293
  result = [
302
294
  cmd,
@@ -307,27 +299,46 @@ module Kitchen
307
299
  ansible_check_flag,
308
300
  ansible_diff_flag,
309
301
  ansible_vault_flag,
302
+ private_key,
310
303
  extra_vars,
311
304
  tags,
312
305
  ansible_extra_flags,
313
- "#{File.join(config[:root_path], File.basename(config[:playbook]))}",
314
- ].join(" ")
306
+ "#{File.join(config[:root_path], File.basename(config[:playbook]))}"
307
+ ].join(' ')
315
308
  info("Going to invoke ansible-playbook with: #{result}")
309
+ if config[:idempotency_test]
310
+ result = "#{result} && echo 'Going to invoke ansible-playbook second time:'; #{result} | tee /tmp/idempotency_test.txt; grep -q 'changed=0.*failed=0' /tmp/idempotency_test.txt && (echo 'Idempotence test: PASS' && exit 0) || (echo 'Idempotence test: FAIL' && exit 1)"
311
+ debug("Full cmd with idempotency test: #{result}")
312
+ end
313
+
316
314
  result
317
315
  end
318
316
  end
319
317
 
320
318
  def ansible_command(script)
321
- config[:ansible_sudo].nil? || config[:ansible_sudo] == true ? sudo_env(script) : script
319
+ if config[:ansible_sudo].nil? || config[:ansible_sudo] == true
320
+ s = https_proxy ? "https_proxy=#{https_proxy}" : nil
321
+ p = http_proxy ? "http_proxy=#{http_proxy}" : nil
322
+ n = no_proxy ? "no_proxy=#{no_proxy}" : nil
323
+ p || s || n ? " #{p} #{s} #{n} sudo -Es #{cd_ansible} #{script}" : "sudo -Es #{cd_ansible} #{script}"
324
+ else
325
+ return script
326
+ end
327
+ end
328
+
329
+ def cd_ansible
330
+ # this is not working so just return nil for now
331
+ # File.exist?('ansible.cfg') ? "cd #{config[:root_path]};" : nil
332
+ nil
322
333
  end
323
334
 
324
335
  protected
325
336
 
326
337
  def load_needed_dependencies!
327
- if File.exists?(ansiblefile)
328
- debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
329
- Ansible::Librarian.load!(logger)
330
- end
338
+ return unless File.exist?(ansiblefile)
339
+
340
+ debug("Ansiblefile found at #{ansiblefile}, loading Librarian-Ansible")
341
+ Ansible::Librarian.load!(logger)
331
342
  end
332
343
 
333
344
  def install_ansible_from_source_command
@@ -357,12 +368,10 @@ module Kitchen
357
368
  end
358
369
 
359
370
  def install_omnibus_command
360
- info("Installing ansible using ansible omnibus")
361
- version = if !config[:ansible_version].nil?
362
- "-v #{config[:ansible_version]}"
363
- else
364
- ""
365
- end
371
+ info('Installing ansible using ansible omnibus')
372
+
373
+ version = ''
374
+ version = "-v #{config[:ansible_version]}" unless config[:ansible_version].nil?
366
375
 
367
376
  <<-INSTALL
368
377
  #{Util.shell_helpers}
@@ -377,69 +386,6 @@ module Kitchen
377
386
  INSTALL
378
387
  end
379
388
 
380
- def install_debian_command
381
- <<-INSTALL
382
- if [ ! $(which ansible) ]; then
383
- #{update_packages_debian_cmd}
384
-
385
- ## Install apt-utils to silence debconf warning: http://serverfault.com/q/358943/77156
386
- #{sudo_env('apt-get')} -y install apt-utils git
387
-
388
- ## Fix debconf tty warning messages
389
- export DEBIAN_FRONTEND=noninteractive
390
-
391
- ## 13.10, 14.04 include add-apt-repository in software-properties-common
392
- #{sudo_env('apt-get')} -y install software-properties-common
393
-
394
- ## 10.04, 12.04 include add-apt-repository in
395
- #{sudo_env('apt-get')} -y install python-software-properties
396
-
397
- ## 10.04 version of add-apt-repository doesn't accept --yes
398
- ## later versions require interaction from user, so we must specify --yes
399
- ## First try with -y flag, else if it fails, try without.
400
- ## "add-apt-repository: error: no such option: -y" is returned but is ok to ignore, we just retry
401
- #{sudo_env('add-apt-repository')} -y #{ansible_apt_repo} || #{sudo_env('add-apt-repository')} #{ansible_apt_repo}
402
- #{sudo_env('apt-get')} update
403
- #{sudo_env('apt-get')} -y install ansible
404
- fi
405
- INSTALL
406
- end
407
-
408
- def install_suse_command
409
- <<-INSTALL
410
- if [ ! $(which ansible) ]; then
411
- #{sudo_env('zypper')} ar #{python_sles_repo}
412
- #{sudo_env('zypper')} ar #{ansible_sles_repo}
413
- #{update_packages_suse_cmd}
414
- #{sudo_env('zypper')} --non-interactive install ansible
415
- fi
416
- INSTALL
417
- end
418
-
419
- def install_redhat_command
420
- <<-INSTALL
421
- if [ ! $(which ansible) ]; then
422
- #{install_epel_repo}
423
- #{sudo_env('rpm')} -ivh #{ansible_yum_repo}
424
- #{update_packages_redhat_cmd}
425
- #{sudo_env('yum')} -y install ansible#{ansible_redhat_version} libselinux-python git
426
- fi
427
- INSTALL
428
- end
429
-
430
- def install_amazon_linux_command
431
- <<-INSTALL
432
- if [ ! $(which ansible) ]; then
433
- #{install_epel_repo}
434
- #{sudo_env('yum-config-manager')} --enable epel/x86_64
435
- #{sudo_env('yum')} -y install ansible#{ansible_redhat_version} git
436
- #{sudo_env('alternatives')} --set python /usr/bin/python2.6
437
- #{sudo_env('yum')} clean all
438
- #{sudo_env('yum')} install yum-python26 -y
439
- fi
440
- INSTALL
441
- end
442
-
443
389
  def setup_ansible_env_from_source
444
390
  "cd #{config[:root_path]}/ansible && source hacking/env-setup && cd ../"
445
391
  end
@@ -560,10 +506,6 @@ module Kitchen
560
506
  config[:ansible_version] ? "=#{config[:ansible_version]}" : nil
561
507
  end
562
508
 
563
- def ansible_redhat_version
564
- config[:ansible_version] ? "-#{config[:ansible_version]}" : nil
565
- end
566
-
567
509
  def ansible_verbose_flag
568
510
  config[:ansible_verbose] ? '-' << ('v' * verbosity_level(config[:ansible_verbosity])) : nil
569
511
  end
@@ -582,7 +524,7 @@ module Kitchen
582
524
  end
583
525
 
584
526
  def ansible_inventory_flag
585
- 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')}"
527
+ 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')}"
586
528
  end
587
529
 
588
530
  def ansible_extra_flags
@@ -593,16 +535,34 @@ module Kitchen
593
535
  config[:ansible_platform].to_s.downcase
594
536
  end
595
537
 
538
+ def ansible_host_key_checking
539
+ config[:ansible_host_key_checking]
540
+ end
541
+
542
+ def private_key
543
+ if config[:private_key]
544
+ "--private-key #{private_key_file}"
545
+ end
546
+ end
547
+
548
+ def private_key_file
549
+ if config[:private_key].start_with?('/') || config[:private_key].start_with?('~')
550
+ "#{config[:private_key]}"
551
+ elsif config[:private_key]
552
+ "#{File.join(config[:root_path], config[:private_key])}"
553
+ end
554
+ end
555
+
596
556
  def update_packages_debian_cmd
597
- config[:update_package_repos] ? "#{sudo_env('apt-get')} update" : nil
557
+ Kitchen::Provisioner::Ansible::Os::Debian.new('debian', config).update_packages_command
598
558
  end
599
559
 
600
560
  def update_packages_suse_cmd
601
- config[:update_package_repos] ? "#{sudo_env('zypper')} --gpg-auto-import-keys ref" : nil
561
+ Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).update_packages_command
602
562
  end
603
563
 
604
564
  def update_packages_redhat_cmd
605
- config[:update_package_repos] ? "#{sudo_env('yum')} makecache" : nil
565
+ Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).update_packages_command
606
566
  end
607
567
 
608
568
  def extra_vars
@@ -622,32 +582,12 @@ module Kitchen
622
582
  bash_tags = config.key?(:attributes) && config[:attributes].key?(:tags) && config[:attributes][:tags].is_a?(Array) ? config[:attributes][:tags] : config[:tags]
623
583
  return nil if bash_tags.empty?
624
584
 
625
- bash_tags = bash_tags.join(",")
585
+ bash_tags = bash_tags.join(',')
626
586
  bash_tags = "-t '#{bash_tags}'"
627
587
  debug(bash_tags)
628
588
  bash_tags
629
589
  end
630
590
 
631
- def ansible_apt_repo
632
- config[:ansible_apt_repo]
633
- end
634
-
635
- def ansible_apt_repo_file
636
- config[:ansible_apt_repo].split('/').last
637
- end
638
-
639
- def ansible_yum_repo
640
- config[:ansible_yum_repo]
641
- end
642
-
643
- def ansible_sles_repo
644
- config[:ansible_sles_repo]
645
- end
646
-
647
- def python_sles_repo
648
- config[:python_sles_repo]
649
- end
650
-
651
591
  def chef_url
652
592
  config[:chef_bootstrap_url]
653
593
  end
@@ -660,10 +600,6 @@ module Kitchen
660
600
  config[:require_chef_for_busser]
661
601
  end
662
602
 
663
- def install_epel_repo
664
- config[:enable_yum_epel] ? sudo_env('yum install epel-release -y') : nil
665
- end
666
-
667
603
  def install_source_rev
668
604
  config[:ansible_source_rev] ? "--branch #{config[:ansible_source_rev]}" : nil
669
605
  end
@@ -684,15 +620,15 @@ module Kitchen
684
620
  s = https_proxy ? "https_proxy=#{https_proxy}" : nil
685
621
  p = http_proxy ? "http_proxy=#{http_proxy}" : nil
686
622
  n = no_proxy ? "no_proxy=#{no_proxy}" : nil
687
- p || s ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
623
+ p || s || n ? "#{sudo('env')} #{p} #{s} #{n} #{pm}" : "#{sudo(pm)}"
688
624
  end
689
625
 
690
626
  def export_http_proxy
691
- cmd = ""
627
+ cmd = ''
692
628
  cmd = " HTTP_PROXY=#{http_proxy}" if http_proxy
693
629
  cmd = "#{cmd} HTTPS_PROXY=#{https_proxy}" if https_proxy
694
630
  cmd = "#{cmd} NO_PROXY=#{no_proxy}" if no_proxy
695
- cmd = "export #{cmd}" if cmd != ""
631
+ cmd = "export #{cmd}" if cmd != ''
696
632
  cmd
697
633
  end
698
634
 
@@ -715,7 +651,7 @@ module Kitchen
715
651
  info('Preparing roles')
716
652
  debug("Using roles from #{roles}")
717
653
 
718
- resolve_with_librarian if File.exists?(ansiblefile)
654
+ resolve_with_librarian if File.exist?(ansiblefile)
719
655
 
720
656
  if galaxy_requirements
721
657
  FileUtils.cp(galaxy_requirements, File.join(sandbox_path, galaxy_requirements))
@@ -733,12 +669,12 @@ module Kitchen
733
669
  info('Preparing ansible.cfg file')
734
670
  ansible_config_file = "#{File.join(sandbox_path, 'ansible.cfg')}"
735
671
  if File.exist?('ansible.cfg')
736
- info("Found existing ansible.cfg")
737
- FileUtils.cp_r('ansible.cfg', ansible_config_file)
672
+ info('Found existing ansible.cfg')
673
+ FileUtils.cp_r('ansible.cfg', ansible_config_file)
738
674
  else
739
675
  info('Empty ansible.cfg generated')
740
- File.open(ansible_config_file, "wb") do |file|
741
- file.write("#no config parameters\n")
676
+ File.open(ansible_config_file, 'wb') do |file|
677
+ file.write("#no config parameters\n")
742
678
  end
743
679
  end
744
680
  end
@@ -746,10 +682,9 @@ module Kitchen
746
682
  def prepare_inventory_file
747
683
  info('Preparing inventory file')
748
684
 
749
- if ansible_inventory_file
750
- debug("Copying inventory file from #{ansible_inventory_file} to #{tmp_inventory_file_path}")
751
- FileUtils.cp_r(ansible_inventory_file, tmp_inventory_file_path)
752
- end
685
+ return unless ansible_inventory_file
686
+ debug("Copying inventory file from #{ansible_inventory_file} to #{tmp_inventory_file_path}")
687
+ FileUtils.cp_r(ansible_inventory_file, tmp_inventory_file_path)
753
688
  end
754
689
 
755
690
  # localhost ansible_connection=local
@@ -760,11 +695,11 @@ module Kitchen
760
695
  info('Preparing hosts file')
761
696
 
762
697
  if config[:hosts].nil?
763
- raise 'No hosts have been set. Please specify one in .kitchen.yml'
698
+ fail 'No hosts have been set. Please specify one in .kitchen.yml'
764
699
  else
765
700
  debug("Using host from #{hosts}")
766
- File.open(File.join(sandbox_path, "hosts"), "wb") do |file|
767
- file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
701
+ File.open(File.join(sandbox_path, 'hosts'), 'wb') do |file|
702
+ file.write("localhost ansible_connection=local\n[#{hosts}]\nlocalhost\n")
768
703
  end
769
704
  end
770
705
  end
@@ -805,10 +740,10 @@ module Kitchen
805
740
 
806
741
  def additional_files
807
742
  additional_files = []
808
- if ( additional_copy )
809
- additional_files = additional_copy.kind_of?(Array) ? additional_copy : [additional_copy]
743
+ if additional_copy
744
+ additional_files = additional_copy.is_a?(Array) ? additional_copy : [additional_copy]
810
745
  end
811
- additional_files.map { |additional_dir | additional_dir.to_s }
746
+ additional_files.map(&:to_s)
812
747
  end
813
748
 
814
749
  def prepare_host_vars
@@ -899,12 +834,12 @@ module Kitchen
899
834
  end
900
835
 
901
836
  def prepare_ansible_vault_password_file
902
- if ansible_vault_password_file
903
- info('Preparing ansible vault password')
904
- debug("Copying ansible vault password file from #{ansible_vault_password_file} to #{tmp_ansible_vault_password_file_path}")
837
+ return unless ansible_vault_password_file
905
838
 
906
- FileUtils.cp(ansible_vault_password_file, tmp_ansible_vault_password_file_path)
907
- end
839
+ info('Preparing ansible vault password')
840
+ debug("Copying ansible vault password file from #{ansible_vault_password_file} to #{tmp_ansible_vault_password_file_path}")
841
+
842
+ FileUtils.cp(ansible_vault_password_file, tmp_ansible_vault_password_file_path)
908
843
  end
909
844
 
910
845
  def resolve_with_librarian