Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Initial Chromium image support for arm64 #524

Merged
merged 1 commit into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions build-chromium.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

VERSION=${1:-101.0.4951.64-0ubuntu0.18.04.1}
TAG=${2:-chromium_101.0}
BASE_TAG=${3:-7.3.6}

# Cleanup stuff
export BUILDKIT_PROGRESS=plain
docker rmi -f selenoid/vnc:$TAG browsers/base:$BASE_TAG $(docker images -q selenoid/dev_chromium:*)
rm -rf ../selenoid-container-tests

# Prepare for building images
go get github.com/markbates/pkger/cmd/pkger
go generate github.com/aerokube/images
go build

# Forked tests with a bugfix
git clone -b add-missing-dependency https://github.com/sskorol/selenoid-container-tests.git ../selenoid-container-tests

# Force build browsers/base image as it has arm64-specific updates
cd ./selenium/base && docker build --no-cache --build-arg UBUNTU_VERSION=18.04 -t browsers/base:$BASE_TAG . && docker system prune -f

# Build chromium image
cd ../../ && ./images chromium -b $VERSION -t selenoid/vnc:$TAG --test && docker system prune -f
94 changes: 94 additions & 0 deletions build/chromium.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package build

import (
"fmt"
"os"
"path/filepath"
)

type Chromium struct {
Requirements
}

func (c *Chromium) Build() error {

pkgSrcPath, pkgVersion, err := c.BrowserSource.Prepare()
if err != nil {
return fmt.Errorf("invalid browser source: %v", err)
}

pkgTagVersion := extractVersion(pkgVersion)

if err != nil {
return fmt.Errorf("parse chromiumdriver version: %v", err)
}

// Build dev image
devDestDir, err := tmpDir()
if err != nil {
return fmt.Errorf("create dev temporary dir: %v", err)
}

srcDir := "chromium/apt"

if pkgSrcPath != "" {
srcDir = "chromium/local"
pkgDestDir := filepath.Join(devDestDir, srcDir)
err := os.MkdirAll(pkgDestDir, 0755)
if err != nil {
return fmt.Errorf("create %v temporary dir: %v", pkgDestDir, err)
}
pkgDestPath := filepath.Join(pkgDestDir, "chromium.deb")
err = os.Rename(pkgSrcPath, pkgDestPath)
if err != nil {
return fmt.Errorf("move package: %v", err)
}
}

devImageTag := fmt.Sprintf("selenoid/dev_chromium:%s", pkgTagVersion)
devImageRequirements := Requirements{NoCache: c.NoCache, Tags: []string{devImageTag}}
devImage, err := NewImage(srcDir, devDestDir, devImageRequirements)
if err != nil {
return fmt.Errorf("init dev image: %v", err)
}
devBuildArgs := []string{fmt.Sprintf("VERSION=%s", pkgVersion)}
devImage.BuildArgs = devBuildArgs
if pkgSrcPath != "" {
devImage.FileServer = true
}

err = devImage.Build()
if err != nil {
return fmt.Errorf("build dev image: %v", err)
}

// Build main image
destDir, err := tmpDir()
if err != nil {
return fmt.Errorf("create temporary dir: %v", err)
}

image, err := NewImage("chromium", destDir, c.Requirements)
if err != nil {
return fmt.Errorf("init image: %v", err)
}
image.BuildArgs = append(image.BuildArgs, fmt.Sprintf("VERSION=%s", pkgTagVersion))

err = image.Build()
if err != nil {
return fmt.Errorf("build image: %v", err)
}

// Must be Chrome even it's Chromium-based container
err = image.Test(c.TestsDir, "chrome", pkgTagVersion)
if err != nil {
return fmt.Errorf("test image: %v", err)
}

err = image.Push()
if err != nil {
return fmt.Errorf("push image: %v", err)
}

return nil
}
26 changes: 26 additions & 0 deletions cmd/chromium.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
"github.com/aerokube/images/build"
"github.com/spf13/cobra"
)

var (
chromiumCmd = &cobra.Command{
Use: "chromium",
Short: "build Chromium image",
RunE: func(cmd *cobra.Command, args []string) error {
req := build.Requirements{
BrowserSource: build.BrowserSource(browserSource),
NoCache: noCache,
TestsDir: testsDir,
RunTests: test,
IgnoreTests: ignoreTests,
Tags: tags,
PushImage: push,
}
chromium := &build.Chromium{req}
return chromium.Build()
},
}
)
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func initFlags() {
func init() {
initFlags()
rootCmd.AddCommand(chromeCmd)
rootCmd.AddCommand(chromiumCmd)
rootCmd.AddCommand(edgeCmd)
rootCmd.AddCommand(firefoxCmd)
rootCmd.AddCommand(operaCmd)
Expand Down
12 changes: 8 additions & 4 deletions selenium/base/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
ARG UBUNTU_VERSION=20.04

FROM golang:1.17 as go

COPY xseld /xseld

COPY fileserver /fileserver

RUN \
if [ `uname -m` = "aarch64" ]; then ARCH="arm64"; else ARCH="amd64"; fi && \
apt-get update && \
apt-get install -y upx-ucl libx11-dev && \
cd /xseld && \
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" && \
GOOS=linux GOARCH=$ARCH go build -ldflags="-s -w" && \
upx /xseld/xseld && \
cd /fileserver && \
go test -race && \
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" && \
GOOS=linux GOARCH=$ARCH go build -ldflags="-s -w" && \
upx /fileserver/fileserver

FROM ubuntu:20.04
# For M1 Chromium images it's required to override a version to 18.04 as latest Ubuntu distributions don't ship updates
FROM ubuntu:$UBUNTU_VERSION

RUN \
apt update && \
Expand Down Expand Up @@ -49,7 +53,6 @@ RUN \
xfonts-base \
xfonts-encodings \
xfonts-utils \
flashplugin-installer \
xvfb \
pulseaudio \
fluxbox \
Expand All @@ -58,6 +61,7 @@ RUN \
wmctrl \
libnss-wrapper \
xsel && \
if [ `uname -m` = "amd64" ]; then apt install -y flashplugin-installer; fi && \
mkdir -p /var/lib/locales/supported.d/ && grep UTF-8 /usr/share/i18n/SUPPORTED > /var/lib/locales/supported.d/all && \
locale-gen && update-locale && \
fc-cache -f -v && \
Expand Down
11 changes: 11 additions & 0 deletions static/chromium/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ARG VERSION
FROM selenoid/dev_chromium:$VERSION

ENV DBUS_SESSION_BUS_ADDRESS=/dev/null
COPY entrypoint.sh /

RUN chmod +x /usr/bin/chromedriver
USER selenium

EXPOSE 4444
ENTRYPOINT ["/entrypoint.sh"]
16 changes: 16 additions & 0 deletions static/chromium/apt/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM browsers/base:7.3.6

ARG VERSION
ARG PACKAGE=chromium-browser

LABEL browser=$PACKAGE:$VERSION

RUN \
apt-get update && \
apt-get -y --no-install-recommends install \
iproute2 \
libgtk-3-0 \
${PACKAGE}=${VERSION} \
chromium-chromedriver=${VERSION} && \
chromium-browser --version && \
rm -Rf /tmp/* && rm -Rf /var/lib/apt/lists/*
87 changes: 87 additions & 0 deletions static/chromium/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash
SCREEN_RESOLUTION=${SCREEN_RESOLUTION:-"1920x1080x24"}
DISPLAY_NUM=99
export DISPLAY=":$DISPLAY_NUM"

VERBOSE=${VERBOSE:-""}
DRIVER_ARGS=${DRIVER_ARGS:-""}
if [ -n "$VERBOSE" ]; then
DRIVER_ARGS="$DRIVER_ARGS --verbose"
fi

clean() {
if [ -n "$FILESERVER_PID" ]; then
kill -TERM "$FILESERVER_PID"
fi
if [ -n "$XSELD_PID" ]; then
kill -TERM "$XSELD_PID"
fi
if [ -n "$XVFB_PID" ]; then
kill -TERM "$XVFB_PID"
fi
if [ -n "$DRIVER_PID" ]; then
kill -TERM "$DRIVER_PID"
fi
if [ -n "$X11VNC_PID" ]; then
kill -TERM "$X11VNC_PID"
fi
if [ -n "$PULSE_PID" ]; then
kill -TERM "$PULSE_PID"
fi
}

trap clean SIGINT SIGTERM

if env | grep -q ROOT_CA_; then
mkdir -p $HOME/.pki/nssdb
certutil -N --empty-password -d sql:$HOME/.pki/nssdb
for e in $(env | grep ROOT_CA_ | sed -e 's/=.*$//'); do
certname=$(echo -n $e | sed -e 's/ROOT_CA_//')
echo ${!e} | base64 -d >/tmp/cert.pem
certutil -A -n ${certname} -t "TC,C,T" -i /tmp/cert.pem -d sql:$HOME/.pki/nssdb
if cat tmp/cert.pem | grep -q "PRIVATE KEY"; then
PRIVATE_KEY_PASS=${PRIVATE_KEY_PASS:-\'\'}
openssl pkcs12 -export -in /tmp/cert.pem -clcerts -nodes -out /tmp/key.p12 -passout pass:${PRIVATE_KEY_PASS} -passin pass:${PRIVATE_KEY_PASS}
pk12util -d sql:$HOME/.pki/nssdb -i /tmp/key.p12 -W ${PRIVATE_KEY_PASS}
rm /tmp/key.p12
fi
rm /tmp/cert.pem
done
fi

/usr/bin/fileserver &
FILESERVER_PID=$!

DISPLAY="$DISPLAY" /usr/bin/xseld &
XSELD_PID=$!

while ip addr | grep inet | grep -q tentative > /dev/null; do sleep 0.1; done

mkdir -p ~/pulse/.config/pulse
echo -n 'gIvST5iz2S0J1+JlXC1lD3HWvg61vDTV1xbmiGxZnjB6E3psXsjWUVQS4SRrch6rygQgtpw7qmghDFTaekt8qWiCjGvB0LNzQbvhfs1SFYDMakmIXuoqYoWFqTJ+GOXYByxpgCMylMKwpOoANEDePUCj36nwGaJNTNSjL8WBv+Bf3rJXqWnJ/43a0hUhmBBt28Dhiz6Yqowa83Y4iDRNJbxih6rB1vRNDKqRr/J9XJV+dOlM0dI+K6Vf5Ag+2LGZ3rc5sPVqgHgKK0mcNcsn+yCmO+XLQHD1K+QgL8RITs7nNeF1ikYPVgEYnc0CGzHTMvFR7JLgwL2gTXulCdwPbg=='| base64 -d>~/pulse/.config/pulse/cookie
HOME=$HOME/pulse pulseaudio --start --exit-idle-time=-1
HOME=$HOME/pulse pactl load-module module-native-protocol-tcp
PULSE_PID=$(ps --no-headers -C pulseaudio -o pid | sed -r 's/( )+//g')

/usr/bin/xvfb-run -l -n "$DISPLAY_NUM" -s "-ac -screen 0 $SCREEN_RESOLUTION -noreset -listen tcp" /usr/bin/fluxbox -display "$DISPLAY" -log /dev/null 2>/dev/null &
XVFB_PID=$!

retcode=1
until [ $retcode -eq 0 ]; do
DISPLAY="$DISPLAY" wmctrl -m >/dev/null 2>&1
retcode=$?
if [ $retcode -ne 0 ]; then
echo Waiting X server...
sleep 0.1
fi
done

if [ "$ENABLE_VNC" == "true" ]; then
x11vnc -display "$DISPLAY" -passwd selenoid -shared -forever -loop500 -rfbport 5900 -rfbportv6 5900 -logfile /dev/null &
X11VNC_PID=$!
fi

DISPLAY="$DISPLAY" /usr/bin/chromedriver --port=4444 --allowed-ips='' --allowed-origins='*' ${DRIVER_ARGS} &
DRIVER_PID=$!

wait
58 changes: 58 additions & 0 deletions static/chromium/local/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
FROM browsers/base:7.3.6

ARG VERSION=noop
ARG PACKAGE=chromium-browser

LABEL browser=$PACKAGE:$VERSION

RUN \
apt-get update && \
apt-get -y --no-install-recommends install gconf-service \
libasound2 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libfreetype6 \
libgcc1 \
libgconf-2-4 \
libgdk-pixbuf2.0-0 \
libglib2.0-0 \
libgtk2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
ca-certificates \
fonts-liberation \
libappindicator3-1 \
libnss3 \
lsb-base \
xdg-utils \
libcurl4 \
iproute2 \
curl \
chromium-chromedriver && \
curl -O http://host.docker.internal:8080/chromium-browser.deb && \
apt-get -y purge curl && \
dpkg -i chromium-browser.deb && \
chromium-browser --version && \
rm -Rf /tmp/* && \
rm -Rf /var/lib/apt/lists/*