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.
- checksums.yaml +4 -4
- data/README.md +130 -150
- data/kitchen-ansible.gemspec +8 -8
- data/lib/kitchen-ansible/version.rb +2 -1
- data/lib/kitchen/provisioner/ansible/config.rb +16 -23
- data/lib/kitchen/provisioner/ansible/librarian.rb +7 -12
- data/lib/kitchen/provisioner/ansible/os.rb +69 -0
- data/lib/kitchen/provisioner/ansible/os/amazon.rb +41 -0
- data/lib/kitchen/provisioner/ansible/os/debian.rb +60 -0
- data/lib/kitchen/provisioner/ansible/os/redhat.rb +68 -0
- data/lib/kitchen/provisioner/ansible/os/suse.rb +43 -0
- data/lib/kitchen/provisioner/ansible_playbook.rb +130 -195
- data/provisioner_options.md +26 -8
- metadata +7 -2
@@ -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
|
-
|
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
|
-
:
|
53
|
-
env.config_db.local[
|
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
|
-
|
75
|
-
|
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
|
-
|
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
|
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.
|
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 = { :
|
57
|
-
if level.is_a?
|
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?
|
61
|
+
elsif level.is_a?(Integer) && level > 0
|
61
62
|
# puts "Log Level is: #{level}"
|
62
63
|
level
|
63
64
|
else
|
64
|
-
|
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(
|
73
|
+
info('Installing ansible from source')
|
73
74
|
cmd = install_ansible_from_source_command
|
74
75
|
elsif config[:require_ansible_repo]
|
75
|
-
|
76
|
-
|
77
|
-
|
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(
|
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
|
-
|
85
|
+
#{Kitchen::Provisioner::Ansible::Os::Redhat.new('redhat', config).install_command}
|
95
86
|
else
|
96
|
-
|
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
|
-
#{
|
90
|
+
#{Kitchen::Provisioner::Ansible::Os::Suse.new('suse', config).install_command}
|
100
91
|
else
|
101
|
-
#{
|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
if [
|
132
|
-
|
133
|
-
|
134
|
-
#{sudo_env('yum')} install -y
|
135
|
-
#{sudo_env('yum')} install -y
|
136
|
-
|
137
|
-
|
138
|
-
|
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')} -
|
141
|
-
#{sudo_env('ln')} -
|
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
|
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
|
204
|
-
|
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
|
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
|
-
|
238
|
+
sudo_env("bash -c '[ -d /etc/ansible ] || mkdir /etc/ansible'")
|
248
239
|
]
|
249
240
|
|
250
241
|
commands << [
|
251
|
-
|
242
|
+
sudo_env('cp'), File.join(config[:root_path], 'ansible.cfg'), '/etc/ansible'
|
252
243
|
].join(' ')
|
253
244
|
|
254
245
|
commands << [
|
255
|
-
|
246
|
+
sudo_env('cp -r'), File.join(config[:root_path], 'group_vars'), '/etc/ansible/.'
|
256
247
|
].join(' ')
|
257
248
|
|
258
249
|
commands << [
|
259
|
-
|
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
|
-
|
268
|
-
|
269
|
-
|
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
|
-
|
292
|
-
|
293
|
-
|
294
|
-
if
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
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
|
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
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
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(
|
361
|
-
|
362
|
-
|
363
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
737
|
-
|
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,
|
741
|
-
|
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
|
-
|
750
|
-
|
751
|
-
|
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
|
-
|
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,
|
767
|
-
|
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
|
809
|
-
additional_files = 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
|
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
|
-
|
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
|
-
|
907
|
-
|
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
|