1
# This is the bcfg2 support for redhat
2
# $Id: Redhat.py 2069 2006-08-15 17:54:20Z desai $
4
'''This is redhat client support'''
5
__revision__ = '$Revision: 2069 $'
7
from Bcfg2.Client.Toolset import Toolset
9
class ToolsetImpl(Toolset):
10
'''This class implelements support for rpm packages and standard chkconfig services'''
12
pkgtool = {'rpm':("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"]))}
14
def __init__(self, cfg, setup):
15
Toolset.__init__(self, cfg, setup)
16
self.pkgwork = {'add':[], 'update':[], 'remove':[]}
18
for pkg in [cpkg for cpkg in self.cfg.findall(".//Package") if not cpkg.attrib.has_key('type')]:
19
pkg.set('type', 'rpm')
20
for srv in [csrv for csrv in self.cfg.findall(".//Service") if not csrv.attrib.has_key('type')]:
21
srv.set('type', 'chkconfig')
22
# relocation hack: we will define one pkgtool per relocation location
23
for pkg in [cpkg for cpkg in self.cfg.findall('.//Package') if cpkg.attrib.has_key('reloc')]:
24
ptoolname = "rpm-reloc-%s" % (pkg.get('reloc'))
25
if not self.pkgtool.has_key(ptoolname):
26
cmd = "rpm --relocate %s --oldpackage --replacepkgs --quiet -U %%s" % (pkg.get('reloc'))
27
self.pkgtool[ptoolname] = (cmd, ("%s", ["url"]))
28
pkg.set('type', ptoolname)
32
'''Refresh memory hashes of packages'''
34
for line in self.saferun("rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}\n'")[1]:
35
(name, version) = line.split()
36
self.installed[name] = version
38
def VerifyService(self, entry):
39
'''Verify Service status for entry'''
41
srvdata = self.saferun('/sbin/chkconfig --list %s | grep -v "unknown service"'
42
% entry.attrib['name'])[1][0].split()
44
# Ocurrs when no lines are returned (service not installed)
45
entry.set('current_status', 'off')
47
if entry.attrib['type'] == 'xinetd':
48
return entry.attrib['status'] == srvdata[1]
51
onlevels = [level.split(':')[0] for level in srvdata[1:] if level.split(':')[1] == 'on']
55
# chkconfig/init.d service
56
if entry.get('status') == 'on':
57
status = len(onlevels) > 0
59
status = len(onlevels) == 0
62
if entry.get('status') == 'on':
63
entry.set('current_status', 'off')
65
entry.set('current_status', 'on')
68
def InstallService(self, entry):
69
'''Install Service entry'''
70
self.saferun("/sbin/chkconfig --add %s"%(entry.attrib['name']))
71
self.logger.info("Installing Service %s" % (entry.get('name')))
72
if not entry.get('status'):
73
self.logger.error("Can't install service %s, not enough data" % (entry.get('name')))
75
if entry.attrib['status'] == 'off':
76
if self.setup['dryrun']:
77
self.logger.info("Disabling server %s" % (entry.get('name')))
79
cmdrc = self.saferun("/sbin/chkconfig %s %s" % (entry.attrib['name'],
80
entry.attrib['status']))[0]
82
if self.setup['dryrun']:
83
self.logger.info("Enabling server %s" % (entry.get('name')))
85
cmdrc = self.saferun("/sbin/chkconfig %s %s" %
86
(entry.attrib['name'], entry.attrib['status']))[0]
89
def VerifyPackage(self, entry, modlist):
90
'''Verify Package status for entry'''
91
if not entry.get('version'):
92
self.logger.error("Can't install package %s, not enough data." % (entry.get('name')))
95
if entry.get('verify', 'false') == 'nomtime':
96
self.logger.debug("Skipping mtime verification for package %s" % (entry.get('name')))
97
rpm_options.append("--nomtime")
98
if self.installed.has_key(entry.get('name')):
99
if entry.get('version') == self.installed[entry.get('name')]:
100
if entry.get('multiarch'):
101
archs = entry.get('multiarch').split()
102
info = self.saferun('rpm -q %s --qf "%%{NAME} %%{VERSION}-%%{RELEASE} %%{ARCH}\n"' % (entry.get('name')))[1]
104
(_, vers, arch) = info.pop().split()
108
self.logger.error("Got pkg install for Package %s: arch %s" % (entry.get('name'), arch))
111
self.logger.error("Package %s not installed for arch: %s" % (entry.get('name'), archs))
113
if (self.setup['quick'] or (entry.get('verify', 'true') == 'false')) or entry.get('multiarch'):
114
if entry.get('verify', 'true') == 'false':
115
self.logger.debug("Skipping checksum verification for package %s" % (entry.get('name')))
118
self.logger.debug("Package %s: wrong version installed. want %s have %s" %
119
(entry.get('name'), entry.get('version'), self.installed[entry.get('name')]))
120
entry.set('current_version', self.installed[entry.get('name')])
123
self.logger.debug("Package %s: not installed" % (entry.get('name')))
124
entry.set('current_exists', 'false')
127
(vstat, output) = self.saferun("rpm --verify -q %s %s-%s" % (" ".join(rpm_options), entry.get('name'), entry.get('version')))
129
if [name for name in output if name.split()[-1] not in modlist]:
130
self.logger.debug("Package %s content verification failed" % entry.get('name'))
134
def HandleExtra(self):
135
'''Deal with extra configuration detected'''
136
if len(self.pkgwork['remove']) > 0:
137
if self.setup['remove'] in ['all', 'packages']:
138
self.logger.info("Removing packages: %s" % self.pkgwork['remove'])
139
if not self.saferun("rpm --quiet -e --allmatches %s" % " ".join(self.pkgwork['remove']))[0]:
140
self.pkgwork['remove'] = []
144
self.logger.info("Found extra packages:")
145
self.logger.info(self.pkgwork['remove'])
146
if len(self.extra_services) > 0:
147
if self.setup['remove'] in ['all', 'services']:
148
self.logger.info('Removing services:')
149
self.logger.info(self.extra_services)
150
for service in self.extra_services:
151
if not self.saferun("/sbin/chkconfig --level 123456 %s off" % service)[0]:
152
self.extra_services.remove(service)
153
self.logger.info("Failed to remove service %s" % (service))
155
self.logger.info('Found extra active services:')
156
self.logger.info(self.extra_services)
159
'''Do standard inventory plus debian extra service check'''
160
Toolset.Inventory(self)
161
allsrv = [line.split()[0] for line in self.saferun("/sbin/chkconfig --list|grep :on")[1]]
162
self.logger.debug('Found active services:')
163
self.logger.debug(allsrv)
164
csrv = self.cfg.findall(".//Service")
165
[allsrv.remove(svc.get('name')) for svc in csrv if
166
svc.get('status') == 'on' and svc.get('name') in allsrv]
167
self.extra_services = allsrv