Skip to content

Instantly share code, notes, and snippets.

@ruario
Last active July 26, 2022 07:23
Show Gist options
  • Save ruario/23da64c334e08e03fffc04a05bbcd567 to your computer and use it in GitHub Desktop.
Save ruario/23da64c334e08e03fffc04a05bbcd567 to your computer and use it in GitHub Desktop.
Run Vivaldi Package (rpm, deb or recompressed contents)

Run Vivaldi Package

The attached script (rvp.sh) will allow you to directly run a Vivaldi .deb or .rpm package without “installing” it. This works by quickly extracting the package contents into /var/tmp and then executing the binary therein (the extracted files are removed when you close Vivaldi).

Vivaldi is run with a temporary user data (settings) that are specific to that exact version. This is to avoid messing up the main install's user data.

To run Vivaldi in this way, make rvp.sh executable and start a build like so:

./rvp.sh vivaldi-snapshot-1.15.1159.7-1.x86_64.rpm

If no package name is provided, then the script will use the most recently updated Vivaldi package it can find in the current working directory.

Caching extracted packages

If you use the same build often you can avoid the need to keep re-extracting stuff by running it like so:

./rvp.sh --cache-build vivaldi-snapshot-1.15.1159.7-1.x86_64.rpm

The next time you run the build the pre-extracted copy will be used, making the startup time the same as an installed build.

Passing Vivaldi command line arguments

You can also pass all the normal, Vivaldi supported command line arguments after the package name. For example, to tell Vivaldi (1.15.1159.7) to start with a curl user agent, you could issue:

./rvp.sh vivaldi-snapshot-1.15.1159.7-1.x86_64.rpm --user-agent="curl/7.59.0"

Advanced options

Run the script with the --help switch to what other options are available.


Vivaldi Package Re-Compress

I also provide a secondary (helper) script vprc.sh (Vivaldi Package Re-Compress), which allows you to convert a normal package into another compression type that extracts faster. This gives you some of the benefit of caching but with less wasted disk space.

For example, the command (below) would convert the rpm to a Zstandard compressed cpio archive (vivaldi-snapshot-1.15.1159.7-1.x86_64.cpio.zst), which will only be a little larger and can typically decompress in less than a 10th of the time.

./vprc.sh vivaldi-snapshot-1.15.1159.7-1.x86_64.rpm zst

Note: You will need to install Zstandard to use this option. Other compression options include Brotli (br), gzip (gz), lzop (lzo), lz4 and bzip2 (via the super fast lbzip2)

To use such a compressed file just issue:

./rvp.sh vivaldi-snapshot-1.15.1159.7-1.x86_64.cpio.zst
#!/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
#!/bin/sh
if [ -n "$2" ]; then
ext="$2"
else
ext=gz
fi
set -eu
available () {
command -v "$1" >/dev/null 2>&1
}
decompress_rpm () {
if available cpio; then
tail -c+`grep -abom1 7zXZ "$1" | cut -d: -f1` "$1" | xz -d | $cmp > "$pkg"
else
echo 'You must install GNU cpio to use this script.' >&2
exit 1
fi
}
decompress_deb () {
if available ar; then
ar p "$1" data.tar.xz | xz -d | $cmp > "$pkg"
else
echo 'You must install GNU binutils to use this script.' >&2
exit 1
fi
}
check_presence () {
if [ -e "$pkg" ]; then
printf "\n\t$pkg already present\n\n" 1>&2
exit 0
fi
}
case "$ext" in
zst*)
ext=zst
if available zstdmt; then
cmp="zstdmt -7"
elif command -v zstd; then
cmp="zstd -5"
else
echo "zStandard is not installed" >&2
exit 1
fi
;;
lz4)
if available lz4; then
cmp="lz4 -4"
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*)
ext=br
if available brotli; then
cmp="brotli -3"
else
echo "Brotli is not installed" >&2
exit 1
fi
;;
gz*)
ext=gz
if available pigz; then
cmp="pigz -1"
else
cmp="gzip -1" >&2
fi
;;
lz)
if available plzip; then
cmp="plzip -1"
else
echo "plzip is not installed" >&2
exit 1
fi
;;
bz2)
if available lbzip2; then
cmp="lbzip2 -1"
elif available pbzip2; then
cmp="pbzip2 -1"
else
echo "There are no multithreaded (high speed) bzip2 compressors installed" >&2
exit 1
fi
;;
*) echo "Unsupported compression type" 1>&2; exit 1 ;;
esac
case "$1" in
*.deb) pkg=`basename "$1" .deb`.tar.$ext; check_presence; decompress_deb "$1" ;;
*.rpm) pkg=`basename "$1" .rpm`.cpio.$ext; check_presence; decompress_rpm "$1" ;;
*) echo "Unknown source package type" 1>&2; exit 1 ;;
esac
printf "\n\tCreated: $pkg\n\n"
@Cqoicebordel
Copy link

It might be interesting to add "--user-data-dir="$HOME/.config/vivaldi-snapshot"" as a single flag to the script.

@ruario
Copy link
Author

ruario commented Apr 20, 2018

Yeah good point. I had considered this, but not gotten around to it yet since I figured it might be only me using it anyway. But sure, why not do something like this? Also since I know the stream I could have that be either "$HOME/.config/vivaldi" or "$HOME/.config/vivaldi-snapshot" as is appropriate. I'll add a switch (when I'm next in the office). Perhaps --default-user-data plus a short form (-d) that does the same (maybe also for a variable for those who want it to be the normal behaviour).

@ruario
Copy link
Author

ruario commented Apr 24, 2018

I should probably update this for anyone reading to say, I added that

@ruario
Copy link
Author

ruario commented May 22, 2018

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.

@ruario
Copy link
Author

ruario commented May 22, 2018

I also tweaked the extraction commands to make them more robust after discovering that GNU cpio is not installed by default on the Antergos Linux live media, meaning that I could not use it to unpack a Vivaldi rpm package. Now I first look for bsdtar and use that instead, if present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment