~ubuntu-branches/ubuntu/hardy/bcfg2/hardy-updates

« back to all changes in this revision

Viewing changes to src/lib/Client/Solaris.py

  • Committer: Bazaar Package Importer
  • Author(s): Sami Haahtinen
  • Date: 2006-11-16 22:39:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061116223916-8dtn3t86cz58vg2x
Tags: 0.8.6.1-1
* New Upstream Release
* Replaced faulty if clause in bcfg2.postrm (Closes: #398772)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# This is the bcfg2 support for solaris
2
 
'''This provides bcfg2 support for Solaris'''
3
 
__revision__ = '$Revision: 2160 $'
4
 
 
5
 
import os
6
 
from glob import glob
7
 
from os import stat, unlink
8
 
from re import compile as regcompile
9
 
from tempfile import mktemp
10
 
 
11
 
from Bcfg2.Client.Toolset import Toolset
12
 
 
13
 
noask = '''
14
 
mail=
15
 
instance=overwrite
16
 
partial=nocheck
17
 
runlevel=nocheck
18
 
idepend=nocheck
19
 
rdepend=nocheck
20
 
space=ask
21
 
setuid=nocheck
22
 
conflict=nocheck
23
 
action=nocheck
24
 
basedir=default
25
 
'''
26
 
 
27
 
class ToolsetImpl(Toolset):
28
 
    '''This class implelements support for SYSV/blastware/encap packages
29
 
    and standard SMF services'''
30
 
    pkgtool = {'sysv':("/usr/sbin/pkgadd %s -d %%s -n %%%%s", (("%s", ["name"]))),
31
 
               'blast':("/opt/csw/bin/pkg-get install %s", ("%s", ["name"])),
32
 
               'encap':("/local/sbin/epkg -l -f -q %s", ("%s", ["url"]))}
33
 
    splitter = regcompile('.*/(?P<name>[\w-]+)\-(?P<version>[\w\.-]+)')
34
 
    ptypes = {}
35
 
    __name__ = 'Solaris'
36
 
    
37
 
    def __init__(self, cfg, setup):
38
 
        Toolset.__init__(self, cfg, setup)
39
 
        self.extra_services = []
40
 
        self.snames = {}
41
 
        self.noaskname = mktemp()
42
 
        try:
43
 
            open(self.noaskname, 'w+').write(noask)
44
 
            self.pkgtool['sysv'] = (self.pkgtool['sysv'][0] % ("-a %s" % (self.noaskname)), self.pkgtool['sysv'][1])
45
 
        except:
46
 
            self.pkgtool['sysv'] = (self.pkgtool['sysv'][0] % (""), self.pkgtool['sysv'][1])
47
 
        try:
48
 
            stat("/opt/csw/bin/pkg-get")
49
 
            self.saferun("/opt/csw/bin/pkg-get -U > /dev/null")
50
 
        except OSError:
51
 
            pass
52
 
        self.Refresh()
53
 
        for pkg in [cpkg for cpkg in self.cfg.findall(".//Package") if not cpkg.attrib.has_key('type')]:
54
 
            pkg.set('type', 'sysv')
55
 
        for pkg in [cpkg for cpkg in self.cfg.findall(".//Package") if cpkg.get('type') == 'sysv']:
56
 
            if pkg.attrib.has_key('url'):
57
 
                pkg.set('url', '/'.join(pkg.get('url').split('/')[:-1]))
58
 
            pkg.set('type', "sysv-%s" % (pkg.get('url')))
59
 
            if not self.pkgtool.has_key(pkg.get('type')):
60
 
                self.pkgtool[pkg.get('type')] = (self.pkgtool['sysv'][0] % (pkg.get('url')),
61
 
                                                        self.pkgtool['sysv'][1])
62
 
            
63
 
    def Refresh(self):
64
 
        '''Refresh memory hashes of packages'''
65
 
        self.installed = {}
66
 
        self.ptypes = {}
67
 
        # Build list of packages
68
 
        lines = self.saferun("/usr/bin/pkginfo -x")[1]
69
 
        while lines:
70
 
            version = lines.pop().split()[1]
71
 
            pkg = lines.pop().split()[0]
72
 
            self.installed[pkg] = version
73
 
            self.ptypes[pkg] = 'sysv'
74
 
        # try to find encap packages
75
 
        for pkg in glob("/local/encap/*"):
76
 
            match = self.splitter.match(pkg)
77
 
            if match:
78
 
                self.installed[match.group('name')] = match.group('version')
79
 
                self.ptypes[match.group('name')] = 'encap'
80
 
            else:
81
 
                print "Failed to split name %s" % pkg
82
 
        #print self.installed.keys()
83
 
 
84
 
    def VerifyService(self, entry):
85
 
        '''Verify Service status for entry'''
86
 
        if not entry.attrib.has_key('FMRI'):
87
 
            name = self.saferun("/usr/bin/svcs -H -o FMRI %s 2>/dev/null" % entry.get('name'))[1]
88
 
            if name:
89
 
                entry.set('FMRI', name[0])
90
 
            else:
91
 
                self.logger.info('Failed to locate FMRI for service %s' % entry.get('name'))
92
 
                return False
93
 
        if entry.get('FMRI').startswith('lrc'):
94
 
            filename = entry.get('FMRI').split('/')[-1]
95
 
            # this is a legacy service
96
 
            gname = "/etc/rc*.d/%s" % filename
97
 
            files = glob(gname.replace('_', '.'))
98
 
            if files:
99
 
                self.logger.debug("Matched %s with %s" % \
100
 
                                  (entry.get("FMRI"), ":".join(files)))
101
 
                return entry.get('status') == 'on'
102
 
            else:
103
 
                self.logger.debug("No service matching %s" % (entry.get("FMRI")))
104
 
                return entry.get('status') == 'off'
105
 
        try:
106
 
            srvdata = self.saferun("/usr/bin/svcs -H -o STA %s" % entry.attrib['name'])[1][0].split()
107
 
        except IndexError:
108
 
            # Ocurrs when no lines are returned (service not installed)
109
 
            return False
110
 
 
111
 
        if entry.get('status') == 'on':
112
 
            return srvdata[0] == 'ON'
113
 
        else:
114
 
            return srvdata[0] in ['OFF', 'UN', 'MNT', 'DIS', 'DGD']
115
 
 
116
 
    def InstallService(self, entry):
117
 
        '''Install Service entry'''
118
 
        if not entry.attrib.has_key('status'):
119
 
            self.logger.info('Insufficient information for Service %s; cannot Install' % entry.get('name'))
120
 
            return False
121
 
        if not entry.attrib.has_key('FMRI'):
122
 
            name = self.saferun("/usr/bin/svcs -H -o FMRI %s 2>/dev/null" % entry.get('name'))[1]
123
 
            if name:
124
 
                entry.set('FMRI', name[0])
125
 
            else:
126
 
                self.logger.info('Failed to locate FMRI for service %s' % entry.get('name'))
127
 
                return False
128
 
        self.logger.info("Installing Service %s" % (entry.get('name')))
129
 
        if entry.attrib['status'] == 'off':
130
 
            if self.setup['dryrun']:
131
 
                print "Disabling Service %s" % (entry.get('name'))
132
 
            else:
133
 
                if entry.get("FMRI").startswith('lrc'):
134
 
                    try:
135
 
                        loc = entry.get("FMRI")[4:].replace('_', '.')
136
 
                        self.logger.debug("Renaming file %s to %s" % \
137
 
                                          (loc, loc.replace('/S', '/DISABLED.S')))
138
 
                        os.rename(loc, loc.replace('/S', '/DISABLED.S'))
139
 
                        return True
140
 
                    except OSError:
141
 
                        self.logger.error("Failed to rename init script %s" % (loc))
142
 
                        return False
143
 
                cmdrc = self.saferun("/usr/sbin/svcadm disable -r %s" % (entry.attrib['FMRI']))[0]
144
 
        else:
145
 
            if self.setup['dryrun']:
146
 
                print "Enabling Service %s" % (entry.attrib['name'])
147
 
            else:
148
 
                if entry.get('FMRI').startswith('lrc'):
149
 
                    loc = entry.get("FMRI")[4:].replace('_', ',')
150
 
                    try:
151
 
                        stat(loc.replace('/S', '/Disabled.'))
152
 
                        self.logger.debug("Renaming file %s to %s" % \
153
 
                                          (loc.replace('/S', '/DISABLED.S'), loc))
154
 
                        os.rename(loc.replace('/S', '/DISABLED.S'), loc)
155
 
                        cmdrc = 0
156
 
                    except:
157
 
                        self.logger.debug("Failed to rename %s to %s" \
158
 
                                          % (loc.replace('/S', '/DISABLED.S'), loc))
159
 
                        cmdrc = 1
160
 
                else:
161
 
                    cmdrc = self.saferun("/usr/sbin/svcadm enable -r %s" % (entry.attrib['FMRI']))[0]
162
 
        return cmdrc == 0
163
 
 
164
 
    def VerifyPackage(self, entry, modlist):
165
 
        '''Verify Package status for entry'''
166
 
        if not entry.get('version'):
167
 
            self.logger.info("Insufficient information of Package %s; cannot Verify" % entry.get('name'))
168
 
            return False
169
 
        if entry.get('type') in ['sysv', 'blast'] or entry.get('type')[:4] == 'sysv':
170
 
            cmdrc = self.saferun("/usr/bin/pkginfo -q -v \"%s\" %s" % (entry.get('version'), entry.get('name')))[0]
171
 
        elif entry.get('type') in ['encap']:
172
 
            cmdrc = self.saferun("/local/sbin/epkg -q -S -k %s-%s >/dev/null" %
173
 
                                 (entry.get('name'), entry.get('version')))[0]
174
 
        if cmdrc != 0:
175
 
            self.logger.debug("Package %s version incorrect" % entry.get('name'))
176
 
        else:
177
 
            if self.setup['quick'] or entry.get('type') == 'encap' or \
178
 
                   entry.attrib.get('verify', 'true') == 'false':
179
 
                return True
180
 
            (vstat, odata) = self.saferun("/usr/sbin/pkgchk -n %s" % (entry.get('name')))
181
 
            if vstat == 0:
182
 
                return True
183
 
            else:
184
 
                output = [line for line in odata if line[:5] == 'ERROR']
185
 
                if len([name for name in output if name.split()[-1] not in modlist]):
186
 
                    self.logger.debug("Package %s content verification failed" % \
187
 
                                      (entry.get('name')))
188
 
                else:
189
 
                    return True
190
 
        return False
191
 
 
192
 
    def Inventory(self):
193
 
        '''Do standard inventory plus debian extra service check'''
194
 
        Toolset.Inventory(self)
195
 
        allsrv = [name for name, version in [ srvc.strip().split() for srvc in
196
 
                                              self.saferun("/usr/bin/svcs -a -H -o FMRI,STATE")[1] ]
197
 
                  if version != 'disabled']
198
 
        csrv = self.cfg.findall(".//Service")
199
 
        # need to build a service name map. services map to a fullname if they are already installed
200
 
        for srv in csrv:
201
 
            name = self.saferun("/usr/bin/svcs -H -o FMRI %s 2>/dev/null" % srv.get('name'))[1]
202
 
            if name:
203
 
                srv.set('FMRI', name[0])
204
 
            else:
205
 
                self.logger.info("Failed to locate FMRI for service %s" % srv.get('name'))
206
 
        #nsrv = [ r for r in [ popen("/usr/bin/svcs -H -o FMRI %s " % s).read().strip() for s in csrv ] if r ]
207
 
        [allsrv.remove(svc.get('FMRI')) for svc in csrv if
208
 
         svc.get('status') == 'on' and svc.get("FMRI") in allsrv]
209
 
        self.extra_services = allsrv
210
 
 
211
 
    def HandleExtra(self):
212
 
        '''Deal with extra configuration detected'''
213
 
        if len(self.pkgwork) > 0:
214
 
            if self.setup['remove'] in ['all', 'packages']:
215
 
                self.logger.info("Removing packages: %s" % (self.pkgwork['remove']))
216
 
                sysvrmpkgs = [pkg for pkg in self.pkgwork['remove'] if self.ptypes[pkg] == 'sysv']
217
 
                enrmpkgs = [pkg for pkg in self.pkgwork['remove'] if self.ptypes[pkg] == 'encap']
218
 
                if sysvrmpkgs:
219
 
                    if not self.saferun("/usr/sbin/pkgrm -a %s -n %s" % \
220
 
                                        (self.noaskname, " ".join(sysvrmpkgs)))[0]:
221
 
                        [self.pkgwork['remove'].remove(pkg) for pkg in sysvrmpkgs]
222
 
                if enrmpkgs:
223
 
                    if not self.saferun("/local/sbin/epkg -l -q -r %s" % " ".join(enrmpkgs))[0]:
224
 
                        [self.pkgwork['remove'].remove(pkg) for pkg in enrmpkgs]
225
 
            else:
226
 
                self.logger.info("Need to remove packages: %s" % (self.pkgwork['remove']))
227
 
        if len(self.extra_services) > 0:
228
 
            self.logger.info("Here")
229
 
            self.logger.info('removal mode is: %s' % (self.setup))
230
 
            if self.setup['remove'] in ['all', 'services']:
231
 
                self.logger.info("Removing services: %s" % (self.extra_services))
232
 
                for service in [svc for svc in self.extra_services if not svc.startswith('lrc:')]:
233
 
                    if not self.saferun("/usr/sbin/svcadm disable %s" % service)[0]:
234
 
                        self.extra_services.remove(service)
235
 
                for svc in [svc for svc in self.extra_services if svc.startswith('lrc:')]:
236
 
                    loc = svc[4:].replace('_', '.')
237
 
                    self.logger.info("Renaming file %s to %s" % \
238
 
                                      (loc, loc.replace('/S', '/DISABLED.S')))
239
 
                    try:
240
 
                        os.rename(loc, loc.replace('/S', '/DISABLED.S'))
241
 
                        self.extra_services.remove(svc)
242
 
                    except OSError:
243
 
                        self.logger.error("Failed to rename %s" % loc)
244
 
 
245
 
            else:
246
 
                self.logger.info("Need to remove services: %s" % (self.extra_services))
247
 
 
248
 
    def Install(self):
249
 
        '''Local install method handling noaskfiles'''
250
 
        Toolset.Install(self)
251
 
        try:
252
 
            unlink(self.noaskname)
253
 
        except:
254
 
            pass
255
 
 
256
 
    def RestartService(self, service):
257
 
        '''Restart a service'''
258
 
        if service.get("FMRI").startswith('lrc'):
259
 
            Toolset.RestartService(self, service)
260
 
        else:
261
 
            if service.get('status') == 'on':
262
 
                self.logger.debug("Restarting service %s" % (service.get("FMRI")))
263
 
                self.saferun("svcadm restart %s" % (service.get("FMRI")))