Skip to content

Commit

Permalink
Fixes to get the Docker image building again
Browse files Browse the repository at this point in the history
Firstly Firefox 60 now throws an error if its run as root inside a
user's home path. Which is great because that revelead my naivety about
using `RUN su user` in the Dockerfile. So now Firefox is running as a
non-root user inside Docker which is what was always best.

Also it turns out that the crude 3 second wait at startup hoping that
Firefox's Marionette had started listening, wasn't good enough. So now
we're actually listening for a log message to know when it's started
now.

Finally make all startup methods use a the post-webext connection state
to send the startup URL to the browser, the other methods just seemed to
flakey.

Includes version bump to 1.0.9
  • Loading branch information
tombh committed Jun 12, 2018
1 parent c13e8d2 commit 2577ea8
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 28 deletions.
18 changes: 9 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
FROM bitnami/minideb:stretch

RUN install_packages xvfb libgtk-3-0 curl ca-certificates bzip2 libdbus-glib-1-2
RUN install_packages xvfb libgtk-3-0 curl ca-certificates bzip2 libdbus-glib-1-2 procps

# Logging client for Google's Stackdriver logging service.
# NB Not used by default. Only used by the Browsh as a Service platform on the
# anonymous accounts.
RUN curl -L -o /usr/local/bin/gcloud_logger https://github.com/tombh/gcloud_pipe_logger/releases/download/v0.0.5/gcloud_pipe_logger_0.0.5_linux_amd64
RUN chmod a+x /usr/local/bin/gcloud_logger

RUN useradd -m user
RUN su user
ENV HOME=/home/user
WORKDIR $HOME

RUN curl -o /etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn-social/hosts

RUN useradd -m user --home /app
USER user
ENV HOME=/app
WORKDIR /app

# These are needed to detect versions
ADD .travis.yml .
ADD ./webext/manifest.json .

# Setup Firefox
ENV PATH="/home/user/bin/firefox:${PATH}"
ENV PATH="/app/bin/firefox:${PATH}"
ADD ./interfacer/contrib/setup_firefox.sh .
RUN ./setup_firefox.sh
RUN rm ./setup_firefox.sh && rm .travis.yml
Expand All @@ -33,11 +33,11 @@ RUN ./setup_browsh.sh
# that all future runs will be consistent.
RUN TERM=xterm script \
--return \
-c "/home/user/browsh" \
-c "/app/browsh" \
/dev/null \
>/dev/null & \
sleep 10
RUN rm ./setup_browsh.sh && rm manifest.json

CMD ["/home/user/browsh"]
CMD ["/app/browsh"]

3 changes: 2 additions & 1 deletion interfacer/src/browsh/browsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ var (
isUseExistingFirefox = flag.Bool("use-existing-ff", false, "Whether Browsh should launch Firefox or not")
useFFProfile = flag.String("ff-profile", "default", "Firefox profile to use")
isDebug = flag.Bool("debug", false, "Log to ./debug.log")
StartupURL = flag.String("startup-url", "https://google.com", "URL to launch at startup")
timeLimit = flag.Int("time-limit", 0, "Kill Browsh after the specified number of seconds")
// StartupURL is the URL of the first tab at boot
StartupURL = flag.String("startup-url", "https://google.com", "URL to launch at startup")
// IsHTTPServer needs to be exported for use in tests
IsHTTPServer = flag.Bool("http-server", false, "Run as an HTTP service")
// HTTPServerPort also needs to be exported for use in tests
Expand Down
8 changes: 3 additions & 5 deletions interfacer/src/browsh/comms.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,7 @@ func webSocketServer(w http.ResponseWriter, r *http.Request) {
} else {
sendTtySize()
}
if IsTesting {
// For some reason, using Firefox's CLI arg `--url https://google.com` doesn't consistently
// work on Travis. So we do it here inse
sendMessageToWebExtension("/new_tab," + *StartupURL)
}
// For some reason, using Firefox's CLI arg `--url https://google.com` doesn't consistently
// work. So we do it here instead.
sendMessageToWebExtension("/new_tab," + *StartupURL)
}
38 changes: 26 additions & 12 deletions interfacer/src/browsh/firefox.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os/exec"
"runtime"
"strings"
"regexp"
"time"

"github.com/gdamore/tcell"
Expand All @@ -18,6 +19,7 @@ import (

var (
marionette net.Conn
isMarionetteListening = false
ffCommandCount = 0
defaultFFPrefs = map[string]string{
"browser.startup.homepage": "'https://www.google.com'",
Expand Down Expand Up @@ -52,6 +54,8 @@ var (
)

func startHeadlessFirefox() {
var isMarionette, isListening bool
checkIfFirefoxIsAlreadyRunning()
Log("Starting Firefox in headless mode")
ensureFirefoxBinary()
args := []string{"--marionette"}
Expand All @@ -77,10 +81,22 @@ func startHeadlessFirefox() {
}
in := bufio.NewScanner(stdout)
for in.Scan() {
isMarionette = strings.Contains(in.Text(), "Marionette")
isListening = strings.Contains(in.Text(), "Listening on port")
if isMarionette && isListening { isMarionetteListening = true }
Log("FF-CONSOLE: " + in.Text())
}
}

func checkIfFirefoxIsAlreadyRunning() {
if runtime.GOOS == "windows" { return }
processes := Shell("ps aux")
r, _ := regexp.Compile("firefox.*--headless")
if r.MatchString(processes) {
Shutdown(errors.New("A headless Firefox is already running"))
}
}

func ensureFirefoxBinary() {
if *firefoxBinary == "firefox" {
switch runtime.GOOS {
Expand Down Expand Up @@ -199,15 +215,6 @@ func sendFirefoxCommand(command string, args map[string]interface{}) {
readMarionette()
}

func loadHomePage() {
// Wait for the CLI websocket server to start listening
time.Sleep(200 * time.Millisecond)
args := map[string]interface{}{
"url": *StartupURL,
}
sendFirefoxCommand("get", args)
}

func setDefaultPreferences() {
for key, value := range defaultFFPrefs {
setFFPreference(key, value)
Expand All @@ -233,12 +240,19 @@ func setupFirefox() {
if (*timeLimit > 0) {
go beginTimeLimit()
}
// TODO: Do something better than just waiting
time.Sleep(3 * time.Second)
waitForMarionette()
firefoxMarionette()
setDefaultPreferences()
installWebextension()
go loadHomePage()
}

func waitForMarionette() {
start := time.Now()
for time.Since(start) < 60 * time.Second {
if isMarionetteListening { return }
time.Sleep(10 * time.Millisecond)
}
Shutdown(errors.New("Marionette didn't start within 60 seconds."))
}

func startFirefox() {
Expand Down
2 changes: 1 addition & 1 deletion webext/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Browsh",
"version": "1.0.8",
"version": "1.0.9",

"description": "Renders the browser as realtime, interactive, TTY-compatible text",

Expand Down

0 comments on commit 2577ea8

Please sign in to comment.