This commit is contained in:
Maxim Slipenko 2023-09-15 18:17:28 +00:00 committed by GitHub
parent ca62d93bc1
commit 58c753dff1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 254 additions and 19 deletions

View File

@ -1,26 +1,32 @@
#!/bin/sh #!/bin/sh
set -e set -e
echo "Activating feature 'color'" WINEVERSION=$WINEVERSION
echo "The provided favorite color is: ${FAVORITE}" WINEHOME="/home/root"
WINEPREFIX="$WINEHOME/.wine32"
WINEARCH="win32"
WINEDEBUG=-all
ensure_nanolayer nanolayer_location "v0.5.0"
# The 'install.sh' entrypoint script is always executed as the root user. $nanolayer_location \
# install \
# These following environment variables are passed in by the dev container CLI. apt-get \
# These may be useful in instances where the context of the final apt-transport-https \
# remoteUser or containerUser is useful. ca-certificates \
# For more details, see https://containers.dev/implementors/features#user-env-var telnet \
echo "The effective dev container remoteUser is '$_REMOTE_USER'" cabextract \
echo "The effective dev container remoteUser's home directory is '$_REMOTE_USER_HOME'" gnupg2 \
wget
echo "The effective dev container containerUser is '$_CONTAINER_USER'" wget https://dl.winehq.org/wine-builds/winehq.key -O - | apt-key add -
echo "The effective dev container containerUser's home directory is '$_CONTAINER_USER_HOME'" echo "deb https://dl.winehq.org/wine-builds/debian bookworm main" > /etc/apt/sources.list.d/winehq.list
{ \
echo "Package: *wine* *wine*:i386"; \
echo "Pin: version $WINEVERSION~bookworm"; \
echo "Pin-Priority: 1001"; \
} > /etc/apt/preferences.d/winehq.pref
cat > /usr/local/bin/color \ $nanolayer_location install apt-get winehq-stable
<< EOF wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks -O /usr/bin/winetricks
#!/bin/sh chmod +rx /usr/bin/winetricks
echo "my favorite color is ${FAVORITE}"
EOF
chmod +x /usr/local/bin/color

172
src/wine/library_scripts.sh Normal file
View File

@ -0,0 +1,172 @@
// https://github.com/devcontainers-contrib/features/blob/696aa94479697cf701c559ef17d4f0bbb86bd00c/src/bikeshed/library_scripts.sh
clean_download() {
# The purpose of this function is to download a file with minimal impact on container layer size
# this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a
# temporary manner, and making sure to
# 1. uninstall the downloader at the return of the function
# 2. revert back any changes to the package installer database/cache (for example apt-get lists)
# The above steps will minimize the leftovers being created while installing the downloader
# Supported distros:
# debian/ubuntu/alpine
url=$1
output_location=$2
tempdir=$(mktemp -d)
downloader_installed=""
_apt_get_install() {
tempdir=$1
# copy current state of apt list - in order to revert back later (minimize contianer layer size)
cp -p -R /var/lib/apt/lists $tempdir
apt-get update -y
apt-get -y install --no-install-recommends wget ca-certificates
}
_apt_get_cleanup() {
tempdir=$1
echo "removing wget"
apt-get -y purge wget --auto-remove
echo "revert back apt lists"
rm -rf /var/lib/apt/lists/*
rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists
}
_apk_install() {
tempdir=$1
# copy current state of apk cache - in order to revert back later (minimize contianer layer size)
cp -p -R /var/cache/apk $tempdir
apk add --no-cache wget
}
_apk_cleanup() {
tempdir=$1
echo "removing wget"
apk del wget
}
# try to use either wget or curl if one of them already installer
if type curl >/dev/null 2>&1; then
downloader=curl
elif type wget >/dev/null 2>&1; then
downloader=wget
else
downloader=""
fi
# in case none of them is installed, install wget temporarly
if [ -z $downloader ] ; then
if [ -x "/usr/bin/apt-get" ] ; then
_apt_get_install $tempdir
elif [ -x "/sbin/apk" ] ; then
_apk_install $tempdir
else
echo "distro not supported"
exit 1
fi
downloader="wget"
downloader_installed="true"
fi
if [ $downloader = "wget" ] ; then
wget -q $url -O $output_location
else
curl -sfL $url -o $output_location
fi
# NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because
# alpine lack bash, and RETURN is not a valid signal under sh shell
if ! [ -z $downloader_installed ] ; then
if [ -x "/usr/bin/apt-get" ] ; then
_apt_get_cleanup $tempdir
elif [ -x "/sbin/apk" ] ; then
_apk_cleanup $tempdir
else
echo "distro not supported"
exit 1
fi
fi
}
ensure_nanolayer() {
# Ensure existance of the nanolayer cli program
local variable_name=$1
local required_version=$2
local __nanolayer_location=""
# If possible - try to use an already installed nanolayer
if [ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]; then
if [ -z "${NANOLAYER_CLI_LOCATION}" ]; then
if type nanolayer >/dev/null 2>&1; then
echo "Found a pre-existing nanolayer in PATH"
__nanolayer_location=nanolayer
fi
elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then
__nanolayer_location=${NANOLAYER_CLI_LOCATION}
echo "Found a pre-existing nanolayer which were given in env variable: $__nanolayer_location"
fi
# make sure its of the required version
if ! [ -z "${__nanolayer_location}" ]; then
local current_version
current_version=$($__nanolayer_location --version)
if ! [ $current_version == $required_version ]; then
echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)"
__nanolayer_location=""
fi
fi
fi
# If not previuse installation found, download it temporarly and delete at the end of the script
if [ -z "${__nanolayer_location}" ]; then
if [ "$(uname -sm)" = 'Linux x86_64' ] || [ "$(uname -sm)" = "Linux aarch64" ]; then
tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX)
clean_up () {
ARG=$?
rm -rf $tmp_dir
exit $ARG
}
trap clean_up EXIT
if [ -x "/sbin/apk" ] ; then
clib_type=musl
else
clib_type=gnu
fi
tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz
# clean download will minimize leftover in case a downloaderlike wget or curl need to be installed
clean_download https://github.com/devcontainers-contrib/cli/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename
tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir"
chmod a+x $tmp_dir/nanolayer
__nanolayer_location=$tmp_dir/nanolayer
else
echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)"
exit 1
fi
fi
# Expose outside the resolved location
export ${variable_name}=$__nanolayer_location
}

10
test/wine/scenarios.json Normal file
View File

@ -0,0 +1,10 @@
{
"hello": {
"image": "mcr.microsoft.com/devcontainers/base:debian",
"features": {
"wine": {
"version": "8.15"
}
}
}
}

47
test/wine/test.sh Normal file
View File

@ -0,0 +1,47 @@
#!/bin/bash
# This test file will be executed against an auto-generated devcontainer.json that
# includes the 'hello' Feature with no options.
#
# For more information, see: https://github.com/devcontainers/cli/blob/main/docs/features/test.md
#
# Eg:
# {
# "image": "<..some-base-image...>",
# "features": {
# "hello": {}
# },
# "remoteUser": "root"
# }
#
# Thus, the value of all options will fall back to the default value in
# the Feature's 'devcontainer-feature.json'.
# For the 'hello' feature, that means the default favorite greeting is 'hey'.
#
# These scripts are run as 'root' by default. Although that can be changed
# with the '--remote-user' flag.
#
# This test can be run with the following command:
#
# devcontainer features test \
# --features hello \
# --remote-user root \
# --skip-scenarios \
# --base-image mcr.microsoft.com/devcontainers/base:ubuntu \
# /path/to/this/repo
set -e
# Optional: Import test library bundled with the devcontainer CLI
# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib
# Provides the 'check' and 'reportResults' commands.
source dev-container-features-test-lib
# Feature-specific tests
# The 'check' command comes from the dev-container-features-test-lib. Syntax is...
# check <LABEL> <cmd> [args...]
check "execute command" bash -c "hello | grep 'hey, $(whoami)!'"
# Report results
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults