diff --git a/.dockerignore b/.dockerignore
index 7a1eba3..8d44ea6 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,2 +1,3 @@
*
!src
+!kasm-desktop-kde
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6dbec11..2c3e8c6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,6 +13,8 @@ stages:
- run
- test
variables:
+ DOCKER_AUTH_CONFIG: ${_DOCKER_AUTH_CONFIG}
+ GIT_SUBMODULE_STRATEGY: normal
KASM_RELEASE: "1.14.0"
TEST_INSTALLER: "https://kasmweb-build-artifacts.s3.amazonaws.com/kasm_backend/1e99090dadb026f1e37e34e53334da20061bc21c/kasm_workspaces_feature_tester-1.15-pre-release_1.15.0.1e9909.tar.gz"
SCAN_CONTAINERS: "true"
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..11fbcfa
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "kasm-desktop-kde"]
+ path = kasm-desktop-kde
+ branch = develop
+ url = https://github.com/kasmtech/KasmOS-KDE-Desktop
diff --git a/ci-scripts/manifest.sh b/ci-scripts/manifest.sh
index 95e9aab..b56a821 100755
--- a/ci-scripts/manifest.sh
+++ b/ci-scripts/manifest.sh
@@ -14,9 +14,17 @@ PULL_BRANCH=${SANITIZED_BRANCH}
# Determine if this is a private or public build
if [[ "${CI_COMMIT_REF_NAME}" == release/* ]] || [[ "${CI_COMMIT_REF_NAME}" == "develop" ]]; then
- ENDPOINT="core-${NAME1}-${NAME2}"
+ if [[ "${NAME1}" == "${NAME2}" ]]; then
+ ENDPOINT="core-${NAME1}"
+ else
+ ENDPOINT="core-${NAME1}-${NAME2}"
+ fi
else
- ENDPOINT="core-${NAME1}-${NAME2}-private"
+ if [[ "${NAME1}" == "${NAME2}" ]]; then
+ ENDPOINT="core-${NAME1}-private"
+ else
+ ENDPOINT="core-${NAME1}-${NAME2}-private"
+ fi
fi
# Determine if this is a rolling build
diff --git a/ci-scripts/template-vars.yaml b/ci-scripts/template-vars.yaml
index fb22d15..58da4bd 100644
--- a/ci-scripts/template-vars.yaml
+++ b/ci-scripts/template-vars.yaml
@@ -27,6 +27,20 @@ files: &UNIVERSAL_CHANGE_FILES
- .gitlab-ci.yml
multiImages:
+ - name1: kasmos
+ name2: kasmos
+ base: debian:bookworm-slim
+ bg: kasmos.png
+ distro: debian
+ dockerfile: dockerfile-kasm-core-kasmos
+ changeFiles:
+ - dockerfile-kasm-core-kasmos
+ - src/ubuntu/install/package_rules/**
+ - src/ubuntu/nvidia/**
+ - src/ubuntu/sysbox/**
+ - src/ubuntu/virtualgl/**
+ - src/ubuntu/install/kde/**
+ - kasm-desktop-kde/**
- name1: ubuntu
name2: bionic
base: ubuntu:18.04
diff --git a/ci-scripts/vulnerability-filter.rego b/ci-scripts/vulnerability-filter.rego
index bd6c653..3b75b25 100644
--- a/ci-scripts/vulnerability-filter.rego
+++ b/ci-scripts/vulnerability-filter.rego
@@ -13,7 +13,7 @@ ignore {
# KASM-5262 - False positives in libssl1.1 library that is manually installed on some distros
ignore {
input.PkgName == "libssl1.1"
- input.InstalledVersion == "1.1.1f-1ubuntu2.20"
+ input.InstalledVersion == "1.1.1f-1ubuntu2.22"
# Evaluate CWE-ID
deny_vulnerability_ids := {
diff --git a/dockerfile-kasm-core-kasmos b/dockerfile-kasm-core-kasmos
new file mode 100644
index 0000000..5ca5b60
--- /dev/null
+++ b/dockerfile-kasm-core-kasmos
@@ -0,0 +1,233 @@
+#### Build Stage ####
+ARG BASE_IMAGE="debian:bookworm-slim"
+FROM $BASE_IMAGE AS base_layer
+
+### Environment config
+ARG BG_IMG=bg_kasmos.png
+ARG DISTRO=debian
+ARG LANG='en_US.UTF-8'
+ARG LANGUAGE='en_US:en'
+ARG LC_ALL='en_US.UTF-8'
+ARG TZ='Etc/UTC'
+ENV DEBIAN_FRONTEND=noninteractive \
+ DISTRO=$DISTRO \
+ HOME=/home/kasm-default-profile \
+ INST_SCRIPTS=/dockerstartup/install \
+ KASM_VNC_PATH=/usr/share/kasmvnc \
+ LANG=$LANG \
+ LANGUAGE=$LANGUAGE \
+ LC_ALL=$LC_ALL \
+ TZ=$TZ \
+ STARTUPDIR=/dockerstartup
+
+### Home setup
+WORKDIR $HOME
+RUN mkdir -p $HOME/Desktop
+
+### Support NVIDIA gpus for graphics acceleration
+RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
+ echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf
+COPY src/ubuntu/install/nvidia/10_nvidia.json /usr/share/glvnd/egl_vendor.d/10_nvidia.json
+
+### Setup package rules
+COPY ./src/ubuntu/install/package_rules $INST_SCRIPTS/package_rules/
+RUN bash $INST_SCRIPTS/package_rules/package_rules.sh && rm -rf $INST_SCRIPTS/package_rules/
+
+### Install common tools
+COPY ./src/ubuntu/install/tools $INST_SCRIPTS/tools/
+RUN bash $INST_SCRIPTS/tools/install_tools.sh && rm -rf $INST_SCRIPTS/tools/
+
+### Copy over the maximization script to our startup dir for use by app images.
+COPY ./src/ubuntu/install/maximize_script $STARTUPDIR/
+
+### Install custom fonts
+COPY ./src/ubuntu/install/fonts $INST_SCRIPTS/fonts/
+RUN bash $INST_SCRIPTS/fonts/install_custom_fonts.sh && rm -rf $INST_SCRIPTS/fonts/
+
+### Install KDE
+COPY ./src/ubuntu/install/kde $INST_SCRIPTS/kde/
+RUN bash $INST_SCRIPTS/kde/install_kde.sh && rm -rf $INST_SCRIPTS/kde/
+COPY ./src/ubuntu/install/kde/desktop_environment_policy.sh $STARTUPDIR/
+COPY ./src/ubuntu/install/kde/auto_start.desktop $HOME/.config/autostart/apply_policy.desktop
+
+### Install kasm_vnc dependencies and binaries
+COPY ./src/ubuntu/install/kasm_vnc $INST_SCRIPTS/kasm_vnc/
+RUN bash $INST_SCRIPTS/kasm_vnc/install_kasm_vnc.sh && rm -rf $INST_SCRIPTS/kasm_vnc/
+COPY ./src/common/install/kasm_vnc/kasmvnc.yaml /etc/kasmvnc/
+
+### Install Kasm Profile Sync
+COPY ./src/ubuntu/install/profile_sync $INST_SCRIPTS/profile_sync/
+RUN bash $INST_SCRIPTS/profile_sync/install_profile_sync.sh
+
+### Install Kasm Upload Server
+COPY ./src/ubuntu/install/kasm_upload_server $INST_SCRIPTS/kasm_upload_server/
+RUN bash $INST_SCRIPTS/kasm_upload_server/install_kasm_upload_server.sh && rm -rf $INST_SCRIPTS/kasm_upload_server/
+
+### Install Audio
+COPY ./src/ubuntu/install/audio $INST_SCRIPTS/audio/
+RUN bash $INST_SCRIPTS/audio/install_audio.sh && rm -rf $INST_SCRIPTS/audio/
+
+### Install Audio Input
+COPY ./src/ubuntu/install/audio_input $INST_SCRIPTS/audio_input/
+RUN bash $INST_SCRIPTS/audio_input/install_audio_input.sh && rm -rf $INST_SCRIPTS/audio_input/
+
+### Install Gamepad Service
+COPY ./src/ubuntu/install/gamepad $INST_SCRIPTS/gamepad/
+RUN bash $INST_SCRIPTS/gamepad/install_gamepad.sh && rm -rf $INST_SCRIPTS/gamepad/
+
+### Install Webcam Service
+COPY ./src/ubuntu/install/webcam $INST_SCRIPTS/webcam/
+RUN bash $INST_SCRIPTS/webcam/install_webcam.sh && rm -rf $INST_SCRIPTS/webcam/
+
+### Install Printer
+COPY ./src/ubuntu/install/printer $INST_SCRIPTS/printer/
+COPY ./src/ubuntu/install/printer/start_cups.sh /etc/cups/start_cups.sh
+RUN bash $INST_SCRIPTS/printer/install_printer.sh && rm -rf $INST_SCRIPTS/printer
+COPY ./src/ubuntu/install/printer/resources/*.ppd /etc/cups/ppd/
+
+### Install custom cursors
+COPY ./src/ubuntu/install/cursors $INST_SCRIPTS/cursors/
+RUN bash $INST_SCRIPTS/cursors/install_cursors.sh && rm -rf $INST_SCRIPTS/cursors/
+
+### Install Squid
+COPY ./src/ubuntu/install/squid/install/ $INST_SCRIPTS/squid_install/
+RUN bash $INST_SCRIPTS/squid_install/install_squid.sh && rm -rf $INST_SCRIPTS/squid_install/
+COPY ./src/ubuntu/install/squid/resources/*.conf /etc/squid/
+COPY ./src/ubuntu/install/squid/resources/start_squid.sh /etc/squid/start_squid.sh
+COPY ./src/ubuntu/install/squid/resources/SN.png /usr/local/squid/share/icons/SN.png
+RUN chown proxy:proxy /usr/local/squid/share/icons/SN.png
+COPY ./src/ubuntu/install/squid/resources/error_message/access_denied.html /usr/local/squid/share/errors/en/ERR_ACCESS_DENIED
+RUN chown proxy:proxy /usr/local/squid/share/errors/en/ERR_ACCESS_DENIED
+RUN rm -rf $INST_SCRIPTS/resources/
+RUN chmod +x /etc/squid/kasm_squid_adapter
+RUN chmod +x /etc/squid/start_squid.sh && chmod 4755 /etc/squid/start_squid.sh
+
+### configure startup
+COPY ./src/common/scripts/kasm_hook_scripts $STARTUPDIR
+ADD ./src/common/startup_scripts $STARTUPDIR
+RUN bash $STARTUPDIR/set_user_permission.sh $STARTUPDIR $HOME && \
+ echo 'source $STARTUPDIR/generate_container_user' >> $HOME/.bashrc
+
+### VirtualGL
+COPY ./src/ubuntu/install/virtualgl $INST_SCRIPTS/virtualgl/
+RUN bash $INST_SCRIPTS/virtualgl/install_virtualgl.sh && rm -rf $INST_SCRIPTS/virtualgl/
+
+### Sysbox support
+COPY ./src/ubuntu/install/sysbox $INST_SCRIPTS/sysbox/
+RUN bash $INST_SCRIPTS/sysbox/install_systemd.sh && rm -rf $INST_SCRIPTS/sysbox/
+
+## Apply KDE theme
+COPY ./kasm-desktop-kde/src /tmp/theme-src
+RUN /tmp/theme-src/install-theme
+COPY ./kasm-desktop-kde/kde-config/.config $HOME/.config
+COPY ./kasm-desktop-kde/kde-config/.local/share/plasma $HOME/.local/share/plasma
+
+## Base Apps
+COPY ./src/kasmos/install/baseapps/ $INST_SCRIPTS/baseapps/
+RUN bash $INST_SCRIPTS/baseapps/install_baseapps.sh \
+ && cp $INST_SCRIPTS/baseapps/*.desktop /usr/share/applications/ \
+ && cp $INST_SCRIPTS/baseapps/notify-send /usr/bin/ \
+ && rm -rf $INST_SCRIPTS/baseapps/
+
+### Create user and home directory for base images that don't already define it
+RUN (groupadd -g 1000 kasm-user \
+ && useradd -M -u 1000 -g 1000 -s /bin/bash kasm-user \
+ && usermod -a -G kasm-user kasm-user) ; exit 0
+ENV HOME=/home/kasm-user
+WORKDIR $HOME
+RUN mkdir -p $HOME && chown -R 1000:0 $HOME
+
+### FIX PERMISSIONS ## Objective is to change the owner of non-home paths to root, remove write permissions, and set execute where required
+# these files are created on container first exec, by the default user, so we have to create them since default will not have write perm
+RUN touch $STARTUPDIR/wm.log \
+ && touch $STARTUPDIR/window_manager_startup.log \
+ && touch $STARTUPDIR/vnc_startup.log \
+ && touch $STARTUPDIR/no_vnc_startup.log \
+ && chown -R root:root $STARTUPDIR \
+ && find $STARTUPDIR -type d -exec chmod 755 {} \; \
+ && find $STARTUPDIR -type f -exec chmod 644 {} \; \
+ && find $STARTUPDIR -type f -iname "*.sh" -exec chmod 755 {} \; \
+ && find $STARTUPDIR -type f -iname "*.py" -exec chmod 755 {} \; \
+ && find $STARTUPDIR -type f -iname "*.rb" -exec chmod 755 {} \; \
+ && find $STARTUPDIR -type f -iname "*.pl" -exec chmod 755 {} \; \
+ && find $STARTUPDIR -type f -iname "*.log" -exec chmod 666 {} \; \
+ && chmod 755 $STARTUPDIR/upload_server/kasm_upload_server \
+ && chmod 755 $STARTUPDIR/audio_input/kasm_audio_input_server \
+ && chmod 755 $STARTUPDIR/gamepad/kasm_gamepad_server \
+ && chmod 755 $STARTUPDIR/webcam/kasm_webcam_server \
+ && chmod 755 $STARTUPDIR/printer/kasm_printer_service \
+ && chmod 755 $STARTUPDIR/generate_container_user \
+ && chmod +x $STARTUPDIR/jsmpeg/kasm_audio_out-linux \
+ && rm -rf $STARTUPDIR/install \
+ && mkdir -p $STARTUPDIR/kasmrx/Downloads \
+ && chown 1000:1000 $STARTUPDIR/kasmrx/Downloads \
+ && chown -R root:root /usr/local/bin \
+ && chown 1000:root /var/run/pulse \
+ && rm -Rf /home/kasm-default-profile/.launchpadlib
+
+### Cleanup job
+COPY ./src/ubuntu/install/cleanup $INST_SCRIPTS/cleanup/
+RUN bash $INST_SCRIPTS/cleanup/cleanup.sh kasmos && rm -rf $INST_SCRIPTS/cleanup/
+
+#### Runtime Stage ####
+FROM scratch
+COPY --from=base_layer / /
+
+### Labels
+LABEL "org.opencontainers.image.authors"='Kasm Tech "info@kasmweb.com"'
+LABEL "com.kasmweb.image"="true"
+LABEL "com.kasmweb.gpu_acceleration_egl"="nvidia"
+
+### Environment config
+ARG DISTRO=debian
+ARG LANG='en_US.UTF-8'
+ARG LANGUAGE='en_US:en'
+ARG LC_ALL='en_US.UTF-8'
+ARG START_PULSEAUDIO=1
+ARG START_DE=kde5
+ARG TZ='Etc/UTC'
+ENV AUDIO_PORT=4901 \
+ DEBIAN_FRONTEND=noninteractive \
+ DISPLAY=:1 \
+ DISTRO=$DISTRO \
+ GOMP_SPINCOUNT=0 \
+ HOME=/home/kasm-user \
+ INST_SCRIPTS=/dockerstartup/install \
+ KASMVNC_AUTO_RECOVER=true \
+ KASM_VNC_PATH=/usr/share/kasmvnc \
+ LANG=$LANG \
+ LANGUAGE=$LANGUAGE \
+ LC_ALL=$LC_ALL \
+ LD_LIBRARY_PATH=/opt/libjpeg-turbo/lib64/:/usr/local/lib/ \
+ LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}:/usr/local/nvidia/lib:/usr/local/nvidia/lib64 \
+ MAX_FRAME_RATE=24 \
+ NO_VNC_PORT=6901 \
+ NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics,compat32,utility \
+ OMP_WAIT_POLICY=PASSIVE \
+ PULSE_RUNTIME_PATH=/var/run/pulse \
+ SDL_GAMECONTROLLERCONFIG="030000005e040000be02000014010000,XInput Controller,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b16,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" \
+ SHELL=/bin/bash \
+ START_PULSEAUDIO=$START_PULSEAUDIO \
+ STARTUPDIR=/dockerstartup \
+ START_DE=$START_DE \
+ TERM=xterm \
+ VNC_COL_DEPTH=24 \
+ VNCOPTIONS="-PreferBandwidth -DynamicQualityMin=4 -DynamicQualityMax=7 -DLP_ClipDelay=0" \
+ VNC_PORT=5901 \
+ VNC_PORT=5901 \
+ VNC_PW=vncpassword \
+ VNC_RESOLUTION=1280x1024 \
+ VNC_RESOLUTION=1280x720 \
+ VNC_VIEW_ONLY_PW=vncviewonlypassword \
+ TZ=$TZ
+
+### Ports and user
+EXPOSE $VNC_PORT \
+ $NO_VNC_PORT \
+ $UPLOAD_PORT \
+ $AUDIO_PORT
+WORKDIR $HOME
+USER 1000
+
+ENTRYPOINT ["/dockerstartup/kasm_default_profile.sh", "/dockerstartup/vnc_startup.sh", "/dockerstartup/kasm_startup.sh"]
+CMD ["--wait"]
diff --git a/docs/core-kasmos/README.md b/docs/core-kasmos/README.md
new file mode 100644
index 0000000..70b49bb
--- /dev/null
+++ b/docs/core-kasmos/README.md
@@ -0,0 +1,7 @@
+# About This Image
+
+This image contains a browser-accessible version of KasmOS.
+
+![Screenshot][Image_Screenshot]
+
+[Image_Screenshot]: https://5856039.fs1.hubspotusercontent-na1.net/hubfs/5856039/dockerhub/image-screenshots/core-kasmos.png "Image Screenshot"
diff --git a/docs/core-kasmos/demo.txt b/docs/core-kasmos/demo.txt
new file mode 100644
index 0000000..47aa17e
--- /dev/null
+++ b/docs/core-kasmos/demo.txt
@@ -0,0 +1,9 @@
+# Live Demo
+
+**Launch a real-time demo in a new browser window:** Live Demo.
+
+
+
+∗*This demo links to a KasmOS Desktop image to show the basic functionality of Kasm Workspaces.*
+
+∗*Note: Demo is limited to 3 minutes and has upload/downloads restricted for security purposes.*
diff --git a/docs/core-kasmos/description.txt b/docs/core-kasmos/description.txt
new file mode 100644
index 0000000..8ee675a
--- /dev/null
+++ b/docs/core-kasmos/description.txt
@@ -0,0 +1 @@
+KasmOS base image for Kasm Workspaces
diff --git a/kasm-desktop-kde b/kasm-desktop-kde
new file mode 160000
index 0000000..44b1b9a
--- /dev/null
+++ b/kasm-desktop-kde
@@ -0,0 +1 @@
+Subproject commit 44b1b9a5c00f111575e93c64f8674cc33c4eb805
diff --git a/src/common/startup_scripts/vnc_startup.sh b/src/common/startup_scripts/vnc_startup.sh
index d59fc18..016fb3f 100755
--- a/src/common/startup_scripts/vnc_startup.sh
+++ b/src/common/startup_scripts/vnc_startup.sh
@@ -29,6 +29,9 @@ if [ "${LC_ALL}" != "en_US.UTF-8" ]; then
export LANGUAGE=${LC_ALL}
fi
+# Dbus
+export $(dbus-launch)
+
# dict to store processes
declare -A KASM_PROCS
@@ -190,24 +193,39 @@ function start_kasmvnc (){
}
function start_window_manager (){
- log "Starting Window Manager"
-
- if [ "${START_XFCE4}" == "1" ] ; then
+ echo -e "\n------------------ Xfce4 window manager startup------------------"
+ if [ "${START_XFCE4}" == "1" ] || [ "${START_DE}" == "xfce4-session" ]; then
if [ -f /opt/VirtualGL/bin/vglrun ] && [ ! -z "${KASM_EGL_CARD}" ] && [ ! -z "${KASM_RENDERD}" ] && [ -O "${KASM_RENDERD}" ] && [ -O "${KASM_EGL_CARD}" ] ; then
echo "Starting XFCE with VirtualGL using EGL device ${KASM_EGL_CARD}"
DISPLAY=:1 /opt/VirtualGL/bin/vglrun -d "${KASM_EGL_CARD}" /usr/bin/startxfce4 --replace &
else
echo "Starting XFCE"
- if [ -f '/usr/bin/zypper' ]; then
- DISPLAY=:1 /usr/bin/dbus-launch /usr/bin/startxfce4 --replace &
- else
- /usr/bin/startxfce4 --replace &
- fi
+ DISPLAY=:1 /usr/bin/startxfce4 --replace &
fi
KASM_PROCS['window_manager']=$!
else
echo "Skipping XFCE Startup"
fi
+ echo -e "\n------------------ Openbox window manager startup------------------"
+ if [ "${START_DE}" == "openbox" ] ; then
+ /usr/bin/openbox-session &
+ KASM_PROCS['window_manager']=$!
+ else
+ echo "Skipping OpenBox Startup"
+ fi
+ echo -e "\n------------------ KDE window manager startup------------------"
+ if [ "${START_DE}" == "kde5" ] ; then
+ if [ -f /opt/VirtualGL/bin/vglrun ] && [ ! -z "${KASM_EGL_CARD}" ] && [ ! -z "${KASM_RENDERD}" ] && [ -O "${KASM_RENDERD}" ] && [ -O "${KASM_EGL_CARD}" ] ; then
+ echo "Starting KDE with VirtualGL using EGL device ${KASM_EGL_CARD}"
+ DISPLAY=:1 /opt/VirtualGL/bin/vglrun -d "${KASM_EGL_CARD}" /usr/bin/startplasma-x11 &
+ else
+ echo "Starting KDE"
+ DISPLAY=:1 /usr/bin/startplasma-x11 &
+ fi
+ KASM_PROCS['window_manager']=$!
+ else
+ echo "Skipping KDE Startup"
+ fi
}
function start_audio_out_websocket (){
@@ -517,7 +535,7 @@ do
# TODO: This will only work if both processes are killed, requires more work
start_upload
;;
- kasm_gamepad)
+ kasm_gamepad)
echo "Gamepad Service Failed"
# TODO: Needs work in python project to support auto restart
# start_gamepad
diff --git a/src/kasmos/install/baseapps/browser.desktop b/src/kasmos/install/baseapps/browser.desktop
new file mode 100644
index 0000000..c617642
--- /dev/null
+++ b/src/kasmos/install/baseapps/browser.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Version=1.0
+Name=Chromium Web Browser
+Exec=kdialog --msgbox "A default internet browser is not installed."
+Terminal=false
+X-MultipleArgs=false
+Type=Application
+Icon=chromium
+Categories=Network;WebBrowser;
+MimeType=text/html;text/xml;application/xhtml_xml;application/x-mimearchive;x-scheme-handler/http;x-scheme-handler/https;
+StartupWMClass=chromium
+StartupNotify=true
+Keywords=browser
\ No newline at end of file
diff --git a/src/kasmos/install/baseapps/docs-editor.desktop b/src/kasmos/install/baseapps/docs-editor.desktop
new file mode 100644
index 0000000..bee0e5d
--- /dev/null
+++ b/src/kasmos/install/baseapps/docs-editor.desktop
@@ -0,0 +1,21 @@
+[Desktop Entry]
+Version=1.0
+Name=Docs
+GenericName=Document Editor
+Comment=Document Editor
+Type=Application
+Exec=kdialog --msgbox "A default document editing program is not installed."
+Terminal=false
+Icon=application-msword
+Keywords=Text;Document;OpenDocument Text;Microsoft Word;Microsoft Works;odt;doc;docx;rtf;
+Categories=Office;WordProcessor;Spreadsheet;
+MimeType=application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-template;application/vnd.oasis.opendocument.text-web;application/vnd.oasis.opendocument.text-master;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.template;application/vnd.sun.xml.writer.global;application/msword;application/vnd.ms-word;application/x-doc;application/rtf;text/rtf;application/vnd.wordperfect;application/wordperfect;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.ms-word.document.macroenabled.12;application/vnd.openxmlformats-officedocument.wordprocessingml.template;application/vnd.ms-word.template.macroenabled.12;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/msexcel;application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-excel.sheet.macroenabled.12;application/vnd.openxmlformats-officedocument.spreadsheetml.template;application/vnd.ms-excel.template.macroenabled.12;application/vnd.ms-excel.sheet.binary.macroenabled.12;text/csv;text/spreadsheet;application/csv;application/excel;application/x-excel;application/x-msexcel;application/x-ms-excel;text/comma-separated-values;text/tab-separated-values;text/x-comma-separated-values;text/x-csv;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocument.presentation-template;application/vnd.sun.xml.impress;application/vnd.sun.xml.impress.template;application/mspowerpoint;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.ms-powerpoint.presentation.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/vnd.ms-powerpoint.slideshow.macroEnabled.12;x-scheme-handler/oo-office;text/docxf;text/oform;
+Actions=NewDocument;
+
+[Desktop Action NewDocument]
+Name=New Document
+Name[de]=Neues Dokument
+Name[fr]=Nouveau document
+Name[es]=Documento nuevo
+Name[ru]=Создать документ
+Exec=/usr/bin/onlyoffice-desktopeditors --new:word
diff --git a/src/kasmos/install/baseapps/install_baseapps.sh b/src/kasmos/install/baseapps/install_baseapps.sh
new file mode 100644
index 0000000..dc0bf4c
--- /dev/null
+++ b/src/kasmos/install/baseapps/install_baseapps.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# Remove unneeded apps
+apt remove -y libnotify4
+
+# Remove menu shortcuts for stuff we don't care to show the user, but don't want to uninstall
+rm /usr/share/applications/vim.desktop
+rm /usr/share/applications/org.kde.plasma.emojier.desktop
+rm /usr/share/applications/kvantummanager.desktop
+
+# Rename the title of some applications
+sed -i 's#Name=KFind#Name=Find#' /usr/share/applications/org.kde.kfind.desktop
+sed -r -i 's#Name(\[\w+\])?=gedit#Name\1=Editor#g' /usr/share/applications/org.gnome.gedit.desktop
+
+# Download Base Elementory applications compiled by Kasm
+# https://kasmweb-build-artifacts.s3.amazonaws.com/kasm_desktop_apps/66826216f0024f5455d18d241dc3e44adbf2c41c/calculator_2.0.3-1_amd64.deb
+BASEURL="https://kasmweb-build-artifacts.s3.amazonaws.com/kasm_desktop_apps"
+COMMITID="3c732e03a9e755aaa1b69f3d56a69964ddf8b8d5"
+ARCH=$(arch | sed 's/aarch64/arm64/g' | sed 's/x86_64/amd64/g')
+
+
+APPS=("calculator_2.0.3-1" "calendar_7.0.0-1" "camera_6.2.2-1" "music_7.0.0-1" "terminal_6.1.2-1" "filemanager_6.5.3-1")
+
+cd $INST_SCRIPTS/baseapps/
+for app in ${APPS[@]}; do
+ wget "${BASEURL}/${COMMITID}/${app}_${ARCH}.deb"
+ apt install -y ./${app}_${ARCH}.deb
+done
+
+# Install base apt apps
+apt update
+apt install -y gedit evince shotwell mpv
+
+# Hide stuff in the menu that we don't want there
+rm -f /usr/share/applications/vim.desktop
+rm -f /usr/share/applications/org.kde.plasma.emojier.desktop
+rm -f /usr/share/applications/kvantummanager.desktop
+
+# Add Custom icons
+cp $INST_SCRIPTS/baseapps/videos.svg /usr/share/icons/hicolor/scalable/apps/
+
+# Customize desktop menu shortcuts
+sed -i 's#Name=KFind#Name=Find#' /usr/share/applications/org.kde.kfind.desktop
+sed -r -i 's#Name(\[\w+\])?=gedit#Name\1=Editor#g' /usr/share/applications/org.gnome.gedit.desktop
+sed -r -i 's#Name(\[\w+\])?=[Ss]hotwell#Name\1=Photos#g' /usr/share/applications/shotwell.desktop
+sed -r -i 's#Icon=.+#Icon=videos#' /usr/share/applications/mpv.desktop
+sed -r -i 's#Name(\[\w+\])?=.+#Name\1=Videos#g' /usr/share/applications/mpv.desktop
+sed -r -i 's#Categories=.+#Categories=System;#' /usr/share/applications/org.kde.kdeconnect.app.desktop
+sed -r -i 's#Categories=.+#Categories=System;#' /usr/share/applications/org.kde.kdeconnect.sms.desktop
+sed -r -i 's#Categories=.+#Categories=System;#' /usr/share/applications/org.kde.kdeconnect_open.desktop
diff --git a/src/kasmos/install/baseapps/notify-send b/src/kasmos/install/baseapps/notify-send
new file mode 100755
index 0000000..1f4114f
--- /dev/null
+++ b/src/kasmos/install/baseapps/notify-send
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+TIMEOUT=
+ICON="/usr/share/icons/Papirus-Dark/24x24/actions/dialog-information.svg"
+TITLE=
+MESSAGE=
+LASTARG=
+
+for var in "$@"
+do
+ if [[ "$var" == -* ]] ; then
+ LASTARG="$var"
+ else
+ if [ -z "$LASTARG" ] ; then
+ if [ -z "$TITLE" ] ; then
+ TITLE="$var"
+ else
+ MESSAGE="$var "
+ fi
+ else
+ case $LASTARG in
+ -t)
+ TIMEOUT=$var
+ ;;
+ -i)
+ ICON=$var
+ ;;
+ esac
+ fi
+ fi
+done
+
+kdialog --passivepopup "$MESSAGE" --icon "$ICON" --title "$TITLE" $TIMEOUT &
\ No newline at end of file
diff --git a/src/kasmos/install/baseapps/present-editor.desktop b/src/kasmos/install/baseapps/present-editor.desktop
new file mode 100644
index 0000000..87d83b4
--- /dev/null
+++ b/src/kasmos/install/baseapps/present-editor.desktop
@@ -0,0 +1,21 @@
+[Desktop Entry]
+Version=1.0
+Name=Slides
+GenericName=Slide Deck Editor
+Comment=Slide Deck Editor
+Type=Application
+Exec=kdialog --msgbox "A default presentation editing program is not installed."
+Terminal=false
+Icon=application-mspowerpoint
+Keywords=Text;Document;OpenDocument Text;Microsoft Word;Microsoft Works;odt;doc;docx;rtf;
+Categories=Office;
+MimeType=application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-template;application/vnd.oasis.opendocument.text-web;application/vnd.oasis.opendocument.text-master;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.template;application/vnd.sun.xml.writer.global;application/msword;application/vnd.ms-word;application/x-doc;application/rtf;text/rtf;application/vnd.wordperfect;application/wordperfect;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.ms-word.document.macroenabled.12;application/vnd.openxmlformats-officedocument.wordprocessingml.template;application/vnd.ms-word.template.macroenabled.12;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/msexcel;application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-excel.sheet.macroenabled.12;application/vnd.openxmlformats-officedocument.spreadsheetml.template;application/vnd.ms-excel.template.macroenabled.12;application/vnd.ms-excel.sheet.binary.macroenabled.12;text/csv;text/spreadsheet;application/csv;application/excel;application/x-excel;application/x-msexcel;application/x-ms-excel;text/comma-separated-values;text/tab-separated-values;text/x-comma-separated-values;text/x-csv;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocument.presentation-template;application/vnd.sun.xml.impress;application/vnd.sun.xml.impress.template;application/mspowerpoint;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.ms-powerpoint.presentation.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/vnd.ms-powerpoint.slideshow.macroEnabled.12;x-scheme-handler/oo-office;text/docxf;text/oform;
+Actions=NewPresentation;
+
+[Desktop Action NewPresentation]
+Name=New Presentation
+Name[de]=Neue Präsentation
+Name[fr]=Nouvelle présentation
+Name[es]=Presentación nueva
+Name[ru]=Создать презентацию
+Exec=/usr/bin/onlyoffice-desktopeditors --new:slide
diff --git a/src/kasmos/install/baseapps/sheets-editor.desktop b/src/kasmos/install/baseapps/sheets-editor.desktop
new file mode 100644
index 0000000..0f29118
--- /dev/null
+++ b/src/kasmos/install/baseapps/sheets-editor.desktop
@@ -0,0 +1,21 @@
+[Desktop Entry]
+Version=1.0
+Name=Sheets
+GenericName=Spreadsheet Editor
+Comment=Spreadsheet Editor
+Type=Application
+Exec=kdialog --msgbox "A default spreadsheet editing program is not installed."
+Terminal=false
+Icon=application-x-excel
+Keywords=Text;Document;OpenDocument Text;Microsoft Word;Microsoft Works;odt;doc;docx;rtf;
+Categories=Office;WordProcessor;Spreadsheet;
+MimeType=application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-template;application/vnd.oasis.opendocument.text-web;application/vnd.oasis.opendocument.text-master;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.template;application/vnd.sun.xml.writer.global;application/msword;application/vnd.ms-word;application/x-doc;application/rtf;text/rtf;application/vnd.wordperfect;application/wordperfect;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.ms-word.document.macroenabled.12;application/vnd.openxmlformats-officedocument.wordprocessingml.template;application/vnd.ms-word.template.macroenabled.12;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/msexcel;application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-excel.sheet.macroenabled.12;application/vnd.openxmlformats-officedocument.spreadsheetml.template;application/vnd.ms-excel.template.macroenabled.12;application/vnd.ms-excel.sheet.binary.macroenabled.12;text/csv;text/spreadsheet;application/csv;application/excel;application/x-excel;application/x-msexcel;application/x-ms-excel;text/comma-separated-values;text/tab-separated-values;text/x-comma-separated-values;text/x-csv;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocument.presentation-template;application/vnd.sun.xml.impress;application/vnd.sun.xml.impress.template;application/mspowerpoint;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.ms-powerpoint.presentation.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.template;application/vnd.ms-powerpoint.template.macroenabled.12;application/vnd.openxmlformats-officedocument.presentationml.slide;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/vnd.ms-powerpoint.slideshow.macroEnabled.12;x-scheme-handler/oo-office;text/docxf;text/oform;
+Actions=NewSpreadsheet;
+
+[Desktop Action NewSpreadsheet]
+Name=New Spreadsheet
+Name[de]=Neues Tabellendokument
+Name[fr]=Nouveau classeur
+Name[es]=Hoja de cálculo nueva
+Name[ru]=Создать эл.таблицу
+Exec=/usr/bin/onlyoffice-desktopeditors --new:cell
diff --git a/src/kasmos/install/baseapps/videos.svg b/src/kasmos/install/baseapps/videos.svg
new file mode 100644
index 0000000..9e00650
--- /dev/null
+++ b/src/kasmos/install/baseapps/videos.svg
@@ -0,0 +1,364 @@
+
+
diff --git a/src/ubuntu/install/audio/install_audio.sh b/src/ubuntu/install/audio/install_audio.sh
index 8b8a4a0..1d5ea9f 100644
--- a/src/ubuntu/install/audio/install_audio.sh
+++ b/src/ubuntu/install/audio/install_audio.sh
@@ -58,7 +58,12 @@ elif [ "${DISTRO}" == "alpine" ]; then
fi
else
apt-get update
- apt-get install -y curl git ffmpeg
+ apt-get install -y \
+ curl \
+ ffmpeg \
+ git \
+ pulseaudio \
+ pulseaudio-utils
fi
mkdir -p /var/run/pulse
diff --git a/src/ubuntu/install/cleanup/cleanup.sh b/src/ubuntu/install/cleanup/cleanup.sh
index 422040d..dae6ab3 100644
--- a/src/ubuntu/install/cleanup/cleanup.sh
+++ b/src/ubuntu/install/cleanup/cleanup.sh
@@ -62,3 +62,19 @@ rm -f \
/etc/xdg/autostart/xfce4-screensaver.desktop \
/etc/xdg/autostart/xfce-polkit.desktop \
/etc/xdg/autostart/xscreensaver.desktop
+
+# Cleanup specific to KasmOS
+if [ "$1" = "kasmos" ] ; then
+ echo "Removing packages from base"
+ packages=("konsole" "geeqie" "gwenview" "imagemagick-6.q16" "kate" "dolphin")
+ for package in ${packages[@]}; do
+ if [[ $(apt -qq list "$package") ]] ; then
+ echo "Removing package $package."
+ apt remove -y ${package}
+ else
+ echo "Package ${package} not found."
+ fi
+ done
+ apt autoremove -y
+
+fi
diff --git a/src/ubuntu/install/kde/auto_start.desktop b/src/ubuntu/install/kde/auto_start.desktop
new file mode 100644
index 0000000..4cb37b8
--- /dev/null
+++ b/src/ubuntu/install/kde/auto_start.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+Comment[en_US]=
+Comment=
+Exec=/dockerstartup/desktop_environment_policy.sh
+GenericName[en_US]=
+GenericName=
+Icon=dialog-scripts
+MimeType=
+Name[en_US]=Unlock KeePassXC database
+Name=Unlock KeePassXC database
+Path=
+StartupNotify=true
+Terminal=false
+TerminalOptions=
+Type=Application
+X-DBUS-ServiceName=
+X-DBUS-StartupType=
+X-KDE-AutostartScript=true
+X-KDE-SubstituteUID=false
+X-KDE-Username=
\ No newline at end of file
diff --git a/src/ubuntu/install/kde/desktop_environment_policy.sh b/src/ubuntu/install/kde/desktop_environment_policy.sh
new file mode 100644
index 0000000..fc581b0
--- /dev/null
+++ b/src/ubuntu/install/kde/desktop_environment_policy.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# TODO: Find explicit way to determine that KDE is ready
+sleep 5
+
+# Disable screen lock
+kwriteconfig5 --file kscreenlockerrc --group Daemon --key Autolock false
+qdbus org.freedesktop.ScreenSaver /ScreenSaver configure
diff --git a/src/ubuntu/install/kde/install_kde.sh b/src/ubuntu/install/kde/install_kde.sh
new file mode 100644
index 0000000..5e29bb5
--- /dev/null
+++ b/src/ubuntu/install/kde/install_kde.sh
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+### every exit != 0 fails the script
+set -e
+
+disable_epel_nss_wrapper_that_breaks_firefox() {
+ yum-config-manager --setopt=epel.exclude=nss_wrapper --save
+}
+
+replace_default_xinit() {
+
+ mkdir -p /etc/X11/xinit
+ cat >/etc/X11/xinit/xinitrc </etc/X11/Xsession.d/99x11-common_start <> /etc/locale.gen
+ locale-gen
+elif [[ "${DISTRO}" == @(centos|oracle7) ]]; then
+ if [ "${DISTRO}" == centos ]; then
+ yum install -y epel-release
+ else
+ yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+ fi
+ disable_epel_nss_wrapper_that_breaks_firefox
+ yum install -y \
+ curl \
+ wmctrl \
+ xclip \
+ xset
+elif [ "$DISTRO" = "oracle8" ]; then
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+ dnf install -y \
+ curl \
+ wmctrl \
+ xclip \
+ xset
+elif [ "$DISTRO" = "oracle9" ]; then
+ dnf config-manager --set-enabled ol9_codeready_builder
+ dnf config-manager --set-enabled ol9_distro_builder
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ wmctrl \
+ xclip \
+ xset
+elif [[ "$DISTRO" == @(rockylinux9|almalinux9) ]]; then
+ dnf config-manager --set-enabled crb
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ gvfs \
+ wmctrl \
+ xclip \
+ xset
+elif [[ "$DISTRO" == @(rockylinux8|almalinux8) ]]; then
+ dnf config-manager --set-enabled powertools
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ gvfs \
+ wmctrl \
+ xclip \
+ xset
+elif [ "$DISTRO" = "opensuse" ]; then
+ zypper install -yn \
+ curl \
+ gvfs \
+ xclip \
+ xset
+elif [[ "$DISTRO" = @(fedora37|fedora38) ]]; then
+ dnf install -y \
+ curl \
+ gvfs \
+ wmctrl \
+ xclip \
+ xset
+elif [ "$DISTRO" = "alpine" ]; then
+ apk add --no-cache \
+ curl \
+ dbus-x11 \
+ gvfs \
+ mesa \
+ mesa-dri-gallium \
+ mesa-gl
+fi
+
+if [[ "${DISTRO}" != @(centos|oracle7|oracle8|fedora37|fedora38|oracle9|rockylinux9|rockylinux8|almalinux8|almalinux9|alpine) ]]; then
+ replace_default_xinit
+ if [ "${START_XFCE4}" == "1" ] ; then
+ replace_default_99x11_common_start
+ fi
+fi
+
+cat >/usr/bin/desktop_ready <>/etc/xdg/autostart/desktop-icons.desktop</etc/X11/xinit/xinitrc </etc/X11/Xsession.d/99x11-common_start <> /etc/locale.gen
+ locale-gen
+elif [[ "${DISTRO}" == @(centos|oracle7) ]]; then
+ if [ "${DISTRO}" == centos ]; then
+ yum install -y epel-release
+ else
+ yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+ fi
+ disable_epel_nss_wrapper_that_breaks_firefox
+ yum install -y \
+ curl \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [ "$DISTRO" = "oracle8" ]; then
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+ dnf install -y \
+ curl \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [ "$DISTRO" = "oracle9" ]; then
+ dnf config-manager --set-enabled ol9_codeready_builder
+ dnf config-manager --set-enabled ol9_distro_builder
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [[ "$DISTRO" == @(rockylinux9|almalinux9) ]]; then
+ dnf config-manager --set-enabled crb
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ gvfs \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [[ "$DISTRO" == @(rockylinux8|almalinux8) ]]; then
+ dnf config-manager --set-enabled powertools
+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+ dnf install -y \
+ curl \
+ dbus-x11 \
+ gvfs \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [ "$DISTRO" = "opensuse" ]; then
+ zypper install -yn \
+ curl \
+ gvfs \
+ openbox \
+ xclip \
+ xset \
+ xterm
+elif [[ "$DISTRO" = @(fedora37|fedora38) ]]; then
+ dnf install -y \
+ curl \
+ gvfs \
+ openbox \
+ wmctrl \
+ xclip \
+ xset \
+ xterm
+elif [ "$DISTRO" = "alpine" ]; then
+ apk add --no-cache \
+ curl \
+ dbus-x11 \
+ gvfs \
+ mesa \
+ mesa-dri-gallium \
+ mesa-gl \
+ openbox \
+ xterm
+fi
+
+if [[ "${DISTRO}" != @(centos|oracle7|oracle8|fedora37|fedora38|oracle9|rockylinux9|rockylinux8|almalinux8|almalinux9|alpine) ]]; then
+ replace_default_xinit
+ if [ "${START_XFCE4}" == "1" ] ; then
+ replace_default_99x11_common_start
+ fi
+fi
+
+cat >/usr/bin/desktop_ready <>/etc/xdg/autostart/desktop-icons.desktop</usr/bin/desktop_ready <