Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

# Author: Alexander Bokovoy <abokovoy@redhat.com> 

# 

# Copyright (C) 2011   Red Hat 

# see file 'COPYING' for use and warranty information 

# 

# This program is free software; you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# This program is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the GNU General Public License 

# along with this program.  If not, see <http://www.gnu.org/licenses/>. 

# 

 

import os 

import time 

 

from ipapython import ipautil, dogtag 

from ipapython.platform import base, redhat 

from ipapython.platform.base import systemd 

from ipapython.platform.fedora16 import selinux 

from ipapython.ipa_log_manager import root_logger 

from ipalib import api 

 

# For beginning just remap names to add .service 

# As more services will migrate to systemd, unit names will deviate and 

# mapping will be kept in this dictionary 

system_units = dict(map(lambda x: (x, "%s.service" % (x)), base.wellknownservices)) 

 

system_units['rpcgssd'] = 'nfs-secure.service' 

system_units['rpcidmapd'] = 'nfs-idmap.service' 

 

# Rewrite dirsrv and pki-tomcatd services as they support instances via separate 

# service generator. To make this working, one needs to have both foo@.servic 

# and foo.target -- the latter is used when request should be coming for 

# all instances (like stop). systemd, unfortunately, does not allow one 

# to request action for all service instances at once if only foo@.service 

# unit is available. To add more, if any of those services need to be 

# started/stopped automagically, one needs to manually create symlinks in 

# /etc/systemd/system/foo.target.wants/ (look into systemd.py's enable() 

# code). 

system_units['dirsrv'] = 'dirsrv@.service' 

# Our directory server instance for PKI is dirsrv@PKI-IPA.service 

system_units['pkids'] = 'dirsrv@PKI-IPA.service' 

# Old style PKI instance 

system_units['pki-cad'] = 'pki-cad@pki-ca.service' 

system_units['pki_cad'] = system_units['pki-cad'] 

# Our PKI instance is pki-tomcatd@pki-tomcat.service 

system_units['pki-tomcatd'] = 'pki-tomcatd@pki-tomcat.service' 

system_units['pki_tomcatd'] = system_units['pki-tomcatd'] 

 

class Fedora16Service(systemd.SystemdService): 

    def __init__(self, service_name): 

        systemd_name = service_name 

        if service_name in system_units: 

            systemd_name = system_units[service_name] 

        else: 

            if len(service_name.split('.')) == 1: 

                # if service_name does not have a dot, it is not foo.service 

                # and not a foo.target. Thus, not correct service name for 

                # systemd, default to foo.service style then 

                systemd_name = "%s.service" % (service_name) 

        super(Fedora16Service, self).__init__(service_name, systemd_name) 

 

# Special handling of directory server service 

# 

# We need to explicitly enable instances to install proper symlinks as 

# dirsrv.target.wants/ dependencies. Standard systemd service class does it 

# on enable() method call. Unfortunately, ipa-server-install does not do 

# explicit dirsrv.enable() because the service startup is handled by ipactl. 

# 

# If we wouldn't do this, our instances will not be started as systemd would 

# not have any clue about instances (PKI-IPA and the domain we serve) at all. 

# Thus, hook into dirsrv.restart(). 

class Fedora16DirectoryService(Fedora16Service): 

    def enable(self, instance_name=""): 

        super(Fedora16DirectoryService, self).enable(instance_name) 

        dirsrv_systemd = "/etc/sysconfig/dirsrv.systemd" 

        if os.path.exists(dirsrv_systemd): 

            # We need to enable LimitNOFILE=8192 in the dirsrv@.service 

            # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the 

            # service parameters is performed via 

            # /etc/sysconfig/dirsrv.systemd file which is imported by systemd 

            # into dirsrv@.service unit 

            replacevars = {'LimitNOFILE':'8192'} 

            ipautil.inifile_replace_variables(dirsrv_systemd, 'service', replacevars=replacevars) 

            selinux.restore_context(dirsrv_systemd) 

            ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False) 

 

    def restart(self, instance_name="", capture_output=True, wait=True): 

        if len(instance_name) > 0: 

            elements = self.systemd_name.split("@") 

            srv_etc = os.path.join(self.SYSTEMD_ETC_PATH, self.systemd_name) 

            srv_tgt = os.path.join(self.SYSTEMD_ETC_PATH, self.SYSTEMD_SRV_TARGET % (elements[0])) 

            srv_lnk = os.path.join(srv_tgt, self.service_instance(instance_name)) 

            if not os.path.exists(srv_etc): 

                self.enable(instance_name) 

            elif not os.path.samefile(srv_etc, srv_lnk): 

                os.unlink(srv_lnk) 

                os.symlink(srv_etc, srv_lnk) 

        super(Fedora16DirectoryService, self).restart(instance_name, capture_output=capture_output, wait=wait) 

 

# Enforce restart of IPA services when we do enable it 

# This gets around the fact that after ipa-server-install systemd thinks 

# ipa.service is not yet started but all services were actually started 

# already. 

class Fedora16IPAService(Fedora16Service): 

    def enable(self, instance_name=""): 

        super(Fedora16IPAService, self).enable(instance_name) 

        self.restart(instance_name) 

 

class Fedora16SSHService(Fedora16Service): 

    def get_config_dir(self, instance_name=""): 

        return '/etc/ssh' 

 

class Fedora16CAService(Fedora16Service): 

    def __wait_until_running(self): 

        # We must not wait for the httpd proxy if httpd is not set up yet. 

        # Unfortunately, knownservices.httpd.is_installed() can return 

        # false positives, so check for existence of our configuration file. 

        # TODO: Use a cleaner solution 

        if not os.path.exists('/etc/httpd/conf.d/ipa.conf'): 

            root_logger.debug( 

                'The httpd proxy is not installed, skipping wait for CA') 

            return 

        if dogtag.install_constants.DOGTAG_VERSION < 10: 

            # The server status information isn't available on DT 9 

            root_logger.debug('Using Dogtag 9, skipping wait for CA') 

            return 

        root_logger.debug('Waiting until the CA is running') 

        timeout = api.env.startup_timeout 

        op_timeout = time.time() + timeout 

        while time.time() < op_timeout: 

            try: 

                status = dogtag.ca_status() 

            except Exception: 

                status = 'check interrupted' 

            root_logger.debug('The CA status is: %s' % status) 

            if status == 'running': 

                break 

            root_logger.debug('Waiting for CA to start...') 

            time.sleep(1) 

        else: 

            raise RuntimeError('CA did not start in %ss' % timeout) 

 

    def start(self, instance_name="", capture_output=True, wait=True): 

        super(Fedora16CAService, self).start( 

            instance_name, capture_output=capture_output, wait=wait) 

        if wait: 

            self.__wait_until_running() 

 

    def restart(self, instance_name="", capture_output=True, wait=True): 

        super(Fedora16CAService, self).restart( 

            instance_name, capture_output=capture_output, wait=wait) 

        if wait: 

            self.__wait_until_running() 

 

# Redirect directory server service through special sub-class due to its 

# special handling of instances 

def f16_service(name): 

    if name == 'dirsrv': 

        return Fedora16DirectoryService(name) 

    if name == 'ipa': 

        return Fedora16IPAService(name) 

    if name == 'sshd': 

        return Fedora16SSHService(name) 

    if name in ('pki-cad', 'pki_cad', 'pki-tomcatd', 'pki_tomcatd'): 

        return Fedora16CAService(name) 

    return Fedora16Service(name) 

 

class Fedora16Services(base.KnownServices): 

    def __init__(self): 

        services = dict() 

        for s in base.wellknownservices: 

            services[s] = f16_service(s) 

        # Call base class constructor. This will lock services to read-only 

        super(Fedora16Services, self).__init__(services)