blob: 901877383a5ff64675a1ada0a0b86a3a98f3def4 [file] [log] [blame] [edit]
#!/usr/bin/env sh
#
# Copyright (C) 2025 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
set -eu
SCRIPTPATH="$(realpath -- "${0}")"
SCRIPTDIR="$(dirname -- "${SCRIPTPATH}")"
WEBKITDIR="$(realpath -- "${SCRIPTDIR}/../..")"
WEBKIT_SOURCE_DIR="${WEBKIT_SOURCE_DIR:-${WEBKITDIR}}"
WEBKIT_SOURCE_DIR="$(realpath -m -- "${WEBKIT_SOURCE_DIR}")"
help() {
cat <<EOF
Usage: ${0} program-to-execute [arguments...]
${0} --create-symlink
This script is used by the WebKit tooling when running inside the
webkit-container-sdk for GTK/WPE port development. It enables building
WebKit and running tests inside a common path at /sdk/webkit.
Options:
-h, --help Show this help message
--create-symlink Create /sdk/webkit as a symlink to ${WEBKIT_SOURCE_DIR}
and exit. Useful for tools not executed through this
wrapper (like gdb) that need to resolve /sdk/webkit paths.
Default behavior:
Creates a private mount namespace where /sdk/webkit is a bind-mount
to ${WEBKIT_SOURCE_DIR}, then executes the specified program.
Examples:
${0} Tools/Scripts/build-webkit --wpe --release
${0} --create-symlink
EOF
exit 0
}
error() {
printf '%s\n' "${@}" 1>&2
exit 1
}
# If path starts with ${WEBKIT_SOURCE_DIR}, replace that prefix with /sdk/webkit.
maybe_replace_path_prefix_to_rootsdk() {
case "${1}" in
"${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*)
printf '%s\n' "/sdk/webkit${1#"${WEBKIT_SOURCE_DIR}"}"
;;
*)
printf '%s\n' "${1}"
;;
esac
}
resolve_relpath_to_abs_if_outside() {
abs=$(realpath -m -- "${ORGPWD}/${1}")
case "${abs}" in
"${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*)
# Inside the tree: keep original relative value
printf '%s\n' "${1}"
;;
*) # relative path outside the tree: make it absolute
printf '%s\n' "${abs}"
;;
esac
}
maybe_update_relpath_to_abs_if_outside() {
case "${1}" in
""|/*|*://*)
# do not touch if is empty or looks like an abs path or a URL
printf '%s\n' "${1}"
;;
.|..|./*|../*|*/*)
resolve_relpath_to_abs_if_outside "${1}"
;;
*)
if [ -L "${1}" ]; then
resolve_relpath_to_abs_if_outside "${1}"
else
printf '%s\n' "${1}"
fi
;;
esac
}
# Convert relative paths to absolute if they point outside ${WEBKIT_SOURCE_DIR}
args_maybe_update_outside_relpaths() {
for arg in "${@}"; do
case "${arg}" in
--*=*) # handle arguments like "--option=value"
key="${arg%%=*}"
val="${arg#*=}"
val="$(maybe_update_relpath_to_abs_if_outside "${val}")"
arg="${key}=${val}"
;;
*)
arg="$(maybe_update_relpath_to_abs_if_outside "${arg}")"
;;
esac
printf "'"
printf '%s' "${arg}" | sed "s/'/'\\\\''/g"
printf "' "
done
}
[ "$#" -ge 1 ] || help
[ "${1}" = "--help" ] && help
[ "${1}" = "-h" ] && help
[ -d "${WEBKIT_SOURCE_DIR}" ] || error "Can't find directory: ${WEBKIT_SOURCE_DIR}"
[ -d /sdk ] || error "Can't find /sdk directory"
[ -w /sdk ] || error "Directory /sdk is not writable for user $(whoami)"
case "${WEBKIT_SOURCE_DIR}" in
/sdk|/sdk/*) error "${0} should not be invoked with WEBKIT_SOURCE_DIR under /sdk directory" ;;
esac
if [ "${1}" = "--create-symlink" ]; then
[ "$#" -ge 2 ] && error "No extra arguments can be passed with --create-symlink"
if [ -L "/sdk/webkit" ]; then
CURSYMLINKDEST="$(realpath -m -- /sdk/webkit)"
if [ "${CURSYMLINKDEST}" != "${WEBKIT_SOURCE_DIR}" ]; then
rm -f "/sdk/webkit"
ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit"
echo "Symlink at /sdk/webkit changed from ${CURSYMLINKDEST} to ${WEBKIT_SOURCE_DIR}"
fi
elif ! [ -e "/sdk/webkit" ]; then
ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit"
else
error "ERROR: /sdk/webkit exists and is not a symlink. This is unexpected"
fi
exit 0
fi
CURUID="$(id -u)"
CURGID="$(id -g)"
ORGPWD="$(pwd)"
SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")"
# Try also with the realpath, just in case pwd is inside a symlinked dir.
if [ "${ORGPWD}" = "${SDKPWD}" ]; then
ORGPWD="$(realpath -- "${ORGPWD}")"
SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")"
fi
# When $(pwd) is inside ${WEBKIT_SOURCE_DIR}, switch (cd) to the equivalent bind-mount path
# under /sdk/webkit. Any relative path arguments that point outside ${WEBKIT_SOURCE_DIR} are
# converted to absolute paths first, since they wouldn't resolve correctly after the switch.
[ "${ORGPWD}" != "${SDKPWD}" ] && eval "set -- $(args_maybe_update_outside_relpaths "${@}")"
# Since util-linux 2.27 is not needed to execute mount --make-rprivate /
# because unshare does that automatically by default for new mount namespaces
exec unshare -rm sh -c '
set -eu
WEBKIT_SOURCE_DIR="${1}"
SDKPWD="${2}"
CURUID="${3}"
CURGID="${4}"
shift 4
mount -t tmpfs -o size=16M tmpfs /sdk
mkdir /sdk/webkit
mount --bind "${WEBKIT_SOURCE_DIR}" /sdk/webkit
cd "${SDKPWD}"
export WEBKIT_CONTAINER_SDK_INSIDE_MOUNT_NAMESPACE=1
exec unshare --map-user="${CURUID}" --map-group="${CURGID}" -- "${@}"
' -- "${WEBKIT_SOURCE_DIR}" "${SDKPWD}" "${CURUID}" "${CURGID}" "${@}"