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
|
"""This provides bcfg2 support for Solaris SYSV packages."""
import tempfile
from Bcfg2.Compat import any # pylint: disable=W0622
import Bcfg2.Client.Tools
import Bcfg2.Client.XML
from Bcfg2.Compat import urlretrieve
# pylint: disable=C0103
noask = '''
mail=
instance=overwrite
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=ask
setuid=nocheck
conflict=nocheck
action=nocheck
basedir=default
'''
# pylint: enable=C0103
class SYSV(Bcfg2.Client.Tools.PkgTool):
"""Solaris SYSV package support."""
__execs__ = ["/usr/sbin/pkgadd", "/usr/bin/pkginfo"]
__handles__ = [('Package', 'sysv')]
__req__ = {'Package': ['name', 'version']}
__ireq__ = {'Package': ['name', 'url', 'version']}
name = 'SYSV'
pkgtype = 'sysv'
pkgtool = ("/usr/sbin/pkgadd %s -n -d %%s", (('%s %s', ['url', 'name'])))
def __init__(self, logger, setup, config):
Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config)
# noaskfile needs to live beyond __init__ otherwise file is removed
self.noaskfile = tempfile.NamedTemporaryFile()
self.noaskname = self.noaskfile.name
# for any pkg files downloaded
self.tmpfiles = []
try:
self.noaskfile.write(noask)
# flush admin file contents to disk
self.noaskfile.flush()
self.pkgtool = (self.pkgtool[0] % ("-a %s" % (self.noaskname)),
self.pkgtool[1])
except: # pylint: disable=W0702
self.pkgtool = (self.pkgtool[0] % "", self.pkgtool[1])
self.origpkgtool = self.pkgtool
def pkgmogrify(self, packages):
""" Take a list of pkg objects, check for a 'simplename' attribute.
If present, insert a _sysv_pkg_path attribute to the package and
download the datastream format SYSV package to a temporary file.
"""
for pkg in packages:
if pkg.get('simplename'):
tmpfile = tempfile.NamedTemporaryFile()
self.tmpfiles.append(tmpfile)
self.logger.info("Downloading %s%s to %s" % (pkg.get('url'),
pkg.get('simplename'), tmpfile.name))
urlretrieve("%s/%s" % (pkg.get('url'), pkg.get('simplename')),
tmpfile.name)
pkg.set('_sysv_pkg_path', tmpfile.name)
def _get_package_command(self, packages):
"""Override the default _get_package_command, replacing the attribute
'url' if '_sysv_pkg_path' if necessary in the returned command
string
"""
if hasattr(self, 'origpkgtool'):
if len(packages) == 1 and '_sysv_pkg_path' in packages[0].keys():
self.pkgtool = (self.pkgtool[0], ('%s %s',
['_sysv_pkg_path', 'name']))
else:
self.pkgtool = self.origpkgtool
pkgcmd = super(SYSV, self)._get_package_command(packages)
self.logger.debug("Calling install command: %s" % pkgcmd)
return pkgcmd
def Install(self, packages, states):
self.pkgmogrify(packages)
super(SYSV, self).Install(packages, states)
def RefreshPackages(self):
"""Refresh memory hashes of packages."""
self.installed = {}
# Build list of packages
lines = self.cmd.run("/usr/bin/pkginfo -x").stdout.splitlines()
while lines:
# Splitting on whitespace means that packages with spaces in
# their version numbers don't work right. Found this with
# IBM TSM software with package versions like
# "Version 6 Release 1 Level 0.0"
# Should probably be done with a regex but this works.
version = lines.pop().split(') ')[1]
pkg = lines.pop().split()[0]
self.installed[pkg] = version
def VerifyPackage(self, entry, modlist):
"""Verify Package status for entry."""
desired_version = entry.get('version')
if desired_version == 'any':
desired_version = self.installed.get(entry.get('name'),
desired_version)
if not self.cmd.run(["/usr/bin/pkginfo", "-q", "-v",
desired_version, entry.get('name')]):
if entry.get('name') in self.installed:
self.logger.debug("Package %s version incorrect: "
"have %s want %s" %
(entry.get('name'),
self.installed[entry.get('name')],
desired_version))
else:
self.logger.debug("Package %s not installed" %
entry.get("name"))
else:
if self.setup['quick'] or \
entry.attrib.get('verify', 'true') == 'false':
return True
rv = self.cmd.run("/usr/sbin/pkgchk -n %s" % entry.get('name'))
if rv.success:
return True
else:
output = [line for line in rv.stdout.splitlines()
if line[:5] == 'ERROR']
if any(name for name in output
if name.split()[-1] not in modlist):
self.logger.debug("Package %s content verification failed"
% entry.get('name'))
else:
return True
return False
def Remove(self, packages):
"""Remove specified Sysv packages."""
names = [pkg.get('name') for pkg in packages]
self.logger.info("Removing packages: %s" % (names))
self.cmd.run("/usr/sbin/pkgrm -a %s -n %s" %
(self.noaskname, names))
self.RefreshPackages()
self.extra = self.FindExtra()
|