|
#!/bin/sh |
|
# A script to directly run a Vivaldi .rpm or .deb package without |
|
# installation. User data will be stored in a version numbered |
|
# temp directory |
|
|
|
# Use the most recent Vivaldi package in the current working |
|
# directory or whatever the user has defined as the first option |
|
# to this script. |
|
|
|
# Provide some help on the available options. |
|
helptext() { |
|
cat << HELP |
|
|
|
Usage: `basename "$0"` [option(s)] [packagename] [vivaldi options] |
|
|
|
If no packagename is provided, then the script will use the most recently |
|
updated Vivaldi package it can find in the current working directory. |
|
|
|
Normal options: |
|
|
|
-h, --help (Show this help text and exit) |
|
-c, --cache-build (Cache build - Avoids re-extraction for each run) |
|
-d, --default-user-data (Use the normal User Data directory) |
|
|
|
Cleanup options: |
|
|
|
--clear-cached-build (Remove the extracted/cached build and exit) |
|
--clear-build-user-data (Remove the per build User Data and exit) |
|
|
|
HELP |
|
} |
|
|
|
# Function to find if various commands are installed |
|
available () { |
|
command -v "$1" >/dev/null 2>&1 |
|
} |
|
|
|
# Handle the script's command line options. |
|
CACHE_PKG=N |
|
USER_DATA=BUILD |
|
CLEAR_CACHE=N |
|
CLEAR_BUD=N |
|
while [ 0 ]; do |
|
if [ "$1" = "-h" -o "$1" = "--help" ]; then |
|
helptext |
|
exit 0 |
|
elif [ "$1" = "-c" -o "$1" = "--cache-build" ]; then |
|
CACHE_PKG=Y |
|
shift 1 |
|
elif [ "$1" = "-d" -o "$1" = "--default-user-data" ]; then |
|
USER_DATA=DEFAULT |
|
shift 1 |
|
elif [ "$1" = "--clear-cached-build" ]; then |
|
CLEAR_CACHE=Y |
|
shift 1 |
|
elif [ "$1" = "--clear-build-user-data" ]; then |
|
CLEAR_BUD=Y |
|
shift 1 |
|
else |
|
break |
|
fi |
|
done |
|
|
|
# Locate a suitable sandbox for users who have a kernel without user namespace support |
|
if [ -z "$CHROME_DEVEL_SANDBOX" ]; then |
|
if available unshare; then |
|
if ! unshare -U true >/dev/null 2>&1; then |
|
# Vivaldi snapshot |
|
if [ -e /opt/vivaldi-snapshot/vivaldi-sandbox ]; then |
|
export CHROME_DEVEL_SANDBOX=/opt/vivaldi-snapshot/vivaldi-sandbox |
|
# Vivaldi stable |
|
elif [ -e /opt/vivaldi/vivaldi-sandbox ]; then |
|
export CHROME_DEVEL_SANDBOX=/opt/vivaldi/vivaldi-sandbox |
|
# Chrome |
|
elif [ -e /opt/google/chrome/chrome-sandbox ]; then |
|
export CHROME_DEVEL_SANDBOX=/opt/google/chrome/chrome-sandbox |
|
# Chromium (location in Arch Linux) |
|
elif [ -e /usr/lib/chromium/chrome-sandbox ]; then |
|
export CHROME_DEVEL_SANDBOX=/usr/lib/chromium/chrome-sandbox |
|
else |
|
echo 'Your Linux kernel does not support user namespaces. Therefore a root owned,' >&2 |
|
echo 'setuid Chromium/Vivaldi sandbox is needed to run securely.' >&2 |
|
echo 'Install a copy of Vivaldi via your package manager to remedy this.' >&2 |
|
exit 1 |
|
fi |
|
fi |
|
fi |
|
fi |
|
|
|
# Take the build as the one provided on the command line or the most recently created in the working directory. |
|
if [ -n "$1" ]; then |
|
PKG="$1" |
|
shift 1 |
|
else |
|
PKG=`ls -t vivaldi-s*.rpm vivaldi-s*.deb vivaldi-s*.cpio.* vivaldi-s*.tar.* 2>/dev/null | head -n 1` |
|
fi |
|
|
|
# Exit as soon as an error is encountered. |
|
set -e |
|
|
|
# Check that a suitable package has been specified. |
|
VIVALDI_PKG_INFO=`echo "$PKG" | sed -n 's/.*\(vivaldi-[a-z]\+\)[_-]\(\([0-9]\+\.\)\{3\}[0-9]\+\)-[0-9]\+[_\.]\([a-z0-9_]\+\)\.\(deb\|rpm\|cpio\..*\|tar\..*\)$/\1:\2:\4/p'` |
|
|
|
if [ -z "$VIVALDI_PKG_INFO" ]; then |
|
echo 'You must specify the path to a locally stored Vivaldi Linux package.' >&2 |
|
helptext >&2 |
|
exit 1 |
|
fi |
|
|
|
if [ ! -r "$PKG" ]; then |
|
echo "$PKG is either not present or cannot be read." >&2 |
|
exit 1 |
|
fi |
|
|
|
# Define the various variables obtained from information in the |
|
# original package name. |
|
VIVALDI_STREAM=`echo "$VIVALDI_PKG_INFO" | cut -d: -f1` |
|
case "$VIVALDI_STREAM" in |
|
vivaldi-stable) VIVALDI_STREAM=vivaldi ;; |
|
vivaldi-beta) VIVALDI_STREAM=vivaldi ;; |
|
esac |
|
|
|
VIVALDI_VERSION=`echo "$VIVALDI_PKG_INFO" | cut -d: -f2` |
|
|
|
VIVALDI_ARCH=`echo "$VIVALDI_PKG_INFO" | cut -d: -f3` |
|
case "$VIVALDI_ARCH" in |
|
x86_64) VIVALDI_ARCH=x64 ;; |
|
amd64) VIVALDI_ARCH=x64 ;; |
|
i386) VIVALDI_ARCH=x86 ;; |
|
armhf) VIVALDI_ARCH=arm32 ;; |
|
arm64) VIVALDI_ARCH=arm64 ;; |
|
esac |
|
|
|
VIVDIR=/var/tmp/"$VIVALDI_STREAM-$VIVALDI_VERSION-$VIVALDI_ARCH-$USER" |
|
VIVBIN="$VIVDIR/opt/$VIVALDI_STREAM/$VIVALDI_STREAM" |
|
VIVUSD="${VIVDIR}-user-data" |
|
|
|
# Clean up cached directories if the user requests this. |
|
clear_dir () { |
|
if [ -d "$1" ]; then |
|
rm -r "$1" |
|
echo "Removed: $1" |
|
else |
|
echo "$1 does not exist, so cannot be removed!" >&2 |
|
fi |
|
} |
|
|
|
if [ "$CLEAR_CACHE" = Y ]; then |
|
clear_dir "$VIVDIR" |
|
fi |
|
|
|
if [ "$CLEAR_BUD" = Y ]; then |
|
clear_dir "$VIVUSD" |
|
fi |
|
|
|
if [ "$CLEAR_CACHE" = Y -o "$CLEAR_BUD" = Y ]; then |
|
exit 0 |
|
fi |
|
|
|
# Function to launch Vivaldi with appropriate options |
|
start_vivaldi () { |
|
printf "Launching Vivaldi ($VIVALDI_VERSION)\n\n" |
|
case "$USER_DATA" in |
|
B*) $VIVBIN --user-data-dir="$VIVUSD" "$@" ;; |
|
D*) $VIVBIN "$@" ;; |
|
esac |
|
} |
|
|
|
# Run Vivaldi without extraction, if the build is already cached. |
|
if [ -d "$VIVDIR" ]; then |
|
printf "\n\nReusing cached, extracted package directory:\n\n\t$VIVDIR\n\n" >&2 |
|
start_vivaldi "$@" |
|
exit 0 |
|
fi |
|
|
|
# Extract the package contents. |
|
set_decompressor () { |
|
case "$1" in |
|
*zst) |
|
if available zstd; then |
|
CMP=zstd |
|
else |
|
echo "zStandard is not installed" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
*lz4) |
|
if available lz4; then |
|
CMP=lz4 |
|
else |
|
echo "LZ4 is not installed" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
*lzo) |
|
if available lzop; then |
|
CMP=lzop |
|
else |
|
echo "Lzop is not installed" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
*br) |
|
if available brotli; then |
|
CMP=brotli |
|
else |
|
echo "Brotli is not installed" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
*gz) CMP=gzip ;; |
|
*lz) |
|
if available plzip; then |
|
CMP=plzip |
|
elif available lzip; then |
|
CMP=lzip |
|
else |
|
echo "Neither plzip, nor lzip is installed" >&2 |
|
exit 1 |
|
fi |
|
;; |
|
*bz2) |
|
if available lbzip2; then |
|
CMP=lbzip2 |
|
elif available pbzip2; then |
|
CMP=pbzip2 |
|
else |
|
CMP=bzip2 |
|
fi |
|
;; |
|
*) echo "Unknown compression type" >&2 ; exit 1 ;; |
|
esac |
|
} |
|
|
|
extract_rpm () { |
|
if available bsdtar; then |
|
bsdtar xf "$1" -C "$VIVDIR" |
|
elif available cpio; then |
|
tail -c+`grep -abom1 7zXZ "$1" | cut -d: -f1` "$1" | xz -d | (cd "$VIVDIR"; cpio --quiet -id) |
|
else |
|
echo 'You must install GNU cpio to use this script.' >&2 |
|
exit 1 |
|
fi |
|
} |
|
|
|
extract_deb () { |
|
if available bsdtar; then |
|
bsdtar xOf "$1" data.tar.xz | tar xJ -C "$VIVDIR" |
|
elif available ar; then |
|
ar p "$1" data.tar.xz | tar xJ -C "$VIVDIR" |
|
else |
|
echo 'You must install GNU binutils to use this script.' >&2 |
|
exit 1 |
|
fi |
|
} |
|
|
|
extract_cpio () { |
|
if available cpio; then |
|
set_decompressor "$PKG" |
|
$CMP -d < "$1"| (cd "$VIVDIR"; cpio --quiet -id) |
|
else |
|
echo 'You must install GNU cpio to use this script.' >&2 |
|
exit 1 |
|
fi |
|
} |
|
|
|
extract_tar () { |
|
set_decompressor "$PKG" |
|
tar xf "$1" -C "$VIVDIR" -I $CMP |
|
} |
|
|
|
mkdir "$VIVDIR" |
|
chmod 755 "$VIVDIR" |
|
|
|
printf "\nExtracting… $PKG\n" |
|
case "$PKG" in |
|
*deb) extract_deb "$PKG" ;; |
|
*rpm) extract_rpm "$PKG" ;; |
|
*.cpio.*) extract_cpio "$PKG" ;; |
|
*.tar.*) extract_tar "$PKG" ;; |
|
esac |
|
|
|
# Delete the bundled SUID because it cannot be setup correctly. |
|
# User's with user namespace support in the kernel do not need it and those |
|
# without will have to use an alternative anyway |
|
find "$VIVDIR" -type f -name vivaldi-sandbox -delete |
|
|
|
# Run Vivaldi |
|
start_vivaldi "$@" |
|
|
|
# Clean up |
|
if [ "$CACHE_PKG" = "N" ]; then |
|
rm -r "$VIVDIR" |
|
fi |
I added support for more distros/kernel configurations. Previously this command could not work for most users on distros like Arch Linux because thier kernel if compiled to not support user namespaces by default. These are needed to sandbox Chromium correctly
Now I check for user namespace support and if it is not present I use the root, SUID sandbox of any installed Vivaldi, Chrome or Chromium I find instead.