forked from Puppet-Finland/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vars.py
236 lines (208 loc) · 9.1 KB
/
vars.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
from fabric.api import *
from fabric.contrib.files import exists
import re
class Vars:
"""Manage parameters based on the operating system"""
def __init__(self, *args, **kwargs):
"""Load and cache host information/facts"""
if 'hostinfo' not in env:
env['hostinfo'] = {}
if env.host_string in env['hostinfo']:
self.set_hostinfo_from_cache()
else:
self.set_hostinfo()
def set_hostinfo(self):
from sys import exit
"""Set hostinfo for this object"""
# Map release files to operating system names and operating system
# families. This approach has been adapted from
# facter/operatingsystem/linux.rb and would be redundant _if_ every OS
# had the lsb_release command at hand out of the box. Note that some
# operating systems such as Fedora may have several release files, so
# the most specific need to be at the top. In other words, "Fedora" is
# more Fedora than RedHat.
self.release_files = { '/etc/fedora-release': { 'osfamily': 'RedHat' },
'/etc/redhat-release': { 'osfamily': 'RedHat' } }
self.release_file = None
self.has_facter = self.has_program("facter")
self.has_lsb_release = self.has_program("lsb_release")
self.lsbdistcodename = self.get_lsbdistcodename()
# Populate OS-specific parameters
osfamily = self.get_osfamily()
if osfamily == 'Debian':
self.os = Debian()
self.osfamily = "Debian"
elif osfamily == 'Ubuntu':
self.os = Debian()
self.osfamily = "Debian"
elif osfamily == 'RedHat' or osfamily == 'CentOS':
self.os = RedHat()
self.osfamily = "RedHat"
else:
print "ERROR: unsupported OS family!"
exit(1)
self.operatingsystem = self.get_operatingsystem()
self.operatingsystemmajrelease = self.get_operatingsystemmajrelease()
self.operatingsystemminrelease = self.get_operatingsystemminrelease()
# Cache this node's information for later use
env['hostinfo'][env.host_string] = self
def set_hostinfo_from_cache(self):
"""Set host information from the cache in env dictionary"""
cached = env['hostinfo'][env.host_string]
self.has_facter = cached.has_facter
self.has_lsb_release = cached.has_lsb_release
self.lsbdistcodename = cached.lsbdistcodename
self.os = cached.os
self.osfamily = cached.osfamily
self.operatingsystem = cached.operatingsystem
self.operatingsystemmajrelease = cached.operatingsystemmajrelease
self.operatingsystemminrelease = cached.operatingsystemminrelease
def has_program(self, name):
"""Check if the node a certain program installed and in PATH"""
with hide("everything"), settings(warn_only=True):
if run("which "+name).succeeded:
return True
else:
return False
def get_fact(self, fact):
"""Get a fact value from facter. Used internally."""
with hide("everything"):
return run("facter "+fact)
def get_release_file_content(self):
"""Get the content of the release file as string"""
with hide("everything"):
return run("cat "+self.release_file)
def get_osfamily(self):
"""Detect operating system family"""
if self.has_facter:
return self.get_fact("osfamily")
elif self.has_lsb_release:
with hide("everything"):
return run("lsb_release -is")
else:
# While this loop is fairly inefficient, replacing it with a
# single Fabric run("ls <filelist>") operation is not a panacea,
# either, as its output may include several files, some of which
# are preferable. So we'd need a prioritization list to make
# sense of the output.
for k, v in self.release_files.iteritems():
if exists(k):
self.release_file = k
return self.release_files[k]['osfamily']
# Could not determine the operating system family
return ""
def get_lsbdistcodename(self):
"""Detect lsbdistcodename"""
# Try facter and fall back to Pythonic detection if Facter is not
# present
if self.has_facter:
return self.get_fact("lsbdistcodename")
elif self.has_lsb_release:
with hide("everything"):
return run("lsb_release -cs")
else:
# Facter returns an empty string here as well
return ""
def get_operatingsystemrelease(self, maj):
"""Get the operating system release. Used internally."""
if maj:
fact = "operatingsystemmajrelease"
index = 0
else:
fact = "operatingsystemminrelease"
index = 1
if self.has_facter:
return self.get_fact(fact)
elif self.has_lsb_release:
with hide("everything"):
fullver = re.split("\.", run("lsb_release -rs"))
return fullver[index]
else:
release = self.get_release_file_content()
if self.operatingsystem == 'Fedora':
if maj: return re.split(" ", release)[2]
else: return "0"
else:
if maj:
return re.split("\.", release)[index][-1:]
else:
return re.split("\.", release)[index][-1:]
def get_operatingsystem(self):
"""Get the operating system name"""
if self.has_facter:
return self.get_fact("operatingsystem")
elif self.has_lsb_release:
with hide("everything"):
return run("lsb_release -is")
else:
release = self.get_release_file_content()
return re.split(" ", release)[0]
def get_operatingsystemmajrelease(self):
"""Get the major version of the operating system"""
return self.get_operatingsystemrelease(maj=True)
def get_operatingsystemminrelease(self):
"""Get the minor version of the operating system"""
return self.get_operatingsystemrelease(maj=False)
class Linux(object):
"""Parameters for Linux-based operating systems"""
def __init__(self, *args, **kwargs):
"""Common settings for Linux"""
if self.has_systemd():
self.service_start_cmd = "systemctl start %s"
self.service_stop_cmd = "systemctl stop %s"
self.service_restart_cmd = "systemctl restart %s"
self.service_status_cmd = "systemctl status %s"
else:
self.service_start_cmd = "service %s start"
self.service_stop_cmd = "service %s stop"
self.service_restart_cmd = "service %s restart"
self.service_status_cmd = "service %s status"
self.default_shell = "/bin/bash"
self.default_loginshell_config = "/etc/profile"
def has_systemd(self):
"""Determine if the operating system uses systemd"""
with hide("everything"), settings(warn_only=True):
if run("which systemctl").succeeded:
return True
else:
return False
class RedHat(Linux):
"""Parameters for RedHat-based operating systems"""
def __init__(self, *args, **kwargs):
super(RedHat, self).__init__()
self.package_refresh_cmd = "yum makecache"
self.package_upgrade_cmd = "yum update"
self.package_install_cmd = "yum -y install %s"
self.package_autoremove_cmd = "yum autoremove"
self.package_remove_cmd = "yum remove %s"
self.package_local_install_cmd = "rpm -ivh %s"
self.package_installed_cmd = "rpm -qs"
self.default_shell_config = "/etc/bashrc"
self.git_package_name = "git"
class Debian(Linux):
"""Parameters for Debian-based operating systems"""
def __init__(self, *args, **kwargs):
super(Debian, self).__init__()
self.package_refresh_cmd = "apt-get update"
self.package_upgrade_cmd = "apt-get dist-upgrade"
self.package_install_cmd = "apt-get -y install %s"
self.package_remove_cmd = "apt-get remove %s"
self.package_autoremove_cmd = "apt-get autoremove"
self.package_local_install_cmd = "dpkg -i %s"
# Using %s after the single quotes does not seem to work
self.package_installed_cmd = "dpkg-query -Wf'${db:Status-abbrev}'"
self.default_shell_config = "/etc/bash.bashrc"
self.git_package_name = "git"
class Trusty(Debian):
"""Parameters for Ubuntu Trusty (14.04)"""
def __init__(self, *args, **kwargs):
super(Trusty, self).__init__()
@task
def test():
"""Verify that operating system variables are functioning correctly"""
vars = Vars()
print "osfamily: "+vars.osfamily
print "operatingsystem: "+vars.operatingsystem
print "operatingsystemmajrelease: "+vars.operatingsystemmajrelease
print "operatingsystemminrelease: "+vars.operatingsystemminrelease
print "lsbdistcodename: "+vars.lsbdistcodename