kitchen-yansible 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/kitchen-yansible.gemspec +59 -0
- data/lib/kitchen-yansible/tools/dependencies.rb +90 -0
- data/lib/kitchen-yansible/tools/exec.rb +111 -0
- data/lib/kitchen-yansible/tools/files.rb +179 -0
- data/lib/kitchen-yansible/tools/install.rb +234 -0
- data/lib/kitchen-yansible/tools/install/amazon.rb +67 -0
- data/lib/kitchen-yansible/tools/install/debian.rb +201 -0
- data/lib/kitchen-yansible/tools/install/fedora.rb +33 -0
- data/lib/kitchen-yansible/tools/install/rhel.rb +225 -0
- data/lib/kitchen-yansible/tools/install/windows.rb +122 -0
- data/lib/kitchen-yansible/version.rb +25 -0
- data/lib/kitchen/provisioner/yansible.rb +243 -0
- metadata +101 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# Author: Eugene Akhmetkhanov <axmetishe+github@gmail.com>
|
2
|
+
# Date: 08-01-2020
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Yansible
|
23
|
+
module Tools
|
24
|
+
class Install
|
25
|
+
class Fedora < RHEL
|
26
|
+
def package_manager
|
27
|
+
"#{sudo_env('dnf')}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
# Author: Eugene Akhmetkhanov <axmetishe+github@gmail.com>
|
2
|
+
# Date: 07-01-2020
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Yansible
|
23
|
+
module Tools
|
24
|
+
class Install
|
25
|
+
class RHEL < Install
|
26
|
+
def preinstall_command
|
27
|
+
"""
|
28
|
+
#{update_path}
|
29
|
+
#{update_cache}
|
30
|
+
|
31
|
+
installPackage () {
|
32
|
+
package=$1
|
33
|
+
#{package_manager} -q info ${package} 2>/dev/null|grep installed &>/dev/null || #{install_package} ${package}
|
34
|
+
}
|
35
|
+
|
36
|
+
enableSCLPackage () {
|
37
|
+
package=$1
|
38
|
+
echo \"Enable ${package}\"
|
39
|
+
grep \"/opt/rh/${package}/enable\" /etc/profile.d/${package}.sh &> /dev/null || {
|
40
|
+
#{sudo('echo')} \"source /opt/rh/${package}/enable\"| #{sudo('tee')} -a /etc/profile.d/${package}.sh
|
41
|
+
}
|
42
|
+
source /opt/rh/${package}/enable
|
43
|
+
}
|
44
|
+
|
45
|
+
installRubySCL () {
|
46
|
+
RUBY_PACKAGE=$(#{package_manager} search -q ruby|grep '^rh-ruby\\([0-9\\.]\\+\\)\\?\\.'|sort -r|head -n1|awk '{print $1}'|awk -F'.' '{print $1}')
|
47
|
+
installPackage ${RUBY_PACKAGE}
|
48
|
+
RUBY_VERSION=\"$(#{package_manager} info ${RUBY_PACKAGE}|grep -i version|awk '{print $3}')\"
|
49
|
+
test -L /usr/lib64/libruby.so.${RUBY_VERSION} || {
|
50
|
+
#{sudo('ln')} -sf /opt/rh/${RUBY_PACKAGE}/root/usr/lib64/libruby.so.${RUBY_VERSION} \\
|
51
|
+
/usr/lib64/libruby.so.${RUBY_VERSION}
|
52
|
+
}
|
53
|
+
#{ruby_alternatives('/usr/local/bin', "/opt/rh/${RUBY_PACKAGE}/root/usr/bin")}
|
54
|
+
enableSCLPackage ${RUBY_PACKAGE}
|
55
|
+
}
|
56
|
+
|
57
|
+
installPythonSCL () {
|
58
|
+
PYTHON_PACKAGE='python27 python27-python-virtualenv'
|
59
|
+
installPackage ${PYTHON_PACKAGE}
|
60
|
+
|
61
|
+
#{alternatives_command} --install /usr/local/bin/python python /opt/rh/python27/root/usr/bin/python 100
|
62
|
+
#{alternatives_command} --set python /opt/rh/python27/root/usr/bin/python
|
63
|
+
|
64
|
+
#{sudo('grep')} 'ANSIBLE_PYTHON_INTERPRETER' /etc/profile.d/ansible.sh &> /dev/null || {
|
65
|
+
#{sudo('echo')} \"export ANSIBLE_PYTHON_INTERPRETER=/usr/local/bin/python\"| #{sudo('tee')} -a /etc/profile.d/ansible.sh
|
66
|
+
}
|
67
|
+
#{sudo('grep')} XDG_DATA_DIRS /etc/sudoers.d/ansible &> /dev/null || {
|
68
|
+
#{sudo('echo')} 'Defaults env_keep += \"XDG_DATA_DIRS PKG_CONFIG_PATH ANSIBLE_PYTHON_INTERPRETER\"' | #{sudo('tee')} -a /etc/sudoers.d/ansible
|
69
|
+
}
|
70
|
+
|
71
|
+
test -L /usr/lib64/libpython2.7.so.1.0 || {
|
72
|
+
#{sudo('ln')} -sf /opt/rh/python27/root/usr/lib64/libpython2.7.so.1.0 \\
|
73
|
+
/usr/lib64/libpython2.7.so.1.0
|
74
|
+
}
|
75
|
+
test -L /usr/lib64/libpython2.7.so || {
|
76
|
+
#{sudo('ln')} -sf /usr/lib64/libpython2.7.so.1.0 /usr/lib64/libpython2.7.so
|
77
|
+
}
|
78
|
+
|
79
|
+
enableSCLPackage 'python27'
|
80
|
+
}
|
81
|
+
|
82
|
+
preInstall () {
|
83
|
+
RHEL_VERSION=$(test -f /etc/system-release-cpe && awk -F':' '{print $5}' /etc/system-release-cpe || echo '0')
|
84
|
+
RHEL_DISTR=$(test -f /etc/system-release-cpe && awk -F':' '{print $3}' /etc/system-release-cpe || echo '0')
|
85
|
+
|
86
|
+
# Sanitize CPE Info
|
87
|
+
case ${RHEL_DISTR} in
|
88
|
+
amazon)
|
89
|
+
RHEL_VERSION=6
|
90
|
+
;;
|
91
|
+
o)
|
92
|
+
RHEL_DISTR=amazon
|
93
|
+
RHEL_VERSION=7
|
94
|
+
;;
|
95
|
+
*)
|
96
|
+
;;
|
97
|
+
esac
|
98
|
+
|
99
|
+
if [[ ${RHEL_VERSION} -eq 6 || ${RHEL_VERSION} -eq 7 ]]; then
|
100
|
+
echo \"We are going to use SCL repository for Python and Ruby installation\"
|
101
|
+
echo \"Working with ${RHEL_DISTR} ${RHEL_VERSION}\"
|
102
|
+
case ${RHEL_DISTR} in
|
103
|
+
centos)
|
104
|
+
installPackage centos-release-scl-rh
|
105
|
+
installPythonSCL
|
106
|
+
installRubySCL
|
107
|
+
;;
|
108
|
+
oracle)
|
109
|
+
installPackage oracle-softwarecollection-release-el${RHEL_VERSION}
|
110
|
+
installRubySCL
|
111
|
+
if [[ ${RHEL_VERSION} -eq 6 ]]; then
|
112
|
+
installPythonSCL
|
113
|
+
fi
|
114
|
+
;;
|
115
|
+
*)
|
116
|
+
echo \"Unsupported RHEL SCL family distribution - ${RHEL_DISTR} ${RHEL_VERSION}\"
|
117
|
+
;;
|
118
|
+
esac
|
119
|
+
fi
|
120
|
+
updatePath
|
121
|
+
}
|
122
|
+
"""
|
123
|
+
end
|
124
|
+
|
125
|
+
def install_python
|
126
|
+
"""
|
127
|
+
installPython () {
|
128
|
+
echo 'Checking Python installation.'
|
129
|
+
searchAlternatives 'python'
|
130
|
+
#{command_exists('python')} || {
|
131
|
+
echo 'Python is not installed, attempt to use package manager.'
|
132
|
+
package=$(#{package_manager} search -q python|grep '^python\\([0-9\\.]\\+\\)\\?\\.'|sort -r|head -n1|awk '{print $1}')
|
133
|
+
echo \"Will try to install '${package}' package.\"
|
134
|
+
#{install_package} ${package}
|
135
|
+
echo 'Checking for installed alternatives.'
|
136
|
+
#{command_exists('python')} || {
|
137
|
+
searchAlternatives 'python'
|
138
|
+
}
|
139
|
+
}
|
140
|
+
#{command_exists('python')} || {
|
141
|
+
echo \"===> Couldn't determine Python executable - exiting now! <===\"
|
142
|
+
exit 1
|
143
|
+
}
|
144
|
+
}
|
145
|
+
"""
|
146
|
+
end
|
147
|
+
|
148
|
+
def install_ruby
|
149
|
+
"""
|
150
|
+
installRuby () {
|
151
|
+
echo 'Checking Ruby installation.'
|
152
|
+
searchAlternatives 'ruby'
|
153
|
+
#{command_exists('ruby')} || {
|
154
|
+
echo 'Ruby is not installed, attempt to use package manager.'
|
155
|
+
package=$(#{package_manager} search -q ruby 2> /dev/null|grep '^ruby\\([0-9\\.]\\+\\)\\?\\.'|sort -r|head -n1|awk '{print $1}')
|
156
|
+
echo \"Will try to install '${package}' package.\"
|
157
|
+
#{install_package} ${package}
|
158
|
+
echo 'Checking for installed alternatives.'
|
159
|
+
#{command_exists('ruby')} || {
|
160
|
+
searchAlternatives 'ruby'
|
161
|
+
}
|
162
|
+
grep 'gem: --no-rdoc --no-ri --no-document' /etc/gemrc &> /dev/null || {
|
163
|
+
#{sudo('echo')} 'gem: --no-rdoc --no-ri --no-document' | #{sudo('tee')} /etc/gemrc
|
164
|
+
}
|
165
|
+
}
|
166
|
+
#{command_exists('ruby')} || {
|
167
|
+
echo \"===> Couldn't determine Ruby executable - exiting now! <===\"
|
168
|
+
exit 1
|
169
|
+
}
|
170
|
+
echo 'Install Busser'
|
171
|
+
#{command_exists('gem')} || {
|
172
|
+
#{install_package} rubygems
|
173
|
+
}
|
174
|
+
#{command_exists('rdoc')} || {
|
175
|
+
#{install_package} rubygem-rdoc
|
176
|
+
}
|
177
|
+
#{sudo('gem')} list | grep busser || {
|
178
|
+
#{sudo('gem')} install busser
|
179
|
+
}
|
180
|
+
test -d /opt/chef/embedded/bin || {
|
181
|
+
#{sudo('mkdir')} -p /opt/chef/embedded/bin
|
182
|
+
}
|
183
|
+
echo 'Making links for Chef'
|
184
|
+
for binary in ruby gem busser; do
|
185
|
+
test -L /opt/chef/embedded/bin/${binary} || {
|
186
|
+
#{sudo('ln')} -sf \"$(command -v ${binary})\" /opt/chef/embedded/bin/${binary}
|
187
|
+
}
|
188
|
+
done
|
189
|
+
}
|
190
|
+
"""
|
191
|
+
end
|
192
|
+
|
193
|
+
def install_virtualenv
|
194
|
+
"""
|
195
|
+
installVirtualenv () {
|
196
|
+
echo 'Checking Virtualenv installation.'
|
197
|
+
searchAlternatives 'virtualenv'
|
198
|
+
#{command_exists('virtualenv')} || {
|
199
|
+
echo 'Virtualenv is not installed, will try to guess its name.'
|
200
|
+
if [ $(#{package_manager} search virtualenv|grep '^python.*-virtualenv'|wc -l) -gt 1 ]; then
|
201
|
+
venvPackage=python$(#{get_python_version})-virtualenv
|
202
|
+
echo \"Will try to install '${venvPackage}' package.\"
|
203
|
+
#{install_package} ${venvPackage}
|
204
|
+
else
|
205
|
+
echo \"Installing via virtual package.\"
|
206
|
+
#{install_package} python-virtualenv
|
207
|
+
fi
|
208
|
+
|
209
|
+
echo 'Checking for installed alternatives.'
|
210
|
+
#{command_exists('virtualenv')} || {
|
211
|
+
searchAlternatives 'virtualenv'
|
212
|
+
}
|
213
|
+
}
|
214
|
+
#{command_exists('virtualenv')} || {
|
215
|
+
echo \"===> Couldn't install Virtualenv - exiting now! <===\"
|
216
|
+
exit 1
|
217
|
+
}
|
218
|
+
}
|
219
|
+
"""
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Author: Eugene Akhmetkhanov <axmetishe+github@gmail.com>
|
2
|
+
# Date: 10-01-2020
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
require 'uri'
|
22
|
+
|
23
|
+
module Kitchen
|
24
|
+
module Yansible
|
25
|
+
module Tools
|
26
|
+
class Install
|
27
|
+
class Windows < Install
|
28
|
+
def pip_required_packages
|
29
|
+
[
|
30
|
+
"ansible#{pip_version(ansible_version)}",
|
31
|
+
"pywinrm"
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def install_win_software(url, distr_dir, install_dir, install_arguments, test_binary )
|
36
|
+
"""
|
37
|
+
$downloadUrl = \"#{url}\"
|
38
|
+
$distrDir=\"#{distr_dir}\"
|
39
|
+
$installerName = \"#{File.basename(URI.parse(url).path)}\"
|
40
|
+
$installDir=\"#{install_dir}\"
|
41
|
+
$testBinary=\"#{test_binary}\"
|
42
|
+
mkdir $distrDir -Force | out-null
|
43
|
+
mkdir $installDir -Force | out-null
|
44
|
+
|
45
|
+
try {
|
46
|
+
$binaryInstalled = $False
|
47
|
+
try {
|
48
|
+
$binaryInstalled=(&{#{test_binary} --version} 2>&1 | % gettype) -ne [System.Management.Automation.ErrorRecord]
|
49
|
+
}
|
50
|
+
catch {
|
51
|
+
echo \"#{test_binary.capitalize} is not installed.\"
|
52
|
+
}
|
53
|
+
if (! $binaryInstalled) {
|
54
|
+
if (! (Test-Path \"${distrDir}\\${installerName}\") ) {
|
55
|
+
echo \"Downloading ${installerName}\"
|
56
|
+
Invoke-WebRequest -DisableKeepAlive -UseBasicParsing -Method GET -Uri \"${downloadUrl}\" -OutFile \"${distrDir}\\${installerName}\"
|
57
|
+
}
|
58
|
+
|
59
|
+
echo \"Installing ${installerName}\"
|
60
|
+
$p = Start-Process -Wait -Passthru -FilePath \"${distrDir}\\${installerName}\" -ArgumentList #{install_arguments.join(', ')}
|
61
|
+
|
62
|
+
if ($p.ExitCode -ne 0) {
|
63
|
+
throw \"${installerName} installation was not successful. Received exit code $($p.ExitCode)\"
|
64
|
+
}
|
65
|
+
} else {
|
66
|
+
echo \"#{test_binary.capitalize} installed already. Skipping.\"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
catch {
|
70
|
+
Write-Error ($_ | ft -Property * | out-string) -ErrorAction Continue
|
71
|
+
exit 1
|
72
|
+
}
|
73
|
+
"""
|
74
|
+
end
|
75
|
+
|
76
|
+
def install_python
|
77
|
+
python_version='3.7.6'
|
78
|
+
base_url="https://www.python.org/ftp/python/#{python_version}"
|
79
|
+
installer_name = "python-#{python_version}-amd64.exe"
|
80
|
+
download_url = "#{base_url}/#{installer_name}"
|
81
|
+
base_dir='C:\\python'
|
82
|
+
distr_dir="#{base_dir}\\distr"
|
83
|
+
install_dir="#{base_dir}\\install"
|
84
|
+
install_args = [ '/passive', 'InstallAllUsers=1', 'PrependPath=1', "TargetDir=\"#{install_dir}\"", '/quiet' ]
|
85
|
+
|
86
|
+
"""
|
87
|
+
#{install_win_software(download_url, distr_dir, install_dir, install_args, "python")}
|
88
|
+
"""
|
89
|
+
end
|
90
|
+
|
91
|
+
def install_ruby
|
92
|
+
ruby_version='2.6.5-1'
|
93
|
+
base_url="https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-#{ruby_version}"
|
94
|
+
installer_name = "rubyinstaller-#{ruby_version}-x64.exe"
|
95
|
+
download_url = "#{base_url}/#{installer_name}"
|
96
|
+
base_dir='C:\\opscode\\chef'
|
97
|
+
distr_dir="#{base_dir}\\distr"
|
98
|
+
install_dir="#{base_dir}\\embedded"
|
99
|
+
install_args = [ '/silent', '/lang=en', '/tasks="assocfiles,modpath"', "/dir=\"#{install_dir}\"" ]
|
100
|
+
|
101
|
+
"""
|
102
|
+
#{install_win_software(download_url, distr_dir, install_dir, install_args, "ruby")}
|
103
|
+
"""
|
104
|
+
end
|
105
|
+
|
106
|
+
def local_install
|
107
|
+
"""
|
108
|
+
$ErrorActionPreference = 'Stop'
|
109
|
+
|
110
|
+
#{install_python}
|
111
|
+
#{install_ruby}
|
112
|
+
"""
|
113
|
+
end
|
114
|
+
|
115
|
+
def remote_install
|
116
|
+
"echo 'Not supported'"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Author: Eugene Akhmetkhanov <axmetishe+github@gmail.com>
|
2
|
+
# Date: 03-01-2020
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
module Kitchen
|
22
|
+
module Yansible
|
23
|
+
VERSION = '0.0.1'.freeze
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# Author: Eugene Akhmetkhanov <axmetishe+github@gmail.com>
|
2
|
+
# Date: 03-01-2020
|
3
|
+
#
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
5
|
+
# or more contributor license agreements. See the NOTICE file
|
6
|
+
# distributed with this work for additional information
|
7
|
+
# regarding copyright ownership. The ASF licenses this file
|
8
|
+
# to you under the Apache License, Version 2.0 (the
|
9
|
+
# "License"); you may not use this file except in compliance
|
10
|
+
# with the License. You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing,
|
15
|
+
# software distributed under the License is distributed on an
|
16
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
17
|
+
# KIND, either express or implied. See the License for the
|
18
|
+
# specific language governing permissions and limitations
|
19
|
+
# under the License.
|
20
|
+
|
21
|
+
require 'kitchen'
|
22
|
+
require 'kitchen/errors'
|
23
|
+
require 'kitchen/provisioner/base'
|
24
|
+
require 'kitchen-yansible/tools/install'
|
25
|
+
require 'kitchen-yansible/tools/files'
|
26
|
+
require 'kitchen-yansible/tools/exec'
|
27
|
+
require 'kitchen-yansible/tools/dependencies'
|
28
|
+
|
29
|
+
module Kitchen
|
30
|
+
module Provisioner
|
31
|
+
class Yansible < Base
|
32
|
+
include Kitchen::Yansible::Tools
|
33
|
+
include Kitchen::Yansible::Tools::Exec
|
34
|
+
include Kitchen::Yansible::Tools::Files
|
35
|
+
include Kitchen::Yansible::Tools::Dependencies
|
36
|
+
|
37
|
+
kitchen_provisioner_api_version 2
|
38
|
+
|
39
|
+
DEFAULT_CONFIG = {
|
40
|
+
remote_executor: false,
|
41
|
+
remote_install_path: '/tmp/ansible',
|
42
|
+
sandboxed_executor: false,
|
43
|
+
playbook: 'default.yml',
|
44
|
+
ansible_binary: 'ansible-playbook',
|
45
|
+
ansible_version: nil,
|
46
|
+
ansible_config: nil,
|
47
|
+
ansible_extra_arguments: nil,
|
48
|
+
ansible_force_color: true,
|
49
|
+
ansible_host_key_checking: false,
|
50
|
+
ansible_winrm_auth_transport: nil,
|
51
|
+
ansible_winrm_cert_validation: 'ignore',
|
52
|
+
ansible_verbose: false,
|
53
|
+
ansible_verbosity: 1,
|
54
|
+
ansible_roles_path: 'roles',
|
55
|
+
dependencies: [],
|
56
|
+
}
|
57
|
+
|
58
|
+
# noinspection RubyYardParamTypeMatch
|
59
|
+
DEFAULT_CONFIG.each { |k, v| default_config k, v }
|
60
|
+
|
61
|
+
def install_command
|
62
|
+
info("Installing provisioner software.")
|
63
|
+
info("Working with '#{@instance.platform.os_type}' platform.")
|
64
|
+
debug("Driver info: '#{@instance.driver.diagnose}'.")
|
65
|
+
debug("Transport info: '#{@instance.transport.diagnose}'.")
|
66
|
+
debug("Platform info: '#{@instance.platform.diagnose}'.")
|
67
|
+
instance_platform = detect_platform
|
68
|
+
|
69
|
+
if @config[:remote_executor]
|
70
|
+
if windows_os?
|
71
|
+
message = unindent(<<-MSG)
|
72
|
+
|
73
|
+
===============================================================================
|
74
|
+
We can't use Windows platform with remote installation.
|
75
|
+
Abandon ship!
|
76
|
+
===============================================================================
|
77
|
+
MSG
|
78
|
+
raise UserError, message
|
79
|
+
end
|
80
|
+
info('Using remote executor.')
|
81
|
+
|
82
|
+
"""
|
83
|
+
#{Install.make(@config, instance_platform).remote_install}
|
84
|
+
"""
|
85
|
+
else
|
86
|
+
info('Using local executor.')
|
87
|
+
if command_exists(command) and !@config[:sandboxed_executor]
|
88
|
+
info('Ansible is installed already - proceeding further steps.')
|
89
|
+
else
|
90
|
+
if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
91
|
+
message = unindent(<<-MSG)
|
92
|
+
|
93
|
+
===============================================================================
|
94
|
+
We can't use Windows platform as a Host system for sandboxing.
|
95
|
+
Abandon ship!
|
96
|
+
===============================================================================
|
97
|
+
MSG
|
98
|
+
raise UserError, message
|
99
|
+
else
|
100
|
+
additional_packages = []
|
101
|
+
info('Checking for sandboxed Ansible version.')
|
102
|
+
|
103
|
+
if windows_os?
|
104
|
+
# ok, adding pywinrm
|
105
|
+
info('==> Windows target platform may be tested only using local Ansible installation! <==')
|
106
|
+
additional_packages.push('pywinrm')
|
107
|
+
end
|
108
|
+
|
109
|
+
# create sandbox
|
110
|
+
if command_exists("#{venv_root}/bin/ansible")
|
111
|
+
info("Ansible is installed at '#{venv_root}'.")
|
112
|
+
else
|
113
|
+
info("Ansible is not installed - will try to create local sandbox for execution")
|
114
|
+
if command_exists('virtualenv')
|
115
|
+
system("virtualenv #{venv_root}")
|
116
|
+
system("#{venv_root}/bin/pip install " +
|
117
|
+
"#{Install.make(@config, instance_platform).pip_required_packages.join(' ')}"
|
118
|
+
)
|
119
|
+
else
|
120
|
+
message = unindent(<<-MSG)
|
121
|
+
|
122
|
+
===============================================================================
|
123
|
+
Couldn't find virtualenv binary for sandboxing.
|
124
|
+
Please make sure execution host has Python and VirtualEnv packages installed.
|
125
|
+
===============================================================================
|
126
|
+
MSG
|
127
|
+
raise UserError, message
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
"""
|
134
|
+
#{Install.make(@config, instance_platform).local_install}
|
135
|
+
"""
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def init_command
|
140
|
+
info("Initializing provisioner software.")
|
141
|
+
"mkdir #{windows_os? ? '-Force' : '-p'} #{config[:root_path]}"
|
142
|
+
end
|
143
|
+
|
144
|
+
def prepare_command
|
145
|
+
info("Preparing configuration for provisioner.")
|
146
|
+
unless @config[:remote_executor]
|
147
|
+
generate_inventory(inventory_file)
|
148
|
+
end
|
149
|
+
|
150
|
+
""
|
151
|
+
end
|
152
|
+
|
153
|
+
def create_sandbox
|
154
|
+
super
|
155
|
+
|
156
|
+
directories = %w[
|
157
|
+
roles
|
158
|
+
host_vars
|
159
|
+
group_vars
|
160
|
+
module_utils
|
161
|
+
library
|
162
|
+
callback_plugins
|
163
|
+
connection_plugins
|
164
|
+
filter_plugins
|
165
|
+
lookup_plugins
|
166
|
+
]
|
167
|
+
|
168
|
+
prepare_dependencies(@config[:dependencies])
|
169
|
+
generate_inventory(inventory_file, remote: true)
|
170
|
+
|
171
|
+
info("Copy dependencies to sandbox")
|
172
|
+
copy_dirs_to_sandbox(dependencies_tmp_dir, dst: 'roles')
|
173
|
+
directories.each do |directory|
|
174
|
+
if File.directory?(directory)
|
175
|
+
info("Copy #{directory} to sandbox")
|
176
|
+
copy_dirs_to_sandbox(directory)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
info("Prepare config")
|
180
|
+
prepare_ansible_config
|
181
|
+
info("Prepare playbook")
|
182
|
+
prepare_playbook_file
|
183
|
+
info("Prepare inventory file")
|
184
|
+
prepare_inventory_file
|
185
|
+
end
|
186
|
+
|
187
|
+
def run_command
|
188
|
+
if @config[:remote_executor]
|
189
|
+
info("Execute Ansible remotely.")
|
190
|
+
|
191
|
+
command_env_script = []
|
192
|
+
command_env.each {|k,v| command_env_script.push(shell_env_var(k, v))}
|
193
|
+
|
194
|
+
"""
|
195
|
+
#{command_env_script.join(' ')}; #{command} #{command_args.join(' ')}
|
196
|
+
"""
|
197
|
+
else
|
198
|
+
info("Execute Ansible locally.")
|
199
|
+
execute_local_command("#{command} #{command_args.join(' ')}", env: command_env, print_stdout: true)
|
200
|
+
|
201
|
+
""
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def command
|
206
|
+
return @command if defined? @command
|
207
|
+
|
208
|
+
@command = @config[:ansible_binary]
|
209
|
+
debug("Ansible command: #{@command}")
|
210
|
+
@command
|
211
|
+
end
|
212
|
+
|
213
|
+
def command_env
|
214
|
+
return @command_env if defined? @command_env
|
215
|
+
|
216
|
+
# noinspection RubyStringKeysInHashInspection
|
217
|
+
@command_env = {
|
218
|
+
'ANSIBLE_FORCE_COLOR' => @config[:ansible_force_color].to_s,
|
219
|
+
'ANSIBLE_HOST_KEY_CHECKING' => @config[:ansible_host_key_checking].to_s,
|
220
|
+
'ANSIBLE_INVENTORY_ENABLED' => 'yaml',
|
221
|
+
'ANSIBLE_RETRY_FILES_ENABLED' => false.to_s,
|
222
|
+
'ANSIBLE_ROLES_PATH' => remote_file_path('roles', fallback: generate_sandbox_path('roles')),
|
223
|
+
}
|
224
|
+
@command_env['ANSIBLE_CONFIG'] = @config[:ansible_config] if @config[:ansible_config]
|
225
|
+
|
226
|
+
@command_env
|
227
|
+
end
|
228
|
+
|
229
|
+
def command_args
|
230
|
+
return @command_args if defined? @command_args
|
231
|
+
|
232
|
+
@command_args = []
|
233
|
+
@config[:ansible_extra_arguments].each { |arg| @command_args.push(arg) } if @config[:ansible_extra_arguments]
|
234
|
+
@config[:ansible_verbose] ? @command_args.push('-' + 'v' * @config[:ansible_verbosity]) : ''
|
235
|
+
@command_args.push("--inventory=#{remote_file_path(ANSIBLE_INVENTORY, fallback: inventory_file)}")
|
236
|
+
@command_args.push("--limit=#{@instance.name}")
|
237
|
+
@command_args.push(remote_file_path(@config[:playbook]))
|
238
|
+
|
239
|
+
@command_args
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|