summaryrefslogtreecommitdiffstats
path: root/src/lib/Client/Tools/DebInit.py
blob: 9bf8bb0480b7743f1265c4f6eefadd958968db5f (plain)
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
'''Debian Init Support for Bcfg2'''
__revision__ = '$Revision$'

import glob, os, re
import Bcfg2.Client.Tools

class DebInit(Bcfg2.Client.Tools.SvcTool):
    '''Debian Service Support for Bcfg2'''
    name = 'DebInit'
    __execs__ = ['/usr/sbin/update-rc.d', '/usr/sbin/invoke-rc.d']
    __handles__ = [('Service', 'deb')]
    __req__ = {'Service': ['name', 'status']}
    svcre = re.compile("/etc/.*/(?P<action>[SK])(?P<sequence>\d+)(?P<name>\S+)")

    # implement entry (Verify|Install) ops
    def VerifyService(self, entry, _):
        '''Verify Service status for entry'''
        rawfiles = glob.glob("/etc/rc*.d/[SK]*%s" % (entry.get('name')))
        files = []
        if entry.get('sequence'):
            start_sequence = int(entry.get('sequence'))
            kill_sequence = 100 - start_sequence
        else:
            start_sequence = None

        for filename in rawfiles:
            match = self.svcre.match(filename)
            if not match:
                self.logger.error("Failed to match file: %s" % filename)
                continue
            if match.group('name') == entry.get('name'):
                files.append(filename)
        if entry.get('status') == 'off':
            if files:
                entry.set('current_status', 'on')
                return False
            else:
                return True
        else:
            if files:
                if start_sequence:
                    for filename in files:
                        match = self.svcre.match(filename)
                        file_sequence = int(match.group('sequence'))
                        if match.group('action') == 'S' and file_sequence != start_sequence:
                            return False
                        if match.group('action') == 'K' and file_sequence != kill_sequence:
                            return False
                return True
            else:
                entry.set('current_status', 'off')
                return False

    def InstallService(self, entry):
        '''Install Service for entry'''
        self.logger.info("Installing Service %s" % (entry.get('name')))
        try:
            os.stat('/etc/init.d/%s' % entry.get('name'))
        except OSError:
            self.logger.debug("Init script for service %s does not exist" % entry.get('name'))
            return False

        if entry.get('status') == 'off':
            self.cmd.run("/usr/sbin/invoke-rc.d %s stop" % (entry.get('name')))
            cmdrc = self.cmd.run("/usr/sbin/update-rc.d -f %s remove" % entry.get('name'))[0]
        else:
            command = "/usr/sbin/update-rc.d %s defaults" % (entry.get('name'))
            if entry.get('sequence'):
                cmdrc = self.cmd.run("/usr/sbin/update-rc.d -f %s remove" % entry.get('name'))[0]
                if cmdrc != 0:
                    return False
                start_sequence = int(entry.get('sequence'))
                kill_sequence = 100 - start_sequence
                command = "%s %d %d" % (command, start_sequence, kill_sequence)
            cmdrc = self.cmd.run(command)[0]
        return cmdrc == 0

    def FindExtra(self):
        '''Find Extra Debian Service Entries'''
        specified = [entry.get('name') for entry in self.getSupportedEntries()]
        extra = []
        for name in [self.svcre.match(fname).group('name') for fname in
                      glob.glob("/etc/rc[12345].d/S*") \
                      if self.svcre.match(fname).group('name') not in specified]:
            if name not in extra:
                extra.append(name)
        return [Bcfg2.Client.XML.Element('Service', name=name, type='deb') for name \
                in extra]

    def Remove(self, _):
        '''Remove extra service entries'''
        # Extra service removal is nonsensical
        # Extra services need to be reflected in the config
        return

    def get_svc_command(self, service, action):
        return '/usr/sbin/invoke-rc.d %s %s' % (service.get('name'), action)