Bearbeiten

Bearbeiten

Um einige JavaScript-Unit-Tests durchzuführen mitKarmaIn einem Docker-Container (basierend auf Ubuntu 14.04) starte ich Firefox im Container mit einemKarma-Skript-Launchermit xvfb-run. Das Startskript sieht folgendermaßen aus:

#!/bin/bash
set -o errexit 

# nasty workaround as xvfb-run doesn't cleanup properly...
trap "pkill -f /usr/lib/firefox/firefox" EXIT

xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox $1

Das Starten des Browsers und Ausführen der Unit-Tests funktioniert sehr gut. Nach der Ausführung der Tests beendet Karma die erzeugte Browserinstanz – in meinem Fall das Skript, das Firefox über xvfb-run gestartet hat.

Im obigen Skript können Sie sehen, dass ich ein Skript registriert habe, trapum den gestarteten Firefox beim Beenden meines Skripts zu beenden. Das funktioniert, aber das Skript ist kein sehr netter Bürger, da es beendet wirdalleInstanzen von Firefox, die derzeit ausgeführt werden, anstatt nur die eine Instanz zu beenden, die vom Skript gestartet wurde. Ich habe zuerst versucht, den xfvb-runProzess zu beenden, aber das Beenden dieses Prozesses hat keine Auswirkungen auf den vom Skript gestarteten Unterprozess xvfb-run...

Wenn ich Firefox xvfb-runmanuell neu starte, werden eine Reihe von Prozessen erzeugt:

root@1d7a5988e521:/data# xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox &
[1] 348
root@1d7a5988e521:/data# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 bash
  348 ?        S      0:00 /bin/sh /usr/bin/xvfb-run --auto-servernum --server-args=-screen 0, 1024x768x16 firefox
  360 ?        S      0:00 Xvfb :99 -screen 0, 1024x768x16 -nolisten tcp -auth /tmp/xvfb-run.bgMEuq/Xauthority
  361 ?        Sl     0:00 /usr/lib/firefox/firefox
  378 ?        S      0:00 dbus-launch --autolaunch bcf665e095759bae9fc1929b57455cad --binary-syntax --close-stderr
  379 ?        Ss     0:00 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
  388 ?        S      0:00 /usr/lib/x86_64-linux-gnu/gconf/gconfd-2
  414 ?        R+     0:00 ps ax
root@1d7a5988e521:/data#

Wenn ich nun den xvfb-runProzess (PID 348) beende, wird nur dieser Prozess beendet und die anderen Prozesse laufen weiter. Wenn ich stattdessen den Firefox-Prozess (PID 361) beende, wird das xvfb-runSkript korrekt beendet und beendet auch die anderen Prozesse. Aus meinem Skript kenne ich aber nur die PID des xvfb-runProzesses...

Bei meinen Recherchen stieß ich aufdieser ziemlich alte FehlerberichtDies xvfb-runscheint immer noch gültig zu sein, obwohl der Fehler bereits 2012 behoben wurde.

Gibt es eine höfliche Möglichkeit, den xvfb-runProzess zu beenden, damit die anderen Prozesse ordnungsgemäß bereinigt werden können?


Ich habe dies bereits auf Stack Overflow gefragt, aber bisher keine Antwort erhalten. Vielleicht ist es etwas OT für Stack Overflow, aber hier besser aufgehoben?!

Antwort1

Es hört sich an, als würden Sie es nur xvfb-runwegen der --auto-servernumFunktionalität verwenden.

Wie @meuh bemerkte: Diese Logik isteigentlich ganz einfach:

# Copyright (C) 2005 The T2 SDE Project
# Copyright (C) XXXX - 2005 Debian
# GNU GPLv2
find_free_servernum() {
    # Sadly, the "local" keyword is not POSIX.  Leave the next line commented in
    # the hope Debian Policy eventually changes to allow it in /bin/sh scripts
    # anyway.
    #local i

    i=$SERVERNUM
    while [ -f /tmp/.X$i-lock ]; do
        i=$(($i + 1))
    done
    echo $i
}

Wenn diese Funktion definiert ist, können Sie einen Aufruf wie diesen versuchen.anstattxvfb-run:

Xvfb :$(find_free_servernum) -screen 0, 1024x768x16 firefox $1 &
THE_PID=$!
# kill Xvfb whenever you feel like it
kill -15 $THE_PID

Mit xvfb-run„entfernt:“ müssen wir uns keine Gedanken mehr darüber machen, wie wir töten xvfb-run.

Antwort2

Ich bin heute auf genau dieses Problem gestoßen.

AlleXserverLassen Sie uns das -terminateArgument stützen.

-beenden

bewirkt, dass der Server beim Zurücksetzen beendet wird, anstatt weiterzulaufen. Dies überschreibt eine vorherige Befehlszeilenoption −noreset.

Daher habe ich es letztendlich mit xvfb-run's angegeben -s:

xvfb-run -d -s '-terminate' firefox --no-remote --profile $PROFILE_DIR $URL

In unserem Fall eines Karma-Testläufers beendet sich der Xvfb-Server selbst, sobald die Firefox-Instanz von Karma geschlossen wird, da sein letzter X-Client (Firefox) beendet wurde. xvfb-run hat die Ausführung auch nach dem Beenden von Firefox abgeschlossen.

Bearbeiten

Am Ende habe ich meine eigene „einfachere“ Version des xvfb-run-Skripts zusammengestellt:


PROFILE=$(mktemp -d)
trap "rm -rf $PROFILE" EXIT

# Start Xvfb and let it find a display number itself.
# Some versions of Xvfb (apparently 1.17.x) refuse to write to stdout
Xvfb -displayfd 4 -terminate -nolisten tcp 4>$PROFILE/.Xdisplay &

# Wait a few seconds for Xvfb to start
sleep ${START_WAIT-2}

${FIREFOX_HOME}/firefox --profile $PROFILE --no-remote --display :$(<$PROFILE/.Xdisplay) "${@?}" &
# Karma appears to send a SIGTERM to the browser when it's done, forward that signal to the Firefox process.
trap "kill -SIGTERM $!" SIGTERM

# Wait for all children to terminate
wait

Antwort3

Meine Lösung bestand darin, xvfb im Docker-Einstiegspunktskript zu starten:

Xvfb :0 -screen 0 1024x768x24 &

Sie können diese gleiche Zeile auch in eine Art Betriebssystem-Startskript (z. B. .bashrc) einfügen, wenn Sie Docker nicht verwenden.

Dann habe ich in einem anderen Skript die Anzeige exportiert und die eigentliche Funktion aufgerufen, die ich verwenden wollte

export DISPLAY=:0
firefox $1

verwandte Informationen