diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 058abaae..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# [Choice] Go version: 1, 1.16, 1.15 -ARG VARIANT=1.18 -FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT} - -# [Option] Install Node.js -ARG DEBIAN_FRONTEND=noninteractive -ARG INSTALL_NODE="true" -ARG NODE_VERSION="lts/*" -RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi \ - # Install Python - && apt-get update \ - && apt-get install -y python3.6 python3-pip \ - # Clean up - && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts - -# Install CI Tools -RUN apt-get update \ - && apt-get install -y shellcheck \ - && su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g markdownlint-cli" 2>&1 \ - && pip3 install pre-commit \ - # Clean up - && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts - -COPY ./scripts /tmp/scripts -RUN apt-get update \ - # Install Go Dev Tools - && bash /tmp/scripts/install_go_dev_tools.sh \ - # Install Docker CLI - && bash /tmp/scripts/docker-debian.sh \ - && rm -rf /tmp/scripts - -# [Optional] Uncomment this section to install additional OS packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends - -# [Optional] Uncomment the next line to use go get to install anything else you need -# RUN go get -x - -# [Optional] Uncomment this line to install global node packages. -# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 - -ENTRYPOINT ["/usr/local/share/docker-init.sh"] -CMD ["sleep", "infinity"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4fca6e11..968c04ba 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,68 +1,35 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/python { - "name": "Go", - "build": { - "dockerfile": "Dockerfile", - "args": { - // Update the VARIANT arg to pick a version of Go: 1, 1.16, 1.15 - "VARIANT": "1.18", - // Options - "INSTALL_NODE": "true", - "NODE_VERSION": "lts/*" - } - }, - "overrideCommand": false, - "mounts": [ - "source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind", - "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/root/.ssh-copy,type=bind,consistency=cached" - ], - // Use this environment variable if you need to bind mount your local source code into a new container. - "remoteEnv": { - "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" - }, - "runArgs": [ - "--init", - "--cap-add=SYS_PTRACE", - "--security-opt", - "seccomp=unconfined" - ], - // Set *default* container specific settings.json values on container create. - "settings": { - "terminal.integrated.defaultProfile.linux": "zsh", - "go.toolsManagement.checkForUpdates": "local", - "go.useLanguageServer": true, - "go.gopath": "/go", - "go.goroot": "/usr/local/go", - "go.formatTool": "goimports", - "go.lintTool": "golangci-lint", - "go.lintFlags": [ - "--fast" - ], - "go.coverOnSave": true, - "go.coverageDecorator": { - "type": "gutter", - "coveredHighlightColor": "rgba(64,128,128,0.5)", - "uncoveredHighlightColor": "rgba(128,64,64,0.25)", - "coveredGutterStyle": "blockgreen", - "uncoveredGutterStyle": "blockred" + "name": "woke", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/python:0-3-bullseye", + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/go:1": { + "version": "1.18" }, - "go.coverOnSingleTest": true, - "editor.formatOnSave": true, - "files.insertFinalNewline": true, - "files.trimFinalNewlines": true, - "files.trimTrailingWhitespace": true + "ghcr.io/guiyomh/features/golangci-lint:0": {}, + "ghcr.io/lukewiwa/features/shellcheck:0": {} }, - // Add the IDs of extensions you want installed when the container is created. + + // Extensions for use in VS Code "extensions": [ - "golang.Go", // Go Extension - "timonwong.shellcheck", // Shellcheck - "davidanson.vscode-markdownlint", // Markdownlint - "eamodio.gitlens", // IDE Git information - "ms-azuretools.vscode-docker" // Docker + "golang.go", + "timonwong.shellcheck", + "davidanson.vscode-markdownlint", + "eamodio.gitlens" ], + // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "mkdir -p /root/.ssh && cp -r /root/.ssh-copy/* /root/.ssh && chmod 700 /root/.ssh && chmod 600 /root/.ssh/id_rsa && chmod 644 /root/.ssh/id_rsa.pub && pre-commit install", - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" + "postCreateCommand": "./.devcontainer/scripts/install_go_dev_tools.sh && pip3 install pre-commit && pre-commit install" + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" } diff --git a/.devcontainer/scripts/docker-debian.sh b/.devcontainer/scripts/docker-debian.sh deleted file mode 100755 index 77a94363..00000000 --- a/.devcontainer/scripts/docker-debian.sh +++ /dev/null @@ -1,303 +0,0 @@ -#!/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] [CLI version] -# shellcheck disable=SC2068,SC2086,SC2155,SC2012,SC2236,SC1091 - -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"} -DOCKER_VERSION=${6:-"latest"} -MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" -DOCKER_DASH_COMPOSE_VERSION="1" - -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 - -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - -# 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 -} - -# Checks if packages are installed and installs them if not -check_packages() { - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update_if_needed - apt-get -y install --no-install-recommends "$@" - fi -} - -# Figure out correct version of a three part version number is not passed -find_version_from_git_tags() { - local variable_name=$1 - local requested_version=${!variable_name} - if [ "${requested_version}" = "none" ]; then return; fi - local repository=$2 - local prefix=${3:-"tags/v"} - local separator=${4:-"."} - local last_part_optional=${5:-"false"} - if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then - local escaped_separator=${separator//./\\.} - local last_part - if [ "${last_part_optional}" = "true" ]; then - last_part="(${escaped_separator}[0-9]+)?" - else - last_part="${escaped_separator}[0-9]+" - fi - local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" - local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" - if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then - declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" - else - set +e - declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" - set -e - fi - fi - if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then - echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 - exit 1 - fi - echo "${variable_name}=${!variable_name}" -} - -# Ensure apt is in non-interactive to avoid prompts -export DEBIAN_FRONTEND=noninteractive - -# Install dependencies -check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr -if ! type git > /dev/null 2>&1; then - apt_get_update_if_needed - apt-get -y install git -fi - -# Source /etc/os-release to get OS info -. /etc/os-release -# Fetch host/container arch. -architecture="$(dpkg --print-architecture)" - -# Set up the necessary apt repos (either Microsoft's or Docker's) -if [ "${USE_MOBY}" = "true" ]; then - - cli_package_name="moby-cli" - - # Import key safely and import Microsoft apt repo - get_common_setting MICROSOFT_GPG_KEYS_URI - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list -else - # Name of proprietary engine package - cli_package_name="docker-ce-cli" - - # Import key safely and import Docker apt repo - curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list -fi - -# Refresh apt lists -apt-get update - -# Soft version matching for CLI -if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then - # Empty, meaning grab whatever "latest" is in apt repo - cli_version_suffix="" -else - # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...) - docker_version_dot_escaped="${DOCKER_VERSION//./\\.}" - docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}" - # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ - docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" - set +e # Don't exit if finding version fails - will handle gracefully - cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" - set -e - if [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ]; then - echo "(!) No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" - apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' - exit 1 - fi - echo "cli_version_suffix ${cli_version_suffix}" -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 - apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx - apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." - else - apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} - fi -fi - -# Install Docker Compose if not already installed and is on a supported architecture -if type docker-compose > /dev/null 2>&1; then - echo "Docker Compose already installed." -else - TARGET_COMPOSE_ARCH="$(uname -m)" - 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 runns on this architecture - if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then - apt_get_update_if_needed - apt-get -y install python3-minimal python3-pip libffi-dev python3-venv - fi - 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-warn-script-location --no-cache-dir --user pipx - pipx_bin=/tmp/pip-tmp/bin/pipx - fi - ${pipx_bin} install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose - rm -rf /tmp/pip-tmp - else - find_version_from_git_tags DOCKER_DASH_COMPOSE_VERSION "https://github.com/docker/compose" "tags/" - echo "(*) Installing docker-compose ${DOCKER_DASH_COMPOSE_VERSION}..." - curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_DASH_COMPOSE_VERSION}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose - chmod +x /usr/local/bin/docker-compose - fi -fi - -# If init file already exists, exit -if [ -f "/usr/local/share/docker-init.sh" ]; then - exit 0 -fi -echo "docker-init doesnt exist, adding..." - -# 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/.pre-commit-config.yaml b/.pre-commit-config.yaml index ca55abcb..5f45a837 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ # First: Install pre-commit https://pre-commit.com/#install # Then, run `pre-commit install` repos: - - repo: git://github.com/caitlinelfring/pre-commit-golang + - repo: https://github.com/caitlinelfring/pre-commit-golang rev: v0.4.0 hooks: - id: go-fmt