Hide keyboard shortcuts

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

# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> 

# 

# This file is part of Ansible 

# 

# Ansible 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. 

# 

# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>. 

 

# Make coding more python3-ish 

from __future__ import (absolute_import, division, print_function) 

__metaclass__ = type 

 

import multiprocessing 

import os 

import sys 

import traceback 

 

from jinja2.exceptions import TemplateNotFound 

 

HAS_PYCRYPTO_ATFORK = False 

try: 

from Crypto.Random import atfork 

HAS_PYCRYPTO_ATFORK = True 

except: 

# We only need to call atfork if pycrypto is used because it will need to 

# reinitialize its RNG. Since old paramiko could be using pycrypto, we 

# need to take charge of calling it. 

pass 

 

from ansible.errors import AnsibleConnectionFailure 

from ansible.executor.task_executor import TaskExecutor 

from ansible.executor.task_result import TaskResult 

from ansible.module_utils._text import to_text 

 

try: 

from __main__ import display 

except ImportError: 

from ansible.utils.display import Display 

display = Display() 

 

__all__ = ['WorkerProcess'] 

 

 

class WorkerProcess(multiprocessing.Process): 

''' 

The worker thread class, which uses TaskExecutor to run tasks 

read from a job queue and pushes results into a results queue 

for reading later. 

''' 

 

def __init__(self, rslt_q, task_vars, host, task, play_context, loader, variable_manager, shared_loader_obj): 

 

super(WorkerProcess, self).__init__() 

# takes a task queue manager as the sole param: 

self._rslt_q = rslt_q 

self._task_vars = task_vars 

self._host = host 

self._task = task 

self._play_context = play_context 

self._loader = loader 

self._variable_manager = variable_manager 

self._shared_loader_obj = shared_loader_obj 

 

73 ↛ 91line 73 didn't jump to line 91, because the condition on line 73 was never false if sys.stdin.isatty(): 

# dupe stdin, if we have one 

self._new_stdin = sys.stdin 

try: 

fileno = sys.stdin.fileno() 

78 ↛ exitline 78 didn't return from function '__init__', because the condition on line 78 was never false if fileno is not None: 

try: 

self._new_stdin = os.fdopen(os.dup(fileno)) 

except OSError: 

# couldn't dupe stdin, most likely because it's 

# not a valid file descriptor, so we just rely on 

# using the one that was passed in 

pass 

except (AttributeError, ValueError): 

# couldn't get stdin's fileno, so we just carry on 

pass 

else: 

# set to /dev/null 

self._new_stdin = os.devnull 

 

def run(self): 

''' 

Called when the process is started. Pushes the result onto the 

results queue. We also remove the host from the blocked hosts list, to 

signify that they are ready for their next task. 

''' 

 

# import cProfile, pstats, StringIO 

# pr = cProfile.Profile() 

# pr.enable() 

 

104 ↛ 105line 104 didn't jump to line 105, because the condition on line 104 was never true if HAS_PYCRYPTO_ATFORK: 

atfork() 

 

try: 

# execute the task and build a TaskResult from the result 

display.debug("running TaskExecutor() for %s/%s" % (self._host, self._task)) 

executor_result = TaskExecutor( 

self._host, 

self._task, 

self._task_vars, 

self._play_context, 

self._new_stdin, 

self._loader, 

self._shared_loader_obj, 

self._rslt_q 

).run() 

 

display.debug("done running TaskExecutor() for %s/%s [%s]" % (self._host, self._task, self._task._uuid)) 

self._host.vars = dict() 

self._host.groups = [] 

task_result = TaskResult( 

self._host.name, 

self._task._uuid, 

executor_result, 

task_fields=self._task.dump_attrs(), 

) 

 

# put the result on the result queue 

display.debug("sending task result for task %s" % self._task._uuid) 

self._rslt_q.put(task_result) 

display.debug("done sending task result for task %s" % self._task._uuid) 

 

except AnsibleConnectionFailure: 

self._host.vars = dict() 

self._host.groups = [] 

task_result = TaskResult( 

self._host.name, 

self._task._uuid, 

dict(unreachable=True), 

task_fields=self._task.dump_attrs(), 

) 

self._rslt_q.put(task_result, block=False) 

 

except Exception as e: 

if not isinstance(e, (IOError, EOFError, KeyboardInterrupt, SystemExit)) or isinstance(e, TemplateNotFound): 

try: 

self._host.vars = dict() 

self._host.groups = [] 

task_result = TaskResult( 

self._host.name, 

self._task._uuid, 

dict(failed=True, exception=to_text(traceback.format_exc()), stdout=''), 

task_fields=self._task.dump_attrs(), 

) 

self._rslt_q.put(task_result, block=False) 

except: 

display.debug(u"WORKER EXCEPTION: %s" % to_text(e)) 

display.debug(u"WORKER TRACEBACK: %s" % to_text(traceback.format_exc())) 

 

display.debug("WORKER PROCESS EXITING") 

 

# pr.disable() 

# s = StringIO.StringIO() 

# sortby = 'time' 

# ps = pstats.Stats(pr, stream=s).sort_stats(sortby) 

# ps.print_stats() 

# with open('worker_%06d.stats' % os.getpid(), 'w') as f: 

# f.write(s.getvalue())