1 import time
2 import os
3 import errno
4 import re
5 import subprocess
6 import signal
7 import tempfile
8 import random
9 import glob
10 from dogtail.config import config
13 """Uses tempfile.NamedTemporaryFile() to create a unique tempfile in
14 config.scratchDir, with a filename like:
15 dogtail-headless-<label>.<random junk>"""
16 prefix = "dogtail-headless-"
17 return tempfile.NamedTemporaryFile(prefix = "%s%s." % (prefix, label),
18 dir = config.scratchDir)
19
21 if (path.startswith(os.path.sep) or
22 path.startswith(os.path.join('.','')) or
23 path.startswith(os.path.join('..',''))):
24 if not os.path.exists(path):
25 raise IOError, (errno.ENOENT, "No such file", path)
26 if not os.access(path, os.X_OK):
27 raise IOError, (errno.ENOEXEC, "Permission denied", path)
28 return True
29
31 - def __init__(self, cmdList, environ = None):
36
38 if self.environ == None: environ = os.environ
39 self.popen = subprocess.Popen(self.cmdList,
40 env = self.environ)
41
42 return self.popen.pid
43
45 return self.popen.wait()
46
48
49
50 os.kill(self.popen.pid, signal.SIGTERM)
51
52 @property
54 if self._exitCode == None:
55 self._exitCode = self.wait()
56 return self._exitCode
57
59 - def __init__(self, server = "/usr/bin/Xorg",
60 xinitrc = "/etc/X11/xinit/Xclients",
61 resolution = "1024x768x16"):
62 """resolution is only used with Xvfb."""
63 testBinary(server)
64 self.server = server
65 self._exitCode = None
66 self.xinit = "/usr/bin/xinit"
67 self.display = None
68 self.xinitrc = xinitrc
69 self.resolution = resolution
70
71 @staticmethod
73 tmp = os.listdir('/tmp')
74 pattern = re.compile('\.X([0-9]+)-lock')
75 usedDisplays = []
76 for file in tmp:
77 match = re.match(pattern, file)
78 if match: usedDisplays.append(int(match.groups()[0]))
79 if not usedDisplays: return ':0'
80 usedDisplays.sort()
81 return ':' + str(usedDisplays[-1] + 1)
82
83 @property
85 self.display = self.findFreeDisplay()
86 cmd = []
87 if self.xinit:
88 cmd.append(self.xinit)
89 if self.xinitrc: cmd.append(self.xinitrc)
90 cmd.append('--')
91 cmd.append(self.server)
92 cmd.append(self.display)
93 cmd.extend(['-ac', '-noreset'])
94 if self.server.endswith('Xvfb'):
95 cmd.extend(['-screen', '0', self.resolution])
96 cmd.append('-shmem')
97 return cmd
98
100 print ' '.join(self.cmdList)
101 self.popen = subprocess.Popen(self.cmdList)
102 return self.popen.pid
103
106
108
109 cookieName = "DOGTAIL_SESSION_COOKIE"
110
111 - def __init__(self, sessionBinary, scriptCmdList = [], scriptDelay = 10, logout = True):
112 testBinary(sessionBinary)
113 self.sessionBinary = sessionBinary
114 self.script = Script(scriptCmdList)
115 self.scriptDelay = scriptDelay
116 self.logout = logout
117 self.xserver = XServer()
118 self._cookie = None
119 self._environment = None
120
122 self.xinitrcFileObj = scratchFile('xinitrc')
123 self.xserver.xinitrc = self.xinitrcFileObj.name
124 self._buildXInitRC(self.xinitrcFileObj)
125 xServerPid = self.xserver.start()
126 time.sleep(self.scriptDelay)
127 self.script.environ = self.environment
128 scriptPid = self.script.start()
129 return (xServerPid, scriptPid)
130
131 @property
133 def isSessionProcess(fileName):
134 try:
135 if os.path.realpath(path + 'exe') != self.sessionBinary:
136 return False
137 except OSError:
138 return False
139 pid = fileName.split('/')[2]
140 if pid == 'self' or pid == str(os.getpid()): return False
141 return True
142
143 def getEnvDict(fileName):
144 try: envString = open(fileName, 'r').read()
145 except IOError: return {}
146 envItems = envString.split('\x00')
147 envDict = {}
148 for item in envItems:
149 if not '=' in item: continue
150 k, v = item.split('=', 1)
151 envDict[k] = v
152 return envDict
153
154 def isSessionEnv(envDict):
155 if not envDict: return False
156 if envDict.get(self.cookieName, 'notacookie') == self.cookie:
157 return True
158 return False
159
160 for path in glob.glob('/proc/*/'):
161 if not isSessionProcess(path): continue
162 envFile = path + 'environ'
163 envDict = getEnvDict(envFile)
164 if isSessionEnv(envDict):
165
166
167 self._environment = envDict
168 if not self._environment:
169 raise RuntimeError("Can't find our environment!")
170 return self._environment
171
173 self.script.wait()
174 return self.xserver.wait()
175
177 try: self.script.stop()
178 except OSError: pass
179 self.xserver.stop()
180
186
187 @property
189 if not self._cookie:
190 self._cookie = "%X" % random.getrandbits(16)
191 return self._cookie
192
194 if self.logout:
195 logoutString = "; dogtail-logout"
196 else:
197 logoutString = ""
198 lines = [
199 "export %s=%s" % (self.cookieName, self.cookie),
200 "gconftool-2 --type bool --set /desktop/gnome/interface/accessibility true",
201 ". /etc/X11/xinit/xinitrc-common",
202 "export %s" % self.cookieName,
203 "exec -l $SHELL -c \"$CK_XINIT_SESSION $SSH_AGENT %s\"" % \
204 self.sessionBinary,
205 ""]
206
207 fileObj.write('\n'.join(lines).strip())
208 fileObj.flush()
209