diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 06285ec..e23e460 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,7 +5,7 @@ variables:
KASM_RELEASE: "1.11.0"
DOCKER_AUTH_CONFIG: ${_DOCKER_AUTH_CONFIG}
PLATFORM: "linux/amd64"
- ARM_BUILDS: ",chromium,firefox,gimp,remmina,terminal,ubuntu-bionic-desktop,ubuntu-focal-desktop,ubuntu-jammy-desktop,vlc,vs-code,doom,sublime-text,tor-browser,java-dev,telegram,opensuse-15-desktop,oracle-8-desktop,libre-office,thunderbird,audacity,deluge,filezilla,inkscape,pinta,qbittorrent,vivaldi,"
+ ARM_BUILDS: ",chromium,firefox,gimp,remmina,terminal,ubuntu-bionic-desktop,ubuntu-focal-desktop,ubuntu-jammy-desktop,vlc,vs-code,doom,sublime-text,tor-browser,java-dev,telegram,opensuse-15-desktop,oracle-8-desktop,libre-office,thunderbird,audacity,deluge,filezilla,inkscape,pinta,qbittorrent,vivaldi,minetest,retroarch,super-tux-kart,"
CORE_IMAGE_TAG: "develop"
CORE_IMAGE: "core-ubuntu-focal"
USE_PRIVATE_IMAGES: 0
@@ -38,6 +38,9 @@ variables:
- vs-code
.MULTI_ARCH_BUILDS2: &MULTI_ARCH_BUILDS2
+ - minetest
+ - retroarch
+ - super-tux-kart
- vivaldi
.SINGLE_ARCH_BUILDS: &SINGLE_ARCH_BUILDS
@@ -137,7 +140,7 @@ build_app_images:
- aws-autoscale
parallel:
matrix:
- - KASM_IMAGE: [doom, sublime-text, gimp, vs-code, teams, only-office, zoom, signal, steam, postman, insomnia, zsnes, vlc, maltego, telegram, hunchly, java-dev, terminal, remmina, discord, libre-office, thunderbird, atom, audacity, deluge, filezilla, inkscape, pinta, qbittorrent, blender, unityhub]
+ - KASM_IMAGE: [sublime-text, gimp, vs-code, teams, only-office, zoom, signal, steam, postman, insomnia, zsnes, vlc, maltego, telegram, hunchly, java-dev, terminal, remmina, discord, libre-office, thunderbird, atom, audacity, deluge, filezilla, inkscape, pinta, qbittorrent, blender, unityhub]
build_ubuntu_desktop_images:
stage: build
@@ -207,6 +210,35 @@ build_non_ubuntu:
matrix:
- KASM_IMAGE: [centos-7-desktop, tracelabs, opensuse-15-desktop, oracle-7-desktop, oracle-8-desktop]
+build_games:
+ stage: build
+ image: ${ORG_NAME}/docker-buildx-private:develop
+ script:
+ - BUILD_PLATFORM=$PLATFORM
+ - if [[ "${ARM_BUILDS}" == *",${KASM_IMAGE},"* ]]; then BUILD_PLATFORM="linux/amd64,linux/arm64"; fi;
+ - echo "Building ${KASM_IMAGE} for platforms ${BUILD_PLATFORM}"
+ # to get qemu ready
+ - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ # to prepare the buildx env
+ - docker buildx create --use
+ # Ensure readme and description files are present
+ - ls docs/$KASM_IMAGE/README.md
+ - ls docs/$KASM_IMAGE/description.txt
+ # Check for private variable to build against private core images
+ - if [[ $USE_PRIVATE_IMAGES -eq 1 ]]; then CORE_IMAGE=$CORE_IMAGE-private; fi;
+
+ - docker buildx build --push --platform $BUILD_PLATFORM -t ${ORG_NAME}/$KASM_IMAGE:$SANITIZED_BRANCH -t ${ORG_NAME}/$KASM_IMAGE:$SANITIZED_ROLLING_BRANCH -t ${ORG_NAME}/$KASM_IMAGE-private:$SANITIZED_BRANCH -t ${ORG_NAME}/$KASM_IMAGE-private:$SANITIZED_ROLLING_BRANCH --build-arg BASE_IMAGE=$CORE_IMAGE --build-arg BASE_TAG=$CORE_IMAGE_TAG -f dockerfile-kasm-$KASM_IMAGE .
+ only:
+ - develop
+ - /^release\/.*$/
+ except:
+ - schedules
+ tags:
+ - aws-autoscale
+ parallel:
+ matrix:
+ - KASM_IMAGE: [doom, minetest, retroarch, super-tux-kart]
+
# These jobs should run on the feature/bugfix branches - anything that is not the develop or release branches. It should only push images to the private repos
build_multi_arch_dev:
stage: build
@@ -332,6 +364,7 @@ test_multi_arch_dev:
except:
- develop
- /^release\/.*$/
+ needs: [ manifest_dev ]
tags:
- ${TAG}
parallel:
@@ -363,6 +396,7 @@ test_multi_arch_dev2:
except:
- develop
- /^release\/.*$/
+ needs: [ manifest_dev2 ]
tags:
- ${TAG}
parallel:
@@ -394,6 +428,7 @@ test_single_arch_dev:
except:
- develop
- /^release\/.*$/
+ needs: [ build_single_arch_dev ]
tags:
- aws-autoscale
parallel:
@@ -412,6 +447,7 @@ manifest_dev:
except:
- develop
- /^release\/.*$/
+ needs: [ build_multi_arch_dev ]
tags:
- aws-autoscale
parallel:
@@ -430,6 +466,7 @@ manifest_dev2:
except:
- develop
- /^release\/.*$/
+ needs: [ build_multi_arch_dev2 ]
tags:
- aws-autoscale
parallel:
@@ -446,6 +483,7 @@ link_tests_single_arch_dev:
except:
- develop
- /^release\/.*$/
+ needs: [ test_single_arch_dev ]
parallel:
matrix:
- KASM_IMAGE: *SINGLE_ARCH_BUILDS
@@ -460,6 +498,7 @@ link_tests_multi_arch_dev:
except:
- develop
- /^release\/.*$/
+ needs: [ test_multi_arch_dev ]
parallel:
matrix:
- ARCH: [ aarch64, x86_64 ]
@@ -475,6 +514,7 @@ link_tests_multi_arch_dev2:
except:
- develop
- /^release\/.*$/
+ needs: [ test_multi_arch_dev2 ]
parallel:
matrix:
- ARCH: [ aarch64, x86_64 ]
@@ -535,7 +575,7 @@ build_schedules_app_images:
- aws-autoscale
parallel:
matrix:
- - KASM_IMAGE: [doom, sublime-text, gimp, vs-code, teams, only-office, zoom, signal, steam, postman, insomnia, zsnes, vlc, maltego, telegram, hunchly, java-dev, terminal, remmina, discord, libre-office, thunderbird, atom, audacity, deluge, filezilla, inkscape, pinta, qbittorrent, blender, unityhub]
+ - KASM_IMAGE: [sublime-text, gimp, vs-code, teams, only-office, zoom, signal, steam, postman, insomnia, zsnes, vlc, maltego, telegram, hunchly, java-dev, terminal, remmina, discord, libre-office, thunderbird, atom, audacity, deluge, filezilla, inkscape, pinta, qbittorrent, blender, unityhub]
build_schedules_ubuntu_desktop_images:
image: ${ORG_NAME}/docker-buildx-private:develop
@@ -602,6 +642,34 @@ build_schedules_non_ubuntu:
matrix:
- KASM_IMAGE: [centos-7-desktop, tracelabs, opensuse-15-desktop, oracle-7-desktop, oracle-8-desktop]
+build_schedules_games:
+ image: ${ORG_NAME}/docker-buildx-private:develop
+ stage: build
+ script:
+ - BUILD_PLATFORM=$PLATFORM
+ - if [[ "${ARM_BUILDS}" == *",${KASM_IMAGE},"* ]]; then BUILD_PLATFORM="linux/amd64,linux/arm64"; fi;
+ - echo "Building ${KASM_IMAGE} for platforms ${BUILD_PLATFORM}"
+ # to get qemu ready
+ - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
+ # to prepare the buildx env
+ - docker buildx create --use
+ # Ensure readme and description files are present
+ - ls docs/$KASM_IMAGE/README.md
+ - ls docs/$KASM_IMAGE/description.txt
+ # Check for private variable to build against private core images
+ - if [[ $USE_PRIVATE_IMAGES -eq 1 ]]; then CORE_IMAGE=$CORE_IMAGE-private; fi;
+
+ # Equivalent to docker build and docker push. Builds amd64 natively uses qemu for arm64.
+ # The only way to push multiple architectures to the same tag is to use buildx.
+ - docker buildx build --push --platform $BUILD_PLATFORM -t ${ORG_NAME}/$KASM_IMAGE:$SANITIZED_ROLLING_BRANCH -t ${ORG_NAME}/$KASM_IMAGE-private:$SANITIZED_ROLLING_BRANCH --build-arg BASE_IMAGE=$CORE_IMAGE --build-arg BASE_TAG="$SANITIZED_ROLLING_BRANCH" -f dockerfile-kasm-$KASM_IMAGE .
+ only:
+ - schedules
+ tags:
+ - aws-autoscale
+ parallel:
+ matrix:
+ - KASM_IMAGE: [doom, minetest, retroarch, super-tux-kart]
+
update_readmes:
stage: readme
script:
@@ -688,6 +756,9 @@ update_readmes2:
parallel:
matrix:
- KASM_IMAGE:
- - vivaldi
+ - minetest
+ - retroarch
+ - super-tux-kart
- ubuntu-jammy-dind
- ubuntu-jammy-dind-rootless
+ - vivaldi
diff --git a/dockerfile-kasm-minetest b/dockerfile-kasm-minetest
new file mode 100644
index 0000000..1af465c
--- /dev/null
+++ b/dockerfile-kasm-minetest
@@ -0,0 +1,34 @@
+ARG BASE_TAG="develop"
+ARG BASE_IMAGE="core-ubuntu-focal"
+FROM kasmweb/$BASE_IMAGE:$BASE_TAG
+USER root
+
+ENV HOME /home/kasm-default-profile
+ENV STARTUPDIR /dockerstartup
+ENV INST_SCRIPTS $STARTUPDIR/install
+WORKDIR $HOME
+
+######### Customize Container Here ###########
+
+
+COPY ./src/ubuntu/install/minetest $INST_SCRIPTS/minetest/
+RUN bash $INST_SCRIPTS/minetest/install_minetest.sh && rm -rf $INST_SCRIPTS/minetest/
+
+COPY ./src/ubuntu/install/minetest/custom_startup.sh $STARTUPDIR/custom_startup.sh
+RUN chmod +x $STARTUPDIR/custom_startup.sh
+RUN chmod 755 $STARTUPDIR/custom_startup.sh
+
+# Update the desktop environment to be optimized for a single application
+RUN cp $HOME/.config/xfce4/xfconf/single-application-xfce-perchannel-xml/* $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/
+RUN cp /usr/share/extra/backgrounds/bg_kasm.png /usr/share/extra/backgrounds/bg_default.png
+RUN apt-get remove -y xfce4-panel
+
+######### End Customizations ###########
+
+RUN chown 1000:0 $HOME
+
+ENV HOME /home/kasm-user
+WORKDIR $HOME
+RUN mkdir -p $HOME && chown -R 1000:0 $HOME
+
+USER 1000
diff --git a/dockerfile-kasm-retroarch b/dockerfile-kasm-retroarch
new file mode 100644
index 0000000..7659ead
--- /dev/null
+++ b/dockerfile-kasm-retroarch
@@ -0,0 +1,34 @@
+ARG BASE_TAG="develop"
+ARG BASE_IMAGE="core-ubuntu-focal"
+FROM kasmweb/$BASE_IMAGE:$BASE_TAG
+USER root
+
+ENV HOME /home/kasm-default-profile
+ENV STARTUPDIR /dockerstartup
+ENV INST_SCRIPTS $STARTUPDIR/install
+WORKDIR $HOME
+
+######### Customize Container Here ###########
+
+
+COPY ./src/ubuntu/install/retroarch $INST_SCRIPTS/retroarch/
+RUN bash $INST_SCRIPTS/retroarch/install_retroarch.sh && rm -rf $INST_SCRIPTS/retroarch/
+
+COPY ./src/ubuntu/install/retroarch/custom_startup.sh $STARTUPDIR/custom_startup.sh
+RUN chmod +x $STARTUPDIR/custom_startup.sh
+RUN chmod 755 $STARTUPDIR/custom_startup.sh
+
+# Update the desktop environment to be optimized for a single application
+RUN cp $HOME/.config/xfce4/xfconf/single-application-xfce-perchannel-xml/* $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/
+RUN cp /usr/share/extra/backgrounds/bg_kasm.png /usr/share/extra/backgrounds/bg_default.png
+RUN apt-get remove -y xfce4-panel
+
+######### End Customizations ###########
+
+RUN chown 1000:0 $HOME
+
+ENV HOME /home/kasm-user
+WORKDIR $HOME
+RUN mkdir -p $HOME && chown -R 1000:0 $HOME
+
+USER 1000
diff --git a/dockerfile-kasm-super-tux-kart b/dockerfile-kasm-super-tux-kart
new file mode 100644
index 0000000..1e57596
--- /dev/null
+++ b/dockerfile-kasm-super-tux-kart
@@ -0,0 +1,34 @@
+ARG BASE_TAG="develop"
+ARG BASE_IMAGE="core-ubuntu-jammy"
+FROM kasmweb/$BASE_IMAGE:$BASE_TAG
+USER root
+
+ENV HOME /home/kasm-default-profile
+ENV STARTUPDIR /dockerstartup
+ENV INST_SCRIPTS $STARTUPDIR/install
+WORKDIR $HOME
+
+######### Customize Container Here ###########
+
+COPY ./src/ubuntu/install/super_tux_kart $INST_SCRIPTS/super_tux_kart/
+RUN bash $INST_SCRIPTS/super_tux_kart/install_super_tux_kart.sh && rm -rf $INST_SCRIPTS/super_tux_kart/
+
+COPY ./src/ubuntu/install/super_tux_kart/custom_startup.sh $STARTUPDIR/custom_startup.sh
+RUN chmod +x $STARTUPDIR/custom_startup.sh
+RUN chmod 755 $STARTUPDIR/custom_startup.sh
+
+# Update the desktop environment to be optimized for a single application
+RUN cp $HOME/.config/xfce4/xfconf/single-application-xfce-perchannel-xml/* $HOME/.config/xfce4/xfconf/xfce-perchannel-xml/
+RUN cp /usr/share/extra/backgrounds/bg_kasm.png /usr/share/extra/backgrounds/bg_default.png
+RUN apt-get remove -y xfce4-panel
+
+######### End Customizations ###########
+
+RUN chown 1000:0 $HOME
+RUN $STARTUPDIR/set_user_permission.sh $HOME
+
+ENV HOME /home/kasm-user
+WORKDIR $HOME
+RUN mkdir -p $HOME && chown -R 1000:0 $HOME
+
+USER 1000
diff --git a/docs/minetest/README.md b/docs/minetest/README.md
new file mode 100644
index 0000000..a2ed31b
--- /dev/null
+++ b/docs/minetest/README.md
@@ -0,0 +1,11 @@
+# About This Image
+
+This Image contains a browser-accessible version of [Minetest](https://www.minetest.net/).
+
+![Screenshot][Image_Screenshot]
+
+[Image_Screenshot]: https://5856039.fs1.hubspotusercontent-na1.net/hubfs/5856039/dockerhub/image-screenshots/minetest.png "Image Screenshot"
+
+# Environment Variables
+
+* `APP_ARGS` - Additional arguments to pass to the application when launched.
diff --git a/docs/minetest/demo.txt b/docs/minetest/demo.txt
new file mode 100644
index 0000000..61a2ec2
--- /dev/null
+++ b/docs/minetest/demo.txt
@@ -0,0 +1,7 @@
+# Live Demo
+
+**Launch a real-time demo in a new browser window:** Live Demo.
+
+
+
+∗*Note: Demo is limited to 3 minutes and has upload/downloads restricted for security purposes.*
diff --git a/docs/minetest/description.txt b/docs/minetest/description.txt
new file mode 100644
index 0000000..0090d27
--- /dev/null
+++ b/docs/minetest/description.txt
@@ -0,0 +1 @@
+Minetest for Kasm Workspaces
diff --git a/docs/retroarch/README.md b/docs/retroarch/README.md
new file mode 100644
index 0000000..97e434e
--- /dev/null
+++ b/docs/retroarch/README.md
@@ -0,0 +1,11 @@
+# About This Image
+
+This Image contains a browser-accessible version of [Retroarch](https://www.retroarch.com/).
+
+![Screenshot][Image_Screenshot]
+
+[Image_Screenshot]: https://5856039.fs1.hubspotusercontent-na1.net/hubfs/5856039/dockerhub/image-screenshots/retroarch.png "Image Screenshot"
+
+# Environment Variables
+
+* `APP_ARGS` - Additional arguments to pass to the application when launched.
diff --git a/docs/retroarch/demo.txt b/docs/retroarch/demo.txt
new file mode 100644
index 0000000..e5aeb34
--- /dev/null
+++ b/docs/retroarch/demo.txt
@@ -0,0 +1,7 @@
+# Live Demo
+
+**Launch a real-time demo in a new browser window:** Live Demo.
+
+
+
+∗*Note: Demo is limited to 3 minutes and has upload/downloads restricted for security purposes.*
diff --git a/docs/retroarch/description.txt b/docs/retroarch/description.txt
new file mode 100644
index 0000000..668e3a9
--- /dev/null
+++ b/docs/retroarch/description.txt
@@ -0,0 +1 @@
+RetroArch for Kasm Workspaces
diff --git a/docs/super-tux-kart/README.md b/docs/super-tux-kart/README.md
new file mode 100644
index 0000000..3655b8e
--- /dev/null
+++ b/docs/super-tux-kart/README.md
@@ -0,0 +1,11 @@
+# About This Image
+
+This Image contains a browser-accessible version of [SuperTuxKart](https://supertuxkart.net/).
+
+![Screenshot][Image_Screenshot]
+
+[Image_Screenshot]: https://5856039.fs1.hubspotusercontent-na1.net/hubfs/5856039/dockerhub/image-screenshots/super-tux-kart.png "Image Screenshot"
+
+# Environment Variables
+
+* `APP_ARGS` - Additional arguments to pass to the application when launched.
diff --git a/docs/super-tux-kart/demo.txt b/docs/super-tux-kart/demo.txt
new file mode 100644
index 0000000..924ebd0
--- /dev/null
+++ b/docs/super-tux-kart/demo.txt
@@ -0,0 +1,7 @@
+# Live Demo
+
+**Launch a real-time demo in a new browser window:** Live Demo.
+
+
+
+∗*Note: Demo is limited to 3 minutes and has upload/downloads restricted for security purposes.*
diff --git a/docs/super-tux-kart/description.txt b/docs/super-tux-kart/description.txt
new file mode 100644
index 0000000..3776042
--- /dev/null
+++ b/docs/super-tux-kart/description.txt
@@ -0,0 +1 @@
+SuperTuxKart for Kasm Workspaces
diff --git a/docs/teams/description.txt b/docs/teams/description.txt
index ebc68d9..9614c9f 100644
--- a/docs/teams/description.txt
+++ b/docs/teams/description.txt
@@ -1 +1 @@
-Steam for Kasm Workspaces
\ No newline at end of file
+Microsoft Teams for Kasm Workspaces
diff --git a/src/ubuntu/install/minetest/custom_startup.sh b/src/ubuntu/install/minetest/custom_startup.sh
new file mode 100644
index 0000000..6a67adb
--- /dev/null
+++ b/src/ubuntu/install/minetest/custom_startup.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+set -ex
+START_COMMAND="/usr/bin/minetest"
+PGREP="minetest"
+export MAXIMIZE="true"
+export MAXIMIZE_NAME="Minetest"
+MAXIMIZE_SCRIPT=$STARTUPDIR/maximize_window.sh
+DEFAULT_ARGS=""
+ARGS=${APP_ARGS:-$DEFAULT_ARGS}
+
+options=$(getopt -o gau: -l go,assign,url: -n "$0" -- "$@") || exit
+eval set -- "$options"
+
+while [[ $1 != -- ]]; do
+ case $1 in
+ -g|--go) GO='true'; shift 1;;
+ -a|--assign) ASSIGN='true'; shift 1;;
+ -u|--url) OPT_URL=$2; shift 2;;
+ *) echo "bad option: $1" >&2; exit 1;;
+ esac
+done
+shift
+
+# Process non-option arguments.
+for arg; do
+ echo "arg! $arg"
+done
+
+FORCE=$2
+
+kasm_exec() {
+ if [ -n "$OPT_URL" ] ; then
+ URL=$OPT_URL
+ elif [ -n "$1" ] ; then
+ URL=$1
+ fi
+
+ # Since we are execing into a container that already has the browser running from startup,
+ # when we don't have a URL to open we want to do nothing. Otherwise a second browser instance would open.
+ if [ -n "$URL" ] ; then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ bash ${MAXIMIZE_SCRIPT} &
+ $START_COMMAND $ARGS $OPT_URL
+ else
+ echo "No URL specified for exec command. Doing nothing."
+ fi
+}
+
+kasm_startup() {
+ if [ -n "$KASM_URL" ] ; then
+ URL=$KASM_URL
+ elif [ -z "$URL" ] ; then
+ URL=$LAUNCH_URL
+ fi
+
+ if [ -z "$DISABLE_CUSTOM_STARTUP" ] || [ -n "$FORCE" ] ; then
+
+ echo "Entering process startup loop"
+ set +x
+ while true
+ do
+ if ! pgrep -x $PGREP > /dev/null
+ then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ set +e
+ bash ${MAXIMIZE_SCRIPT} &
+ source $STARTUPDIR/generate_container_user
+ $START_COMMAND $ARGS $URL
+ set -e
+ fi
+ sleep 1
+ done
+ set -x
+
+ fi
+
+}
+
+if [ -n "$GO" ] || [ -n "$ASSIGN" ] ; then
+ kasm_exec
+else
+ kasm_startup
+fi
diff --git a/src/ubuntu/install/minetest/install_minetest.sh b/src/ubuntu/install/minetest/install_minetest.sh
new file mode 100644
index 0000000..a734938
--- /dev/null
+++ b/src/ubuntu/install/minetest/install_minetest.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+set -ex
+apt-get update
+apt-get install -y minetest
+
+# Add desktop icon
+cp /usr/share/applications/net.minetest.minetest.desktop $HOME/Desktop/
+chmod +x $HOME/Desktop/net.minetest.minetest.desktop
+
+# Wrap game bin for VGL support
+cat >/usr/bin/minetest <&2; exit 1;;
+ esac
+done
+shift
+
+# Process non-option arguments.
+for arg; do
+ echo "arg! $arg"
+done
+
+FORCE=$2
+
+kasm_exec() {
+ if [ -n "$OPT_URL" ] ; then
+ URL=$OPT_URL
+ elif [ -n "$1" ] ; then
+ URL=$1
+ fi
+
+ # Since we are execing into a container that already has the browser running from startup,
+ # when we don't have a URL to open we want to do nothing. Otherwise a second browser instance would open.
+ if [ -n "$URL" ] ; then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ bash ${MAXIMIZE_SCRIPT} &
+ $START_COMMAND $ARGS $OPT_URL
+ else
+ echo "No URL specified for exec command. Doing nothing."
+ fi
+}
+
+kasm_startup() {
+ if [ -n "$KASM_URL" ] ; then
+ URL=$KASM_URL
+ elif [ -z "$URL" ] ; then
+ URL=$LAUNCH_URL
+ fi
+
+ if [ -z "$DISABLE_CUSTOM_STARTUP" ] || [ -n "$FORCE" ] ; then
+
+ echo "Entering process startup loop"
+ set +x
+ while true
+ do
+ if ! pgrep -x $PGREP > /dev/null
+ then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ set +e
+ bash ${MAXIMIZE_SCRIPT} &
+ source $STARTUPDIR/generate_container_user
+ $START_COMMAND $ARGS $URL
+ set -e
+ fi
+ sleep 1
+ done
+ set -x
+
+ fi
+
+}
+
+if [ -n "$GO" ] || [ -n "$ASSIGN" ] ; then
+ kasm_exec
+else
+ kasm_startup
+fi
diff --git a/src/ubuntu/install/retroarch/install_retroarch.sh b/src/ubuntu/install/retroarch/install_retroarch.sh
new file mode 100644
index 0000000..4119e29
--- /dev/null
+++ b/src/ubuntu/install/retroarch/install_retroarch.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+set -ex
+SCRIPT_PATH="$( cd "$(dirname "$0")" ; pwd -P )"
+add-apt-repository -y ppa:libretro/stable
+apt-get update
+apt-get install -y retroarch
+cp /usr/share/applications/retroarch.desktop $HOME/Desktop/
+chmod +x $HOME/Desktop/retroarch.desktop
+
+mkdir -p $HOME/.config/retroarch/{assets,cores}
+cp $SCRIPT_PATH/retroarch.cfg $HOME/.config/retroarch/retroarch.cfg
+echo "Downloading Assets"
+wget -q https://buildbot.libretro.com/assets/frontend/assets.zip
+wget -q https://buildbot.libretro.com/assets/frontend/info.zip
+unzip assets.zip -d $HOME/.config/retroarch/assets
+unzip info.zip -d $HOME/.config/retroarch/cores
+rm -f assets.zip info.zip
+chown -R 1000:1000 $HOME/.config/retroarch
+
+# Wrap with VGL
+rm /usr/bin/retroarch
+cat >/usr/bin/retroarch </usr/bin/desktop_ready <&2; exit 1;;
+ esac
+done
+shift
+
+# Process non-option arguments.
+for arg; do
+ echo "arg! $arg"
+done
+
+FORCE=$2
+
+kasm_exec() {
+ if [ -n "$OPT_URL" ] ; then
+ URL=$OPT_URL
+ elif [ -n "$1" ] ; then
+ URL=$1
+ fi
+
+ # Since we are execing into a container that already has the browser running from startup,
+ # when we don't have a URL to open we want to do nothing. Otherwise a second browser instance would open.
+ if [ -n "$URL" ] ; then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ bash ${MAXIMIZE_SCRIPT} &
+ $START_COMMAND $ARGS $OPT_URL
+ else
+ echo "No URL specified for exec command. Doing nothing."
+ fi
+}
+
+kasm_startup() {
+ if [ -n "$KASM_URL" ] ; then
+ URL=$KASM_URL
+ elif [ -z "$URL" ] ; then
+ URL=$LAUNCH_URL
+ fi
+
+ if [ -z "$DISABLE_CUSTOM_STARTUP" ] || [ -n "$FORCE" ] ; then
+
+ echo "Entering process startup loop"
+ set +x
+ while true
+ do
+ if ! pgrep -x $PGREP > /dev/null
+ then
+ /usr/bin/filter_ready
+ /usr/bin/desktop_ready
+ set +e
+ bash ${MAXIMIZE_SCRIPT} &
+ source $STARTUPDIR/generate_container_user
+ $START_COMMAND $ARGS $URL
+ set -e
+ fi
+ sleep 1
+ done
+ set -x
+
+ fi
+
+}
+
+if [ -n "$GO" ] || [ -n "$ASSIGN" ] ; then
+ kasm_exec
+else
+ kasm_startup
+fi
diff --git a/src/ubuntu/install/super_tux_kart/install_super_tux_kart.sh b/src/ubuntu/install/super_tux_kart/install_super_tux_kart.sh
new file mode 100644
index 0000000..2d2f6f4
--- /dev/null
+++ b/src/ubuntu/install/super_tux_kart/install_super_tux_kart.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+set -ex
+VERSION="1.3"
+ARCH=$(uname -m | sed 's/aarch64/arm64/g' | sed 's/x86_64/amd64/g')
+build=64bit
+if [ "${ARCH}" == "arm64" ] ; then
+ build=arm64
+fi
+
+# Install binary version from github
+mkdir -p /opt/super_tux_kart
+cd /tmp/
+wget -q https://github.com/supertuxkart/stk-code/releases/download/${VERSION}/SuperTuxKart-${VERSION}-linux-${build}.tar.xz
+tar -xf SuperTuxKart* -C /opt/super_tux_kart/
+sed -i "s@Exec=supertuxkart@Exec=/opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/run_game.sh@g" /opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/data/supertuxkart.desktop
+sed -i "s@Icon=supertuxkart@Icon=/opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/data/supertuxkart.icns@g" /opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/data/supertuxkart.desktop
+cp /opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/data/supertuxkart.desktop /usr/share/applications/
+chmod +x /usr/share/applications/supertuxkart.desktop
+cp /opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/data/supertuxkart.desktop $HOME/Desktop
+chmod +x $HOME/Desktop/supertuxkart.desktop
+chown 1000:1000 $HOME/Desktop/supertuxkart.desktop
+
+# Modify startup script for VGL
+cat >/opt/super_tux_kart/SuperTuxKart-${VERSION}-linux-${build}/run_game.sh </usr/bin/desktop_ready <