Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: switch to core20 for snap #127320

Merged
merged 3 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/azure-pipelines/linux/snap-build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ steps:
x64) SNAPCRAFT_TARGET_ARGS="" ;;
*) SNAPCRAFT_TARGET_ARGS="--target-arch $(VSCODE_ARCH)" ;;
esac
(cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft prime $SNAPCRAFT_TARGET_ARGS && snap pack prime --compression=lzo --filename="$SNAP_PATH")
(cd $SNAP_ROOT/code-* && sudo --preserve-env snapcraft snap $SNAPCRAFT_TARGET_ARGS --output "$SNAP_PATH")

# Export SNAP_PATH
echo "##vso[task.setvariable variable=SNAP_PATH]$SNAP_PATH"
Expand Down
3 changes: 2 additions & 1 deletion build/azure-pipelines/product-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ resources:
endpoint: VSCodeHub
options: --user 0:0 --cap-add SYS_ADMIN
- container: snapcraft
image: snapcore/snapcraft:stable
image: vscodehub.azurecr.io/vscode-linux-build-agent:snapcraft-x64
endpoint: VSCodeHub

stages:
- stage: Compile
Expand Down
218 changes: 210 additions & 8 deletions resources/linux/snap/electron-launch
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,64 @@
# We need to handle that case and reset $SNAP
SNAP=$(echo "$SNAP" | sed -e "s|/var/lib/snapd||g")

#
# Exports are based on https://github.com/snapcore/snapcraft/blob/master/extensions/desktop/common/desktop-exports
#

# 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 <path> [<mkdir-options>]...
#
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
}

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
}

# shellcheck source=/dev/null
source "$SNAP_USER_DATA/.last_revision" 2>/dev/null || true
if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_VERSION" ]; 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
ensure_dir_exists "$SNAP_USER_DATA/.config"
chmod 700 "$SNAP_USER_DATA/.config"

if [ "$SNAP_ARCH" == "amd64" ]; then
ARCH="x86_64-linux-gnu"
elif [ "$SNAP_ARCH" == "armhf" ]; then
Expand All @@ -14,21 +72,165 @@ else
ARCH="$SNAP_ARCH-linux-gnu"
fi

GDK_CACHE_DIR="$SNAP_USER_COMMON/.cache"
if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$GDK_CACHE_DIR" ]]; then
export SNAP_LAUNCHER_ARCH_TRIPLET="$ARCH"

function is_subpath() {
dir="$(realpath "$1")"
parent="$(realpath "$2")"
[ "${dir##"${parent}"/}" != "${dir}" ] && return 0 || return 1
}

function can_open_file() {
[ -f "$1" ] && [ -r "$1" ]
}

# XDG Config
prepend_dir XDG_CONFIG_DIRS "$SNAP/etc/xdg"

# Define snaps' own data dir
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
ensure_dir_exists "$SNAP_USER_DATA/.local/share"

# 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 "$SNAP_USER_DATA/.local/share"

# Set cache folder to local path
if [[ -d "$SNAP_USER_DATA/.cache" && ! -e "$SNAP_USER_COMMON/.cache" ]]; then
# the .cache directory used to be stored under $SNAP_USER_DATA, migrate it
mv "$SNAP_USER_DATA/.cache" "$SNAP_USER_COMMON/"
fi
[ ! -d "$GDK_CACHE_DIR" ] && mkdir -p "$GDK_CACHE_DIR"
ensure_dir_exists "$SNAP_USER_COMMON/.cache"

# 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/usr/lib/locale"

# If detect wayland server socket, then set environment so applications prefer
# wayland, and setup compat symlink (until we use user mounts. Remember,
# XDG_RUNTIME_DIR is /run/user/<uid>/snap.$SNAP so look in the parent directory
# for the socket. For details:
# https://forum.snapcraft.io/t/wayland-dconf-and-xdg-runtime-dir/186/10
# Applications that don't support wayland natively may define DISABLE_WAYLAND
# (to any non-empty value) to skip that logic entirely.
wayland_available=false
if [[ -n "$XDG_RUNTIME_DIR" && -z "$DISABLE_WAYLAND" ]]; then
wdisplay="wayland-0"
if [ -n "$WAYLAND_DISPLAY" ]; then
wdisplay="$WAYLAND_DISPLAY"
fi
wayland_sockpath="$XDG_RUNTIME_DIR/../$wdisplay"
wayland_snappath="$XDG_RUNTIME_DIR/$wdisplay"
if [ -S "$wayland_sockpath" ]; then
# if running under wayland, use it
#export WAYLAND_DEBUG=1
# shellcheck disable=SC2034
wayland_available=true
# create the compat symlink for now
if [ ! -e "$wayland_snappath" ]; then
ln -s "$wayland_sockpath" "$wayland_snappath"
fi
fi
fi

# Keep an array of data dirs, for looping through them
IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS"

# Build mime.cache
# needed for gtk and qt icon
if [ "$needs_update" = true ]; then
rm -rf "$SNAP_USER_DATA/.local/share/mime"
if [ ! -f "$SNAP/usr/share/mime/mime.cache" ]; then
if command -v update-mime-database >/dev/null; then
cp --preserve=timestamps -dR "$SNAP/usr/share/mime" "$SNAP_USER_DATA/.local/share"
async_exec update-mime-database "$SNAP_USER_DATA/.local/share/mime"
fi
fi
fi

# Gio modules and cache (including gsettings module)
export GIO_MODULE_DIR="$SNAP_USER_COMMON/.cache/gio-modules"
function compile_giomodules {
if [ -f "$1/glib-2.0/gio-querymodules" ]; then
rm -rf "$GIO_MODULE_DIR"
ensure_dir_exists "$GIO_MODULE_DIR"
ln -s "$1"/gio/modules/*.so "$GIO_MODULE_DIR"
"$1/glib-2.0/gio-querymodules" "$GIO_MODULE_DIR"
fi
}
if [ "$needs_update" = true ]; then
async_exec compile_giomodules "$SNAP/usr/lib/$ARCH"
fi

# Setup compiled gsettings schema
GS_SCHEMA_DIR="$SNAP_USER_DATA/.local/share/glib-2.0/schemas"
function compile_schemas {
if [ -f "$1" ]; then
rm -rf "$GS_SCHEMA_DIR"
ensure_dir_exists "$GS_SCHEMA_DIR"
for ((i = 0; i < ${#data_dirs_array[@]}; i++)); do
schema_dir="${data_dirs_array[$i]}/glib-2.0/schemas"
if [ -f "$schema_dir/gschemas.compiled" ]; then
# This directory already has compiled schemas
continue
fi
if [ -n "$(ls -A "$schema_dir"/*.xml 2>/dev/null)" ]; then
ln -s "$schema_dir"/*.xml "$GS_SCHEMA_DIR"
fi
if [ -n "$(ls -A "$schema_dir"/*.override 2>/dev/null)" ]; then
ln -s "$schema_dir"/*.override "$GS_SCHEMA_DIR"
fi
done
# Only compile schemas if we copied anything
if [ -n "$(ls -A "$GS_SCHEMA_DIR"/*.xml "$GS_SCHEMA_DIR"/*.override 2>/dev/null)" ]; then
"$1" "$GS_SCHEMA_DIR"
fi
fi
}
if [ "$needs_update" = true ]; then
async_exec compile_schemas "$SNAP/usr/lib/$ARCH/glib-2.0/glib-compile-schemas"
fi

# Gdk-pixbuf loaders
export GDK_PIXBUF_MODULE_FILE="$GDK_CACHE_DIR/gdk-pixbuf-loaders.cache"
export GDK_PIXBUF_MODULE_FILE="$SNAP_USER_COMMON/.cache/gdk-pixbuf-loaders.cache"
export GDK_PIXBUF_MODULEDIR="$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders"
if [ -f "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" ]; then
"$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" > "$GDK_PIXBUF_MODULE_FILE"
if [ "$needs_update" = true ] || [ ! -f "$GDK_PIXBUF_MODULE_FILE" ]; then
rm -f "$GDK_PIXBUF_MODULE_FILE"
if [ -f "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" ]; then
async_exec "$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders" > "$GDK_PIXBUF_MODULE_FILE"
fi
fi

# shellcheck disable=SC2154
if [ "$wayland_available" = true ]; then
export GDK_BACKEND="wayland"
fi

# Create $XDG_RUNTIME_DIR if not exists (to be removed when https://pad.lv/1656340 is fixed)
[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p -m 700 "$XDG_RUNTIME_DIR"
append_dir GTK_PATH "$SNAP/usr/lib/$ARCH/gtk-3.0"
append_dir GTK_PATH "$SNAP/usr/lib/gtk-3.0"

# ibus and fcitx integration
GTK_IM_MODULE_DIR="$SNAP_USER_COMMON/.cache/immodules"
export GTK_IM_MODULE_FILE="$GTK_IM_MODULE_DIR/immodules.cache"
# shellcheck disable=SC2154
if [ "$needs_update" = true ]; then
rm -rf "$GTK_IM_MODULE_DIR"
ensure_dir_exists "$GTK_IM_MODULE_DIR"
ln -s "$SNAP"/usr/lib/"$ARCH"/gtk-3.0/3.0.0/immodules/*.so "$GTK_IM_MODULE_DIR"
async_exec "$SNAP/usr/lib/$ARCH/libgtk-3-0/gtk-query-immodules-3.0" > "$GTK_IM_MODULE_FILE"
fi

# shellcheck disable=SC2154
[ "$needs_update" = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_VERSION" > "$SNAP_USER_DATA/.last_revision"

wait_for_async_execs

exec "$@"
66 changes: 42 additions & 24 deletions resources/linux/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,73 @@ architectures:

grade: stable
confinement: classic
base: core20
compression: lzo

parts:
gnome:
plugin: nil
build-packages:
- software-properties-common
override-pull: |
add-apt-repository -y ppa:ubuntu-desktop/gnome-3-26
apt -y update

code:
after:
- gnome
plugin: dump
source: .
stage-packages:
- ibus-gtk3
- fcitx-frontend-gtk3
- gvfs-libs
- ca-certificates
- libasound2
- libgconf-2-4
- libglib2.0-bin
- libgnome-keyring0
- libatk-bridge2.0-0
- libatk1.0-0
- libatspi2.0-0
- libcairo2
- libcanberra-gtk3-module
- libcurl3-gnutls
- libcurl3-nss
- libcurl4
- libdrm2
- libgbm1
- libgl1
- libglib2.0-0
- libgtk-3-0
- libnotify4
- libnspr4
- libnss3
- libpcre3
- libpulse0
- libpango-1.0-0
- libsecret-1-0
- libxcomposite1
- libxdamage1
- libxfixes3
- libxkbcommon0
- libxkbfile1
- libxrandr2
- libxss1
- libxtst6
- zlib1g
- locales-all
- packagekit-gtk3-module
- xdg-utils
prime:
- -usr/share/doc
- -usr/share/fonts
- -usr/share/icons
- -usr/share/lintian
- -usr/share/man
override-build: |
snapcraftctl build
patchelf --force-rpath --set-rpath '$ORIGIN/../../lib/x86_64-linux-gnu:$ORIGIN:/snap/core20/current/lib/x86_64-linux-gnu' $SNAPCRAFT_PART_INSTALL/usr/share/@@NAME@@/chrome_crashpad_handler
cleanup:
after:
- code
plugin: nil
build-snaps:
- core20
override-prime: |
set -eux
for snap in "core20"; do
cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
done
patchelf --print-rpath $SNAPCRAFT_PRIME/usr/share/@@NAME@@/chrome_crashpad_handler


apps:
@@NAME@@:
command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --no-sandbox
common-id: @@NAME@@.desktop
environment:
GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas
GTK_USE_PORTAL: 1

url-handler:
command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --open-url --no-sandbox
environment:
GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas
GTK_USE_PORTAL: 1
9 changes: 9 additions & 0 deletions src/vs/platform/native/electron-main/nativeHostMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,14 +451,23 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
// Remove some environment variables before opening to avoid issues...
const gdkPixbufModuleFile = process.env['GDK_PIXBUF_MODULE_FILE'];
const gdkPixbufModuleDir = process.env['GDK_PIXBUF_MODULEDIR'];
const gtkIMModuleFile = process.env['GTK_IM_MODULE_FILE'];
const gdkBackend = process.env['GDK_BACKEND'];
const gioModuleDir = process.env['GIO_MODULE_DIR'];
delete process.env['GDK_PIXBUF_MODULE_FILE'];
delete process.env['GDK_PIXBUF_MODULEDIR'];
delete process.env['GTK_IM_MODULE_FILE'];
delete process.env['GDK_BACKEND'];
delete process.env['GIO_MODULE_DIR'];

shell.openExternal(url);

// ...but restore them after
process.env['GDK_PIXBUF_MODULE_FILE'] = gdkPixbufModuleFile;
process.env['GDK_PIXBUF_MODULEDIR'] = gdkPixbufModuleDir;
process.env['GTK_IM_MODULE_FILE'] = gtkIMModuleFile;
process.env['GDK_BACKEND'] = gdkBackend;
process.env['GIO_MODULE_DIR'] = gioModuleDir;
}

moveItemToTrash(windowId: number | undefined, fullPath: string): Promise<void> {
Expand Down