Fixes to get the Docker image building again
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
This commit is contained in:
parent
c13e8d26f6
commit
2577ea896b
18
Dockerfile
18
Dockerfile
|
@ -1,6 +1,6 @@
|
||||||
FROM bitnami/minideb:stretch
|
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.
|
# Logging client for Google's Stackdriver logging service.
|
||||||
# NB Not used by default. Only used by the Browsh as a Service platform on the
|
# NB Not used by default. Only used by the Browsh as a Service platform on the
|
||||||
|
@ -8,19 +8,19 @@ RUN install_packages xvfb libgtk-3-0 curl ca-certificates bzip2 libdbus-glib-1-2
|
||||||
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 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 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 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
|
# These are needed to detect versions
|
||||||
ADD .travis.yml .
|
ADD .travis.yml .
|
||||||
ADD ./webext/manifest.json .
|
ADD ./webext/manifest.json .
|
||||||
|
|
||||||
# Setup Firefox
|
# Setup Firefox
|
||||||
ENV PATH="/home/user/bin/firefox:${PATH}"
|
ENV PATH="/app/bin/firefox:${PATH}"
|
||||||
ADD ./interfacer/contrib/setup_firefox.sh .
|
ADD ./interfacer/contrib/setup_firefox.sh .
|
||||||
RUN ./setup_firefox.sh
|
RUN ./setup_firefox.sh
|
||||||
RUN rm ./setup_firefox.sh && rm .travis.yml
|
RUN rm ./setup_firefox.sh && rm .travis.yml
|
||||||
|
@ -33,11 +33,11 @@ RUN ./setup_browsh.sh
|
||||||
# that all future runs will be consistent.
|
# that all future runs will be consistent.
|
||||||
RUN TERM=xterm script \
|
RUN TERM=xterm script \
|
||||||
--return \
|
--return \
|
||||||
-c "/home/user/browsh" \
|
-c "/app/browsh" \
|
||||||
/dev/null \
|
/dev/null \
|
||||||
>/dev/null & \
|
>/dev/null & \
|
||||||
sleep 10
|
sleep 10
|
||||||
RUN rm ./setup_browsh.sh && rm manifest.json
|
RUN rm ./setup_browsh.sh && rm manifest.json
|
||||||
|
|
||||||
CMD ["/home/user/browsh"]
|
CMD ["/app/browsh"]
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,9 @@ var (
|
||||||
isUseExistingFirefox = flag.Bool("use-existing-ff", false, "Whether Browsh should launch Firefox or not")
|
isUseExistingFirefox = flag.Bool("use-existing-ff", false, "Whether Browsh should launch Firefox or not")
|
||||||
useFFProfile = flag.String("ff-profile", "default", "Firefox profile to use")
|
useFFProfile = flag.String("ff-profile", "default", "Firefox profile to use")
|
||||||
isDebug = flag.Bool("debug", false, "Log to ./debug.log")
|
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")
|
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 needs to be exported for use in tests
|
||||||
IsHTTPServer = flag.Bool("http-server", false, "Run as an HTTP service")
|
IsHTTPServer = flag.Bool("http-server", false, "Run as an HTTP service")
|
||||||
// HTTPServerPort also needs to be exported for use in tests
|
// HTTPServerPort also needs to be exported for use in tests
|
||||||
|
|
|
@ -144,9 +144,7 @@ func webSocketServer(w http.ResponseWriter, r *http.Request) {
|
||||||
} else {
|
} else {
|
||||||
sendTtySize()
|
sendTtySize()
|
||||||
}
|
}
|
||||||
if IsTesting {
|
// For some reason, using Firefox's CLI arg `--url https://google.com` doesn't consistently
|
||||||
// For some reason, using Firefox's CLI arg `--url https://google.com` doesn't consistently
|
// work. So we do it here instead.
|
||||||
// work on Travis. So we do it here inse
|
sendMessageToWebExtension("/new_tab," + *StartupURL)
|
||||||
sendMessageToWebExtension("/new_tab," + *StartupURL)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
|
@ -18,6 +19,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
marionette net.Conn
|
marionette net.Conn
|
||||||
|
isMarionetteListening = false
|
||||||
ffCommandCount = 0
|
ffCommandCount = 0
|
||||||
defaultFFPrefs = map[string]string{
|
defaultFFPrefs = map[string]string{
|
||||||
"browser.startup.homepage": "'https://www.google.com'",
|
"browser.startup.homepage": "'https://www.google.com'",
|
||||||
|
@ -52,6 +54,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func startHeadlessFirefox() {
|
func startHeadlessFirefox() {
|
||||||
|
var isMarionette, isListening bool
|
||||||
|
checkIfFirefoxIsAlreadyRunning()
|
||||||
Log("Starting Firefox in headless mode")
|
Log("Starting Firefox in headless mode")
|
||||||
ensureFirefoxBinary()
|
ensureFirefoxBinary()
|
||||||
args := []string{"--marionette"}
|
args := []string{"--marionette"}
|
||||||
|
@ -77,10 +81,22 @@ func startHeadlessFirefox() {
|
||||||
}
|
}
|
||||||
in := bufio.NewScanner(stdout)
|
in := bufio.NewScanner(stdout)
|
||||||
for in.Scan() {
|
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())
|
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() {
|
func ensureFirefoxBinary() {
|
||||||
if *firefoxBinary == "firefox" {
|
if *firefoxBinary == "firefox" {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
|
@ -199,15 +215,6 @@ func sendFirefoxCommand(command string, args map[string]interface{}) {
|
||||||
readMarionette()
|
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() {
|
func setDefaultPreferences() {
|
||||||
for key, value := range defaultFFPrefs {
|
for key, value := range defaultFFPrefs {
|
||||||
setFFPreference(key, value)
|
setFFPreference(key, value)
|
||||||
|
@ -233,12 +240,19 @@ func setupFirefox() {
|
||||||
if (*timeLimit > 0) {
|
if (*timeLimit > 0) {
|
||||||
go beginTimeLimit()
|
go beginTimeLimit()
|
||||||
}
|
}
|
||||||
// TODO: Do something better than just waiting
|
waitForMarionette()
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
firefoxMarionette()
|
firefoxMarionette()
|
||||||
setDefaultPreferences()
|
setDefaultPreferences()
|
||||||
installWebextension()
|
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() {
|
func startFirefox() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Browsh",
|
"name": "Browsh",
|
||||||
"version": "1.0.8",
|
"version": "1.0.9",
|
||||||
|
|
||||||
"description": "Renders the browser as realtime, interactive, TTY-compatible text",
|
"description": "Renders the browser as realtime, interactive, TTY-compatible text",
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue