vagrant-salt 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rst +131 -170
- data/example/complete/Vagrantfile +67 -0
- data/example/complete/salt/custom-bootstrap-salt.sh +2425 -0
- data/example/complete/salt/key/master.pem +30 -0
- data/example/complete/salt/key/master.pub +14 -0
- data/example/complete/salt/key/minion.pem +30 -0
- data/example/complete/salt/key/minion.pub +14 -0
- data/example/complete/salt/master +459 -0
- data/example/{salt/minion.conf → complete/salt/minion} +1 -2
- data/example/{salt → complete/salt}/roots/pillar/top.sls +0 -0
- data/example/complete/salt/roots/salt/nginx.sls +5 -0
- data/example/complete/salt/roots/salt/top.sls +3 -0
- data/example/masterless/Vagrantfile +18 -0
- data/example/masterless/salt/minion +219 -0
- data/example/{salt/roots/salt → masterless/salt/roots/pillar}/top.sls +0 -0
- data/example/masterless/salt/roots/salt/nginx.sls +5 -0
- data/example/masterless/salt/roots/salt/top.sls +3 -0
- data/lib/vagrant-salt.rb +16 -3
- data/lib/vagrant-salt/config.rb +103 -0
- data/lib/vagrant-salt/errors.rb +11 -0
- data/lib/vagrant-salt/plugin.rb +31 -0
- data/lib/vagrant-salt/provisioner.rb +211 -104
- data/lib/vagrant-salt/version.rb +5 -0
- data/scripts/.travis.yml +16 -0
- data/scripts/ChangeLog +39 -0
- data/scripts/LICENSE +16 -0
- data/scripts/README.rst +124 -35
- data/scripts/bootstrap-salt-minion.sh +1815 -381
- data/scripts/bootstrap-salt.sh +2425 -0
- data/scripts/salt-bootstrap.sh +2425 -0
- data/scripts/tests/README.rst +38 -0
- data/scripts/tests/bootstrap/__init__.py +11 -0
- data/{example/salt/key/KEYPAIR_GOES_HERE → scripts/tests/bootstrap/ext/__init__.py} +0 -0
- data/scripts/tests/bootstrap/ext/console.py +100 -0
- data/scripts/tests/bootstrap/ext/os_data.py +199 -0
- data/scripts/tests/bootstrap/test_install.py +586 -0
- data/scripts/tests/bootstrap/test_lint.py +27 -0
- data/scripts/tests/bootstrap/test_usage.py +28 -0
- data/scripts/tests/bootstrap/unittesting.py +216 -0
- data/scripts/tests/ext/checkbashisms +640 -0
- data/scripts/tests/install-testsuite-deps.py +99 -0
- data/scripts/tests/runtests.py +207 -0
- data/templates/locales/en.yml +14 -0
- data/vagrant-salt.gemspec +2 -2
- metadata +43 -10
- data/example/Vagrantfile +0 -26
- data/lib/vagrant_init.rb +0 -1
@@ -0,0 +1,38 @@
|
|
1
|
+
Salt Bootstrap Script - Integration Testing
|
2
|
+
===========================================
|
3
|
+
|
4
|
+
Testing ``salt-bootstrap`` requires both Python and Perl.
|
5
|
+
|
6
|
+
Yes, it's weird that a shell script uses either one of the above languages for testing itself, the
|
7
|
+
explanation though, is simple.
|
8
|
+
|
9
|
+
Perl is required because we use a script, `checkbashisms`_, which does exactly what it's name says.
|
10
|
+
In our case, it tries it's best to find non ``POSIX`` compliant code in our bootstrap script since
|
11
|
+
we require the script to be able to properly execute in any ``POSIX`` compliant shell.
|
12
|
+
|
13
|
+
Python is used in the integration tests. It greatly simplifies running these tests and can even
|
14
|
+
provide some JUnit compliant XML used to generate reports of those tests. Doing this job in shell
|
15
|
+
scripting would be too cumbersome and too complicated.
|
16
|
+
|
17
|
+
Running the tests suite
|
18
|
+
-----------------------
|
19
|
+
|
20
|
+
.. warning:: The test suite is **destructive**. It will install/un-install packages on your system.
|
21
|
+
You must run the suite using ``sudo`` or most / all of the tests will be skipped.
|
22
|
+
|
23
|
+
Running the tests suite is as simple as:
|
24
|
+
|
25
|
+
.. code:: console
|
26
|
+
|
27
|
+
sudo python tests/runtests.py
|
28
|
+
|
29
|
+
For additional information on the available options:
|
30
|
+
|
31
|
+
.. code:: console
|
32
|
+
|
33
|
+
python tests/runtests.py --help
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
.. _`checkbashisms`: http://sourceforge.net/projects/checkbaskisms/
|
38
|
+
.. vim: fenc=utf-8 spell spl=en cc=100 tw=99 fo=want sts=2 sw=2 et
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
bootstrap
|
4
|
+
~~~~~~~~~
|
5
|
+
|
6
|
+
salt-bootstrap script unittesting
|
7
|
+
|
8
|
+
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
9
|
+
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
|
10
|
+
:license: Apache 2.0, see LICENSE for more details.
|
11
|
+
"""
|
File without changes
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# vim: sw=4 ts=4 fenc=utf-8
|
3
|
+
'''
|
4
|
+
getTerminalSize()
|
5
|
+
- get width and height of console
|
6
|
+
- works on linux,os x,windows,cygwin(windows)
|
7
|
+
- taken from http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python
|
8
|
+
'''
|
9
|
+
|
10
|
+
# Import python libs
|
11
|
+
import os
|
12
|
+
import platform
|
13
|
+
import struct
|
14
|
+
import ctypes
|
15
|
+
import subprocess
|
16
|
+
import fcntl
|
17
|
+
import termios
|
18
|
+
|
19
|
+
__all__ = ['getTerminalSize']
|
20
|
+
|
21
|
+
|
22
|
+
def getTerminalSize():
|
23
|
+
current_os = platform.system()
|
24
|
+
tuple_xy=None
|
25
|
+
if current_os == 'Windows':
|
26
|
+
tuple_xy = _getTerminalSize_windows()
|
27
|
+
if tuple_xy is None:
|
28
|
+
tuple_xy = _getTerminalSize_tput()
|
29
|
+
# needed for window's python in cygwin's xterm!
|
30
|
+
if current_os == 'Linux' or current_os == 'Darwin' or current_os.startswith('CYGWIN'):
|
31
|
+
tuple_xy = _getTerminalSize_linux()
|
32
|
+
if tuple_xy is None:
|
33
|
+
print 'default'
|
34
|
+
tuple_xy = (80, 25) # default value
|
35
|
+
return tuple_xy
|
36
|
+
|
37
|
+
|
38
|
+
def _getTerminalSize_windows():
|
39
|
+
res=None
|
40
|
+
try:
|
41
|
+
# stdin handle is -10
|
42
|
+
# stdout handle is -11
|
43
|
+
# stderr handle is -12
|
44
|
+
|
45
|
+
h = ctypes.windll.kernel32.GetStdHandle(-12)
|
46
|
+
csbi = ctypes.create_string_buffer(22)
|
47
|
+
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
|
48
|
+
except Exception:
|
49
|
+
return None
|
50
|
+
if res:
|
51
|
+
(bufx, bufy, curx, cury, wattr,
|
52
|
+
left, top, right, bottom, maxx, maxy) = struct.unpack('hhhhHhhhhhh', csbi.raw)
|
53
|
+
sizex = right - left + 1
|
54
|
+
sizey = bottom - top + 1
|
55
|
+
return sizex, sizey
|
56
|
+
else:
|
57
|
+
return None
|
58
|
+
|
59
|
+
|
60
|
+
def _getTerminalSize_tput():
|
61
|
+
# get terminal width
|
62
|
+
# src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
|
63
|
+
try:
|
64
|
+
proc=subprocess.Popen(['tput', 'cols'],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
|
65
|
+
output=proc.communicate(input=None)
|
66
|
+
cols=int(output[0])
|
67
|
+
proc=subprocess.Popen(['tput', 'lines'],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
|
68
|
+
output=proc.communicate(input=None)
|
69
|
+
rows=int(output[0])
|
70
|
+
return (cols,rows)
|
71
|
+
except Exception:
|
72
|
+
return None
|
73
|
+
|
74
|
+
|
75
|
+
def _getTerminalSize_linux():
|
76
|
+
def ioctl_GWINSZ(fd):
|
77
|
+
try:
|
78
|
+
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,'1234'))
|
79
|
+
except Exception:
|
80
|
+
return None
|
81
|
+
return cr
|
82
|
+
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
|
83
|
+
if not cr:
|
84
|
+
try:
|
85
|
+
fd = os.open(os.ctermid(), os.O_RDONLY)
|
86
|
+
cr = ioctl_GWINSZ(fd)
|
87
|
+
os.close(fd)
|
88
|
+
except Exception:
|
89
|
+
pass
|
90
|
+
if not cr:
|
91
|
+
try:
|
92
|
+
cr = (os.environ['LINES'], os.environ['COLUMNS'])
|
93
|
+
except Exception:
|
94
|
+
return None
|
95
|
+
return int(cr[1]), int(cr[0])
|
96
|
+
|
97
|
+
|
98
|
+
if __name__ == '__main__':
|
99
|
+
sizex,sizey=getTerminalSize()
|
100
|
+
print 'width =',sizex,'height =',sizey
|
@@ -0,0 +1,199 @@
|
|
1
|
+
'''
|
2
|
+
This file was copied and adapted from salt's source code
|
3
|
+
'''
|
4
|
+
|
5
|
+
import os
|
6
|
+
import re
|
7
|
+
import sys
|
8
|
+
import platform
|
9
|
+
# Extend the default list of supported distros. This will be used for the
|
10
|
+
# /etc/DISTRO-release checking that is part of platform.linux_distribution()
|
11
|
+
from platform import _supported_dists
|
12
|
+
_supported_dists += ('arch', 'mageia', 'meego', 'vmware', 'bluewhite64',
|
13
|
+
'slamd64', 'ovs', 'system', 'mint', 'oracle')
|
14
|
+
|
15
|
+
_REPLACE_LINUX_RE = re.compile(r'linux', re.IGNORECASE)
|
16
|
+
|
17
|
+
# This maps (at most) the first ten characters (no spaces, lowercased) of
|
18
|
+
# 'osfullname' to the 'os' grain that Salt traditionally uses.
|
19
|
+
# Please see os_data() and _supported_dists.
|
20
|
+
# If your system is not detecting properly it likely needs an entry here.
|
21
|
+
_OS_NAME_MAP = {
|
22
|
+
'redhatente': 'RedHat',
|
23
|
+
'gentoobase': 'Gentoo',
|
24
|
+
'archarm': 'Arch ARM',
|
25
|
+
'arch': 'Arch',
|
26
|
+
'debian': 'Debian',
|
27
|
+
'debiangnu/': 'Debian',
|
28
|
+
'fedoraremi': 'Fedora',
|
29
|
+
'amazonami': 'Amazon',
|
30
|
+
'alt': 'ALT',
|
31
|
+
'oracleserv': 'OEL',
|
32
|
+
}
|
33
|
+
|
34
|
+
# Map the 'os' grain to the 'os_family' grain
|
35
|
+
# These should always be capitalized entries as the lookup comes
|
36
|
+
# post-_OS_NAME_MAP. If your system is having trouble with detection, please
|
37
|
+
# make sure that the 'os' grain is capitalized and working correctly first.
|
38
|
+
_OS_FAMILY_MAP = {
|
39
|
+
'Ubuntu': 'Debian',
|
40
|
+
'Fedora': 'RedHat',
|
41
|
+
'CentOS': 'RedHat',
|
42
|
+
'GoOSe': 'RedHat',
|
43
|
+
'Scientific': 'RedHat',
|
44
|
+
'Amazon': 'RedHat',
|
45
|
+
'CloudLinux': 'RedHat',
|
46
|
+
'OVS': 'RedHat',
|
47
|
+
'OEL': 'RedHat',
|
48
|
+
'Mandrake': 'Mandriva',
|
49
|
+
'ESXi': 'VMWare',
|
50
|
+
'Mint': 'Debian',
|
51
|
+
'VMWareESX': 'VMWare',
|
52
|
+
'Bluewhite64': 'Bluewhite',
|
53
|
+
'Slamd64': 'Slackware',
|
54
|
+
'SLES': 'Suse',
|
55
|
+
'SUSE Enterprise Server': 'Suse',
|
56
|
+
'SUSE Enterprise Server': 'Suse',
|
57
|
+
'SLED': 'Suse',
|
58
|
+
'openSUSE': 'Suse',
|
59
|
+
'SUSE': 'Suse',
|
60
|
+
'Solaris': 'Solaris',
|
61
|
+
'SmartOS': 'Solaris',
|
62
|
+
'Arch ARM': 'Arch',
|
63
|
+
'ALT': 'RedHat',
|
64
|
+
'Trisquel': 'Debian'
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
def os_data():
|
69
|
+
'''
|
70
|
+
Return grains pertaining to the operating system
|
71
|
+
'''
|
72
|
+
grains = {
|
73
|
+
'num_gpus': 0,
|
74
|
+
'gpus': [],
|
75
|
+
}
|
76
|
+
|
77
|
+
# Windows Server 2008 64-bit
|
78
|
+
# ('Windows', 'MINIONNAME', '2008ServerR2', '6.1.7601', 'AMD64', 'Intel64 Fam ily 6 Model 23 Stepping 6, GenuineIntel')
|
79
|
+
# Ubuntu 10.04
|
80
|
+
# ('Linux', 'MINIONNAME', '2.6.32-38-server', '#83-Ubuntu SMP Wed Jan 4 11:26:59 UTC 2012', 'x86_64', '')
|
81
|
+
(grains['kernel'], grains['nodename'],
|
82
|
+
grains['kernelrelease'], version, grains['cpuarch'], _) = platform.uname()
|
83
|
+
if sys.platform.startswith('win'):
|
84
|
+
grains['osrelease'] = grains['kernelrelease']
|
85
|
+
grains['osversion'] = grains['kernelrelease'] = version
|
86
|
+
grains['os'] = 'Windows'
|
87
|
+
grains['os_family'] = 'Windows'
|
88
|
+
return grains
|
89
|
+
elif sys.platform.startswith('linux'):
|
90
|
+
# Add lsb grains on any distro with lsb-release
|
91
|
+
try:
|
92
|
+
import lsb_release
|
93
|
+
release = lsb_release.get_distro_information()
|
94
|
+
for key, value in release.iteritems():
|
95
|
+
grains['lsb_{0}'.format(key.lower())] = value # override /etc/lsb-release
|
96
|
+
except ImportError:
|
97
|
+
# if the python library isn't available, default to regex
|
98
|
+
if os.path.isfile('/etc/lsb-release'):
|
99
|
+
with open('/etc/lsb-release') as ifile:
|
100
|
+
for line in ifile:
|
101
|
+
# Matches any possible format:
|
102
|
+
# DISTRIB_ID="Ubuntu"
|
103
|
+
# DISTRIB_ID='Mageia'
|
104
|
+
# DISTRIB_ID=Fedora
|
105
|
+
# DISTRIB_RELEASE='10.10'
|
106
|
+
# DISTRIB_CODENAME='squeeze'
|
107
|
+
# DISTRIB_DESCRIPTION='Ubuntu 10.10'
|
108
|
+
regex = re.compile('^(DISTRIB_(?:ID|RELEASE|CODENAME|DESCRIPTION))=(?:\'|")?([\w\s\.-_]+)(?:\'|")?')
|
109
|
+
match = regex.match(line.rstrip('\n'))
|
110
|
+
if match:
|
111
|
+
# Adds: lsb_distrib_{id,release,codename,description}
|
112
|
+
grains['lsb_{0}'.format(match.groups()[0].lower())] = match.groups()[1].rstrip()
|
113
|
+
elif os.path.isfile('/etc/os-release'):
|
114
|
+
# Arch ARM linux
|
115
|
+
with open('/etc/os-release') as ifile:
|
116
|
+
# Imitate lsb-release
|
117
|
+
for line in ifile:
|
118
|
+
# NAME="Arch Linux ARM"
|
119
|
+
# ID=archarm
|
120
|
+
# ID_LIKE=arch
|
121
|
+
# PRETTY_NAME="Arch Linux ARM"
|
122
|
+
# ANSI_COLOR="0;36"
|
123
|
+
# HOME_URL="http://archlinuxarm.org/"
|
124
|
+
# SUPPORT_URL="https://archlinuxarm.org/forum"
|
125
|
+
# BUG_REPORT_URL="https://github.com/archlinuxarm/PKGBUILDs/issues"
|
126
|
+
regex = re.compile('^([\w]+)=(?:\'|")?([\w\s\.-_]+)(?:\'|")?')
|
127
|
+
match = regex.match(line.rstrip('\n'))
|
128
|
+
if match:
|
129
|
+
name, value = match.groups()
|
130
|
+
if name.lower() == 'name':
|
131
|
+
grains['lsb_distrib_id'] = value.strip()
|
132
|
+
elif os.path.isfile('/etc/altlinux-release'):
|
133
|
+
# ALT Linux
|
134
|
+
grains['lsb_distrib_id'] = 'altlinux'
|
135
|
+
with open('/etc/altlinux-release') as ifile:
|
136
|
+
# This file is symlinked to from:
|
137
|
+
# /etc/fedora-release
|
138
|
+
# /etc/redhat-release
|
139
|
+
# /etc/system-release
|
140
|
+
for line in ifile:
|
141
|
+
# ALT Linux Sisyphus (unstable)
|
142
|
+
comps = line.split()
|
143
|
+
if comps[0] == 'ALT':
|
144
|
+
grains['lsb_distrib_release'] = comps[2]
|
145
|
+
grains['lsb_distrib_codename'] = \
|
146
|
+
comps[3].replace('(', '').replace(')', '')
|
147
|
+
# Use the already intelligent platform module to get distro info
|
148
|
+
(osname, osrelease, oscodename) = platform.linux_distribution(
|
149
|
+
supported_dists=_supported_dists)
|
150
|
+
# Try to assign these three names based on the lsb info, they tend to
|
151
|
+
# be more accurate than what python gets from /etc/DISTRO-release.
|
152
|
+
# It's worth noting that Ubuntu has patched their Python distribution
|
153
|
+
# so that platform.linux_distribution() does the /etc/lsb-release
|
154
|
+
# parsing, but we do it anyway here for the sake for full portability.
|
155
|
+
grains['osfullname'] = grains.get('lsb_distrib_id', osname).strip()
|
156
|
+
grains['osrelease'] = grains.get('lsb_distrib_release', osrelease).strip()
|
157
|
+
grains['oscodename'] = grains.get('lsb_distrib_codename', oscodename).strip()
|
158
|
+
distroname = _REPLACE_LINUX_RE.sub('', grains['osfullname']).strip()
|
159
|
+
# return the first ten characters with no spaces, lowercased
|
160
|
+
shortname = distroname.replace(' ', '').lower()[:10]
|
161
|
+
# this maps the long names from the /etc/DISTRO-release files to the
|
162
|
+
# traditional short names that Salt has used.
|
163
|
+
grains['os'] = _OS_NAME_MAP.get(shortname, distroname)
|
164
|
+
elif grains['kernel'] == 'SunOS':
|
165
|
+
grains['os'] = 'Solaris'
|
166
|
+
if os.path.isfile('/etc/release'):
|
167
|
+
with open('/etc/release', 'r') as fp_:
|
168
|
+
rel_data = fp_.read()
|
169
|
+
if 'SmartOS' in rel_data:
|
170
|
+
grains['os'] = 'SmartOS'
|
171
|
+
#grains.update(_sunos_cpudata(grains))
|
172
|
+
elif grains['kernel'] == 'VMkernel':
|
173
|
+
grains['os'] = 'ESXi'
|
174
|
+
elif grains['kernel'] == 'Darwin':
|
175
|
+
grains['os'] = 'MacOS'
|
176
|
+
# grains.update(_bsd_cpudata(grains))
|
177
|
+
else:
|
178
|
+
grains['os'] = grains['kernel']
|
179
|
+
if grains['kernel'] in ('FreeBSD', 'OpenBSD'):
|
180
|
+
grains['os'] = grains['kernel']
|
181
|
+
grains['os_family'] = grains['os']
|
182
|
+
grains['osfullname'] = "{0} {1}".format(grains['kernel'], grains['kernelrelease'])
|
183
|
+
grains['osrelease'] = grains['kernelrelease']
|
184
|
+
# grains.update(_bsd_cpudata(grains))
|
185
|
+
if not grains['os']:
|
186
|
+
grains['os'] = 'Unknown {0}'.format(grains['kernel'])
|
187
|
+
grains['os_family'] = 'Unknown'
|
188
|
+
else:
|
189
|
+
# this assigns family names based on the os name
|
190
|
+
# family defaults to the os name if not found
|
191
|
+
grains['os_family'] = _OS_FAMILY_MAP.get(grains['os'], grains['os'])
|
192
|
+
|
193
|
+
return grains
|
194
|
+
|
195
|
+
GRAINS = os_data()
|
196
|
+
|
197
|
+
if __name__ == '__main__':
|
198
|
+
import pprint
|
199
|
+
pprint.pprint(GRAINS)
|
@@ -0,0 +1,586 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
'''
|
3
|
+
bootstrap.test_install
|
4
|
+
~~~~~~~~~~~~~~~~~~~~~~
|
5
|
+
|
6
|
+
Run installation tests.
|
7
|
+
|
8
|
+
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
9
|
+
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
|
10
|
+
:license: Apache 2.0, see LICENSE for more details.
|
11
|
+
'''
|
12
|
+
|
13
|
+
import glob
|
14
|
+
import shutil
|
15
|
+
from bootstrap.unittesting import *
|
16
|
+
|
17
|
+
|
18
|
+
CLEANUP_COMMANDS_BY_OS_FAMILY = {
|
19
|
+
'Arch': [
|
20
|
+
'pacman -Qs python2-crypto && pacman -Rsc --noconfirm python2-crypto && exit $? || exit 0',
|
21
|
+
'pacman -Qs python2-distribute && pacman -Rsc --noconfirm python2-distribute && exit $? || exit 0',
|
22
|
+
'pacman -Qs python2-jinja && pacman -Rsc --noconfirm python2-jinja && exit $? || exit 0',
|
23
|
+
'pacman -Qs python2-m2crypto && pacman -Rsc --noconfirm python2-m2crypto && exit $? || exit 0',
|
24
|
+
'pacman -Qs python2-markupsafe && pacman -Rsc --noconfirm python2-markupsafe && exit $? || exit 0',
|
25
|
+
'pacman -Qs python2-msgpack && pacman -Rsc --noconfirm python2-msgpack && exit $? || exit 0',
|
26
|
+
'pacman -Qs python2-psutil && pacman -Rsc --noconfirm python2-psutil && exit $? || exit 0',
|
27
|
+
'pacman -Qs python2-pyzmq && pacman -Rsc --noconfirm python2-pyzmq && exit $? || exit 0',
|
28
|
+
'pacman -Qs zeromq && pacman -Rsc --noconfirm zeromq && exit $? || exit 0',
|
29
|
+
],
|
30
|
+
'Debian': [
|
31
|
+
'apt-get remove -y -o DPkg::Options::=--force-confold '
|
32
|
+
'--purge salt-master salt-minion salt-syndic python-crypto '
|
33
|
+
'python-jinja2 python-m2crypto python-yaml msgpack-python python-zmq',
|
34
|
+
'apt-get autoremove -y -o DPkg::Options::=--force-confold --purge',
|
35
|
+
'rm -rf /etc/apt/sources.list.d/saltstack-salt-*'
|
36
|
+
],
|
37
|
+
'RedHat': [
|
38
|
+
'yum -y remove salt-minion salt-master',
|
39
|
+
'yum -y remove python{0}-m2crypto m2crypto python{0}-crypto '
|
40
|
+
'python{0}-msgpack python{0}-zmq python{0}-jinja2'.format(
|
41
|
+
GRAINS['osrelease'].split('.')[0] == '5' and '26' or ''
|
42
|
+
),
|
43
|
+
],
|
44
|
+
'FreeBSD': [
|
45
|
+
'pkg delete -y swig sysutils/py-salt',
|
46
|
+
'pkg autoremove -y'
|
47
|
+
],
|
48
|
+
'Solaris': [
|
49
|
+
'pkgin -y rm libtool-base autoconf automake libuuid gcc-compiler '
|
50
|
+
'gmake py27-setuptools py27-yaml py27-crypto swig',
|
51
|
+
'svcs network/salt-minion >/dev/null 2>&1 && svcadm disable network/salt-minion >/dev/null 2>&1 || exit 0',
|
52
|
+
'svcs network/salt-minion >/dev/null 2>&1 && svccfg delete network/salt-minion >/dev/null 2>&1 || exit 0',
|
53
|
+
'svcs network/salt-master >/dev/null 2>&1 && svcadm disable network/salt-master >/dev/null 2>&1 || exit 0',
|
54
|
+
'svcs network/salt-master >/dev/null 2>&1 && svccfg delete network/salt-master >/dev/null 2>&1 || exit 0',
|
55
|
+
'svcs network/salt-syndic >/dev/null 2>&1 && svcadm disable network/salt-syndic >/dev/null 2>&1 || exit 0',
|
56
|
+
'svcs network/salt-syndic >/dev/null 2>&1 && svccfg delete network/salt-syndic >/dev/null 2>&1 || exit 0'
|
57
|
+
],
|
58
|
+
'Suse': [
|
59
|
+
'(zypper --non-interactive se -i salt-master || exit 0 && zypper --non-interactive remove salt-master && exit 0) || '
|
60
|
+
'(rpm -q salt-master && rpm -e --noscripts salt-master || exit 0)',
|
61
|
+
'(zypper --non-interactive se -i salt-minion || exit 0 && zypper --non-interactive remove salt-minion && exit 0) || '
|
62
|
+
'(rpm -q salt-minion && rpm -e --noscripts salt-minion || exit 0)',
|
63
|
+
'(zypper --non-interactive se -i salt-syndic || exit 0 && zypper --non-interactive remove salt-syndic && exit 0) || '
|
64
|
+
'(rpm -q salt-syndic && rpm -e --noscripts salt-syndic || exit 0)',
|
65
|
+
'(zypper --non-interactive se -i salt || exit 0 && zypper --non-interactive remove salt && exit 0) || '
|
66
|
+
'(rpm -q salt && rpm -e --noscripts salt || exit 0)',
|
67
|
+
'pip uninstall -y salt >/dev/null 2>&1 || exit 0',
|
68
|
+
'pip uninstall -y PyYaml >/dev/null 2>&1 || exit 0',
|
69
|
+
'zypper --non-interactive remove libzmq3 python-Jinja2 '
|
70
|
+
'python-M2Crypto python-PyYAML python-msgpack-python '
|
71
|
+
'python-pycrypto python-pyzmq',
|
72
|
+
]
|
73
|
+
}
|
74
|
+
|
75
|
+
OS_REQUIRES_PIP_ALLOWED = (
|
76
|
+
# Some distributions can only install salt or some of its dependencies
|
77
|
+
# passing -P to the bootstrap script.
|
78
|
+
# The GRAINS['os'] which are in this list, requires that extra argument.
|
79
|
+
'Debian',
|
80
|
+
'SmartOS',
|
81
|
+
'Suse' # Need to revisit openSUSE and SLES for the proper OS grain.
|
82
|
+
)
|
83
|
+
|
84
|
+
# SLES grains differ from openSUSE, let do a 1:1 direct mapping
|
85
|
+
CLEANUP_COMMANDS_BY_OS_FAMILY['SUSE Enterprise Server'] = CLEANUP_COMMANDS_BY_OS_FAMILY['Suse']
|
86
|
+
|
87
|
+
|
88
|
+
class InstallationTestCase(BootstrapTestCase):
|
89
|
+
|
90
|
+
def setUp(self):
|
91
|
+
if os.geteuid() is not 0:
|
92
|
+
self.skipTest('you must be root to run this test')
|
93
|
+
|
94
|
+
if GRAINS['os_family'] not in CLEANUP_COMMANDS_BY_OS_FAMILY:
|
95
|
+
self.skipTest(
|
96
|
+
'There is not `tearDown()` clean up support for {0!r} OS '
|
97
|
+
'family.'.format(
|
98
|
+
GRAINS['os_family']
|
99
|
+
)
|
100
|
+
)
|
101
|
+
|
102
|
+
def tearDown(self):
|
103
|
+
for cleanup in CLEANUP_COMMANDS_BY_OS_FAMILY[GRAINS['os_family']]:
|
104
|
+
print 'Running cleanup command {0!r}'.format(cleanup)
|
105
|
+
self.assert_script_result(
|
106
|
+
'Failed to execute cleanup command {0!r}'.format(cleanup),
|
107
|
+
(
|
108
|
+
0, # Proper exit code without errors.
|
109
|
+
|
110
|
+
4, # ZYPPER_EXIT_ERR_ZYPP: A problem reported by ZYPP
|
111
|
+
# library.
|
112
|
+
|
113
|
+
65, # FreeBSD throws this error code when the packages
|
114
|
+
# being un-installed were not installed in the first
|
115
|
+
# place.
|
116
|
+
|
117
|
+
100, # Same as above but on Ubuntu with a another errno
|
118
|
+
|
119
|
+
104, # ZYPPER_EXIT_INF_CAP_NOT_FOUND: Returned by the
|
120
|
+
# install and the remove command in case any of
|
121
|
+
# the arguments does not match any of the available
|
122
|
+
# (or installed) package names or other capabilities.
|
123
|
+
),
|
124
|
+
self.run_script(
|
125
|
+
script=None,
|
126
|
+
args=cleanup.split(),
|
127
|
+
timeout=15 * 60,
|
128
|
+
stream_stds=True
|
129
|
+
)
|
130
|
+
)
|
131
|
+
|
132
|
+
# As a last resort, by hand house cleaning...
|
133
|
+
for glob_rule in ('/tmp/git', '/usr/lib*/python*/site-packages/salt*',
|
134
|
+
'/usr/bin/salt*', '/usr/lib/systemd/system/salt*',
|
135
|
+
'/etc/init*/salt*', '/usr/share/doc/salt*',
|
136
|
+
'/usr/share/man/man*/salt*', '/var/*/salt*',
|
137
|
+
'/etc/salt'):
|
138
|
+
for entry in glob.glob(glob_rule):
|
139
|
+
if os.path.isfile(entry):
|
140
|
+
print 'Removing file {0!r}'.format(entry)
|
141
|
+
os.remove(entry)
|
142
|
+
elif os.path.isdir(entry):
|
143
|
+
print 'Removing directory {0!r}'.format(entry)
|
144
|
+
shutil.rmtree(entry)
|
145
|
+
|
146
|
+
def test_install_using_bash(self):
|
147
|
+
if not os.path.exists('/bin/bash'):
|
148
|
+
self.skipTest('\'/bin/bash\' was not found on this system')
|
149
|
+
|
150
|
+
args = []
|
151
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
152
|
+
args.append('-P')
|
153
|
+
|
154
|
+
self.assert_script_result(
|
155
|
+
'Failed to install using bash',
|
156
|
+
0,
|
157
|
+
self.run_script(
|
158
|
+
args=args,
|
159
|
+
executable='/bin/bash',
|
160
|
+
timeout=15 * 60,
|
161
|
+
stream_stds=True
|
162
|
+
)
|
163
|
+
)
|
164
|
+
|
165
|
+
# Try to get the versions report
|
166
|
+
self.assert_script_result(
|
167
|
+
'Failed to get the versions report (\'--versions-report\')',
|
168
|
+
0,
|
169
|
+
self.run_script(
|
170
|
+
script=None,
|
171
|
+
args=('salt-minion', '--versions-report'),
|
172
|
+
timeout=15 * 60,
|
173
|
+
stream_stds=True
|
174
|
+
)
|
175
|
+
)
|
176
|
+
|
177
|
+
def test_install_using_sh(self):
|
178
|
+
args = []
|
179
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
180
|
+
args.append('-P')
|
181
|
+
|
182
|
+
self.assert_script_result(
|
183
|
+
'Failed to install using sh',
|
184
|
+
0,
|
185
|
+
self.run_script(
|
186
|
+
args=args,
|
187
|
+
timeout=15 * 60,
|
188
|
+
stream_stds=True
|
189
|
+
)
|
190
|
+
)
|
191
|
+
|
192
|
+
# Try to get the versions report
|
193
|
+
self.assert_script_result(
|
194
|
+
'Failed to get the versions report (\'--versions-report\')',
|
195
|
+
0,
|
196
|
+
self.run_script(
|
197
|
+
script=None,
|
198
|
+
args=('salt-minion', '--versions-report'),
|
199
|
+
timeout=15 * 60,
|
200
|
+
stream_stds=True
|
201
|
+
)
|
202
|
+
)
|
203
|
+
|
204
|
+
def test_install_explicit_stable(self):
|
205
|
+
args = []
|
206
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
207
|
+
args.append('-P')
|
208
|
+
|
209
|
+
args.append('stable')
|
210
|
+
|
211
|
+
self.assert_script_result(
|
212
|
+
'Failed to install explicit stable using sh',
|
213
|
+
0,
|
214
|
+
self.run_script(
|
215
|
+
args=args,
|
216
|
+
timeout=15 * 60,
|
217
|
+
stream_stds=True
|
218
|
+
)
|
219
|
+
)
|
220
|
+
|
221
|
+
# Try to get the versions report
|
222
|
+
self.assert_script_result(
|
223
|
+
'Failed to get the versions report (\'--versions-report\')',
|
224
|
+
0,
|
225
|
+
self.run_script(
|
226
|
+
script=None,
|
227
|
+
args=('salt-minion', '--versions-report'),
|
228
|
+
timeout=15 * 60,
|
229
|
+
stream_stds=True
|
230
|
+
)
|
231
|
+
)
|
232
|
+
|
233
|
+
def test_install_daily(self):
|
234
|
+
args = []
|
235
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
236
|
+
args.append('-P')
|
237
|
+
|
238
|
+
args.append('daily')
|
239
|
+
|
240
|
+
rc, out, err = self.run_script(
|
241
|
+
args=args, timeout=15 * 60, stream_stds=True
|
242
|
+
)
|
243
|
+
if GRAINS['os'] in ('Ubuntu', 'Trisquel'):
|
244
|
+
self.assert_script_result(
|
245
|
+
'Failed to install daily',
|
246
|
+
0, (rc, out, err)
|
247
|
+
)
|
248
|
+
|
249
|
+
# Try to get the versions report
|
250
|
+
self.assert_script_result(
|
251
|
+
'Failed to get the versions report (\'--versions-report\')',
|
252
|
+
0,
|
253
|
+
self.run_script(
|
254
|
+
script=None,
|
255
|
+
args=('salt-minion', '--versions-report'),
|
256
|
+
timeout=15 * 60,
|
257
|
+
stream_stds=True
|
258
|
+
)
|
259
|
+
)
|
260
|
+
else:
|
261
|
+
self.assert_script_result(
|
262
|
+
'Although system is not Ubuntu, we managed to install',
|
263
|
+
1, (rc, out, err)
|
264
|
+
)
|
265
|
+
|
266
|
+
def test_install_stable_piped_through_sh(self):
|
267
|
+
args = 'cat {0} | sh '.format(BOOTSTRAP_SCRIPT_PATH).split()
|
268
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
269
|
+
args.extend('-s -- -P'.split())
|
270
|
+
|
271
|
+
self.assert_script_result(
|
272
|
+
'Failed to install stable piped through sh',
|
273
|
+
0,
|
274
|
+
self.run_script(
|
275
|
+
script=None,
|
276
|
+
args=args,
|
277
|
+
timeout=15 * 60,
|
278
|
+
stream_stds=True
|
279
|
+
)
|
280
|
+
)
|
281
|
+
|
282
|
+
# Try to get the versions report
|
283
|
+
self.assert_script_result(
|
284
|
+
'Failed to get the versions report (\'--versions-report\')',
|
285
|
+
0,
|
286
|
+
self.run_script(
|
287
|
+
script=None,
|
288
|
+
args=('salt-minion', '--versions-report'),
|
289
|
+
timeout=15 * 60,
|
290
|
+
stream_stds=True
|
291
|
+
)
|
292
|
+
)
|
293
|
+
|
294
|
+
#def test_install_latest_from_git_develop(self):
|
295
|
+
# args = []
|
296
|
+
# if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
297
|
+
# args.append('-P')
|
298
|
+
#
|
299
|
+
# args.extend(['git', 'develop'])
|
300
|
+
#
|
301
|
+
# self.assert_script_result(
|
302
|
+
# 'Failed to install using latest git develop',
|
303
|
+
# 0,
|
304
|
+
# self.run_script(
|
305
|
+
# args=args,
|
306
|
+
# timeout=15 * 60,
|
307
|
+
# stream_stds=True
|
308
|
+
# )
|
309
|
+
# )
|
310
|
+
#
|
311
|
+
# # Try to get the versions report
|
312
|
+
# self.assert_script_result(
|
313
|
+
# 'Failed to get the versions report (\'--versions-report\')',
|
314
|
+
# 0,
|
315
|
+
# self.run_script(
|
316
|
+
# script=None,
|
317
|
+
# args=('salt', '--versions-report'),
|
318
|
+
# timeout=15 * 60,
|
319
|
+
# stream_stds=True
|
320
|
+
# )
|
321
|
+
# )
|
322
|
+
|
323
|
+
def test_install_specific_git_tag(self):
|
324
|
+
args = []
|
325
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
326
|
+
args.append('-P')
|
327
|
+
|
328
|
+
args.extend(['git', 'v0.13.1'])
|
329
|
+
|
330
|
+
self.assert_script_result(
|
331
|
+
'Failed to install using specific git tag',
|
332
|
+
0,
|
333
|
+
self.run_script(
|
334
|
+
args=args,
|
335
|
+
timeout=15 * 60,
|
336
|
+
stream_stds=True
|
337
|
+
)
|
338
|
+
)
|
339
|
+
|
340
|
+
# Try to get the versions report
|
341
|
+
self.assert_script_result(
|
342
|
+
'Failed to get the versions report (\'--versions-report\')',
|
343
|
+
0,
|
344
|
+
self.run_script(
|
345
|
+
script=None,
|
346
|
+
args=('salt', '--versions-report'),
|
347
|
+
timeout=15 * 60,
|
348
|
+
stream_stds=True
|
349
|
+
)
|
350
|
+
)
|
351
|
+
|
352
|
+
def test_install_specific_git_sha(self):
|
353
|
+
args = []
|
354
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
355
|
+
args.append('-P')
|
356
|
+
|
357
|
+
args.extend(['git', '2b6264de62bf2ea221bb2c0b8af36dfcfaafe7cf'])
|
358
|
+
|
359
|
+
self.assert_script_result(
|
360
|
+
'Failed to install using specific git sha',
|
361
|
+
0,
|
362
|
+
self.run_script(
|
363
|
+
args=args,
|
364
|
+
timeout=15 * 60,
|
365
|
+
stream_stds=True
|
366
|
+
)
|
367
|
+
)
|
368
|
+
|
369
|
+
# Try to get the versions report
|
370
|
+
self.assert_script_result(
|
371
|
+
'Failed to get the versions report (\'--versions-report\')',
|
372
|
+
0,
|
373
|
+
self.run_script(
|
374
|
+
script=None,
|
375
|
+
args=('salt', '--versions-report'),
|
376
|
+
timeout=15 * 60,
|
377
|
+
stream_stds=True
|
378
|
+
)
|
379
|
+
)
|
380
|
+
|
381
|
+
def test_config_only_without_config_dir_fails(self):
|
382
|
+
'''
|
383
|
+
Test running in configuration mode only without providing the necessary
|
384
|
+
configuration directory fails.
|
385
|
+
'''
|
386
|
+
self.assert_script_result(
|
387
|
+
'The script successfully executed even though no configuration '
|
388
|
+
'directory was provided.',
|
389
|
+
1,
|
390
|
+
self.run_script(args=('-C',))
|
391
|
+
)
|
392
|
+
|
393
|
+
def test_config_with_a_non_existing_configuration_dir_fails(self):
|
394
|
+
'''
|
395
|
+
Do we fail if the passed configuration directory passed does not exits?
|
396
|
+
'''
|
397
|
+
self.assert_script_result(
|
398
|
+
'The script successfully executed even though the configuration '
|
399
|
+
'directory provided does not exist.',
|
400
|
+
1,
|
401
|
+
self.run_script(
|
402
|
+
args=('-C', '-c', '/tmp/this-directory-must-not-exist')
|
403
|
+
)
|
404
|
+
)
|
405
|
+
|
406
|
+
def test_config_only_without_actually_configuring_anything_fails(self):
|
407
|
+
'''
|
408
|
+
Test running in configuration mode only without actually configuring
|
409
|
+
anything fails.
|
410
|
+
'''
|
411
|
+
rc, out, err = self.run_script(
|
412
|
+
args=('-C', '-n', '-c', '/tmp'),
|
413
|
+
)
|
414
|
+
|
415
|
+
self.assert_script_result(
|
416
|
+
'The script did not show a warning even though no configuration '
|
417
|
+
'was done.',
|
418
|
+
0, (rc, out, err)
|
419
|
+
)
|
420
|
+
self.assertIn(
|
421
|
+
'WARN: No configuration or keys were copied over. No '
|
422
|
+
'configuration was done!',
|
423
|
+
'\n'.join(out)
|
424
|
+
)
|
425
|
+
|
426
|
+
def test_install_salt_master(self):
|
427
|
+
'''
|
428
|
+
Test if installing a salt-master works
|
429
|
+
'''
|
430
|
+
args = []
|
431
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
432
|
+
args.append('-P')
|
433
|
+
|
434
|
+
args.extend(['-N', '-M'])
|
435
|
+
|
436
|
+
self.assert_script_result(
|
437
|
+
'Failed to install salt-master',
|
438
|
+
0,
|
439
|
+
self.run_script(
|
440
|
+
args=args,
|
441
|
+
timeout=15 * 60,
|
442
|
+
stream_stds=True
|
443
|
+
)
|
444
|
+
)
|
445
|
+
|
446
|
+
# Try to get the versions report
|
447
|
+
self.assert_script_result(
|
448
|
+
'Failed to get the versions report from salt-master',
|
449
|
+
0,
|
450
|
+
self.run_script(
|
451
|
+
script=None,
|
452
|
+
args=('salt-master', '--versions-report'),
|
453
|
+
timeout=15 * 60,
|
454
|
+
stream_stds=True
|
455
|
+
)
|
456
|
+
)
|
457
|
+
|
458
|
+
def test_install_salt_syndic(self):
|
459
|
+
'''
|
460
|
+
Test if installing a salt-syndic works
|
461
|
+
'''
|
462
|
+
if GRAINS['os'] == 'Debian':
|
463
|
+
self.skipTest(
|
464
|
+
'Currently the debian stable package will have the syndic '
|
465
|
+
'waiting for a connection to a master.'
|
466
|
+
)
|
467
|
+
|
468
|
+
args = []
|
469
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
470
|
+
args.append('-P')
|
471
|
+
|
472
|
+
args.extend(['-N', '-S'])
|
473
|
+
|
474
|
+
self.assert_script_result(
|
475
|
+
'Failed to install salt-syndic',
|
476
|
+
0,
|
477
|
+
self.run_script(
|
478
|
+
args=args,
|
479
|
+
timeout=15 * 60,
|
480
|
+
stream_stds=True
|
481
|
+
)
|
482
|
+
)
|
483
|
+
|
484
|
+
# Try to get the versions report
|
485
|
+
self.assert_script_result(
|
486
|
+
'Failed to get the versions report from salt-syndic',
|
487
|
+
0,
|
488
|
+
self.run_script(
|
489
|
+
script=None,
|
490
|
+
args=('salt-syndic', '--versions-report'),
|
491
|
+
timeout=15 * 60,
|
492
|
+
stream_stds=True
|
493
|
+
)
|
494
|
+
)
|
495
|
+
|
496
|
+
def test_install_pip_not_allowed(self):
|
497
|
+
'''
|
498
|
+
Check if distributions which require `-P` to allow pip to install
|
499
|
+
packages, fail if that flag is not passed.
|
500
|
+
'''
|
501
|
+
if GRAINS['os'] not in OS_REQUIRES_PIP_ALLOWED:
|
502
|
+
self.skipTest(
|
503
|
+
'Distribution {0} does not require the extra `-P` flag'.format(
|
504
|
+
GRAINS['os']
|
505
|
+
)
|
506
|
+
)
|
507
|
+
|
508
|
+
self.assert_script_result(
|
509
|
+
'Even though {0} is flagged as requiring the extra `-P` flag to '
|
510
|
+
'allow packages to be installed by pip, it did not fail when we '
|
511
|
+
'did not pass it'.format(GRAINS['os']),
|
512
|
+
1,
|
513
|
+
self.run_script(
|
514
|
+
timeout=15 * 60,
|
515
|
+
stream_stds=True
|
516
|
+
)
|
517
|
+
)
|
518
|
+
|
519
|
+
def test_install_from_git_on_checked_out_repository(self):
|
520
|
+
'''
|
521
|
+
Check if the script properly updates an already checked out repository.
|
522
|
+
'''
|
523
|
+
if not os.path.isdir('/tmp/git'):
|
524
|
+
os.makedirs('/tmp/git')
|
525
|
+
|
526
|
+
# Clone salt from git
|
527
|
+
self.assert_script_result(
|
528
|
+
'Failed to clone salt\'s git repository',
|
529
|
+
0,
|
530
|
+
self.run_script(
|
531
|
+
script=None,
|
532
|
+
args=('git', 'clone', 'https://github.com/saltstack/salt.git'),
|
533
|
+
cwd='/tmp/git',
|
534
|
+
timeout=15 * 60,
|
535
|
+
stream_stds=True
|
536
|
+
)
|
537
|
+
)
|
538
|
+
|
539
|
+
# Check-out a specific revision
|
540
|
+
self.assert_script_result(
|
541
|
+
'Failed to checkout v0.12.1 from salt\'s cloned git repository',
|
542
|
+
0,
|
543
|
+
self.run_script(
|
544
|
+
script=None,
|
545
|
+
args=('git', 'checkout', 'v0.12.1'),
|
546
|
+
cwd='/tmp/git/salt',
|
547
|
+
timeout=15 * 60,
|
548
|
+
stream_stds=True
|
549
|
+
)
|
550
|
+
)
|
551
|
+
|
552
|
+
# Now run the bootstrap script over an existing git checkout and see
|
553
|
+
# if it properly updates.
|
554
|
+
args = []
|
555
|
+
if GRAINS['os'] in OS_REQUIRES_PIP_ALLOWED:
|
556
|
+
args.append('-P')
|
557
|
+
|
558
|
+
args.extend(['git', 'v0.13.1'])
|
559
|
+
|
560
|
+
self.assert_script_result(
|
561
|
+
'Failed to install using specific git tag',
|
562
|
+
0,
|
563
|
+
self.run_script(
|
564
|
+
args=args,
|
565
|
+
timeout=15 * 60,
|
566
|
+
stream_stds=True
|
567
|
+
)
|
568
|
+
)
|
569
|
+
|
570
|
+
# Get the version from the salt binary just installed
|
571
|
+
# Do it as a two step so we can check the returning output.
|
572
|
+
rc, out, err = self.run_script(
|
573
|
+
script=None,
|
574
|
+
args=('salt', '--version'),
|
575
|
+
timeout=15 * 60,
|
576
|
+
stream_stds=True
|
577
|
+
)
|
578
|
+
|
579
|
+
self.assert_script_result(
|
580
|
+
'Failed to get the salt version',
|
581
|
+
0, (rc, out, err)
|
582
|
+
)
|
583
|
+
|
584
|
+
# Make sure the installation updated the git repository to the proper
|
585
|
+
# git tag before installing.
|
586
|
+
self.assertIn('0.13.1', '\n'.join(out))
|