-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwrapped-firefox-launcher.nix
138 lines (138 loc) · 4.9 KB
/
wrapped-firefox-launcher.nix
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
{
pkgs ? import <nixpkgs> {}, firefox ? p: p.firefox, firefoxName ? "firefox"
, marionette ? p: (import ./marionette-python-packages.nix {pkgs = p;}).marionette-harness
, profileContent ? null
, baseProfile ? import ./firefox-profile.nix { inherit pkgs firefox; finalContent = profileContent; }
, name ? "firefox-launcher"
}:
rec {
socatCmd = (pkgs.lib.getBin pkgs.socat) + "/bin/socat";
firefoxCmd = (pkgs.lib.getBin pkgs.firefox) + "/bin/" + firefoxName;
unionfsCmd = (pkgs.lib.getBin pkgs.unionfs-fuse) + "/bin/unionfs";
xdummyCmd = (pkgs.lib.getBin pkgs.xdummy) + "/bin/xdummy";
xpropCmd = (pkgs.lib.getBin pkgs.xorg.xprop) + "/bin/xprop";
fuserCmd = (pkgs.lib.getBin pkgs.psmisc) + "/bin/fuser";
marionette_ = if builtins.isFunction marionette then marionette pkgs else marionette;
marionetteEnv = pkgs.runCommand "marionette-env" { buildInputs = [ marionette_ ]; } ''
echo "export PYTHONPATH='$PYTHONPATH'; export PATH='$PATH'" > "$out"
'';
marionettePythonPrologue = ''
from marionette_driver.marionette import Marionette;
from marionette_driver.addons import Addons;
import os;
import sys;
retry=10
while retry > 0:
try:
session = Marionette(host="127.0.0.1",port=os.getenv("MARIONETTE_PORT") or 2828,bin=False,socket_timeout=3600,startup_timeout=1);
if session.start_session(timeout=3):
retry = -1
except Exception:
retry = retry-1
os.sleep(0.5)
if retry==0:
print("Could not connect")
exit()
while True:
try:
code = sys.stdin.readline()
if not code:
exit()
value = (eval(code))
if value != None:
print(unicode(value).encode("utf-8"))
except EOFError:
exit()
except Exception as e:
print(e)
'';
combineProfileScript = ''
if test -n "$FIREFOX_PROFILE"; then
_FIREFOX_PROFILE="$FIREFOX_PROFILE"
else
mkdir -p "/''${TMPDIR:-tmp}/ff.$USER/profiles/"
_FIREFOX_PROFILE="$(mktemp -d -p "/''${TMPDIR:-/tmp}/ff.$USER/profiles/")"
fi
test -n "${baseProfile}" && yes n | cp -riT "${baseProfile}" "$_FIREFOX_PROFILE"
'';
homeScript = ''
if test -z "$HOME" || ! test -d "$HOME"; then
export HOME="$(mktemp -d)"
_HOME_KILL="$HOME"
else
_HOME_KILL=
fi;
'';
marionettePythonRunner = pkgs.writeScript "marionette-runner" ''
pypy -u -c '${marionettePythonPrologue}'
'';
marionetteScript = ''
if test -n "$MARIONETTE_SOCKET"; then
export MARIONETTE_PORT="''${MARIONETTE_PORT:-2828}"
export PYTHONIOENCODING=utf-8:surrogateencode
export LANG=en_US.UTF-8
(
source "${marionetteEnv}"
"${socatCmd}" -t 60 unix-listen:"$MARIONETTE_SOCKET",forever,fork,rcvbuf=1,sndbuf=1 exec:'${marionettePythonRunner}',rcvbuf=1,sndbuf=1 &
"${socatCmd}" -t 60 unix-listen:"$MARIONETTE_SOCKET.port",forever,fork tcp-connect:127.0.0.1:"$MARIONETTE_PORT" &
while ! ( test -e "$MARIONETTE_SOCKET" && test -e "$MARIONETTE_SOCKET.port" ; ); do
sleep 0.1
done
chmod a+rw "$MARIONETTE_SOCKET"{,.port}
echo "MARIONETTE_SOCKET=$MARIONETTE_SOCKET" >&2
)
fi
'';
cleanupScript = ''
if test -n "$_HOME_KILL"; then
echo "Removing [[$_HOME_KILL]]" >&2
rm -rf "$_HOME_KILL"
echo "Removed [[$_HOME_KILL]]" >&2
fi
if test -n "$MARIONETTE_SOCKET"; then
"${fuserCmd}" "$MARIONETTE_SOCKET" -k -s 2> /dev/null
rm -f "$MARIONETTE_SOCKET"
fi
echo "making accessible [[$FIREFOX_PROFILE]]" >&2
chmod a+rwX -R "$FIREFOX_PROFILE"/* 2> /dev/null
test -n "$FIREFOX_PROFILE_KILL" &&
rm -rf "$FIREFOX_PROFILE"
'';
firefoxProfileCombiner = pkgs.writeScriptBin "combine-firefox-profile" ''
export FIREFOX_PROFILE="$1"
${combineProfileScript}
echo "$_FIREFOX_PROFILE"
'';
displayScript=''
if test -n "$FIREFOX_DISPLAY"; then
export DISPLAY="$FIREFOX_DISPLAY"
"${xdummyCmd}" "$DISPLAY" &
while ! "${xpropCmd}" -root; do
sleep 1;
done
echo "Virtual local DISPLAY=$DISPLAY" >&2
fi
'';
firefoxLauncher = pkgs.writeScriptBin name ''#! /bin/sh
${homeScript}
${marionetteScript}
${displayScript}
echo "$FIREFOX_EXTRA_PREFS" >> "$FIREFOX_PROFILE/prefs.js"
if test -n "$MARIONETTE_PORT"; then
sed -e '/marionette[.]defaultPrefs[.]port/d' -i "$FIREFOX_PROFILE/prefs.js"
echo "user_pref(\"marionette.defaultPrefs.port\",\"$MARIONETTE_PORT\");" >> "$FIREFOX_PROFILE/prefs.js"
"${firefoxCmd}" --profile "$FIREFOX_PROFILE" --new-instance --marionette "$@"
else
"${firefoxCmd}" --profile "$FIREFOX_PROFILE" --new-instance "$@"
fi
echo "${firefoxName} finished" >&2
exit_value="$?"
${cleanupScript}
exit $exit_value
'';
firefoxScripts = pkgs.runCommand "firefox-scripts" {} ''
mkdir -p "$out/bin"
ln -s "${firefoxProfileCombiner}"/bin/* "$out/bin"
ln -s "${firefoxLauncher}"/bin/* "$out/bin"
'';
}