Add support for skipping docker-compose
v1 operations during Docker feature install script (#533)
* Add support for skipping docker-compose operations * Move changes from auto-generated files to templates and bump version * Add test * Add test conditions * Add test conditions for docker-outside-of-docker * install.sh set -x for debugging * set -x * Move compose-switch check in docker-outside-of-docker test * Put into correct test * Test for correct path
This commit is contained in:
parent
b16ff1efb7
commit
4312340798
11 changed files with 152 additions and 87 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "docker-in-docker",
|
"id": "docker-in-docker",
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"name": "Docker (Docker-in-Docker)",
|
"name": "Docker (Docker-in-Docker)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker",
|
||||||
"description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.",
|
"description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.",
|
||||||
|
@ -23,11 +23,12 @@
|
||||||
"dockerDashComposeVersion": {
|
"dockerDashComposeVersion": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
"none",
|
||||||
"v1",
|
"v1",
|
||||||
"v2"
|
"v2"
|
||||||
],
|
],
|
||||||
"default": "v1",
|
"default": "v1",
|
||||||
"description": "Default version of Docker Compose (v1 or v2)"
|
"description": "Default version of Docker Compose (v1 or v2 or none)"
|
||||||
},
|
},
|
||||||
"azureDnsAutoDetection": {
|
"azureDnsAutoDetection": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version
|
DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version
|
||||||
USE_MOBY="${MOBY:-"true"}"
|
USE_MOBY="${MOBY:-"true"}"
|
||||||
DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2
|
DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 or none
|
||||||
AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}"
|
AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}"
|
||||||
DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}"
|
DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}"
|
||||||
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
||||||
|
@ -242,58 +242,61 @@ fi
|
||||||
|
|
||||||
echo "Finished installing docker / moby!"
|
echo "Finished installing docker / moby!"
|
||||||
|
|
||||||
# Install Docker Compose if not already installed and is on a supported architecture
|
# If 'docker-compose' command is to be included
|
||||||
if type docker-compose > /dev/null 2>&1; then
|
if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then
|
||||||
echo "Docker Compose v1 already installed."
|
# Install Docker Compose if not already installed and is on a supported architecture
|
||||||
else
|
if type docker-compose > /dev/null 2>&1; then
|
||||||
target_compose_arch="${architecture}"
|
echo "Docker Compose v1 already installed."
|
||||||
if [ "${target_compose_arch}" = "amd64" ]; then
|
|
||||||
target_compose_arch="x86_64"
|
|
||||||
fi
|
|
||||||
if [ "${target_compose_arch}" != "x86_64" ]; then
|
|
||||||
# Use pip to get a version that runs on this architecture
|
|
||||||
check_packages python3-minimal python3-pip libffi-dev python3-venv
|
|
||||||
export PIPX_HOME=/usr/local/pipx
|
|
||||||
mkdir -p ${PIPX_HOME}
|
|
||||||
export PIPX_BIN_DIR=/usr/local/bin
|
|
||||||
export PYTHONUSERBASE=/tmp/pip-tmp
|
|
||||||
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
|
|
||||||
pipx_bin=pipx
|
|
||||||
if ! type pipx > /dev/null 2>&1; then
|
|
||||||
pip3 install --disable-pip-version-check --no-cache-dir --user pipx
|
|
||||||
pipx_bin=/tmp/pip-tmp/bin/pipx
|
|
||||||
fi
|
|
||||||
${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
|
||||||
rm -rf /tmp/pip-tmp
|
|
||||||
else
|
else
|
||||||
compose_v1_version="1"
|
target_compose_arch="${architecture}"
|
||||||
find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/"
|
if [ "${target_compose_arch}" = "amd64" ]; then
|
||||||
echo "(*) Installing docker-compose ${compose_v1_version}..."
|
target_compose_arch="x86_64"
|
||||||
curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
|
fi
|
||||||
chmod +x /usr/local/bin/docker-compose
|
if [ "${target_compose_arch}" != "x86_64" ]; then
|
||||||
|
# Use pip to get a version that runs on this architecture
|
||||||
|
check_packages python3-minimal python3-pip libffi-dev python3-venv
|
||||||
|
export PIPX_HOME=/usr/local/pipx
|
||||||
|
mkdir -p ${PIPX_HOME}
|
||||||
|
export PIPX_BIN_DIR=/usr/local/bin
|
||||||
|
export PYTHONUSERBASE=/tmp/pip-tmp
|
||||||
|
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
|
||||||
|
pipx_bin=pipx
|
||||||
|
if ! type pipx > /dev/null 2>&1; then
|
||||||
|
pip3 install --disable-pip-version-check --no-cache-dir --user pipx
|
||||||
|
pipx_bin=/tmp/pip-tmp/bin/pipx
|
||||||
|
fi
|
||||||
|
${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
||||||
|
rm -rf /tmp/pip-tmp
|
||||||
|
else
|
||||||
|
compose_v1_version="1"
|
||||||
|
find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/"
|
||||||
|
echo "(*) Installing docker-compose ${compose_v1_version}..."
|
||||||
|
curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
|
||||||
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation
|
# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation
|
||||||
current_v1_compose_path="$(which docker-compose)"
|
current_v1_compose_path="$(which docker-compose)"
|
||||||
target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1"
|
target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1"
|
||||||
if ! type compose-switch > /dev/null 2>&1; then
|
if ! type compose-switch > /dev/null 2>&1; then
|
||||||
echo "(*) Installing compose-switch..."
|
echo "(*) Installing compose-switch..."
|
||||||
compose_switch_version="latest"
|
compose_switch_version="latest"
|
||||||
find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch"
|
find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch"
|
||||||
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch
|
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch
|
||||||
chmod +x /usr/local/bin/compose-switch
|
chmod +x /usr/local/bin/compose-switch
|
||||||
# TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11
|
# TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11
|
||||||
|
|
||||||
# Setup v1 CLI as alternative in addition to compose-switch (which maps to v2)
|
# Setup v1 CLI as alternative in addition to compose-switch (which maps to v2)
|
||||||
mv "${current_v1_compose_path}" "${target_v1_compose_path}"
|
mv "${current_v1_compose_path}" "${target_v1_compose_path}"
|
||||||
update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99
|
update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99
|
||||||
update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1
|
update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1
|
||||||
fi
|
fi
|
||||||
if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
|
if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
|
||||||
update-alternatives --set docker-compose "${target_v1_compose_path}"
|
update-alternatives --set docker-compose "${target_v1_compose_path}"
|
||||||
else
|
else
|
||||||
update-alternatives --set docker-compose /usr/local/bin/compose-switch
|
update-alternatives --set docker-compose /usr/local/bin/compose-switch
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If init file already exists, exit
|
# If init file already exists, exit
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "docker-outside-of-docker",
|
"id": "docker-outside-of-docker",
|
||||||
"version": "1.2.1",
|
"version": "1.3.0",
|
||||||
"name": "Docker (docker-outside-of-docker)",
|
"name": "Docker (docker-outside-of-docker)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker",
|
||||||
"description": "Re-use the host docker socket, adding the Docker CLI to a container. Feature invokes a script to enable using a forwarded Docker socket within a container to run Docker commands.",
|
"description": "Re-use the host docker socket, adding the Docker CLI to a container. Feature invokes a script to enable using a forwarded Docker socket within a container to run Docker commands.",
|
||||||
|
@ -23,11 +23,12 @@
|
||||||
"dockerDashComposeVersion": {
|
"dockerDashComposeVersion": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
"none",
|
||||||
"v1",
|
"v1",
|
||||||
"v2"
|
"v2"
|
||||||
],
|
],
|
||||||
"default": "v2",
|
"default": "v2",
|
||||||
"description": "Compose version to use for docker-compose (v1 or v2)"
|
"description": "Compose version to use for docker-compose (v1 or v2 or none)"
|
||||||
},
|
},
|
||||||
"installDockerBuildx": {
|
"installDockerBuildx": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
DOCKER_VERSION="${VERSION:-"latest"}"
|
DOCKER_VERSION="${VERSION:-"latest"}"
|
||||||
USE_MOBY="${MOBY:-"true"}"
|
USE_MOBY="${MOBY:-"true"}"
|
||||||
DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" # v1 or v2
|
DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 or none
|
||||||
|
|
||||||
ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}"
|
ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}"
|
||||||
SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}"
|
SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}"
|
||||||
|
@ -216,43 +216,46 @@ else
|
||||||
unset buildx buildx_path
|
unset buildx buildx_path
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install Docker Compose if not already installed and is on a supported architecture
|
# If 'docker-compose' command is to be included
|
||||||
if type docker-compose > /dev/null 2>&1; then
|
if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then
|
||||||
echo "Docker Compose already installed."
|
# Install Docker Compose if not already installed and is on a supported architecture
|
||||||
elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
|
if type docker-compose > /dev/null 2>&1; then
|
||||||
TARGET_COMPOSE_ARCH="$(uname -m)"
|
echo "Docker Compose already installed."
|
||||||
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
|
elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
|
||||||
TARGET_COMPOSE_ARCH="x86_64"
|
TARGET_COMPOSE_ARCH="$(uname -m)"
|
||||||
fi
|
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
|
||||||
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
|
TARGET_COMPOSE_ARCH="x86_64"
|
||||||
# Use pip to get a version that runs on this architecture
|
fi
|
||||||
check_packages python3-minimal python3-pip libffi-dev python3-venv
|
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
|
||||||
export PIPX_HOME=/usr/local/pipx
|
# Use pip to get a version that runs on this architecture
|
||||||
mkdir -p ${PIPX_HOME}
|
check_packages python3-minimal python3-pip libffi-dev python3-venv
|
||||||
export PIPX_BIN_DIR=/usr/local/bin
|
export PIPX_HOME=/usr/local/pipx
|
||||||
export PYTHONUSERBASE=/tmp/pip-tmp
|
mkdir -p ${PIPX_HOME}
|
||||||
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
|
export PIPX_BIN_DIR=/usr/local/bin
|
||||||
pipx_bin=pipx
|
export PYTHONUSERBASE=/tmp/pip-tmp
|
||||||
if ! type pipx > /dev/null 2>&1; then
|
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
|
||||||
pip3 install --disable-pip-version-check --no-cache-dir --user pipx
|
pipx_bin=pipx
|
||||||
pipx_bin=/tmp/pip-tmp/bin/pipx
|
if ! type pipx > /dev/null 2>&1; then
|
||||||
|
pip3 install --disable-pip-version-check --no-cache-dir --user pipx
|
||||||
|
pipx_bin=/tmp/pip-tmp/bin/pipx
|
||||||
|
fi
|
||||||
|
${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
||||||
|
rm -rf /tmp/pip-tmp
|
||||||
|
else
|
||||||
|
compose_v1_version="1"
|
||||||
|
find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/"
|
||||||
|
echo "(*) Installing docker-compose ${compose_v1_version}..."
|
||||||
|
curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
|
||||||
|
chmod +x /usr/local/bin/docker-compose
|
||||||
fi
|
fi
|
||||||
${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
|
||||||
rm -rf /tmp/pip-tmp
|
|
||||||
else
|
else
|
||||||
compose_v1_version="1"
|
echo "(*) Installing compose-switch as docker-compose..."
|
||||||
find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/"
|
compose_switch_version="latest"
|
||||||
echo "(*) Installing docker-compose ${compose_v1_version}..."
|
find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch"
|
||||||
curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
|
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose
|
||||||
chmod +x /usr/local/bin/docker-compose
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
# TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo "(*) Installing compose-switch as docker-compose..."
|
|
||||||
compose_switch_version="latest"
|
|
||||||
find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch"
|
|
||||||
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose
|
|
||||||
chmod +x /usr/local/bin/docker-compose
|
|
||||||
# TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Setup a docker group in the event the docker socket's group is not root
|
# Setup a docker group in the event the docker socket's group is not root
|
||||||
|
|
3
test/docker-in-docker/docker_build.sh
Normal file → Executable file
3
test/docker-in-docker/docker_build.sh
Normal file → Executable file
|
@ -9,5 +9,8 @@ source dev-container-features-test-lib
|
||||||
check "docker-buildx" docker buildx version
|
check "docker-buildx" docker buildx version
|
||||||
check "docker-build" docker build ./
|
check "docker-build" docker build ./
|
||||||
|
|
||||||
|
check "installs docker-compose v1 install" bash -c "type docker-compose"
|
||||||
|
check "installs compose-switch" bash -c "[[ -f /usr/local/bin/compose-switch ]]"
|
||||||
|
|
||||||
# Report result
|
# Report result
|
||||||
reportResults
|
reportResults
|
||||||
|
|
16
test/docker-in-docker/docker_build_no_compose.sh
Executable file
16
test/docker-in-docker/docker_build_no_compose.sh
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Optional: Import test library
|
||||||
|
source dev-container-features-test-lib
|
||||||
|
|
||||||
|
# Definition specific tests
|
||||||
|
check "docker-buildx" docker buildx version
|
||||||
|
check "docker-build" docker build ./
|
||||||
|
|
||||||
|
check "not installing compose skips docker-compose v1 install" bash -c "! type docker-compose"
|
||||||
|
check "not installing compose skips compose-switch" bash -c "[[ ! -f /usr/local/bin/compose-switch ]]"
|
||||||
|
|
||||||
|
# Report result
|
||||||
|
reportResults
|
|
@ -58,5 +58,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"remoteUser": "node"
|
"remoteUser": "node"
|
||||||
|
},
|
||||||
|
"docker_build_no_compose": {
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
|
||||||
|
"features": {
|
||||||
|
"docker-in-docker": {
|
||||||
|
"dockerDashComposeVersion": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"remoteUser": "node"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
2
test/docker-outside-of-docker/docker_build.sh
Normal file → Executable file
2
test/docker-outside-of-docker/docker_build.sh
Normal file → Executable file
|
@ -9,5 +9,7 @@ source dev-container-features-test-lib
|
||||||
check "docker-buildx" docker buildx version
|
check "docker-buildx" docker buildx version
|
||||||
check "docker-build" docker build ./
|
check "docker-build" docker build ./
|
||||||
|
|
||||||
|
check "installs docker-compose v1 install" bash -c "type docker-compose"
|
||||||
|
|
||||||
# Report result
|
# Report result
|
||||||
reportResults
|
reportResults
|
||||||
|
|
15
test/docker-outside-of-docker/docker_build_no_compose.sh
Executable file
15
test/docker-outside-of-docker/docker_build_no_compose.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Optional: Import test library
|
||||||
|
source dev-container-features-test-lib
|
||||||
|
|
||||||
|
# Definition specific tests
|
||||||
|
check "docker-buildx" docker buildx version
|
||||||
|
check "docker-build" docker build ./
|
||||||
|
|
||||||
|
check "not installing compose skips docker-compose v1 install" bash -c "! type docker-compose"
|
||||||
|
|
||||||
|
# Report result
|
||||||
|
reportResults
|
|
@ -9,5 +9,7 @@ source dev-container-features-test-lib
|
||||||
check "docker compose" bash -c "docker compose version | grep -E '2.[0-9]+.[0-9]+'"
|
check "docker compose" bash -c "docker compose version | grep -E '2.[0-9]+.[0-9]+'"
|
||||||
check "docker-compose" bash -c "docker-compose --version | grep -E '2.[0-9]+.[0-9]+'"
|
check "docker-compose" bash -c "docker-compose --version | grep -E '2.[0-9]+.[0-9]+'"
|
||||||
|
|
||||||
|
check "installs compose-switch as docker-compose" bash -c "[[ -f /usr/local/bin/docker-compose ]]"
|
||||||
|
|
||||||
# Report result
|
# Report result
|
||||||
reportResults
|
reportResults
|
||||||
|
|
|
@ -115,5 +115,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"containerUser": "vscode"
|
"containerUser": "vscode"
|
||||||
|
},
|
||||||
|
"docker_build_no_compose": {
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
|
||||||
|
"features": {
|
||||||
|
"docker-in-docker": {
|
||||||
|
"dockerDashComposeVersion": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"remoteUser": "node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue