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

# This file is part of Buildbot.  Buildbot 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, version 2. 

# 

# 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, write to the Free Software Foundation, Inc., 51 

# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 

# 

# Copyright Buildbot Team Members 

 

from twisted.python import log 

from twisted.internet import defer 

from twisted.application import service 

from buildbot.pbutil import NewCredPerspective 

from buildbot.sourcestamp import SourceStamp 

from buildbot import interfaces, config 

from buildbot.process.properties import Properties 

 

class DebugServices(config.ReconfigurableServiceMixin, service.MultiService): 

 

    def __init__(self, master): 

        service.MultiService.__init__(self) 

        self.setName('debug_services') 

        self.master = master 

 

        self.debug_port = None 

        self.debug_password = None 

        self.debug_registration = None 

        self.manhole = None 

 

 

    @defer.inlineCallbacks 

    def reconfigService(self, new_config): 

 

        # debug client 

        config_changed = (self.debug_port != new_config.slavePortnum or 

                          self.debug_password != new_config.debugPassword) 

 

        if not new_config.debugPassword or config_changed: 

            if self.debug_registration: 

                yield self.debug_registration.unregister() 

                self.debug_registration = None 

 

        if new_config.debugPassword and config_changed: 

            factory = lambda mind, user : DebugPerspective(self.master) 

            self.debug_registration = self.master.pbmanager.register( 

                    new_config.slavePortnum, "debug", new_config.debugPassword, 

                    factory) 

 

        self.debug_password = new_config.debugPassword 

        if self.debug_password: 

            self.debug_port = new_config.slavePortnum 

        else: 

            self.debug_port = None 

 

        # manhole 

        if new_config.manhole != self.manhole: 

            if self.manhole: 

                yield defer.maybeDeferred(lambda : 

                        self.manhole.disownServiceParent()) 

                self.manhole.master = None 

                self.manhole = None 

 

            if new_config.manhole: 

                self.manhole = new_config.manhole 

                self.manhole.master = self.master 

                self.manhole.setServiceParent(self) 

 

        # chain up 

        yield config.ReconfigurableServiceMixin.reconfigService(self, 

                                                    new_config) 

 

 

    @defer.inlineCallbacks 

    def stopService(self): 

        if self.debug_registration: 

            yield self.debug_registration.unregister() 

            self.debug_registration = None 

 

        # manhole will get stopped as a sub-service 

 

        yield defer.maybeDeferred(lambda : 

                service.MultiService.stopService(self)) 

 

        # clean up 

        if self.manhole: 

            self.manhole.master = None 

            self.manhole = None 

 

 

class DebugPerspective(NewCredPerspective): 

 

    def __init__(self, master): 

        self.master = master 

 

    def attached(self, mind): 

        return self 

 

    def detached(self, mind): 

        pass 

 

    def perspective_requestBuild(self, buildername, reason, branch, 

                            revision, properties={}): 

        c = interfaces.IControl(self.master) 

        bc = c.getBuilder(buildername) 

        ss = SourceStamp(branch, revision) 

        bpr = Properties() 

        bpr.update(properties, "remote requestBuild") 

        return bc.submitBuildRequest(ss, reason, bpr) 

 

    def perspective_pingBuilder(self, buildername): 

        c = interfaces.IControl(self.master) 

        bc = c.getBuilder(buildername) 

        bc.ping() 

 

    def perspective_reload(self): 

        log.msg("debug client - triggering master reconfig") 

        self.master.reconfig() 

 

    def perspective_pokeIRC(self): 

        log.msg("saying something on IRC") 

        from buildbot.status import words 

        for s in self.master: 

            if isinstance(s, words.IRC): 

                bot = s.f 

                for channel in bot.channels: 

                    print " channel", channel 

                    bot.p.msg(channel, "Ow, quit it") 

 

    def perspective_print(self, msg): 

        log.msg("debug %s" % msg)