diff --git a/NodeMultibrowser/Dockerfile b/NodeMultibrowser/Dockerfile new file mode 100644 index 000000000..026b33589 --- /dev/null +++ b/NodeMultibrowser/Dockerfile @@ -0,0 +1,287 @@ +ARG NAMESPACE="selenium" +ARG VERSION=latest +ARG BASE=node-base +FROM ${NAMESPACE}/${BASE}:${VERSION} +ARG AUTHORS +LABEL authors=${AUTHORS} + +USER root + + +############################################## +# # +# # +# CHROME # +# # +# # +############################################## + +#============================================ +# Google Chrome +#============================================ +# can specify versions by CHROME_VERSION; +# e.g. google-chrome-stable +# google-chrome-beta +# google-chrome-unstable +#============================================ +ARG CHROME_VERSION="google-chrome-stable" +RUN curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list \ + && apt-get update -qqy \ + && if echo "${CHROME_VERSION}" | grep -qE "google-chrome-stable[_|=][0-9]*"; \ + then \ + CHROME_VERSION=$(echo "$CHROME_VERSION" | tr '=' '_') \ + && wget -qO google-chrome.deb "https://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/${CHROME_VERSION}_$(dpkg --print-architecture).deb" \ + && apt-get -qqy --no-install-recommends install --allow-downgrades ./google-chrome.deb \ + && rm -rf google-chrome.deb ; \ + else \ + apt-get -qqy --no-install-recommends install ${CHROME_VERSION} ; \ + fi \ + && rm /etc/apt/sources.list.d/google-chrome.list \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +#================================= +# Chrome Launch Script Wrapper +#================================= +COPY --chown="${SEL_UID}:${SEL_GID}" wrap_chrome_binary /opt/bin/wrap_chrome_binary +RUN chmod +x /opt/bin/wrap_chrome_binary +RUN /opt/bin/wrap_chrome_binary + +#============================================ +# Chrome webdriver +#============================================ +# can specify versions by CHROME_DRIVER_VERSION +# Latest released version will be used by default +#============================================ +ARG CHROME_DRIVER_VERSION +RUN DRIVER_ARCH=$(if [ "$(dpkg --print-architecture)" = "amd64" ]; then echo "linux64"; else echo "linux-aarch64"; fi) \ + && if [ ! -z "$CHROME_DRIVER_VERSION" ]; \ + then CHROME_DRIVER_URL=https://storage.googleapis.com/chrome-for-testing-public/$CHROME_DRIVER_VERSION/${DRIVER_ARCH}/chromedriver-${DRIVER_ARCH}.zip ; \ + else CHROME_MAJOR_VERSION=$(google-chrome --version | sed -E "s/.* ([0-9]+)(\.[0-9]+){3}.*/\1/") \ + && if [ $CHROME_MAJOR_VERSION -lt 115 ]; then \ + echo "Geting ChromeDriver latest version from https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROME_MAJOR_VERSION}" \ + && CHROME_DRIVER_VERSION=$(wget -qO- https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROME_MAJOR_VERSION} | sed 's/\r$//') \ + && CHROME_DRIVER_URL=https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip ; \ + else \ + echo "Geting ChromeDriver latest version from https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_${CHROME_MAJOR_VERSION}" \ + && CHROME_DRIVER_VERSION=$(wget -qO- https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_${CHROME_MAJOR_VERSION} | sed 's/\r$//') \ + && CHROME_DRIVER_URL=https://storage.googleapis.com/chrome-for-testing-public/$CHROME_DRIVER_VERSION/${DRIVER_ARCH}/chromedriver-${DRIVER_ARCH}.zip ; \ + fi \ + fi \ + && echo "Using ChromeDriver from: "$CHROME_DRIVER_URL \ + && echo "Using ChromeDriver version: "$CHROME_DRIVER_VERSION \ + && wget --no-verbose -O /tmp/chromedriver_${DRIVER_ARCH}.zip $CHROME_DRIVER_URL \ + && rm -rf /opt/selenium/chromedriver \ + && unzip /tmp/chromedriver_${DRIVER_ARCH}.zip -d /opt/selenium \ + && rm /tmp/chromedriver_${DRIVER_ARCH}.zip \ + && mv /opt/selenium/chromedriver /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION || true \ + && mv /opt/selenium/chromedriver-${DRIVER_ARCH}/chromedriver /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION || true \ + && chmod 755 /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION \ + && ln -fs /opt/selenium/chromedriver-$CHROME_DRIVER_VERSION /usr/bin/chromedriver + +#============================================ +# Chrome cleanup script and supervisord file +#============================================ +COPY --chown="${SEL_UID}:${SEL_GID}" chrome-cleanup.sh /opt/bin/chrome-cleanup.sh +RUN chmod +x /opt/bin/chrome-cleanup.sh +COPY --chown="${SEL_UID}:${SEL_GID}" chrome-cleanup.conf /etc/supervisor/conf.d/chrome-cleanup.conf + + + + + + + + + + + +############################################## +# # +# # +# EDGE # +# # +# # +############################################## + + + + +#============================================ +# Microsoft Edge +#============================================ +# can specify versions by EDGE_VERSION; +# e.g. microsoft-edge-beta=88.0.692.0-1 +#============================================ +ARG EDGE_VERSION="microsoft-edge-stable" +RUN wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/microsoft.gpg >/dev/null \ + && echo "deb https://packages.microsoft.com/repos/edge stable main" >> /etc/apt/sources.list.d/microsoft-edge.list \ + && apt-get update -qqy \ + && if echo "${EDGE_VERSION}" | grep -qE "microsoft-edge-stable[_|=][0-9]*"; \ + then \ + EDGE_VERSION=$(echo "$EDGE_VERSION" | tr '=' '_') \ + && wget -qO microsoft-edge.deb "https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/${EDGE_VERSION}_$(dpkg --print-architecture).deb" \ + && apt-get -qqy --no-install-recommends install --allow-downgrades ./microsoft-edge.deb \ + && rm -rf microsoft-edge.deb ; \ + else \ + apt-get -qqy --no-install-recommends install ${EDGE_VERSION} ; \ + fi \ + && rm /etc/apt/sources.list.d/microsoft-edge.list \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +#================================= +# Edge Launch Script Wrapper +#================================= +COPY --chown="${SEL_UID}:${SEL_GID}" wrap_edge_binary /opt/bin/wrap_edge_binary +RUN chmod +x /opt/bin/wrap_edge_binary +RUN /opt/bin/wrap_edge_binary + +#============================================ +# Edge webdriver +#============================================ +# can specify versions by EDGE_DRIVER_VERSION +# Latest released version will be used by default +#============================================ +ARG EDGE_DRIVER_VERSION +RUN DRIVER_ARCH=$(if [ "$(dpkg --print-architecture)" = "amd64" ]; then echo "linux64"; else echo "linux-aarch64"; fi) \ + && if [ -z "$EDGE_DRIVER_VERSION" ]; \ + then EDGE_MAJOR_VERSION=$(microsoft-edge --version | sed -E "s/.* ([0-9]+)(\.[0-9]+){3}.*/\1/") \ + && EDGE_DRIVER_VERSION=$(wget --no-verbose -O - "https://msedgedriver.azureedge.net/LATEST_RELEASE_${EDGE_MAJOR_VERSION}_LINUX" | tr -cd "\11\12\15\40-\176" | tr -d "\r"); \ + fi \ + && echo "Using msedgedriver version: "$EDGE_DRIVER_VERSION \ + && wget --no-verbose -O /tmp/msedgedriver_${DRIVER_ARCH}.zip https://msedgedriver.azureedge.net/$EDGE_DRIVER_VERSION/edgedriver_${DRIVER_ARCH}.zip \ + && rm -rf /opt/selenium/msedgedriver \ + && unzip /tmp/msedgedriver_${DRIVER_ARCH}.zip -d /opt/selenium \ + && rm /tmp/msedgedriver_${DRIVER_ARCH}.zip \ + && mv /opt/selenium/msedgedriver /opt/selenium/msedgedriver-$EDGE_DRIVER_VERSION \ + && chmod 755 /opt/selenium/msedgedriver-$EDGE_DRIVER_VERSION \ + && ln -fs /opt/selenium/msedgedriver-$EDGE_DRIVER_VERSION /usr/bin/msedgedriver + +#============================================ +# Edge cleanup script and supervisord file +#============================================ +COPY --chown="${SEL_UID}:${SEL_GID}" edge-cleanup.sh /opt/bin/edge-cleanup.sh +COPY --chown="${SEL_UID}:${SEL_GID}" edge-cleanup.conf /etc/supervisor/conf.d/edge-cleanup.conf +RUN chmod +x /opt/bin/edge-cleanup.sh + + + + + + + + +############################################## +# # +# # +# FIREFOX # +# # +# # +############################################## + + +#============================================ +# Firefox cleanup script and supervisord file +#============================================ +COPY --chown="${SEL_UID}:${SEL_GID}" firefox-cleanup.sh get_lang_package.sh install-firefox-apt.sh install-firefox-package.sh /opt/bin/ +COPY --chown="${SEL_UID}:${SEL_GID}" firefox-cleanup.conf /etc/supervisor/conf.d/firefox-cleanup.conf +RUN chmod +x /opt/bin/firefox-cleanup.sh /opt/bin/get_lang_package.sh /opt/bin/install-firefox-apt.sh /opt/bin/install-firefox-package.sh + + + +#========= +# Firefox +#========= +ARG FIREFOX_VERSION=latest +ARG FIREFOX_DOWNLOAD_URL="" +ARG FIREFOX_LANG_VERSION=${FIREFOX_VERSION} +RUN apt-get update -qqy && \ + FIREFOX_MAJOR_VERSION=${FIREFOX_VERSION%%.*} && \ + ARCH=$(if [ "$(dpkg --print-architecture)" = "amd64" ]; then echo "x86_64"; else echo "aarch64"; fi) && \ + if [ "$(dpkg --print-architecture)" = "amd64" ] || [ $FIREFOX_VERSION = "latest" ] || [ "${FIREFOX_MAJOR_VERSION}" -ge 136 ]; then \ + if [ $FIREFOX_VERSION = "latest" ] || [ $FIREFOX_VERSION = "beta-latest" ] || [ $FIREFOX_VERSION = "nightly-latest" ] || [ $FIREFOX_VERSION = "devedition-latest" ] || [ $FIREFOX_VERSION = "esr-latest" ]; then \ + /opt/bin/install-firefox-apt.sh \ + && FIREFOX_VERSION=$(echo "-$FIREFOX_VERSION" | sed 's/-latest//') \ + && apt install -y firefox$FIREFOX_VERSION \ + && INSTALL_VIA_APT=true \ + && if [ $FIREFOX_VERSION = "-beta" ] || [ $FIREFOX_VERSION = "-nightly" ] || [ $FIREFOX_VERSION = "-devedition" ] || [ $FIREFOX_VERSION = "-esr" ]; then \ + ln -fs $(which firefox$FIREFOX_VERSION) /usr/bin/firefox ; \ + fi ; \ + else \ + FIREFOX_DOWNLOAD_URL="https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-$ARCH/en-US/firefox-$FIREFOX_VERSION.deb" \ + && if [ "404" = "$(curl -s -o /dev/null -w "%{http_code}" $FIREFOX_DOWNLOAD_URL)" ]; then \ + FIREFOX_DOWNLOAD_URL="https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-$ARCH/en-US/firefox-$FIREFOX_VERSION.tar.bz2" ; \ + fi ; \ + fi \ + else \ + if [ ${FIREFOX_VERSION} = "latest" ] && [ ${FIREFOX_DOWNLOAD_URL} = "" ]; then \ + FIREFOX_VERSION="nightly-latest" ; \ + /opt/bin/install-firefox-apt.sh \ + && FIREFOX_VERSION=$(echo "-$FIREFOX_VERSION" | sed 's/-latest//') \ + && apt install -y firefox$FIREFOX_VERSION \ + && INSTALL_VIA_APT=true \ + && if [ $FIREFOX_VERSION = "-nightly" ]; then \ + ln -fs $(which firefox$FIREFOX_VERSION) /usr/bin/firefox ; \ + fi ; \ + else \ + FIREFOX_VERSION="nightly-latest" \ + && FIREFOX_VERSION=$(echo "-$FIREFOX_VERSION" | sed 's/-latest//') \ + FIREFOX_DOWNLOAD_URL="${FIREFOX_DOWNLOAD_URL}" ; \ + fi ; \ + fi && \ + if [ "${INSTALL_VIA_APT}" != "true" ]; then \ + /opt/bin/install-firefox-package.sh "${FIREFOX_DOWNLOAD_URL}" "${FIREFOX_VERSION}" ; \ + fi \ + # Download the language pack for Firefox + && /opt/bin/get_lang_package.sh ${FIREFOX_LANG_VERSION} \ + # Do one more upgrade to fix possible CVEs from Firefox dependencies + && apt-get update -qqy \ + && apt-get upgrade -yq \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +#============ +# GeckoDriver +#============ +ARG GECKODRIVER_VERSION=latest +RUN LATEST_VERSION=$(curl -sk https://api.github.com/repos/mozilla/geckodriver/releases/latest | jq -r '.tag_name') \ + && DRIVER_ARCH=$(if [ "$(dpkg --print-architecture)" = "amd64" ]; then echo "linux64"; else echo "linux-aarch64"; fi) \ + && GK_VERSION=$(if [ ${GECKODRIVER_VERSION:-latest} = "latest" ]; then echo "${LATEST_VERSION}"; else echo $GECKODRIVER_VERSION; fi) \ + && echo "Using GeckoDriver version: "$GK_VERSION \ + && wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/${GK_VERSION}/geckodriver-${GK_VERSION}-${DRIVER_ARCH}.tar.gz \ + && rm -rf /opt/geckodriver \ + && tar -C /opt -zxf /tmp/geckodriver.tar.gz \ + && rm /tmp/geckodriver.tar.gz \ + && mv /opt/geckodriver /opt/geckodriver-$GK_VERSION \ + && chmod 755 /opt/geckodriver-$GK_VERSION \ + && ln -fs /opt/geckodriver-$GK_VERSION /usr/bin/geckodriver + + + + + + + +######## +# SET USER +######## +USER ${SEL_UID} + + + + +#============================================ +# Dumping Browser information for config +#============================================ +RUN echo "chrome" > /opt/selenium/browser_name +RUN google-chrome --version | awk '{print $3}' | cut -d'.' -f1,2 >> /opt/selenium/browser_version +RUN echo "\"goog:chromeOptions\": {\"binary\": \"/usr/bin/google-chrome\"}" >> /opt/selenium/browser_binary_location + +RUN echo "MicrosoftEdge" > /opt/selenium/browser_name +RUN microsoft-edge --version | awk '{print $3}' | cut -d'.' -f1,2 >> /opt/selenium/browser_version +RUN echo "\"ms:edgeOptions\": {\"binary\": \"/usr/bin/microsoft-edge\"}" >> /opt/selenium/browser_binary_location + +RUN echo "firefox" > /opt/selenium/browser_name +RUN firefox --version | awk '{print $3}' >> /opt/selenium/browser_version +RUN echo "\"moz:firefoxOptions\": {\"binary\": \"/usr/bin/firefox\"}" >> /opt/selenium/browser_binary_location + +ENV SE_OTEL_SERVICE_NAME="selenium-node-multibrowser" \ No newline at end of file diff --git a/NodeMultibrowser/chrome-cleanup.conf b/NodeMultibrowser/chrome-cleanup.conf new file mode 100644 index 000000000..f543ada49 --- /dev/null +++ b/NodeMultibrowser/chrome-cleanup.conf @@ -0,0 +1,21 @@ +; Documentation of this file format -> http://supervisord.org/configuration.html + +; Priority 0 - xvfb & fluxbox, 5 - x11vnc, 10 - noVNC, 15 - selenium-node + +[program:chromeleftoverscleanup] +priority=20 +command=bash -c "if [ ${SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP} = "true" ]; then /opt/bin/chrome-cleanup.sh; fi" +autostart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +autorestart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +stopsignal=INT + +;Logs +redirect_stderr=false +stdout_logfile=/var/log/supervisor/chrome-leftover-cleanup-stdout.log +stderr_logfile=/var/log/supervisor/chrome-leftover-cleanup-stderr.log +stdout_logfile_maxbytes=50MB +stderr_logfile_maxbytes=50MB +stdout_logfile_backups=5 +stderr_logfile_backups=5 +stdout_capture_maxbytes=50MB +stderr_capture_maxbytes=50MB diff --git a/NodeMultibrowser/chrome-cleanup.sh b/NodeMultibrowser/chrome-cleanup.sh new file mode 100755 index 000000000..31565c8cf --- /dev/null +++ b/NodeMultibrowser/chrome-cleanup.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Return error exit code in case of any failure, so supervisord will restart the script +set -e + +cleanup_stuck_chrome_processes() { + echo -n "Killing Chrome processes older than ${SE_BROWSER_LEFTOVERS_PROCESSES_SECS} seconds... " + ps -e -o pid,etimes,command | grep -v grep | grep chrome/chrome | awk '{if($2>'${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}') print $0}' | awk '{print $1}' | xargs -r kill -9 + echo "DONE." +} + +cleanup_tmp_chrome_files() { + echo -n "Deleting all Chrome files in /tmp... " + find /tmp -name ".com.google.Chrome.*" -type d -mtime +${SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS} -exec rm -rf "{}" + + echo "DONE." +} + +echo "Chrome cleanup script init with parameters: SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS=${SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS}, SE_BROWSER_LEFTOVERS_PROCESSES_SECS=${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}, SE_BROWSER_LEFTOVERS_INTERVAL_SECS=${SE_BROWSER_LEFTOVERS_INTERVAL_SECS}." + +# Start the main loop +while :; do + echo "Starting cleanup daemon script." + + # Clean up stuck processes + cleanup_stuck_chrome_processes + + # Wait a few seconds for the processes to stop before removing files + sleep 5 + + # Clean up temporary files + cleanup_tmp_chrome_files + + # Go to sleep for 1 hour + echo "Cleanup daemon sleeping for ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} seconds." + sleep ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} +done diff --git a/NodeMultibrowser/edge-cleanup.conf b/NodeMultibrowser/edge-cleanup.conf new file mode 100644 index 000000000..9782cdb1d --- /dev/null +++ b/NodeMultibrowser/edge-cleanup.conf @@ -0,0 +1,21 @@ +; Documentation of this file format -> http://supervisord.org/configuration.html + +; Priority 0 - xvfb & fluxbox, 5 - x11vnc, 10 - noVNC, 15 - selenium-node + +[program:edgeleftoverscleanup] +priority=20 +command=bash -c "if [ ${SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP} = "true" ]; then /opt/bin/edge-cleanup.sh; fi" +autostart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +autorestart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +stopsignal=INT + +;Logs +redirect_stderr=false +stdout_logfile=/var/log/supervisor/edge-leftover-cleanup-stdout.log +stderr_logfile=/var/log/supervisor/edge-leftover-cleanup-stderr.log +stdout_logfile_maxbytes=50MB +stderr_logfile_maxbytes=50MB +stdout_logfile_backups=5 +stderr_logfile_backups=5 +stdout_capture_maxbytes=50MB +stderr_capture_maxbytes=50MB \ No newline at end of file diff --git a/NodeMultibrowser/edge-cleanup.sh b/NodeMultibrowser/edge-cleanup.sh new file mode 100644 index 000000000..e607e082c --- /dev/null +++ b/NodeMultibrowser/edge-cleanup.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Return error exit code in case of any failure, so supervisord will restart the script +set -e + +cleanup_stuck_edge_processes() { + echo -n "Killing Edge processes older than ${SE_BROWSER_LEFTOVERS_PROCESSES_SECS} seconds... " + ps -e -o pid,etimes,command | grep -v grep | grep msedge/msedge | awk '{if($2>'${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}') print $0}' | awk '{print $1}' | xargs -r kill -9 + echo "DONE." +} + +cleanup_tmp_edge_files() { + echo -n "Deleting all Edge files in /tmp... " + find /tmp -name ".com.microsoft.Edge.*" -type d -mtime +${SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS} -exec rm -rf "{}" + + echo "DONE." +} + +echo "Edge cleanup script init with parameters: SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS=${SE_BROWSER_LEFTOVERS_TEMPFILES_DAYS}, SE_BROWSER_LEFTOVERS_PROCESSES_SECS=${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}, SE_BROWSER_LEFTOVERS_INTERVAL_SECS=${SE_BROWSER_LEFTOVERS_INTERVAL_SECS}." + +# Start the main loop +while :; do + echo "Starting cleanup daemon script." + + # Clean up stuck processes + cleanup_stuck_edge_processes + + # Wait a few seconds for the processes to stop before removing files + sleep 5 + + # Clean up temporary files + cleanup_tmp_edge_files + + # Go to sleep for 1 hour + echo "Cleanup daemon sleeping for ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} seconds." + sleep ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} +done \ No newline at end of file diff --git a/NodeMultibrowser/firefox-cleanup.conf b/NodeMultibrowser/firefox-cleanup.conf new file mode 100644 index 000000000..205873772 --- /dev/null +++ b/NodeMultibrowser/firefox-cleanup.conf @@ -0,0 +1,21 @@ +; Documentation of this file format -> http://supervisord.org/configuration.html + +; Priority 0 - xvfb & fluxbox, 5 - x11vnc, 10 - noVNC, 15 - selenium-node + +[program:firefoxleftoverscleanup] +priority=20 +command=bash -c "if [ ${SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP} = "true" ]; then /opt/bin/firefox-cleanup.sh; fi" +autostart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +autorestart=%(ENV_SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP)s +stopsignal=INT + +;Logs +redirect_stderr=false +stdout_logfile=/var/log/supervisor/firefox-leftover-cleanup-stdout.log +stderr_logfile=/var/log/supervisor/firefox-leftover-cleanup-stderr.log +stdout_logfile_maxbytes=50MB +stderr_logfile_maxbytes=50MB +stdout_logfile_backups=5 +stderr_logfile_backups=5 +stdout_capture_maxbytes=50MB +stderr_capture_maxbytes=50MB \ No newline at end of file diff --git a/NodeMultibrowser/firefox-cleanup.sh b/NodeMultibrowser/firefox-cleanup.sh new file mode 100644 index 000000000..9ab61a795 --- /dev/null +++ b/NodeMultibrowser/firefox-cleanup.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Return error exit code in case of any failure, so supervisord will restart the script +set -e + +cleanup_stuck_firefox_processes() { + echo -n "Killing Firefox processes older than ${SE_BROWSER_LEFTOVERS_PROCESSES_SECS} seconds... " + ps -e -o pid,etimes,command | grep -v grep | grep firefox-bin | awk '{if($2>'${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}') print $0}' | awk '{print $1}' | xargs -r kill -9 + echo "DONE." +} + +echo "Firefox cleanup script init with parameters: SE_BROWSER_LEFTOVERS_PROCESSES_SECS=${SE_BROWSER_LEFTOVERS_PROCESSES_SECS}, SE_BROWSER_LEFTOVERS_INTERVAL_SECS=${SE_BROWSER_LEFTOVERS_INTERVAL_SECS}." + +# Start the main loop +while :; do + echo "Starting cleanup daemon script." + + # Clean up stuck processes + cleanup_stuck_firefox_processes + + # Go to sleep for 1 hour + echo "Cleanup daemon sleeping for ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} seconds." + sleep ${SE_BROWSER_LEFTOVERS_INTERVAL_SECS} +done \ No newline at end of file diff --git a/NodeMultibrowser/get_lang_package.sh b/NodeMultibrowser/get_lang_package.sh new file mode 100644 index 000000000..5d80b463b --- /dev/null +++ b/NodeMultibrowser/get_lang_package.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +function on_exit() { + local exit_code=$? + rm -f /tmp/xpi_files.txt + exit $exit_code +} +trap on_exit EXIT ERR + +# Script is used to download language packs for a specific version of Firefox. +# It requires the version number as the first argument and the target directory as the second argument. + +VERSION=${1:-$(curl -sk https://product-details.mozilla.org/1.0/firefox_versions.json | jq -r '.LATEST_FIREFOX_VERSION')} +TARGET_DIR="${2:-$(dirname $(readlink -f $(which firefox)))/distribution/extensions}" +BASE_URL="https://ftp.mozilla.org/pub/firefox/releases/$VERSION/linux-x86_64/xpi/" +if [ "404" = "$(curl -s -o /dev/null -w "%{http_code}" ${BASE_URL})" ]; then + VERSION="$(curl -sk https://product-details.mozilla.org/1.0/firefox_versions.json | jq -r '.LATEST_FIREFOX_VERSION')" + BASE_URL="https://ftp.mozilla.org/pub/firefox/releases/$VERSION/linux-x86_64/xpi/" +fi + +# Create target directory if it doesn't exist +mkdir -p "${TARGET_DIR}" + +# Download the list of files +wget -q -O - "${BASE_URL}" | grep -oP '(?<=href=")[^"]*.xpi' >/tmp/xpi_files.txt + +echo "Downloading language packs for Firefox version $VERSION to $TARGET_DIR ..." + +# Loop through each file and download it +while IFS= read -r file; do + file=$(basename "${file}") + echo "Downloading "${BASE_URL}${file}" ..." + curl -sk -o "${TARGET_DIR}/${file}" "${BASE_URL}${file}" + target_file="${TARGET_DIR}/langpack-${file%.xpi}@firefox.mozilla.org.xpi" + mv "${TARGET_DIR}/${file}" "${target_file}" + if [ -f "${target_file}" ]; then + echo "Downloaded ${target_file}" + fi +done /dev/null + +gpg -n -q --import --import-options import-show /etc/apt/keyrings/packages.mozilla.org.asc | awk '/pub/{getline; gsub(/^ +| +$/,""); if($0 == "35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3") print "\nThe key fingerprint matches ("$0").\n"; else print "\nVerification failed: the fingerprint ("$0") does not match the expected one.\n"}' + +echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | sudo tee -a /etc/apt/sources.list.d/mozilla.list >/dev/null + +echo ' +Package: * +Pin: origin packages.mozilla.org +Pin-Priority: 1000 +' | sudo tee /etc/apt/preferences.d/mozilla + +sudo apt-get update \ No newline at end of file diff --git a/NodeMultibrowser/install-firefox-package.sh b/NodeMultibrowser/install-firefox-package.sh new file mode 100644 index 000000000..18b792974 --- /dev/null +++ b/NodeMultibrowser/install-firefox-package.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +FIREFOX_DOWNLOAD_URL=$1 +FIREFOX_VERSION=$2 + +function extract_package_tar_bz2() { + sudo rm -rf /opt/firefox + tar -C /opt -xjf /tmp/firefox.tar.bz2 + rm -rf /tmp/firefox.tar.bz2 +} + +function extract_package_tar_xz() { + sudo rm -rf /opt/firefox + tar -C /opt -xJf /tmp/firefox.tar.xz + rm -rf /tmp/firefox.tar.xz +} + +function install_package() { + sudo apt-get -qqy --no-install-recommends install libavcodec-extra libgtk-3-dev libdbus-glib-1-dev xz-utils + echo "Installing Firefox from package..." + sudo mv /opt/firefox "/opt/firefox-${FIREFOX_VERSION}" + sudo mkdir -p "/opt/firefox-${FIREFOX_VERSION}/distribution/extensions" + sudo ln -fs "/opt/firefox-${FIREFOX_VERSION}/firefox" /usr/bin/firefox +} + +if [[ "${FIREFOX_DOWNLOAD_URL}" == *".deb"* ]]; then + echo "Downloading Firefox from ${FIREFOX_DOWNLOAD_URL}" + wget -q -O /tmp/firefox.deb "${FIREFOX_DOWNLOAD_URL}" + echo "Installing Firefox from deb package..." + sudo apt-get install -y --allow-downgrades -f /tmp/firefox.deb + rm -f /tmp/firefox.deb + if [ $FIREFOX_VERSION = "-beta" ] || [ $FIREFOX_VERSION = "-nightly" ] || [ $FIREFOX_VERSION = "-devedition" ] || [ $FIREFOX_VERSION = "-esr" ]; then + sudo ln -fs $(which firefox${FIREFOX_VERSION}) /usr/bin/firefox + fi +elif [[ "${FIREFOX_DOWNLOAD_URL}" == *".tar.bz2"* ]]; then + echo "Downloading Firefox from ${FIREFOX_DOWNLOAD_URL}" + wget -q -O /tmp/firefox.tar.bz2 "${FIREFOX_DOWNLOAD_URL}" + extract_package_tar_bz2 + install_package + rm -f /tmp/firefox.tar.bz2 +elif [[ "${FIREFOX_DOWNLOAD_URL}" == *".tar.xz"* ]]; then + echo "Downloading Firefox from ${FIREFOX_DOWNLOAD_URL}" + wget -q -O /tmp/firefox.tar.xz "${FIREFOX_DOWNLOAD_URL}" + extract_package_tar_xz + install_package + rm -f /tmp/firefox.tar.xz +fi \ No newline at end of file diff --git a/NodeMultibrowser/wrap_chrome_binary b/NodeMultibrowser/wrap_chrome_binary new file mode 100755 index 000000000..ff97ca1bb --- /dev/null +++ b/NodeMultibrowser/wrap_chrome_binary @@ -0,0 +1,36 @@ +#!/bin/bash + +WRAPPER_PATH=$(readlink -f /usr/bin/google-chrome) +BASE_PATH="$WRAPPER_PATH-base" +mv "$WRAPPER_PATH" "$BASE_PATH" + +cat >"$WRAPPER_PATH" <<_EOF +#!/bin/bash + +# umask 002 ensures default permissions of files are 664 (rw-rw-r--) and directories are 775 (rwxrwxr-x). +umask 002 + +# Debian/Ubuntu seems to not respect --lang, it instead needs to be a LANGUAGE environment var +# See: https://stackoverflow.com/a/41893197/359999 +for var in "\$@"; do + if [[ \$var == --lang=* ]]; then + LANGUAGE=\${var//--lang=} + fi +done + +# Set language environment variable +export LANGUAGE="\$LANGUAGE" + +# Capture the filtered environment variables start with "SE_BROWSER_ARGS_" into an array +mapfile -t BROWSER_ARGS_ARRAY < <(printenv | grep ^SE_BROWSER_ARGS_) +# Iterate over the array +for var in "\${BROWSER_ARGS_ARRAY[@]}"; do + # Split the variable into name and value + IFS='=' read -r name value <<< "\$var" + SE_BROWSER_ARGS="\$SE_BROWSER_ARGS \$value" +done + +# Note: exec -a below is a bashism. +exec -a "\$0" "$BASE_PATH" --no-sandbox \$SE_BROWSER_ARGS "\$@" +_EOF +chmod +x "$WRAPPER_PATH" diff --git a/NodeMultibrowser/wrap_edge_binary b/NodeMultibrowser/wrap_edge_binary new file mode 100755 index 000000000..379bfedea --- /dev/null +++ b/NodeMultibrowser/wrap_edge_binary @@ -0,0 +1,36 @@ +#!/bin/bash + +WRAPPER_PATH=$(readlink -f /usr/bin/microsoft-edge) +BASE_PATH="$WRAPPER_PATH-base" +mv "$WRAPPER_PATH" "$BASE_PATH" + +cat >"$WRAPPER_PATH" <<_EOF +#!/bin/bash + +# umask 002 ensures default permissions of files are 664 (rw-rw-r--) and directories are 775 (rwxrwxr-x). +umask 002 + +# Debian/Ubuntu seems to not respect --lang, it instead needs to be a LANGUAGE environment var +# See: https://stackoverflow.com/a/41893197/359999 +for var in "\$@"; do + if [[ \$var == --lang=* ]]; then + LANGUAGE=\${var//--lang=} + fi +done + +# Set language environment variable +export LANGUAGE="\$LANGUAGE" + +# Capture the filtered environment variables start with "SE_BROWSER_ARGS_" into an array +mapfile -t BROWSER_ARGS_ARRAY < <(printenv | grep ^SE_BROWSER_ARGS_) +# Iterate over the array +for var in "\${BROWSER_ARGS_ARRAY[@]}"; do + # Split the variable into name and value + IFS='=' read -r name value <<< "\$var" + SE_BROWSER_ARGS="\$SE_BROWSER_ARGS \$value" +done + +# Note: exec -a below is a bashism. +exec -a "\$0" "$BASE_PATH" --no-sandbox \$SE_BROWSER_ARGS "\$@" +_EOF +chmod +x "$WRAPPER_PATH" \ No newline at end of file