зеркало из https://github.com/microsoft/MLOS.git
devcontainer build fixups for macOS clients (#874)
# Pull Request ## Title Fixups to the devcontainer build for macOS clients. --- ## Description - Use a more portalable random number generator - Address some differences in docker.sock privileges. - Address differences in `stat` arguments. - Switch to wget mode for conda installation to workaround lack of arm64 apt repo. - When pulling base images to prime cache, use the appropriate architecture (for Windows we only support amd64 for now). - Remove `:latest` from `cache-from` args for `podman` compliance. - Address some differences in `sed` syntax. - Fixes #873 --- ## Type of Change - 🛠️ Bug fix --- ## Testing - local MacBook testing - CI testing for Linux --- ## Additional Notes Doesn't currently do builds for arm64 platform in the pipeline. Can work towards addressing that in the future.
This commit is contained in:
Родитель
d2738e70e5
Коммит
72e10d1833
|
@ -64,12 +64,9 @@ COPY --from=deps-prep --chown=vscode:conda /tmp/conda-tmp/mlos_deps.yml /tmp/con
|
||||||
# Combine the installation of miniconda and the mlos dependencies into a single step in order to save space.
|
# Combine the installation of miniconda and the mlos dependencies into a single step in order to save space.
|
||||||
# This allows the mlos env to reference the base env's packages without duplication across layers.
|
# This allows the mlos env to reference the base env's packages without duplication across layers.
|
||||||
RUN echo "Setup miniconda" \
|
RUN echo "Setup miniconda" \
|
||||||
&& curl -Ss https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/conda.gpg > /dev/null \
|
&& curl -Ss --url https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-$(uname -m).sh -o /tmp/miniconda3.sh \
|
||||||
&& gpg --keyring /etc/apt/trusted.gpg.d/conda.gpg --no-default-keyring --fingerprint 34161F5BF5EB1D4BFBBB8F0A8AEB4F8B29D82806 \
|
&& sudo sh /tmp/miniconda3.sh -b -u -p /opt/conda \
|
||||||
&& echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/conda.gpg] https://repo.anaconda.com/pkgs/misc/debrepo/conda stable main" | sudo tee /etc/apt/sources.list.d/conda.list \
|
&& rm -rf /tmp/miniconda3.sh \
|
||||||
&& sudo apt-get update \
|
|
||||||
&& sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends conda \
|
|
||||||
&& sudo apt-get clean && sudo rm -rf /var/lib/apt/lists/* \
|
|
||||||
&& echo "# Adjust the conda installation to be user/group writable." \
|
&& echo "# Adjust the conda installation to be user/group writable." \
|
||||||
&& sudo /opt/conda/bin/conda init --system \
|
&& sudo /opt/conda/bin/conda init --system \
|
||||||
&& sudo chgrp -R conda /opt/conda \
|
&& sudo chgrp -R conda /opt/conda \
|
||||||
|
|
|
@ -35,7 +35,7 @@ if ("$env:NO_CACHE" -eq 'true') {
|
||||||
else {
|
else {
|
||||||
$cacheFrom = 'mloscore.azurecr.io/devcontainer-cli:latest'
|
$cacheFrom = 'mloscore.azurecr.io/devcontainer-cli:latest'
|
||||||
$devcontainer_cli_build_args += " --cache-from $cacheFrom"
|
$devcontainer_cli_build_args += " --cache-from $cacheFrom"
|
||||||
docker pull $cacheFrom
|
docker pull --platform linux/amd64 $cacheFrom
|
||||||
}
|
}
|
||||||
|
|
||||||
$cmd = "docker.exe build -t devcontainer-cli:latest -t cspell:latest " +
|
$cmd = "docker.exe build -t devcontainer-cli:latest -t cspell:latest " +
|
||||||
|
|
|
@ -10,20 +10,26 @@ set -eu
|
||||||
scriptdir=$(dirname "$(readlink -f "$0")")
|
scriptdir=$(dirname "$(readlink -f "$0")")
|
||||||
cd "$scriptdir/"
|
cd "$scriptdir/"
|
||||||
|
|
||||||
|
source ../common.sh
|
||||||
|
|
||||||
# Build the helper container that has the devcontainer CLI for building the devcontainer.
|
# Build the helper container that has the devcontainer CLI for building the devcontainer.
|
||||||
|
|
||||||
if [ ! -w /var/run/docker.sock ]; then
|
if [ ! -w /var/run/docker.sock ]; then
|
||||||
echo "ERROR: $USER does not have write access to /var/run/docker.sock. Please add $USER to the docker group." >&2
|
echo "ERROR: $USER does not have write access to /var/run/docker.sock. Please add $USER to the docker group." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
DOCKER_GID=$(stat -c'%g' /var/run/docker.sock)
|
DOCKER_GID=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker.sock)
|
||||||
# Make this work inside a devcontainer as well.
|
# Make this work inside a devcontainer as well.
|
||||||
if [ -w /var/run/docker-host.sock ]; then
|
if [ -w /var/run/docker-host.sock ]; then
|
||||||
DOCKER_GID=$(stat -c'%g' /var/run/docker-host.sock)
|
DOCKER_GID=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker-host.sock)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-1}
|
export DOCKER_BUILDKIT=${DOCKER_BUILDKIT:-1}
|
||||||
|
|
||||||
|
# TODO: Add multiplatform build support?
|
||||||
|
#devcontainer_cli_build_args='--platform linux/amd64,linux/arm64'
|
||||||
devcontainer_cli_build_args=''
|
devcontainer_cli_build_args=''
|
||||||
|
|
||||||
if docker buildx version 2>/dev/null; then
|
if docker buildx version 2>/dev/null; then
|
||||||
devcontainer_cli_build_args+=' --progress=plain'
|
devcontainer_cli_build_args+=' --progress=plain'
|
||||||
else
|
else
|
||||||
|
@ -33,10 +39,10 @@ fi
|
||||||
if [ "${NO_CACHE:-}" == 'true' ]; then
|
if [ "${NO_CACHE:-}" == 'true' ]; then
|
||||||
devcontainer_cli_build_args+=' --no-cache --pull'
|
devcontainer_cli_build_args+=' --no-cache --pull'
|
||||||
else
|
else
|
||||||
cacheFrom='mloscore.azurecr.io/devcontainer-cli:latest'
|
cacheFrom='mloscore.azurecr.io/devcontainer-cli'
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
devcontainer_cli_build_args+=" --cache-from $cacheFrom"
|
devcontainer_cli_build_args+=" --cache-from $cacheFrom"
|
||||||
docker --config="$tmpdir" pull "$cacheFrom" || true
|
docker --config="$tmpdir" pull --platform linux/$(uname -m) "$cacheFrom" || true
|
||||||
rmdir "$tmpdir"
|
rmdir "$tmpdir"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,13 @@ if ($null -eq $env:DOCKER_BUILDKIT) {
|
||||||
$devcontainer_build_args = ''
|
$devcontainer_build_args = ''
|
||||||
if ("$env:NO_CACHE" -eq 'true') {
|
if ("$env:NO_CACHE" -eq 'true') {
|
||||||
$base_image = (Get-Content "$rootdir/.devcontainer/Dockerfile" | Select-String '^FROM' | Select-Object -ExpandProperty Line | ForEach-Object { $_ -replace '^FROM\s+','' } | ForEach-Object { $_ -replace ' AS\s+.*','' } | Select-Object -First 1)
|
$base_image = (Get-Content "$rootdir/.devcontainer/Dockerfile" | Select-String '^FROM' | Select-Object -ExpandProperty Line | ForEach-Object { $_ -replace '^FROM\s+','' } | ForEach-Object { $_ -replace ' AS\s+.*','' } | Select-Object -First 1)
|
||||||
docker pull $base_image
|
docker pull --platform linux/amd64 $base_image
|
||||||
$devcontainer_build_args = '--no-cache'
|
$devcontainer_build_args = '--no-cache'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$cacheFrom = 'mloscore.azurecr.io/mlos-devcontainer:latest'
|
$cacheFrom = 'mloscore.azurecr.io/mlos-devcontainer:latest'
|
||||||
$devcontainer_build_args = "--cache-from $cacheFrom"
|
$devcontainer_build_args = "--cache-from $cacheFrom"
|
||||||
docker pull "$cacheFrom"
|
docker pull --platform linux/amd64 "$cacheFrom"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make this work inside a devcontainer as well.
|
# Make this work inside a devcontainer as well.
|
||||||
|
|
|
@ -12,16 +12,21 @@ repo_root=$(readlink -f "$scriptdir/../..")
|
||||||
repo_name=$(basename "$repo_root")
|
repo_name=$(basename "$repo_root")
|
||||||
cd "$scriptdir/"
|
cd "$scriptdir/"
|
||||||
|
|
||||||
|
source ../common.sh
|
||||||
|
|
||||||
DEVCONTAINER_IMAGE="devcontainer-cli:latest"
|
DEVCONTAINER_IMAGE="devcontainer-cli:latest"
|
||||||
MLOS_AUTOTUNING_IMAGE="mlos-devcontainer:latest"
|
MLOS_AUTOTUNING_IMAGE="mlos-devcontainer:latest"
|
||||||
|
|
||||||
# Build the helper container that has the devcontainer CLI for building the devcontainer.
|
# Build the helper container that has the devcontainer CLI for building the devcontainer.
|
||||||
NO_CACHE=${NO_CACHE:-} ./build-devcontainer-cli.sh
|
NO_CACHE=${NO_CACHE:-} ./build-devcontainer-cli.sh
|
||||||
|
|
||||||
DOCKER_GID=$(stat -c'%g' /var/run/docker.sock)
|
DOCKER_GID=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker.sock)
|
||||||
# Make this work inside a devcontainer as well.
|
# Make this work inside a devcontainer as well.
|
||||||
if [ -w /var/run/docker-host.sock ]; then
|
if [ -w /var/run/docker-host.sock ]; then
|
||||||
DOCKER_GID=$(stat -c'%g' /var/run/docker-host.sock)
|
DOCKER_GID=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker-host.sock)
|
||||||
|
fi
|
||||||
|
if [[ $OSTYPE =~ darwin* ]]; then
|
||||||
|
DOCKER_GID=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build the devcontainer image.
|
# Build the devcontainer image.
|
||||||
|
@ -30,7 +35,7 @@ rootdir="$repo_root"
|
||||||
# Run the initialize command on the host first.
|
# Run the initialize command on the host first.
|
||||||
# Note: command should already pull the cached image if possible.
|
# Note: command should already pull the cached image if possible.
|
||||||
pwd
|
pwd
|
||||||
devcontainer_json=$(cat "$rootdir/.devcontainer/devcontainer.json" | sed -e 's|^\s*//.*||' -e 's|/\*|\n&|g;s|*/|&\n|g' | sed -e '/\/\*/,/*\//d')
|
devcontainer_json=$(cat "$rootdir/.devcontainer/devcontainer.json" | sed -e 's|^[ \t]*//.*||' -e 's|/\*|\n&|g;s|*/|&\n|g' | sed -e '/\/\*/,/*\//d')
|
||||||
initializeCommand=$(echo "$devcontainer_json" | docker run -i --rm $DEVCONTAINER_IMAGE jq -e -r '.initializeCommand[]')
|
initializeCommand=$(echo "$devcontainer_json" | docker run -i --rm $DEVCONTAINER_IMAGE jq -e -r '.initializeCommand[]')
|
||||||
if [ -z "$initializeCommand" ]; then
|
if [ -z "$initializeCommand" ]; then
|
||||||
echo "No initializeCommand found in devcontainer.json" >&2
|
echo "No initializeCommand found in devcontainer.json" >&2
|
||||||
|
@ -39,16 +44,18 @@ else
|
||||||
eval "pushd "$rootdir/"; $initializeCommand; popd"
|
eval "pushd "$rootdir/"; $initializeCommand; popd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# TODO: Add multi-platform build support?
|
||||||
|
#devcontainer_build_args='--platform linux/amd64,linux/arm64'
|
||||||
devcontainer_build_args=''
|
devcontainer_build_args=''
|
||||||
if [ "${NO_CACHE:-}" == 'true' ]; then
|
if [ "${NO_CACHE:-}" == 'true' ]; then
|
||||||
base_image=$(grep '^FROM ' "$rootdir/.devcontainer/Dockerfile" | sed -e 's/^FROM //' -e 's/ AS .*//' | head -n1)
|
base_image=$(grep '^FROM ' "$rootdir/.devcontainer/Dockerfile" | sed -e 's/^FROM //' -e 's/ AS .*//' | head -n1)
|
||||||
docker pull "$base_image" || true
|
docker pull --platform linux/$(uname -m) "$base_image" || true
|
||||||
devcontainer_build_args='--no-cache'
|
devcontainer_build_args='--no-cache'
|
||||||
else
|
else
|
||||||
cache_from='mloscore.azurecr.io/mlos-devcontainer:latest'
|
cache_from='mloscore.azurecr.io/mlos-devcontainer'
|
||||||
devcontainer_build_args="--cache-from $cache_from --cache-from mlos-devcontainer:latest"
|
devcontainer_build_args="--cache-from $cache_from --cache-from mlos-devcontainer"
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
docker --config="$tmpdir" pull "$cache_from" || true
|
docker --config="$tmpdir" pull --platform linux/$(uname -m) "$cache_from" || true
|
||||||
rmdir "$tmpdir"
|
rmdir "$tmpdir"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
##
|
||||||
|
## Copyright (c) Microsoft Corporation.
|
||||||
|
## Licensed under the MIT License.
|
||||||
|
##
|
||||||
|
case $OSTYPE in
|
||||||
|
linux*)
|
||||||
|
STAT_FORMAT_GID_ARGS="-c%g"
|
||||||
|
STAT_FORMAT_INODE_ARGS="-c%i"
|
||||||
|
;;
|
||||||
|
darwin*)
|
||||||
|
STAT_FORMAT_GID_ARGS="-f%g"
|
||||||
|
STAT_FORMAT_INODE_ARGS="-f%i"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "ERROR: Unhandled OSTYPE: $OSTYPE"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -20,7 +20,8 @@ if [ ! -f .env ]; then
|
||||||
fi
|
fi
|
||||||
# Also prep the random NGINX_PORT for the docker-compose command.
|
# Also prep the random NGINX_PORT for the docker-compose command.
|
||||||
if ! [ -e .devcontainer/.env ] || ! egrep -q "^NGINX_PORT=[0-9]+$" .devcontainer/.env; then
|
if ! [ -e .devcontainer/.env ] || ! egrep -q "^NGINX_PORT=[0-9]+$" .devcontainer/.env; then
|
||||||
NGINX_PORT=$(($(shuf -i 0-30000 -n 1) + 80))
|
RANDOM=$$
|
||||||
|
NGINX_PORT=$((($RANDOM % 30000) + 1 + 80))
|
||||||
echo "NGINX_PORT=$NGINX_PORT" > .devcontainer/.env
|
echo "NGINX_PORT=$NGINX_PORT" > .devcontainer/.env
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -55,6 +56,6 @@ if [ "${NO_CACHE:-}" != 'true' ]; then
|
||||||
## Make sure we use an empty config to avoid auth issues for devs with the
|
## Make sure we use an empty config to avoid auth issues for devs with the
|
||||||
## registry, which should allow anonymous pulls
|
## registry, which should allow anonymous pulls
|
||||||
#tmpdir=$(mktemp -d)
|
#tmpdir=$(mktemp -d)
|
||||||
#docker --config="$tmpdir" pull -q "$cacheFrom" >/dev/null || true
|
#docker --config="$tmpdir" pull --platform linux/$(uname -m) -q "$cacheFrom" >/dev/null || true
|
||||||
#rmdir "$tmpdir"
|
#rmdir "$tmpdir"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -49,5 +49,5 @@ if ($env:NO_CACHE -ne 'true') {
|
||||||
$cacheFrom = 'mloscore.azurecr.io/mlos-devcontainer'
|
$cacheFrom = 'mloscore.azurecr.io/mlos-devcontainer'
|
||||||
# Skip pulling for now (see TODO note above)
|
# Skip pulling for now (see TODO note above)
|
||||||
Write-Host "Consider pulling image $cacheFrom for build caching."
|
Write-Host "Consider pulling image $cacheFrom for build caching."
|
||||||
#docker pull $cacheFrom
|
#docker pull --platform linux/amd64 $cacheFrom
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,20 @@ repo_root=$(readlink -f "$scriptdir/../..")
|
||||||
repo_name=$(basename "$repo_root")
|
repo_name=$(basename "$repo_root")
|
||||||
cd "$repo_root"
|
cd "$repo_root"
|
||||||
|
|
||||||
container_name="$repo_name.$(stat -c%i "$repo_root/")"
|
source .devcontainer/common.sh
|
||||||
|
|
||||||
|
container_name="$repo_name.$(stat $STAT_FORMAT_INODE_ARGS "$repo_root/")"
|
||||||
|
|
||||||
# Be sure to use the host workspace folder if available.
|
# Be sure to use the host workspace folder if available.
|
||||||
workspace_root=${LOCAL_WORKSPACE_FOLDER:-$repo_root}
|
workspace_root=${LOCAL_WORKSPACE_FOLDER:-$repo_root}
|
||||||
|
|
||||||
if [ -e /var/run/docker-host.sock ]; then
|
if [ -e /var/run/docker-host.sock ]; then
|
||||||
docker_gid=$(stat -c%g /var/run/docker-host.sock)
|
docker_gid=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker-host.sock)
|
||||||
else
|
else
|
||||||
docker_gid=$(stat -c%g /var/run/docker.sock)
|
docker_gid=$(stat $STAT_FORMAT_GID_ARGS /var/run/docker.sock)
|
||||||
|
fi
|
||||||
|
if [[ $OSTYPE =~ darwin* ]]; then
|
||||||
|
docker_gid=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"ms-python.pylint",
|
"ms-python.pylint",
|
||||||
"ms-python.python",
|
"ms-python.python",
|
||||||
"ms-python.vscode-pylance",
|
"ms-python.vscode-pylance",
|
||||||
|
"ms-vscode-remote.remote-containers",
|
||||||
"ms-vsliveshare.vsliveshare",
|
"ms-vsliveshare.vsliveshare",
|
||||||
"njpwerner.autodocstring",
|
"njpwerner.autodocstring",
|
||||||
"redhat.vscode-yaml",
|
"redhat.vscode-yaml",
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -23,7 +23,7 @@ MKDIR_BUILD := $(shell test -d build || mkdir build)
|
||||||
#CONDA_INFO_LEVEL ?= -q
|
#CONDA_INFO_LEVEL ?= -q
|
||||||
|
|
||||||
# Run make in parallel by default.
|
# Run make in parallel by default.
|
||||||
MAKEFLAGS += -j$(shell nproc)
|
MAKEFLAGS += -j$(shell nproc 2>/dev/null || sysctl -n hw.ncpu)
|
||||||
#MAKEFLAGS += -Oline
|
#MAKEFLAGS += -Oline
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
Загрузка…
Ссылка в новой задаче