4
# Usage: dogtail-run-headless ./some-dogtail-script.py
6
# This script launches an X server using the virtual framebuffer, allowing
7
# dogtail scripts to be run on headless servers. The server starts a minimal
8
# GNOME session, based on Nat Friedman's notes here:
9
# http://nat.org/2005/october/#Keep-It-Simple-Stupid
10
# Dogtail scripts are run in the current directory. After the script
11
# terminates, so does the X server.
13
# The X server can be connected to using VNC via the following steps:
15
# port=`"x11vnc -display :1 -viewonly -bg" | grep PORT)`
16
# port=`echo "$port" | sed -e's/PORT=//'`
17
# port=`expr $port - 5900`
19
# vncviewer localhost:$port
21
# Author: Zack Cerza <zcerza@redhat.com>
24
A11Y_ENABLED=`gconftool-2 --get /desktop/gnome/interface/accessibility`
26
if test x$A11Y_ENABLED = xfalse; then
27
echo "Enabling accessibility support for GNOME"
28
gconftool-2 --set --type bool /desktop/gnome/interface/accessibility true
31
EXIT_CODE_FILE=/tmp/dogtail-run-headless.exitcode
33
mv -f ~/.xinitrc ~/.xinitrc-user 2>/dev/null && \
34
echo "Moving ~/.xinitrc to ~/.xinitrc-user temporarily"
36
# xinit doesn't allow specifying an alternate xinitrc
37
cat << EOF > ~/.xinitrc
39
gnome-settings-daemon &
43
gconftool-2 --set --type bool /desktop/gnome/interface/accessibility true
45
cd $PWD && dogtail-detect-session && sh -c "$@"; echo -n \$? > $EXIT_CODE_FILE
48
echo "Starting GNOME Session..."
49
xinit -- /usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x24 -fbdir /tmp :1
51
if test x$A11Y_ENABLED = xfalse; then
52
echo "Re-disabling accessibility support for GNOME"
53
gconftool-2 --set --type bool /desktop/gnome/interface/accessibility false
57
mv -f ~/.xinitrc-user ~/.xinitrc 2>/dev/null && \
58
echo "Restored ~/.xinitrc"
60
exit `cat $EXIT_CODE_FILE`
6
This script launches an X server using the virtual framebuffer, allowing
7
dogtail scripts to be run on headless servers.
8
The server can currently use a minimal GNOME session, or just metacity.
10
Dogtail scripts are run in the current directory. After the script
11
terminates, so does the X server.
13
__author__ = "Zack Cerza <zcerza@redhat.com>"
16
Usage: dogtail-run-headless <options> <script>
20
-h, --help Display this message.
22
-g, --gnome Use a GNOME session.
24
-n, --none Use a minimal session, consisting of just metacity.
26
-k, --kde Use a KDE session (not implemented).
35
gconfClient = gconf.client_get_default()
40
a11yGConfKey = '/desktop/gnome/interface/accessibility'
46
def makeSureGNOMEIsAccessible():
47
global a11yIsEnabled, a11yWasEnabled
48
a11yIsEnabled = gconfClient.get_bool(a11yGConfKey)
49
a11yWasEnabled = a11yIsEnabled
52
print "Temporarily enabling accessibility support for GNOME"
53
gconfClient.set_bool(a11yGConfKey, True)
54
a11yIsEnabled = gconfClient.get_bool(a11yGConfKey)
62
def findFreeDisplay():
64
tmp = os.listdir('/tmp')
65
pattern = re.compile('\.X([0-9]+)-lock')
68
match = re.match(pattern, file)
69
if match: numbers.append(int(match.groups()[0]))
70
if not numbers: return ':0'
72
return ':' + str(numbers[-1] + 1)
74
server = os.popen('/usr/bin/which Xvfb 2>/dev/null')
76
print "Cannot find Xvfb"
78
server = server.readlines()[0].strip()
81
resolution = '1024x768x16'
82
cmd = 'xinit %s -- %s %s -screen 0 %s -ac -noreset -shmem' % \
83
(client, server, findFreeDisplay(), resolution)
97
longOpts = ['help', 'gnome', 'kde', 'none']
99
opts, args = getopt.getopt(argv[1:], shortOpts, longOpts)
100
except getopt.GetoptError:
108
# take the '-' out of e.g. '-h'
109
if len(opt) == 2: opt = opt[1]
110
# take the '--' out of e.g. '--help'
111
if len(opt) > 2: opt = opt[2:]
114
for opt, arg in opts:
116
if opt in (shortOpts[0], longOpts[0]):
121
print "You must specify a script to execute in the headless session."
125
print "You may only specify one script to execute in the headless session."
127
print "Note: If you're trying to have dogtail-run-headless run a script using certain"
128
print "environment values, use the following format (note the quotation marks):"
130
print ' dogtail-run-headless "VAR=value /path/to/script.py"'
136
pid = str(os.getpid())
138
exitCodeFile = "/tmp/dogtail-headless-exitcode." + pid
141
xinitrc = file("/tmp/dogtail-headless-xinitrc." + pid, 'w')
142
xinitrc.write('#!/bin/sh\n')
144
if opt in (shortOpts[1], longOpts[1]):
145
# (Fake) GNOME session
147
# Damn binaries, always ambling about the filesystem
148
if os.path.exists('/usr/libexec/gnome-settings-daemon'):
149
xinitrc.write('/usr/libexec/')
150
xinitrc.write('gnome-settings-daemon &\n')
151
xinitrc.write('gnome-panel &\n')
152
xinitrc.write('nautilus -n &\n')
153
xinitrc.write('metacity &\n')
154
xinitrc.write('sleep 10\n')
155
xinitrc.write('cd %s && dogtail-detect-session && sh -c "%s"; echo -n $? > %s\n' % (os.getcwdu(), script, exitCodeFile))
158
makeSureGNOMEIsAccessible()
160
exitCode = int(file(exitCodeFile, 'r').read())
163
elif opt in (shortOpts[2], longOpts[2]):
165
print "Sorry, this is just a placeholder. KDE4 should support dogtail, and vice versa."
169
elif opt in (shortOpts[3], longOpts[3]):
171
xinitrc.write('metacity &\n')
172
xinitrc.write('sleep 3\n')
173
xinitrc.write('cd %s && sh -c "%s"; echo -n $? > %s\n' % (os.getcwdu(), script, exitCodeFile))
176
makeSureGNOMEIsAccessible()
178
exitCode = int(file(exitCodeFile, 'r').read())
182
if not a11yWasEnabled: gconfClient.set_bool(a11yGConfKey, False)
184
os.remove(exitCodeFile)
190
if __name__ == "__main__":
192
try: exitCode = main(sys.argv)
195
traceback.print_exc()
198
except: traceback.print_exc()