From f6594c923160ca8643e84698463bff2f513a1df7 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 20:17:09 +0000 Subject: [PATCH 1/7] test: use base ubuntu:noble image for testing template --- .github/workflows/release.yaml | 5 +++- .github/workflows/test-image.yaml | 2 +- .github/workflows/test-template.yaml | 24 +++++++------------ images/simple-workspace/Dockerfile | 26 -------------------- templates/docker/homelab-workspace/main.tf | 28 ++++++++++++++++------ 5 files changed, 34 insertions(+), 51 deletions(-) delete mode 100644 images/simple-workspace/Dockerfile diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 29fe43ce..a292368e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -87,6 +87,7 @@ jobs: echo "sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" publish-image: + if: github.event_name == 'workflow_dispatch' needs: [create-release] uses: ppat/images/.github/workflows/build-image-workflow.yaml@main with: @@ -106,8 +107,9 @@ jobs: FETCH_GH_TOKEN=${{ secrets.GITHUB_TOKEN }} publish-template: - runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' needs: [create-release, publish-image] + runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout @@ -178,6 +180,7 @@ jobs: coder template push \ --directory ${TEMPLATE_DIR} \ --var workspace_image=${WORKSPACE_IMAGE} \ + --var test_mode=false \ --name ${TEMPLATE_VERSION} \ --message "${RELEASE_MSG}" \ --yes \ diff --git a/.github/workflows/test-image.yaml b/.github/workflows/test-image.yaml index 719aa621..01668b4c 100644 --- a/.github/workflows/test-image.yaml +++ b/.github/workflows/test-image.yaml @@ -6,7 +6,7 @@ name: "test image" on: pull_request: paths: - - 'images/**' + - 'images/homelab-workspace/**' - '.github/workflows/test-image.yaml' workflow_dispatch: diff --git a/.github/workflows/test-template.yaml b/.github/workflows/test-template.yaml index d3de78fa..c910abd1 100644 --- a/.github/workflows/test-template.yaml +++ b/.github/workflows/test-template.yaml @@ -58,21 +58,6 @@ jobs: # renovate: datasource=github-releases depName=nestybox/sysbox SYSBOX_VERSION: "0.6.4" - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3 - with: - driver-opts: network=host - - - name: Build image for testing template - uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c # v6 - with: - context: ./images/simple-workspace - load: true - push: false - tags: simple-workspace:latest - allow: network.host - network: host - - name: Start local coder instance # yamllint disable-line rule:indentation run: | @@ -123,7 +108,14 @@ jobs: export TEMPLATE_NAME="test-$(date --utc +%Y%m%d-%H%M%SZ)" echo "TEMPLATE_NAME=${TEMPLATE_NAME}" >> $GITHUB_ENV echo "Publishing template ${TEMPLATE_DIR} as ${TEMPLATE_NAME}..." - coder template push --directory ${TEMPLATE_DIR} --var workspace_image=simple-workspace:latest --yes ${TEMPLATE_NAME} + set -x + coder template push \ + --directory ${TEMPLATE_DIR} \ + --var workspace_image=ubuntu:noble \ + --var test_mode=true \ + --yes \ + ${TEMPLATE_NAME} + set +x echo echo "Confirming template has been published..." diff --git a/images/simple-workspace/Dockerfile b/images/simple-workspace/Dockerfile deleted file mode 100644 index 31f2d36c..00000000 --- a/images/simple-workspace/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM ubuntu:noble@sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30 - -# shell options to ensure RUN statements fail on error -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -# minimum requirements for running coder agent -RUN apt-get update && \ - DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends \ - bash \ - curl \ - git \ - sudo \ - unzip \ - wget && \ - apt-get autoremove -y && \ - apt-get clean -y && \ - apt-get autoremove -y && \ - apt-get clean -y && \ - rm -rf /tmp/* /var/cache/debconf/* /var/cache/python/* /var/lib/apt/lists/* /var/log/* /var/tmp/* - -ARG USER=coder -RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \ - && echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${USER} \ - && chmod 0440 /etc/sudoers.d/${USER} -USER ${USER} -WORKDIR /home/${USER} diff --git a/templates/docker/homelab-workspace/main.tf b/templates/docker/homelab-workspace/main.tf index 8b665835..eadeacf4 100644 --- a/templates/docker/homelab-workspace/main.tf +++ b/templates/docker/homelab-workspace/main.tf @@ -27,9 +27,12 @@ variable "workspace_image" { type = string } +variable "test_mode" { + type = bool +} + locals { - test_mode = (var.workspace_image == "simple-workspace:latest") - username = local.test_mode ? "coder" : data.coder_workspace_owner.me.name + username = var.test_mode ? "coder" : data.coder_workspace_owner.me.name container_volume_mounts = { "home" = "/home/${local.username}", @@ -41,16 +44,16 @@ locals { } # create docker volumes in test_mode - docker_volumes = local.test_mode ? ["home", "docker"] : [] + docker_volumes = var.test_mode ? ["home", "docker"] : [] # create bind mounts otherwise - bind_mounts = local.test_mode ? [] : ["home", "docker"] + bind_mounts = var.test_mode ? [] : ["home", "docker"] } resource "coder_agent" "main" { arch = "amd64" os = "linux" - startup_script = local.test_mode ? "/bin/bash --noprofile --norc" : "/bin/bash --noprofile --norc /opt/coder/bin/agent-startup.sh" + startup_script = var.test_mode ? "/bin/bash --noprofile --norc" : "/bin/bash --noprofile --norc /opt/coder/bin/agent-startup.sh" startup_script_behavior = "blocking" metadata { @@ -123,9 +126,20 @@ locals { standard_init_script = replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal") entrypoint_script = < /tmp/coder-agent-init-script.sh <<'EOT' ${local.standard_init_script} EOT +echo +echo "Checking minimum requirements for coder agent..." +if (command -v curl && command -v sudo) > /dev/null; then + echo "Minimum requirements for running coder agent is met." +else + echo "Installing minimum required software for running coder agent..." + apt-get update + DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends curl sudo +fi +echo chmod 755 /tmp/coder-agent-init-script.sh if [[ "$ENTRYPOINT_MODE" == "SUPERVISED" ]]; then echo "Running in supervised mode..." @@ -144,7 +158,7 @@ resource "docker_container" "workspace" { count = data.coder_workspace.me.start_count image = docker_image.workspace_image.image_id - name = local.test_mode ? data.coder_workspace.me.name : "${lower(local.username)}-${lower(data.coder_workspace.me.name)}" + name = var.test_mode ? data.coder_workspace.me.name : "${lower(local.username)}-${lower(data.coder_workspace.me.name)}" hostname = data.coder_workspace.me.name runtime = "sysbox-runc" user = "0:0" @@ -153,7 +167,7 @@ resource "docker_container" "workspace" { env = [ "CODER_AGENT_TOKEN=${coder_agent.main.token}", - "ENTRYPOINT_MODE=${local.test_mode ? "UNSUPERVISED" : "SUPERVISED"}" + "ENTRYPOINT_MODE=${var.test_mode ? "UNSUPERVISED" : "SUPERVISED"}" ] host { host = "host.docker.internal" From 3c2efbfb61e8aa6bacc93b9d5386badb8d7fc911 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 20:48:38 +0000 Subject: [PATCH 2/7] test: use base ubuntu:noble image for testing template --- .../coder/entrypoint-prepare.sh | 63 --------- .../docker/homelab-workspace/coder-agent.tf | 56 ++++++++ templates/docker/homelab-workspace/main.tf | 131 +++--------------- .../docker/homelab-workspace/terraform.tf | 18 +++ .../docker/homelab-workspace/variables.tf | 7 + templates/docker/homelab-workspace/volumes.tf | 25 ++++ 6 files changed, 125 insertions(+), 175 deletions(-) delete mode 100755 images/homelab-workspace/coder/entrypoint-prepare.sh create mode 100644 templates/docker/homelab-workspace/coder-agent.tf create mode 100644 templates/docker/homelab-workspace/terraform.tf create mode 100644 templates/docker/homelab-workspace/variables.tf create mode 100644 templates/docker/homelab-workspace/volumes.tf diff --git a/images/homelab-workspace/coder/entrypoint-prepare.sh b/images/homelab-workspace/coder/entrypoint-prepare.sh deleted file mode 100755 index 9579d6cc..00000000 --- a/images/homelab-workspace/coder/entrypoint-prepare.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -set -eo pipefail - -if [[ $EUID -ne 0 ]]; then - echo "Should be run as root" - exit 1 -fi - -USERNAME="" -while [[ "$#" -gt 0 ]]; do - case $1 in - --username) - USERNAME="$2"; shift; - if [[ -z "${USERNAME}" ]]; then - echo "--username is required" - exit 1 - fi - ;; - *) echo "Unknown parameter passed: $1"; echo; exit 1 ;; - esac - shift -done -if [[ -z "${USERNAME}" ]]; then - echo "--username is required" - exit 1 -fi - -update_user() { - local username="$1" - local home_dir="/home/${username}" - - echo "- Modifying user..." - usermod --home $home_dir --shell /bin/bash --login $username coder - - # allow coder user to sudo to so that they can run any system actions (such as using apt-get) within their workspace container. - echo "- Enabling sudo" - echo "${username} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd - echo -} - -maintain_directories() { - local username="$1" - local home_dir="/home/${username}" - - echo "- Creating directories..." - mkdir -p $home_dir - ln -sf $home_dir /home/coder - mkdir -p $home_dir/.log/ - echo "- Updating directory permissions..." - chown $username:coder $home_dir - chown $username:coder $home_dir/.log/ - echo -} - -main() { - echo "Updating user: coder -> ${username}" - update_user $USERNAME - echo "Maintain required directories..." - maintain_directories $USERNAME - echo "Complete." -} - -main diff --git a/templates/docker/homelab-workspace/coder-agent.tf b/templates/docker/homelab-workspace/coder-agent.tf new file mode 100644 index 00000000..4c1fa8a2 --- /dev/null +++ b/templates/docker/homelab-workspace/coder-agent.tf @@ -0,0 +1,56 @@ +resource "coder_agent" "main" { + arch = "amd64" + os = "linux" + startup_script = var.test_mode ? "/bin/bash --noprofile --norc" : "/bin/bash --noprofile --norc /opt/coder/bin/agent-startup.sh" + startup_script_behavior = "blocking" + + metadata { + display_name = "CPU Usage" + key = "0_cpu_usage" + script = "coder stat cpu" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "Memory Usage" + key = "1_mem_usage" + script = "coder stat mem --prefix Gi" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "Home Disk" + key = "3_home_disk" + script = "coder stat disk --path $${HOME}" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "CPU Usage (Host)" + key = "4_cpu_usage_host" + script = "coder stat cpu --host" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "Memory Usage (Host)" + key = "5_mem_usage_host" + script = "coder stat mem --host" + interval = 60 + timeout = 1 + } + + metadata { + display_name = "Load Average" + key = "load" + script = < /tmp/coder-agent-init-script.sh <<'EOT' ${local.standard_init_script} EOT +chmod 755 /tmp/coder-agent-init-script.sh echo echo "Checking minimum requirements for coder agent..." -if (command -v curl && command -v sudo) > /dev/null; then +if (command -v curl && command -v sudo && command -v useradd) > /dev/null; then echo "Minimum requirements for running coder agent is met." else echo "Installing minimum required software for running coder agent..." apt-get update - DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends curl sudo + DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends curl sudo adduser +fi +if grep coder /etc/passwd > /dev/null; then + echo "Modifying user: coder -> ${local.username}..." + usermod --home /home/${local.username} --shell /bin/bash --login $username coder +else + echo "Creating user - ${local.username}..." + useradd --groups sudo --home-dir /home/${local.username} --shell /bin/bash ${local.username} fi +# allow coder user to sudo to so that they can run any system actions (such as using apt-get) within their workspace container. +echo "Enabling ${local.username} to sudo" +echo "${local.username} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${local.username} +chmod 0440 /etc/sudoers.d/${local.username} +echo +echo "Creating directories and updating directory permissions..." +mkdir -p /home/${local.username}/.log/ +chown ${local.username} /home/${local.username} +chown ${local.username} /home/${local.username}/.log/ echo -chmod 755 /tmp/coder-agent-init-script.sh if [[ "$ENTRYPOINT_MODE" == "SUPERVISED" ]]; then echo "Running in supervised mode..." - /opt/coder/bin/entrypoint-prepare.sh --username ${local.username} echo -e "#!/bin/bash\nsudo -u ${local.username} --preserve-env=CODER_AGENT_TOKEN /bin/bash /tmp/coder-agent-init-script.sh" > /tmp/coder-agent-wrapper.sh chmod 755 /tmp/coder-agent-wrapper.sh exec /usr/bin/supervisord -c /etc/supervisord.conf diff --git a/templates/docker/homelab-workspace/terraform.tf b/templates/docker/homelab-workspace/terraform.tf new file mode 100644 index 00000000..a1894b29 --- /dev/null +++ b/templates/docker/homelab-workspace/terraform.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">= 1.8" + + required_providers { + coder = { + source = "coder/coder" + version = "~> 1.0.0" + } + docker = { + source = "kreuzwerker/docker" + version = "~> 3.0.2" + } + } +} + +provider "docker" { + host = "unix:///var/run/docker.sock" +} diff --git a/templates/docker/homelab-workspace/variables.tf b/templates/docker/homelab-workspace/variables.tf new file mode 100644 index 00000000..91980dda --- /dev/null +++ b/templates/docker/homelab-workspace/variables.tf @@ -0,0 +1,7 @@ +variable "workspace_image" { + type = string +} + +variable "test_mode" { + type = bool +} diff --git a/templates/docker/homelab-workspace/volumes.tf b/templates/docker/homelab-workspace/volumes.tf new file mode 100644 index 00000000..8304f634 --- /dev/null +++ b/templates/docker/homelab-workspace/volumes.tf @@ -0,0 +1,25 @@ +locals { + container_volume_mounts = { + "home" = "/home/${local.username}", + "docker" = "/var/lib/docker" + } + bind_mount_host_paths = { + "home" = "/srv/workspaces/${local.username}", + "docker" = "/srv/workspaces/${local.username}-${data.coder_workspace.me.name}-docker" + } + + # create docker volumes in test_mode + docker_volumes = var.test_mode ? ["home", "docker"] : [] + # create bind mounts otherwise + bind_mounts = var.test_mode ? [] : ["home", "docker"] +} + + +resource "docker_volume" "volume" { + for_each = toset(local.docker_volumes) + + name = "coder-${data.coder_workspace.me.id}-${each.key}" + lifecycle { + ignore_changes = all + } +} From 6bf4d372209f3b5e205bae326795ef7fb0bca212 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 20:51:41 +0000 Subject: [PATCH 3/7] test: use base ubuntu:noble image for testing template --- .github/workflows/test-template.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-template.yaml b/.github/workflows/test-template.yaml index c910abd1..eb51967b 100644 --- a/.github/workflows/test-template.yaml +++ b/.github/workflows/test-template.yaml @@ -165,6 +165,7 @@ jobs: echo "Created workspace is in an unhealthy state." exit 1 fi + docker logs ${WORKSPACE_NAME} - name: Test - connect to created workspace id: check-workspace-connect From 22880f99869763afda6bab89eb7637edaab1d022 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 20:56:33 +0000 Subject: [PATCH 4/7] test: use base ubuntu:noble image for testing template --- .github/workflows/release.yaml | 2 -- templates/docker/homelab-workspace/main.tf | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a292368e..0af38550 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -87,7 +87,6 @@ jobs: echo "sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" publish-image: - if: github.event_name == 'workflow_dispatch' needs: [create-release] uses: ppat/images/.github/workflows/build-image-workflow.yaml@main with: @@ -107,7 +106,6 @@ jobs: FETCH_GH_TOKEN=${{ secrets.GITHUB_TOKEN }} publish-template: - if: github.event_name == 'workflow_dispatch' needs: [create-release, publish-image] runs-on: ubuntu-latest timeout-minutes: 15 diff --git a/templates/docker/homelab-workspace/main.tf b/templates/docker/homelab-workspace/main.tf index 0cd98deb..63fe2e07 100644 --- a/templates/docker/homelab-workspace/main.tf +++ b/templates/docker/homelab-workspace/main.tf @@ -18,6 +18,7 @@ locals { standard_init_script = replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal") entrypoint_script = <&1 echo "Writing coder agent init script to file..." cat > /tmp/coder-agent-init-script.sh <<'EOT' ${local.standard_init_script} From 50f49e89ae626c2c9bb3fd49688ad778417d8cea Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 20:58:11 +0000 Subject: [PATCH 5/7] test: use base ubuntu:noble image for testing template --- templates/docker/homelab-workspace/main.tf | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/templates/docker/homelab-workspace/main.tf b/templates/docker/homelab-workspace/main.tf index 63fe2e07..fa7f66fe 100644 --- a/templates/docker/homelab-workspace/main.tf +++ b/templates/docker/homelab-workspace/main.tf @@ -19,12 +19,13 @@ locals { entrypoint_script = <&1 +echo "---------------------------------------------------------------------------------" echo "Writing coder agent init script to file..." cat > /tmp/coder-agent-init-script.sh <<'EOT' ${local.standard_init_script} EOT chmod 755 /tmp/coder-agent-init-script.sh -echo +echo "---------------------------------------------------------------------------------" echo "Checking minimum requirements for coder agent..." if (command -v curl && command -v sudo && command -v useradd) > /dev/null; then echo "Minimum requirements for running coder agent is met." @@ -33,6 +34,7 @@ else apt-get update DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends curl sudo adduser fi +echo "---------------------------------------------------------------------------------" if grep coder /etc/passwd > /dev/null; then echo "Modifying user: coder -> ${local.username}..." usermod --home /home/${local.username} --shell /bin/bash --login $username coder @@ -44,19 +46,20 @@ fi echo "Enabling ${local.username} to sudo" echo "${local.username} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${local.username} chmod 0440 /etc/sudoers.d/${local.username} -echo +echo "---------------------------------------------------------------------------------" echo "Creating directories and updating directory permissions..." mkdir -p /home/${local.username}/.log/ chown ${local.username} /home/${local.username} chown ${local.username} /home/${local.username}/.log/ -echo +echo "---------------------------------------------------------------------------------" +echo "Preparation complete. Starting coder agent..." if [[ "$ENTRYPOINT_MODE" == "SUPERVISED" ]]; then - echo "Running in supervised mode..." + echo "Running agent in supervised mode..." echo -e "#!/bin/bash\nsudo -u ${local.username} --preserve-env=CODER_AGENT_TOKEN /bin/bash /tmp/coder-agent-init-script.sh" > /tmp/coder-agent-wrapper.sh chmod 755 /tmp/coder-agent-wrapper.sh exec /usr/bin/supervisord -c /etc/supervisord.conf else - echo "Running in unsupervised mode..." + echo "Running agent in unsupervised mode..." sudo -u ${local.username} --preserve-env=CODER_AGENT_TOKEN /bin/bash /tmp/coder-agent-init-script.sh fi EOF From 082c6ab4a91b0b335d20537bb10965115f78916e Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 21:01:30 +0000 Subject: [PATCH 6/7] test: use base ubuntu:noble image for testing template --- .github/workflows/test-template.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test-template.yaml b/.github/workflows/test-template.yaml index eb51967b..49972dbe 100644 --- a/.github/workflows/test-template.yaml +++ b/.github/workflows/test-template.yaml @@ -165,7 +165,6 @@ jobs: echo "Created workspace is in an unhealthy state." exit 1 fi - docker logs ${WORKSPACE_NAME} - name: Test - connect to created workspace id: check-workspace-connect @@ -185,7 +184,7 @@ jobs: docker logs -n 100 coder-coder-1 echo echo Container logs: - docker logs -n 100 ${WORKSPACE_NAME} + docker logs 100 ${WORKSPACE_NAME} echo echo Workspace status coder show ${WORKSPACE_NAME} From b2718e4f8ae324836fb060205e57f6223f4e8e37 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Fri, 19 Jul 2024 21:09:43 +0000 Subject: [PATCH 7/7] test: use base ubuntu:noble image for testing template --- .github/workflows/test-image.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-image.yaml b/.github/workflows/test-image.yaml index 01668b4c..e332723f 100644 --- a/.github/workflows/test-image.yaml +++ b/.github/workflows/test-image.yaml @@ -81,8 +81,8 @@ jobs: echo "Done" echo - echo "Running entrypoint preparation script..." - docker exec $container_name sudo -u root /opt/coder/bin/entrypoint-prepare.sh --username $test_user + echo "Create test user within container..." + docker exec $container_name sudo -u root useradd --groups sudo --shell /bin/bash $test_user echo "Done" echo