diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 287ca85650b..15ca9b3f7f8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -34,4 +34,10 @@ RUN echo 'complete -F __start_kubectl k' >> "/home/vscode/.bashrc" RUN curl -sL "https://raw.githubusercontent.com/go-task/task/v3.0.0/completion/bash/task.bash" > "/home/vscode/.task.completion.sh" \ && echo 'source /home/vscode/.task.completion.sh' >> /home/vscode/.bashrc -ENV KIND_CLUSTER_NAME=k8sinfra +ENV KIND_CLUSTER_NAME=aso + +# install docker, from: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md +COPY library-scripts/docker-debian.sh /tmp/library-scripts/ +RUN bash /tmp/library-scripts/docker-debian.sh +ENTRYPOINT ["/usr/local/share/docker-init.sh"] +CMD ["sleep", "infinity"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9e26fba16c9..42b857c334e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,11 @@ { "name": "Go", "build": { "dockerfile": "Dockerfile" }, - "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], + "runArgs": [ + "--cap-add=SYS_PTRACE", + "--security-opt", "seccomp=unconfined", + "--init", // runs an init process: https://docs.docker.com/engine/reference/run/#specify-an-init-process + ], // Set *default* container specific settings.json values on container create. "settings": { @@ -34,5 +38,9 @@ // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "go version", - "remoteUser": "vscode" + "remoteUser": "vscode", + + // to allow docker use from inside container: https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-from-docker + "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], + "overrideCommand": false } diff --git a/.devcontainer/library-scripts/docker-debian.sh b/.devcontainer/library-scripts/docker-debian.sh new file mode 100644 index 00000000000..dca4a0eac3c --- /dev/null +++ b/.devcontainer/library-scripts/docker-debian.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- +# +# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md +# Maintainer: The VS Code and Codespaces Teams +# +# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby] + +ENABLE_NONROOT_DOCKER=${1:-"true"} +SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"} +TARGET_SOCKET=${3:-"/var/run/docker.sock"} +USERNAME=${4:-"automatic"} +USE_MOBY=${5:-"true"} + +set -e + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Determine the appropriate non-root user +if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in ${POSSIBLE_USERS[@]}; do + if id -u ${CURRENT_USER} > /dev/null 2>&1; then + USERNAME=${CURRENT_USER} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi +elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then + USERNAME=root +fi + +# Function to run apt-get if needed +apt-get-update-if-needed() +{ + if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update + else + echo "Skipping apt-get update." + fi +} + +# Ensure apt is in non-interactive to avoid prompts +export DEBIAN_FRONTEND=noninteractive + +# Install apt-transport-https, curl, lsb-release, gpg if missing +if ! dpkg -s apt-transport-https curl ca-certificates lsb-release > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then + apt-get-update-if-needed + apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates lsb-release gnupg2 +fi + +# Install Docker / Moby CLI if not already installed +if type docker > /dev/null 2>&1; then + echo "Docker / Moby CLI already installed." +else + if [ "${USE_MOBY}" = "true" ]; then + DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]') + CODENAME=$(lsb_release -cs) + curl -s https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT) + echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-${DISTRO}-${CODENAME}-prod ${CODENAME} main" > /etc/apt/sources.list.d/microsoft.list + apt-get update + apt-get -y install --no-install-recommends moby-cli moby-buildx + else + curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT) + echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list + apt-get update + apt-get -y install --no-install-recommends docker-ce-cli + fi +fi + +# Install Docker Compose if not already installed +if type docker-compose > /dev/null 2>&1; then + echo "Docker Compose already installed." +else + LATEST_COMPOSE_VERSION=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)") + curl -fsSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose +fi + +# If init file already exists, exit +if [ -f "/usr/local/share/docker-init.sh" ]; then + exit 0 +fi + +# By default, make the source and target sockets the same +if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then + touch "${SOURCE_SOCKET}" + ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}" +fi + +# Add a stub if not adding non-root user access, user is root +if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then + echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh + chmod +x /usr/local/share/docker-init.sh + exit 0 +fi + +# If enabling non-root access and specified user is found, setup socat and add script +chown -h "${USERNAME}":root "${TARGET_SOCKET}" +if ! dpkg -s socat > /dev/null 2>&1; then + apt-get-update-if-needed + apt-get -y install socat +fi +tee /usr/local/share/docker-init.sh > /dev/null \ +<< EOF +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +set -e + +SOCAT_PATH_BASE=/tmp/vscr-docker-from-docker +SOCAT_LOG=\${SOCAT_PATH_BASE}.log +SOCAT_PID=\${SOCAT_PATH_BASE}.pid + +# Wrapper function to only use sudo if not already root +sudoIf() +{ + if [ "\$(id -u)" -ne 0 ]; then + sudo "\$@" + else + "\$@" + fi +} + +# Log messages +log() +{ + echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null +} + +echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null +log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}" + +# If enabled, try to add a docker group with the right GID. If the group is root, +# fall back on using socat to forward the docker socket to another unix socket so +# that we can set permissions on it without affecting the host. +if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then + SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET}) + if [ "\${SOCKET_GID}" != "0" ]; then + log "Adding user to group with GID \${SOCKET_GID}." + if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then + sudoIf groupadd --gid \${SOCKET_GID} docker-host + fi + # Add user to group if not already in it + if [ "\$(id ${USERNAME} | grep -E "groups.*(=|,)\${SOCKET_GID}\(")" = "" ]; then + sudoIf usermod -aG \${SOCKET_GID} ${USERNAME} + fi + else + # Enable proxy if not already running + if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then + log "Enabling socket proxy." + log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode" + sudoIf rm -rf ${TARGET_SOCKET} + (sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null) + else + log "Socket proxy already running." + fi + fi + log "Success" +fi + +# Execute whatever commands were passed in (if any). This allows us +# to set this script to ENTRYPOINT while still executing the default CMD. +set +e +exec "\$@" +EOF +chmod +x /usr/local/share/docker-init.sh +chown ${USERNAME}:root /usr/local/share/docker-init.sh +echo "Done!" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a0d83131ce6..c484cc9ee11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,13 +48,13 @@ jobs: # This controller requires cert-manager and can be installed with: kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v0.13.0/cert-manager.yaml - kubectl apply namespace k8s-infra-system + kubectl apply namespace azureoperator-system cat < 86400) | .Name'`; \ + | jq -r '.[] | select(.Name | test("^asotest")) | select(.CreatedAt == null or now-(.CreatedAt | fromdate) > 86400) | .Name'`; \ for rgname in ${rgs[@]} ; do \ echo "$rgname will be deleted"; \ az group delete --name $rgname --no-wait --yes; \ diff --git a/hack/README-old_root.md b/hack/README-old_root.md index 783ec2dc065..ee37c1fbc93 100644 --- a/hack/README-old_root.md +++ b/hack/README-old_root.md @@ -23,20 +23,20 @@ This project is experimental and is not supported. - Long term support ## Getting Started -To get started you are going to need a cluster to deploy k8s-infra. You can use any 1.16.0+ K8s +To get started you are going to need a cluster to deploy `azure-service-operator`. You can use any 1.16.0+ K8s cluster. To get going quicker, just spin up a local cluster using [Kind](https://kind.sigs.k8s.io). -To get started using the Azure k8s-infra infrastructure provider, visit our [releases](https://github.com/Azure/azure-service-operator/releases), +To get started using the Azure `azure-service-operator` infrastructure provider, visit our [releases](https://github.com/Azure/azure-service-operator/releases), and follow the instructions for the latest release. Once the controller has been installed in your cluster, you should be able to run the following: ```bash $ k get pod -A -NAMESPACE NAME READY STATUS RESTARTS AGE -k8s-infra-system k8s-infra-controller-manager-b98bc664-6h6sv 2/2 Running 0 7m15s +NAMESPACE NAME READY STATUS RESTARTS AGE +azureoperator-system aso-controller-manager-b98bc664-6h6sv 2/2 Running 0 7m15s # check out the logs for the running controller -$ k logs pod/k8s-infra-controller-manager-b98bc664-6h6sv -n k8s-infra-system -c manager +$ k logs pod/aso-controller-manager-b98bc664-6h6sv -n azureoperator-system -c manager # let's create an Azure ResourceGroup in westus2 with the name "foo-2019" cat <