From df57846dfbb6612d54a20778f08784b40b78d02c Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Tue, 28 Mar 2023 18:33:59 -0600 Subject: [PATCH 1/2] cloud-init: preserve ephemeral cloud-init logs in target to aid in debug --- subiquity/server/controllers/shutdown.py | 12 + system_setup/ubuntu-wsl-setup | 373 ----------------------- 2 files changed, 12 insertions(+), 373 deletions(-) delete mode 100755 system_setup/ubuntu-wsl-setup diff --git a/subiquity/server/controllers/shutdown.py b/subiquity/server/controllers/shutdown.py index cd2c6396..c3360b68 100644 --- a/subiquity/server/controllers/shutdown.py +++ b/subiquity/server/controllers/shutdown.py @@ -100,6 +100,18 @@ class ShutdownController(SubiquityController): if self.opts.dry_run: os.makedirs(target_logs, exist_ok=True) else: + # Preserve ephemeral boot cloud-init logs if applicable + cloudinit_logs = [ + cloudinit_log + for cloudinit_log in ( + "/var/log/cloud-init.log", + "/var/log/cloud-init-output.log" + ) + if os.path.exists(cloudinit_log) + ] + if cloudinit_logs: + await arun_command( + ['cp', '-a'] + cloudinit_logs + ['/var/log/installer']) await arun_command( ['cp', '-aT', '/var/log/installer', target_logs]) # Close the permissions from group writes on the target. diff --git a/system_setup/ubuntu-wsl-setup b/system_setup/ubuntu-wsl-setup deleted file mode 100755 index 6fef384b..00000000 --- a/system_setup/ubuntu-wsl-setup +++ /dev/null @@ -1,373 +0,0 @@ -#!/bin/bash - -################# -# Launcher init # -################# - -START=$(date +%s.%N) - -function exit_if_not_wsl2() { - # WSLInterop ensures we are under WSL (either 1 or 2). - # config.gz ensures we have a kernel. WSL 1 does not have one. - # grep'ing /proc/version for 'WSL2' would work, but users can change that - # when compiling their own kernel. - if ! [[ -f "/proc/sys/fs/binfmt_misc/WSLInterop" && -f "/proc/config.gz" ]]; then - echo "WSL 2 not detected. Exiting." - exit 125 - fi -} - -# ensure_dir_exists calls `mkdir -p` if the given path is not a directory. -# This speeds up execution time by avoiding unnecessary calls to mkdir. -# -# Usage: ensure_dir_exists []... -# -function ensure_dir_exists() { - [ -d "$1" ] || mkdir -p "$@" -} - -declare -A PIDS -function async_exec() { - "$@" & - PIDS[$!]=$* -} -function wait_for_async_execs() { - for pid in "${!PIDS[@]}" - do - wait "$pid" && continue || echo "ERROR: ${PIDS[$pid]} exited abnormally with status $?" - done -} - -# Proceed only if in WSL 2: -exit_if_not_wsl2 - -# shellcheck source=/dev/null -source "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true -if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then - needs_update=false -else - needs_update=true -fi - -# Set $REALHOME to the users real home directory -REALHOME=$(getent passwd $UID | cut -d ':' -f 6) - -# Set config folder to local path -export XDG_CONFIG_HOME="$SNAP_USER_DATA/.config" -ensure_dir_exists "$XDG_CONFIG_HOME" -chmod 700 "$XDG_CONFIG_HOME" - -# If the user has modified their user-dirs settings, force an update -if [[ -f "$REALHOME/.config/user-dirs.dirs" ]]; then - if [[ -f "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" ]]; then - if [[ "$(md5sum < "$REALHOME/.config/user-dirs.dirs")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum")" || - ( -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" && - "$(md5sum < "$REALHOME/.config/user-dirs.locale")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.locale.md5sum")" ) ]]; then - needs_update=true - fi - else - # shellcheck disable=SC2034 - needs_update=true - fi -fi - -if [ "$SNAP_ARCH" = "amd64" ]; then - ARCH="x86_64-linux-gnu" -elif [ "$SNAP_ARCH" = "armhf" ]; then - ARCH="arm-linux-gnueabihf" -elif [ "$SNAP_ARCH" = "arm64" ]; then - ARCH="aarch64-linux-gnu" -elif [ "$SNAP_ARCH" = "ppc64el" ]; then - ARCH="powerpc64le-linux-gnu" -else - ARCH="$SNAP_ARCH-linux-gnu" -fi - -export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH" - -# Don't LD_PRELOAD bindtextdomain for classic snaps -if ! grep -qs "^\s*confinement:\s*classic\s*" "$SNAP/meta/snap.yaml"; then - if [ -f "$SNAP/gnome-platform/lib/$ARCH/bindtextdomain.so" ]; then - export LD_PRELOAD="$LD_PRELOAD:$SNAP/gnome-platform/\$LIB/bindtextdomain.so" - elif [ -f "$SNAP/lib/$ARCH/bindtextdomain.so" ]; then - export LD_PRELOAD="$LD_PRELOAD:$SNAP/\$LIB/bindtextdomain.so" - fi -fi - - -############################################### -# Launcher common exports for any desktop app # -############################################### - -# Note: We avoid using `eval` because we don't want to expand variable names -# in paths. For example: LD_LIBRARY_PATH paths might contain `$LIB`. -function prepend_dir() { - local -n var="$1" - local dir="$2" - # We can't check if the dir exists when the dir contains variables - if [[ "$dir" == *"\$"* || -d "$dir" ]]; then - export "${!var}=${dir}${var:+:$var}" - fi -} - -function append_dir() { - local -n var="$1" - local dir="$2" - # We can't check if the dir exists when the dir contains variables - if [[ "$dir" == *"\$"* || -d "$dir" ]]; then - export "${!var}=${var:+$var:}${dir}" - fi -} - -function can_open_file() { - [ -f "$1" ] && [ -r "$1" ] -} - -function update_xdg_dirs_values() { - local save_initial_values=false - local XDG_DIRS="DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES" - unset XDG_SPECIAL_DIRS_PATHS - - if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" ]; then - # shellcheck source=/dev/null - source "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" - fi - - if [ -z ${XDG_SPECIAL_DIRS+x} ]; then - save_initial_values=true - fi - - for d in $XDG_DIRS; do - var="XDG_${d}_DIR" - value="${!var}" - - if [ "$save_initial_values" = true ]; then - XDG_SPECIAL_DIRS+=("$var") - XDG_SPECIAL_DIRS_INITIAL_PATHS+=("$value") - fi - - XDG_SPECIAL_DIRS_PATHS+=("$value") - done -} - -function is_subpath() { - dir="$(realpath "$1")" - parent="$(realpath "$2")" - [ "${dir##$parent/}" != "$dir" ] && return 0 || return 1 -} - -append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib/$ARCH" -append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" -append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib" -append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib" -prepend_dir PATH "$SNAP_DESKTOP_RUNTIME/usr/bin" - -# XDG Config -prepend_dir XDG_CONFIG_DIRS "$SNAP_DESKTOP_RUNTIME/etc/xdg" -prepend_dir XDG_CONFIG_DIRS "$SNAP/etc/xdg" - -# Define snaps' own data dir -prepend_dir XDG_DATA_DIRS "$SNAP_DESKTOP_RUNTIME/usr/share" -prepend_dir XDG_DATA_DIRS "$SNAP/usr/share" -prepend_dir XDG_DATA_DIRS "$SNAP/share" -prepend_dir XDG_DATA_DIRS "$SNAP/data-dir" -prepend_dir XDG_DATA_DIRS "$SNAP_USER_DATA" - -# Set XDG_DATA_HOME to local path -export XDG_DATA_HOME="$SNAP_USER_DATA/.local/share" -ensure_dir_exists "$XDG_DATA_HOME" - -# Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME: -# https://bugzilla.gnome.org/show_bug.cgi?id=741335 -prepend_dir XDG_DATA_DIRS "$XDG_DATA_HOME" - -# Set cache folder to local path -export XDG_CACHE_HOME="$SNAP_USER_COMMON/.cache" -if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$XDG_CACHE_HOME" ]]; then - # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it - mv "$SNAP_USER_DATA/.cache" "$SNAP_USER_COMMON/" -fi -ensure_dir_exists "$XDG_CACHE_HOME" - -# Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed) -# shellcheck disable=SC2174 -ensure_dir_exists "$XDG_RUNTIME_DIR" -m 700 - -# Ensure the app finds locale definitions (requires locales-all to be installed) -append_dir LOCPATH "$SNAP_DESKTOP_RUNTIME/usr/lib/locale" - -# If any, keep track of where XDG dirs were so we can potentially migrate the content later -update_xdg_dirs_values - -# Setup user-dirs.* or run xdg-user-dirs-update if needed -needs_xdg_update=false -needs_xdg_reload=false -needs_xdg_links=false - -if [ "$HOME" != "$SNAP_USER_DATA" ] && ! is_subpath "$XDG_CONFIG_HOME" "$HOME"; then - for f in user-dirs.dirs user-dirs.locale; do - if [ -f "$HOME/.config/$f" ]; then - mv "$HOME/.config/$f" "$XDG_CONFIG_HOME" - needs_xdg_reload=true - fi - done -fi - -if can_open_file "$REALHOME/.config/user-dirs.dirs"; then - # shellcheck disable=SC2154 - if [ "$needs_update" = true ] || [ "$needs_xdg_reload" = true ]; then - sed "/^#/!s#\$HOME#${REALHOME}#g" "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs" - md5sum < "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" - # It's possible user-dirs.dirs exists when user-dirs.locale doesn't. This - # simply means the user opted to never ask to translate their user dirs - if can_open_file "$REALHOME/.config/user-dirs.locale"; then - cp -a "$REALHOME/.config/user-dirs.locale" "$XDG_CONFIG_HOME" - md5sum < "$REALHOME/.config/user-dirs.locale" > "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" - elif [ -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" ]; then - rm "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" - fi - needs_xdg_reload=true - fi -else - needs_xdg_update=true - needs_xdg_links=true -fi - -if [ $needs_xdg_reload = true ]; then - update_xdg_dirs_values - needs_xdg_reload=false -fi - -# Check if we can actually read the contents of each xdg dir -for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do - if ! can_open_file "${XDG_SPECIAL_DIRS_PATHS[$i]}"; then - needs_xdg_update=true - needs_xdg_links=true - break - fi -done - -# If needs XDG update and xdg-user-dirs-update exists in $PATH, run it -if [ "$needs_xdg_update" = true ] && command -v xdg-user-dirs-update >/dev/null; then - xdg-user-dirs-update - update_xdg_dirs_values -fi - -# Create links for user-dirs.dirs -if [ "$needs_xdg_links" = true ]; then - for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do - b="$(realpath "${XDG_SPECIAL_DIRS_PATHS[$i]}" --relative-to="$HOME" 2>/dev/null)" - if [[ -n "$b" && "$b" != "." && -e "$REALHOME/$b" ]]; then - [ -d "$HOME/$b" ] && rmdir "$HOME/$b" 2> /dev/null - [ ! -e "$HOME/$b" ] && ln -s "$REALHOME/$b" "$HOME/$b" - fi - done -else - # If we aren't creating new links, check if we have content saved in old locations and move it - for ((i = 0; i < ${#XDG_SPECIAL_DIRS[@]}; i++)); do - old="${XDG_SPECIAL_DIRS_INITIAL_PATHS[$i]}" - new="${XDG_SPECIAL_DIRS_PATHS[$i]}" - if [ -L "$old" ] && [ -d "$new" ] && [ "$(readlink "$old" 2>/dev/null)" != "$new" ] && - (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then - mv -vn "$old"/* "$new"/ 2>/dev/null - elif [ -d "$old" ] && [ -d "$new" ] && [ "$old" != "$new" ] && - (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then - mv -vn "$old"/* "$new"/ 2>/dev/null - fi - done -fi - -# Keep an array of data dirs, for looping through them -IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS" - -# Font Config and themes -export FONTCONFIG_PATH="$SNAP_DESKTOP_RUNTIME/etc/fonts" -export FONTCONFIG_FILE="$SNAP_DESKTOP_RUNTIME/etc/fonts/fonts.conf" - -function make_user_fontconfig { - echo "" - if [ -d "$REALHOME/.local/share/fonts" ]; then - echo " $REALHOME/.local/share/fonts" - fi - if [ -d "$REALHOME/.fonts" ]; then - echo " $REALHOME/.fonts" - fi - for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do - if [ -d "${data_dirs_array[$i]}/fonts" ]; then - echo " ${data_dirs_array[$i]}/fonts" - fi - done - # We need to include a user-writable cachedir first to support - # caching of per-user fonts. - echo ' fontconfig' - echo " $SNAP_COMMON/fontconfig" - echo "" -} - -if [ "$needs_update" = true ]; then - rm -rf "$XDG_DATA_HOME"/{fontconfig,fonts,fonts-*,themes,.themes} - - # This fontconfig fragment is installed in a location that is - # included by the system fontconfig configuration: namely the - # etc/fonts/conf.d/50-user.conf file. - ensure_dir_exists "$XDG_CONFIG_HOME/fontconfig" - async_exec make_user_fontconfig > "$XDG_CONFIG_HOME/fontconfig/fonts.conf" - - # the themes symlink are needed for GTK 3.18 when the prefix isn't changed - # GTK 3.20 looks into XDG_DATA_DIRS which has connected themes. - if [ -d "$SNAP/data-dir/themes" ]; then - ln -sf "$SNAP/data-dir/themes" "$XDG_DATA_HOME" - ln -sfn "$SNAP/data-dir/themes" "$SNAP_USER_DATA/.themes" - elif [ -d "$SNAP_DESKTOP_RUNTIME/usr/share/themes" ]; then - ln -sf "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$XDG_DATA_HOME" - ln -sfn "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$SNAP_USER_DATA/.themes" - fi -fi - -# Testability support -append_dir LD_LIBRARY_PATH "$SNAP/testability" -append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH" -append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH/mesa" - - -[ "$needs_update" = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision" - -wait_for_async_execs - -if [ -n "$SNAP_DESKTOP_DEBUG" ]; then - echo "desktop-launch elapsed time: $(date +%s.%N --date="$START seconds ago")" - echo "Now running: exec $*" -fi - -PATH="${SNAP}/usr/sbin:${SNAP}/usr/bin:${SNAP}/sbin:${SNAP}/bin" -PATH="${PATH}:${SNAP_CORE_DIR}/usr/sbin:${SNAP_CORE_DIR}/usr/bin:${SNAP_CORE_DIR}/sbin:${SNAP_CORE_DIR}/bin" - -# configure python environment -export PYTHONIOENCODING=utf-8 -PYTHONPATH=$SNAP/lib/python3.10/site-packages -PYTHONPATH=$SNAP/usr/lib/python3/site-packages:$PYTHONPATH -PYTHONPATH=$SNAP/usr/lib/python3/dist-packages:$PYTHONPATH -export PYTHONPATH -export PYTHON=$SNAP/usr/bin/python3.10 -export SNAP_PYTHON=$PYTHON -# ensure curtin points at PYTHON -export PY3OR2_PYTHON=$PYTHON -# base directory for subiquity to locate resources -export SUBIQUITY_ROOT=$SNAP - -BIN="$PYTHON -m system_setup.cmd.server" -args="" -for arg in $@; do - if [ ${arg} = "--server-only" ]; then - # Just eat that argument. It's useful for the GUI context only, - # since here the server only startup option is the default. - continue - fi - if [ ${arg} = "-t" -o ${arg} = "--text" ]; then - BIN="$PYTHON -m system_setup.cmd.tui" - continue - fi - args="$args $arg" -done - -exec $BIN $args From 5711b17b1322d34b25615bcd09ee889755a98ba7 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Wed, 29 Mar 2023 16:02:53 -0600 Subject: [PATCH 2/2] system-setup: restore accidentally deleted file --- system_setup/ubuntu-wsl-setup | 373 ++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100755 system_setup/ubuntu-wsl-setup diff --git a/system_setup/ubuntu-wsl-setup b/system_setup/ubuntu-wsl-setup new file mode 100755 index 00000000..6fef384b --- /dev/null +++ b/system_setup/ubuntu-wsl-setup @@ -0,0 +1,373 @@ +#!/bin/bash + +################# +# Launcher init # +################# + +START=$(date +%s.%N) + +function exit_if_not_wsl2() { + # WSLInterop ensures we are under WSL (either 1 or 2). + # config.gz ensures we have a kernel. WSL 1 does not have one. + # grep'ing /proc/version for 'WSL2' would work, but users can change that + # when compiling their own kernel. + if ! [[ -f "/proc/sys/fs/binfmt_misc/WSLInterop" && -f "/proc/config.gz" ]]; then + echo "WSL 2 not detected. Exiting." + exit 125 + fi +} + +# ensure_dir_exists calls `mkdir -p` if the given path is not a directory. +# This speeds up execution time by avoiding unnecessary calls to mkdir. +# +# Usage: ensure_dir_exists []... +# +function ensure_dir_exists() { + [ -d "$1" ] || mkdir -p "$@" +} + +declare -A PIDS +function async_exec() { + "$@" & + PIDS[$!]=$* +} +function wait_for_async_execs() { + for pid in "${!PIDS[@]}" + do + wait "$pid" && continue || echo "ERROR: ${PIDS[$pid]} exited abnormally with status $?" + done +} + +# Proceed only if in WSL 2: +exit_if_not_wsl2 + +# shellcheck source=/dev/null +source "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true +if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then + needs_update=false +else + needs_update=true +fi + +# Set $REALHOME to the users real home directory +REALHOME=$(getent passwd $UID | cut -d ':' -f 6) + +# Set config folder to local path +export XDG_CONFIG_HOME="$SNAP_USER_DATA/.config" +ensure_dir_exists "$XDG_CONFIG_HOME" +chmod 700 "$XDG_CONFIG_HOME" + +# If the user has modified their user-dirs settings, force an update +if [[ -f "$REALHOME/.config/user-dirs.dirs" ]]; then + if [[ -f "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" ]]; then + if [[ "$(md5sum < "$REALHOME/.config/user-dirs.dirs")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum")" || + ( -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" && + "$(md5sum < "$REALHOME/.config/user-dirs.locale")" != "$(cat "$XDG_CONFIG_HOME/user-dirs.locale.md5sum")" ) ]]; then + needs_update=true + fi + else + # shellcheck disable=SC2034 + needs_update=true + fi +fi + +if [ "$SNAP_ARCH" = "amd64" ]; then + ARCH="x86_64-linux-gnu" +elif [ "$SNAP_ARCH" = "armhf" ]; then + ARCH="arm-linux-gnueabihf" +elif [ "$SNAP_ARCH" = "arm64" ]; then + ARCH="aarch64-linux-gnu" +elif [ "$SNAP_ARCH" = "ppc64el" ]; then + ARCH="powerpc64le-linux-gnu" +else + ARCH="$SNAP_ARCH-linux-gnu" +fi + +export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH" + +# Don't LD_PRELOAD bindtextdomain for classic snaps +if ! grep -qs "^\s*confinement:\s*classic\s*" "$SNAP/meta/snap.yaml"; then + if [ -f "$SNAP/gnome-platform/lib/$ARCH/bindtextdomain.so" ]; then + export LD_PRELOAD="$LD_PRELOAD:$SNAP/gnome-platform/\$LIB/bindtextdomain.so" + elif [ -f "$SNAP/lib/$ARCH/bindtextdomain.so" ]; then + export LD_PRELOAD="$LD_PRELOAD:$SNAP/\$LIB/bindtextdomain.so" + fi +fi + + +############################################### +# Launcher common exports for any desktop app # +############################################### + +# Note: We avoid using `eval` because we don't want to expand variable names +# in paths. For example: LD_LIBRARY_PATH paths might contain `$LIB`. +function prepend_dir() { + local -n var="$1" + local dir="$2" + # We can't check if the dir exists when the dir contains variables + if [[ "$dir" == *"\$"* || -d "$dir" ]]; then + export "${!var}=${dir}${var:+:$var}" + fi +} + +function append_dir() { + local -n var="$1" + local dir="$2" + # We can't check if the dir exists when the dir contains variables + if [[ "$dir" == *"\$"* || -d "$dir" ]]; then + export "${!var}=${var:+$var:}${dir}" + fi +} + +function can_open_file() { + [ -f "$1" ] && [ -r "$1" ] +} + +function update_xdg_dirs_values() { + local save_initial_values=false + local XDG_DIRS="DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES" + unset XDG_SPECIAL_DIRS_PATHS + + if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" ]; then + # shellcheck source=/dev/null + source "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" + fi + + if [ -z ${XDG_SPECIAL_DIRS+x} ]; then + save_initial_values=true + fi + + for d in $XDG_DIRS; do + var="XDG_${d}_DIR" + value="${!var}" + + if [ "$save_initial_values" = true ]; then + XDG_SPECIAL_DIRS+=("$var") + XDG_SPECIAL_DIRS_INITIAL_PATHS+=("$value") + fi + + XDG_SPECIAL_DIRS_PATHS+=("$value") + done +} + +function is_subpath() { + dir="$(realpath "$1")" + parent="$(realpath "$2")" + [ "${dir##$parent/}" != "$dir" ] && return 0 || return 1 +} + +append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib/$ARCH" +append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH" +append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib" +append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/lib" +prepend_dir PATH "$SNAP_DESKTOP_RUNTIME/usr/bin" + +# XDG Config +prepend_dir XDG_CONFIG_DIRS "$SNAP_DESKTOP_RUNTIME/etc/xdg" +prepend_dir XDG_CONFIG_DIRS "$SNAP/etc/xdg" + +# Define snaps' own data dir +prepend_dir XDG_DATA_DIRS "$SNAP_DESKTOP_RUNTIME/usr/share" +prepend_dir XDG_DATA_DIRS "$SNAP/usr/share" +prepend_dir XDG_DATA_DIRS "$SNAP/share" +prepend_dir XDG_DATA_DIRS "$SNAP/data-dir" +prepend_dir XDG_DATA_DIRS "$SNAP_USER_DATA" + +# Set XDG_DATA_HOME to local path +export XDG_DATA_HOME="$SNAP_USER_DATA/.local/share" +ensure_dir_exists "$XDG_DATA_HOME" + +# Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME: +# https://bugzilla.gnome.org/show_bug.cgi?id=741335 +prepend_dir XDG_DATA_DIRS "$XDG_DATA_HOME" + +# Set cache folder to local path +export XDG_CACHE_HOME="$SNAP_USER_COMMON/.cache" +if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$XDG_CACHE_HOME" ]]; then + # the .cache directory used to be stored under $SNAP_USER_DATA, migrate it + mv "$SNAP_USER_DATA/.cache" "$SNAP_USER_COMMON/" +fi +ensure_dir_exists "$XDG_CACHE_HOME" + +# Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed) +# shellcheck disable=SC2174 +ensure_dir_exists "$XDG_RUNTIME_DIR" -m 700 + +# Ensure the app finds locale definitions (requires locales-all to be installed) +append_dir LOCPATH "$SNAP_DESKTOP_RUNTIME/usr/lib/locale" + +# If any, keep track of where XDG dirs were so we can potentially migrate the content later +update_xdg_dirs_values + +# Setup user-dirs.* or run xdg-user-dirs-update if needed +needs_xdg_update=false +needs_xdg_reload=false +needs_xdg_links=false + +if [ "$HOME" != "$SNAP_USER_DATA" ] && ! is_subpath "$XDG_CONFIG_HOME" "$HOME"; then + for f in user-dirs.dirs user-dirs.locale; do + if [ -f "$HOME/.config/$f" ]; then + mv "$HOME/.config/$f" "$XDG_CONFIG_HOME" + needs_xdg_reload=true + fi + done +fi + +if can_open_file "$REALHOME/.config/user-dirs.dirs"; then + # shellcheck disable=SC2154 + if [ "$needs_update" = true ] || [ "$needs_xdg_reload" = true ]; then + sed "/^#/!s#\$HOME#${REALHOME}#g" "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs" + md5sum < "$REALHOME/.config/user-dirs.dirs" > "$XDG_CONFIG_HOME/user-dirs.dirs.md5sum" + # It's possible user-dirs.dirs exists when user-dirs.locale doesn't. This + # simply means the user opted to never ask to translate their user dirs + if can_open_file "$REALHOME/.config/user-dirs.locale"; then + cp -a "$REALHOME/.config/user-dirs.locale" "$XDG_CONFIG_HOME" + md5sum < "$REALHOME/.config/user-dirs.locale" > "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" + elif [ -f "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" ]; then + rm "$XDG_CONFIG_HOME/user-dirs.locale.md5sum" + fi + needs_xdg_reload=true + fi +else + needs_xdg_update=true + needs_xdg_links=true +fi + +if [ $needs_xdg_reload = true ]; then + update_xdg_dirs_values + needs_xdg_reload=false +fi + +# Check if we can actually read the contents of each xdg dir +for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do + if ! can_open_file "${XDG_SPECIAL_DIRS_PATHS[$i]}"; then + needs_xdg_update=true + needs_xdg_links=true + break + fi +done + +# If needs XDG update and xdg-user-dirs-update exists in $PATH, run it +if [ "$needs_xdg_update" = true ] && command -v xdg-user-dirs-update >/dev/null; then + xdg-user-dirs-update + update_xdg_dirs_values +fi + +# Create links for user-dirs.dirs +if [ "$needs_xdg_links" = true ]; then + for ((i = 0; i < ${#XDG_SPECIAL_DIRS_PATHS[@]}; i++)); do + b="$(realpath "${XDG_SPECIAL_DIRS_PATHS[$i]}" --relative-to="$HOME" 2>/dev/null)" + if [[ -n "$b" && "$b" != "." && -e "$REALHOME/$b" ]]; then + [ -d "$HOME/$b" ] && rmdir "$HOME/$b" 2> /dev/null + [ ! -e "$HOME/$b" ] && ln -s "$REALHOME/$b" "$HOME/$b" + fi + done +else + # If we aren't creating new links, check if we have content saved in old locations and move it + for ((i = 0; i < ${#XDG_SPECIAL_DIRS[@]}; i++)); do + old="${XDG_SPECIAL_DIRS_INITIAL_PATHS[$i]}" + new="${XDG_SPECIAL_DIRS_PATHS[$i]}" + if [ -L "$old" ] && [ -d "$new" ] && [ "$(readlink "$old" 2>/dev/null)" != "$new" ] && + (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then + mv -vn "$old"/* "$new"/ 2>/dev/null + elif [ -d "$old" ] && [ -d "$new" ] && [ "$old" != "$new" ] && + (is_subpath "$old" "$SNAP_USER_DATA" || is_subpath "$old" "$SNAP_USER_COMMON"); then + mv -vn "$old"/* "$new"/ 2>/dev/null + fi + done +fi + +# Keep an array of data dirs, for looping through them +IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS" + +# Font Config and themes +export FONTCONFIG_PATH="$SNAP_DESKTOP_RUNTIME/etc/fonts" +export FONTCONFIG_FILE="$SNAP_DESKTOP_RUNTIME/etc/fonts/fonts.conf" + +function make_user_fontconfig { + echo "" + if [ -d "$REALHOME/.local/share/fonts" ]; then + echo " $REALHOME/.local/share/fonts" + fi + if [ -d "$REALHOME/.fonts" ]; then + echo " $REALHOME/.fonts" + fi + for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do + if [ -d "${data_dirs_array[$i]}/fonts" ]; then + echo " ${data_dirs_array[$i]}/fonts" + fi + done + # We need to include a user-writable cachedir first to support + # caching of per-user fonts. + echo ' fontconfig' + echo " $SNAP_COMMON/fontconfig" + echo "" +} + +if [ "$needs_update" = true ]; then + rm -rf "$XDG_DATA_HOME"/{fontconfig,fonts,fonts-*,themes,.themes} + + # This fontconfig fragment is installed in a location that is + # included by the system fontconfig configuration: namely the + # etc/fonts/conf.d/50-user.conf file. + ensure_dir_exists "$XDG_CONFIG_HOME/fontconfig" + async_exec make_user_fontconfig > "$XDG_CONFIG_HOME/fontconfig/fonts.conf" + + # the themes symlink are needed for GTK 3.18 when the prefix isn't changed + # GTK 3.20 looks into XDG_DATA_DIRS which has connected themes. + if [ -d "$SNAP/data-dir/themes" ]; then + ln -sf "$SNAP/data-dir/themes" "$XDG_DATA_HOME" + ln -sfn "$SNAP/data-dir/themes" "$SNAP_USER_DATA/.themes" + elif [ -d "$SNAP_DESKTOP_RUNTIME/usr/share/themes" ]; then + ln -sf "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$XDG_DATA_HOME" + ln -sfn "$SNAP_DESKTOP_RUNTIME/usr/share/themes" "$SNAP_USER_DATA/.themes" + fi +fi + +# Testability support +append_dir LD_LIBRARY_PATH "$SNAP/testability" +append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH" +append_dir LD_LIBRARY_PATH "$SNAP/testability/$ARCH/mesa" + + +[ "$needs_update" = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > "$SNAP_USER_DATA/.last_revision" + +wait_for_async_execs + +if [ -n "$SNAP_DESKTOP_DEBUG" ]; then + echo "desktop-launch elapsed time: $(date +%s.%N --date="$START seconds ago")" + echo "Now running: exec $*" +fi + +PATH="${SNAP}/usr/sbin:${SNAP}/usr/bin:${SNAP}/sbin:${SNAP}/bin" +PATH="${PATH}:${SNAP_CORE_DIR}/usr/sbin:${SNAP_CORE_DIR}/usr/bin:${SNAP_CORE_DIR}/sbin:${SNAP_CORE_DIR}/bin" + +# configure python environment +export PYTHONIOENCODING=utf-8 +PYTHONPATH=$SNAP/lib/python3.10/site-packages +PYTHONPATH=$SNAP/usr/lib/python3/site-packages:$PYTHONPATH +PYTHONPATH=$SNAP/usr/lib/python3/dist-packages:$PYTHONPATH +export PYTHONPATH +export PYTHON=$SNAP/usr/bin/python3.10 +export SNAP_PYTHON=$PYTHON +# ensure curtin points at PYTHON +export PY3OR2_PYTHON=$PYTHON +# base directory for subiquity to locate resources +export SUBIQUITY_ROOT=$SNAP + +BIN="$PYTHON -m system_setup.cmd.server" +args="" +for arg in $@; do + if [ ${arg} = "--server-only" ]; then + # Just eat that argument. It's useful for the GUI context only, + # since here the server only startup option is the default. + continue + fi + if [ ${arg} = "-t" -o ${arg} = "--text" ]; then + BIN="$PYTHON -m system_setup.cmd.tui" + continue + fi + args="$args $arg" +done + +exec $BIN $args