From 979430d635d73822daf16859cee503bc4f3e7d39 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Sat, 17 Aug 2024 02:33:32 +1000 Subject: [PATCH] chore: manage dogfood template using coderd provider (#14321) --- .github/workflows/ci.yaml | 2 +- .github/workflows/dogfood.yaml | 23 +- Makefile | 2 +- dogfood/{ => contents}/Dockerfile | 0 dogfood/{ => contents}/Dockerfile.nix | 0 dogfood/{ => contents}/Makefile | 0 dogfood/{ => contents}/README.md | 0 dogfood/{ => contents}/devcontainer.json | 0 .../files/etc/apt/apt.conf.d/80-no-recommends | 0 .../files/etc/apt/apt.conf.d/80-retries | 0 .../files/etc/apt/preferences.d/docker | 0 .../files/etc/apt/preferences.d/github-cli | 0 .../files/etc/apt/preferences.d/google-cloud | 0 .../files/etc/apt/preferences.d/hashicorp | 0 .../files/etc/apt/preferences.d/ppa | 0 .../files/etc/apt/sources.list.d/docker.list | 0 .../etc/apt/sources.list.d/google-cloud.list | 0 .../etc/apt/sources.list.d/hashicorp.list | 0 .../etc/apt/sources.list.d/postgresql.list | 0 .../files/etc/apt/sources.list.d/ppa.list | 0 .../files/etc/docker/daemon.json | 0 .../files/usr/share/keyrings/ansible.gpg | Bin .../files/usr/share/keyrings/docker.gpg | Bin .../files/usr/share/keyrings/fish-shell.gpg | Bin .../files/usr/share/keyrings/git-core.gpg | Bin .../files/usr/share/keyrings/github-cli.gpg | Bin .../files/usr/share/keyrings/google-cloud.gpg | Bin .../files/usr/share/keyrings/hashicorp.gpg | Bin .../files/usr/share/keyrings/helix.gpg | Bin .../files/usr/share/keyrings/neovim.gpg | Bin .../files/usr/share/keyrings/postgresql.gpg | Bin dogfood/{ => contents}/guide.md | 0 dogfood/contents/main.tf | 373 ++++++++++++++++ dogfood/{ => contents}/update-keys.sh | 2 +- dogfood/main.tf | 407 +++--------------- envbuilder-dogfood/main.tf | 4 +- 36 files changed, 444 insertions(+), 369 deletions(-) rename dogfood/{ => contents}/Dockerfile (100%) rename dogfood/{ => contents}/Dockerfile.nix (100%) rename dogfood/{ => contents}/Makefile (100%) rename dogfood/{ => contents}/README.md (100%) rename dogfood/{ => contents}/devcontainer.json (100%) rename dogfood/{ => contents}/files/etc/apt/apt.conf.d/80-no-recommends (100%) rename dogfood/{ => contents}/files/etc/apt/apt.conf.d/80-retries (100%) rename dogfood/{ => contents}/files/etc/apt/preferences.d/docker (100%) rename dogfood/{ => contents}/files/etc/apt/preferences.d/github-cli (100%) rename dogfood/{ => contents}/files/etc/apt/preferences.d/google-cloud (100%) rename dogfood/{ => contents}/files/etc/apt/preferences.d/hashicorp (100%) rename dogfood/{ => contents}/files/etc/apt/preferences.d/ppa (100%) rename dogfood/{ => contents}/files/etc/apt/sources.list.d/docker.list (100%) rename dogfood/{ => contents}/files/etc/apt/sources.list.d/google-cloud.list (100%) rename dogfood/{ => contents}/files/etc/apt/sources.list.d/hashicorp.list (100%) rename dogfood/{ => contents}/files/etc/apt/sources.list.d/postgresql.list (100%) rename dogfood/{ => contents}/files/etc/apt/sources.list.d/ppa.list (100%) rename dogfood/{ => contents}/files/etc/docker/daemon.json (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/ansible.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/docker.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/fish-shell.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/git-core.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/github-cli.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/google-cloud.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/hashicorp.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/helix.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/neovim.gpg (100%) rename dogfood/{ => contents}/files/usr/share/keyrings/postgresql.gpg (100%) rename dogfood/{ => contents}/guide.md (100%) create mode 100644 dogfood/contents/main.tf rename dogfood/{ => contents}/update-keys.sh (97%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7ec086c8a7..68ef5dec82 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -168,7 +168,7 @@ jobs: - name: Get golangci-lint cache dir run: | - linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/Dockerfile | cut -d '=' -f 2) + linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/contents/Dockerfile | cut -d '=' -f 2) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$linter_ver dir=$(golangci-lint cache status | awk '/Dir/ { print $2 }') echo "LINT_CACHE_DIR=$dir" >> $GITHUB_ENV diff --git a/.github/workflows/dogfood.yaml b/.github/workflows/dogfood.yaml index 5f04ae95d1..84ddc5fe40 100644 --- a/.github/workflows/dogfood.yaml +++ b/.github/workflows/dogfood.yaml @@ -56,7 +56,7 @@ jobs: project: b4q6ltmpzh token: ${{ secrets.DEPOT_TOKEN }} buildx-fallback: true - context: "{{defaultContext}}:dogfood" + context: "{{defaultContext}}:dogfood/contents" pull: true save: true push: ${{ github.ref == 'refs/heads/main' }} @@ -69,7 +69,7 @@ jobs: token: ${{ secrets.DEPOT_TOKEN }} buildx-fallback: true context: "." - file: "dogfood/Dockerfile.nix" + file: "dogfood/contents/Dockerfile.nix" pull: true save: true push: ${{ github.ref == 'refs/heads/main' }} @@ -90,6 +90,9 @@ jobs: cd dogfood terraform init -upgrade terraform validate + cd contents + terraform init -upgrade + terraform validate - name: Get short commit SHA if: github.ref == 'refs/heads/main' @@ -101,22 +104,16 @@ jobs: id: message run: echo "pr_title=$(git log --format=%s -n 1 ${{ github.sha }})" >> $GITHUB_OUTPUT - - name: "Get latest Coder binary from the server" - if: github.ref == 'refs/heads/main' - run: | - curl -fsSL "https://dev.coder.com/bin/coder-linux-amd64" -o "./coder" - chmod +x "./coder" - - name: "Push template" if: github.ref == 'refs/heads/main' run: | - ./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION --message="$CODER_TEMPLATE_MESSAGE" + terraform apply -auto-approve env: # Consumed by Coder CLI CODER_URL: https://dev.coder.com CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }} # Template source & details - CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }} - CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }} - CODER_TEMPLATE_DIR: ./dogfood - CODER_TEMPLATE_MESSAGE: ${{ steps.message.outputs.pr_title }} + TF_VAR_CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }} + TF_VAR_CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }} + TF_VAR_CODER_TEMPLATE_DIR: ./dogfood/contents + TF_VAR_CODER_TEMPLATE_MESSAGE: ${{ steps.message.outputs.pr_title }} diff --git a/Makefile b/Makefile index f608c4965d..97fc34cb81 100644 --- a/Makefile +++ b/Makefile @@ -451,7 +451,7 @@ lint/ts: lint/go: ./scripts/check_enterprise_imports.sh - linter_ver=$(shell egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/Dockerfile | cut -d '=' -f 2) + linter_ver=$(shell egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/contents/Dockerfile | cut -d '=' -f 2) go run github.com/golangci/golangci-lint/cmd/golangci-lint@v$$linter_ver run .PHONY: lint/go diff --git a/dogfood/Dockerfile b/dogfood/contents/Dockerfile similarity index 100% rename from dogfood/Dockerfile rename to dogfood/contents/Dockerfile diff --git a/dogfood/Dockerfile.nix b/dogfood/contents/Dockerfile.nix similarity index 100% rename from dogfood/Dockerfile.nix rename to dogfood/contents/Dockerfile.nix diff --git a/dogfood/Makefile b/dogfood/contents/Makefile similarity index 100% rename from dogfood/Makefile rename to dogfood/contents/Makefile diff --git a/dogfood/README.md b/dogfood/contents/README.md similarity index 100% rename from dogfood/README.md rename to dogfood/contents/README.md diff --git a/dogfood/devcontainer.json b/dogfood/contents/devcontainer.json similarity index 100% rename from dogfood/devcontainer.json rename to dogfood/contents/devcontainer.json diff --git a/dogfood/files/etc/apt/apt.conf.d/80-no-recommends b/dogfood/contents/files/etc/apt/apt.conf.d/80-no-recommends similarity index 100% rename from dogfood/files/etc/apt/apt.conf.d/80-no-recommends rename to dogfood/contents/files/etc/apt/apt.conf.d/80-no-recommends diff --git a/dogfood/files/etc/apt/apt.conf.d/80-retries b/dogfood/contents/files/etc/apt/apt.conf.d/80-retries similarity index 100% rename from dogfood/files/etc/apt/apt.conf.d/80-retries rename to dogfood/contents/files/etc/apt/apt.conf.d/80-retries diff --git a/dogfood/files/etc/apt/preferences.d/docker b/dogfood/contents/files/etc/apt/preferences.d/docker similarity index 100% rename from dogfood/files/etc/apt/preferences.d/docker rename to dogfood/contents/files/etc/apt/preferences.d/docker diff --git a/dogfood/files/etc/apt/preferences.d/github-cli b/dogfood/contents/files/etc/apt/preferences.d/github-cli similarity index 100% rename from dogfood/files/etc/apt/preferences.d/github-cli rename to dogfood/contents/files/etc/apt/preferences.d/github-cli diff --git a/dogfood/files/etc/apt/preferences.d/google-cloud b/dogfood/contents/files/etc/apt/preferences.d/google-cloud similarity index 100% rename from dogfood/files/etc/apt/preferences.d/google-cloud rename to dogfood/contents/files/etc/apt/preferences.d/google-cloud diff --git a/dogfood/files/etc/apt/preferences.d/hashicorp b/dogfood/contents/files/etc/apt/preferences.d/hashicorp similarity index 100% rename from dogfood/files/etc/apt/preferences.d/hashicorp rename to dogfood/contents/files/etc/apt/preferences.d/hashicorp diff --git a/dogfood/files/etc/apt/preferences.d/ppa b/dogfood/contents/files/etc/apt/preferences.d/ppa similarity index 100% rename from dogfood/files/etc/apt/preferences.d/ppa rename to dogfood/contents/files/etc/apt/preferences.d/ppa diff --git a/dogfood/files/etc/apt/sources.list.d/docker.list b/dogfood/contents/files/etc/apt/sources.list.d/docker.list similarity index 100% rename from dogfood/files/etc/apt/sources.list.d/docker.list rename to dogfood/contents/files/etc/apt/sources.list.d/docker.list diff --git a/dogfood/files/etc/apt/sources.list.d/google-cloud.list b/dogfood/contents/files/etc/apt/sources.list.d/google-cloud.list similarity index 100% rename from dogfood/files/etc/apt/sources.list.d/google-cloud.list rename to dogfood/contents/files/etc/apt/sources.list.d/google-cloud.list diff --git a/dogfood/files/etc/apt/sources.list.d/hashicorp.list b/dogfood/contents/files/etc/apt/sources.list.d/hashicorp.list similarity index 100% rename from dogfood/files/etc/apt/sources.list.d/hashicorp.list rename to dogfood/contents/files/etc/apt/sources.list.d/hashicorp.list diff --git a/dogfood/files/etc/apt/sources.list.d/postgresql.list b/dogfood/contents/files/etc/apt/sources.list.d/postgresql.list similarity index 100% rename from dogfood/files/etc/apt/sources.list.d/postgresql.list rename to dogfood/contents/files/etc/apt/sources.list.d/postgresql.list diff --git a/dogfood/files/etc/apt/sources.list.d/ppa.list b/dogfood/contents/files/etc/apt/sources.list.d/ppa.list similarity index 100% rename from dogfood/files/etc/apt/sources.list.d/ppa.list rename to dogfood/contents/files/etc/apt/sources.list.d/ppa.list diff --git a/dogfood/files/etc/docker/daemon.json b/dogfood/contents/files/etc/docker/daemon.json similarity index 100% rename from dogfood/files/etc/docker/daemon.json rename to dogfood/contents/files/etc/docker/daemon.json diff --git a/dogfood/files/usr/share/keyrings/ansible.gpg b/dogfood/contents/files/usr/share/keyrings/ansible.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/ansible.gpg rename to dogfood/contents/files/usr/share/keyrings/ansible.gpg diff --git a/dogfood/files/usr/share/keyrings/docker.gpg b/dogfood/contents/files/usr/share/keyrings/docker.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/docker.gpg rename to dogfood/contents/files/usr/share/keyrings/docker.gpg diff --git a/dogfood/files/usr/share/keyrings/fish-shell.gpg b/dogfood/contents/files/usr/share/keyrings/fish-shell.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/fish-shell.gpg rename to dogfood/contents/files/usr/share/keyrings/fish-shell.gpg diff --git a/dogfood/files/usr/share/keyrings/git-core.gpg b/dogfood/contents/files/usr/share/keyrings/git-core.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/git-core.gpg rename to dogfood/contents/files/usr/share/keyrings/git-core.gpg diff --git a/dogfood/files/usr/share/keyrings/github-cli.gpg b/dogfood/contents/files/usr/share/keyrings/github-cli.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/github-cli.gpg rename to dogfood/contents/files/usr/share/keyrings/github-cli.gpg diff --git a/dogfood/files/usr/share/keyrings/google-cloud.gpg b/dogfood/contents/files/usr/share/keyrings/google-cloud.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/google-cloud.gpg rename to dogfood/contents/files/usr/share/keyrings/google-cloud.gpg diff --git a/dogfood/files/usr/share/keyrings/hashicorp.gpg b/dogfood/contents/files/usr/share/keyrings/hashicorp.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/hashicorp.gpg rename to dogfood/contents/files/usr/share/keyrings/hashicorp.gpg diff --git a/dogfood/files/usr/share/keyrings/helix.gpg b/dogfood/contents/files/usr/share/keyrings/helix.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/helix.gpg rename to dogfood/contents/files/usr/share/keyrings/helix.gpg diff --git a/dogfood/files/usr/share/keyrings/neovim.gpg b/dogfood/contents/files/usr/share/keyrings/neovim.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/neovim.gpg rename to dogfood/contents/files/usr/share/keyrings/neovim.gpg diff --git a/dogfood/files/usr/share/keyrings/postgresql.gpg b/dogfood/contents/files/usr/share/keyrings/postgresql.gpg similarity index 100% rename from dogfood/files/usr/share/keyrings/postgresql.gpg rename to dogfood/contents/files/usr/share/keyrings/postgresql.gpg diff --git a/dogfood/guide.md b/dogfood/contents/guide.md similarity index 100% rename from dogfood/guide.md rename to dogfood/contents/guide.md diff --git a/dogfood/contents/main.tf b/dogfood/contents/main.tf new file mode 100644 index 0000000000..58c78fbec1 --- /dev/null +++ b/dogfood/contents/main.tf @@ -0,0 +1,373 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + docker = { + source = "kreuzwerker/docker" + version = "~> 3.0.0" + } + } +} + +locals { + // These are cluster service addresses mapped to Tailscale nodes. Ask Dean or + // Kyle for help. + docker_host = { + "" = "tcp://dogfood-ts-cdr-dev.tailscale.svc.cluster.local:2375" + "us-pittsburgh" = "tcp://dogfood-ts-cdr-dev.tailscale.svc.cluster.local:2375" + "eu-helsinki" = "tcp://reinhard-hel-cdr-dev.tailscale.svc.cluster.local:2375" + "ap-sydney" = "tcp://wolfgang-syd-cdr-dev.tailscale.svc.cluster.local:2375" + "sa-saopaulo" = "tcp://oberstein-sao-cdr-dev.tailscale.svc.cluster.local:2375" + "za-jnb" = "tcp://greenhill-jnb-cdr-dev.tailscale.svc.cluster.local:2375" + } + + repo_base_dir = data.coder_parameter.repo_base_dir.value == "~" ? "/home/coder" : replace(data.coder_parameter.repo_base_dir.value, "/^~\\//", "/home/coder/") + repo_dir = replace(module.git-clone.repo_dir, "/^~\\//", "/home/coder/") + container_name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" +} + +data "coder_parameter" "repo_base_dir" { + type = "string" + name = "Coder Repository Base Directory" + default = "~" + description = "The directory specified will be created (if missing) and [coder/coder](https://github.com/coder/coder) will be automatically cloned into [base directory]/coder 🪄." + mutable = true +} + +data "coder_parameter" "image_type" { + type = "string" + name = "Coder Image" + default = "codercom/oss-dogfood:latest" + description = "The Docker image used to run your workspace. Choose between nix and non-nix images." + option { + icon = "/icon/coder.svg" + name = "Dogfood (Default)" + value = "codercom/oss-dogfood:latest" + } + option { + icon = "/icon/nix.svg" + name = "Dogfood Nix (Experimental)" + value = "codercom/oss-dogfood-nix:latest" + } +} + +data "coder_parameter" "region" { + type = "string" + name = "Region" + icon = "/emojis/1f30e.png" + default = "us-pittsburgh" + option { + icon = "/emojis/1f1fa-1f1f8.png" + name = "Pittsburgh" + value = "us-pittsburgh" + } + option { + icon = "/emojis/1f1eb-1f1ee.png" + name = "Helsinki" + value = "eu-helsinki" + } + option { + icon = "/emojis/1f1e6-1f1fa.png" + name = "Sydney" + value = "ap-sydney" + } + option { + icon = "/emojis/1f1e7-1f1f7.png" + name = "São Paulo" + value = "sa-saopaulo" + } + option { + icon = "/emojis/1f1ff-1f1e6.png" + name = "Johannesburg" + value = "za-jnb" + } +} + +provider "docker" { + host = lookup(local.docker_host, data.coder_parameter.region.value) +} + +provider "coder" {} + +data "coder_external_auth" "github" { + id = "github" +} + +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +module "slackme" { + source = "registry.coder.com/modules/slackme/coder" + version = "1.0.2" + agent_id = coder_agent.dev.id + auth_provider_id = "slack" +} + +module "dotfiles" { + source = "registry.coder.com/modules/dotfiles/coder" + version = "1.0.15" + agent_id = coder_agent.dev.id +} + +module "git-clone" { + source = "registry.coder.com/modules/git-clone/coder" + version = "1.0.12" + agent_id = coder_agent.dev.id + url = "https://github.com/coder/coder" + base_dir = local.repo_base_dir +} + +module "personalize" { + source = "registry.coder.com/modules/personalize/coder" + version = "1.0.2" + agent_id = coder_agent.dev.id +} + +module "code-server" { + source = "registry.coder.com/modules/code-server/coder" + version = "1.0.15" + agent_id = coder_agent.dev.id + folder = local.repo_dir + auto_install_extensions = true +} + +module "jetbrains_gateway" { + source = "registry.coder.com/modules/jetbrains-gateway/coder" + version = "1.0.13" + agent_id = coder_agent.dev.id + agent_name = "dev" + folder = local.repo_dir + jetbrains_ides = ["GO", "WS"] + default = "GO" + latest = true +} + +module "filebrowser" { + source = "registry.coder.com/modules/filebrowser/coder" + version = "1.0.8" + agent_id = coder_agent.dev.id +} + +module "coder-login" { + source = "registry.coder.com/modules/coder-login/coder" + version = "1.0.15" + agent_id = coder_agent.dev.id +} + +resource "coder_agent" "dev" { + arch = "amd64" + os = "linux" + dir = local.repo_dir + env = { + OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, + } + startup_script_behavior = "blocking" + + # The following metadata blocks are optional. They are used to display + # information about your workspace in the dashboard. You can remove them + # if you don't want to display any information. + metadata { + display_name = "CPU Usage" + key = "cpu_usage" + order = 0 + script = "coder stat cpu" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage" + key = "ram_usage" + order = 1 + script = "coder stat mem" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "CPU Usage (Host)" + key = "cpu_usage_host" + order = 2 + script = "coder stat cpu --host" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage (Host)" + key = "ram_usage_host" + order = 3 + script = "coder stat mem --host" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "Swap Usage (Host)" + key = "swap_usage_host" + order = 4 + script = <&1 | awk ' $0 ~ "Word of the Day: [A-z]+" { print $5; exit }' + EOT + interval = 86400 + timeout = 5 + } + + startup_script = <<-EOT + set -eux -o pipefail + + # Allow synchronization between scripts. + trap 'touch /tmp/.coder-startup-script.done' EXIT + + # Start Docker service + sudo service docker start + # Install playwright dependencies + # We want to use the playwright version from site/package.json + # Check if the directory exists At workspace creation as the coder_script runs in parallel so clone might not exist yet. + while ! [[ -f "${local.repo_dir}/site/package.json" ]]; do + sleep 1 + done + cd "${local.repo_dir}/site" && pnpm install && pnpm playwright:install + EOT +} + +resource "docker_volume" "home_volume" { + name = "coder-${data.coder_workspace.me.id}-home" + # Protect the volume from being deleted due to changes in attributes. + lifecycle { + ignore_changes = all + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + # This field becomes outdated if the workspace is renamed but can + # be useful for debugging or cleaning out dangling volumes. + labels { + label = "coder.workspace_name_at_creation" + value = data.coder_workspace.me.name + } +} + +data "docker_registry_image" "dogfood" { + name = data.coder_parameter.image_type.value +} + +resource "docker_image" "dogfood" { + name = "${data.coder_parameter.image_type.value}@${data.docker_registry_image.dogfood.sha256_digest}" + pull_triggers = [ + data.docker_registry_image.dogfood.sha256_digest, + sha1(join("", [for f in fileset(path.module, "files/*") : filesha1(f)])), + filesha1("Dockerfile"), + filesha1("Dockerfile.nix"), + ] + keep_locally = true +} + +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = docker_image.dogfood.name + name = local.container_name + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = data.coder_workspace.me.name + # Use the docker gateway if the access URL is 127.0.0.1 + entrypoint = ["sh", "-c", coder_agent.dev.init_script] + # CPU limits are unnecessary since Docker will load balance automatically + memory = data.coder_workspace_owner.me.name == "code-asher" ? 65536 : 32768 + runtime = "sysbox-runc" + env = [ + "CODER_AGENT_TOKEN=${coder_agent.dev.token}", + "USE_CAP_NET_ADMIN=true", + ] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + volumes { + container_path = "/home/coder/" + volume_name = docker_volume.home_volume.name + read_only = false + } + capabilities { + add = ["CAP_NET_ADMIN", "CAP_SYS_NICE"] + } + # Add labels in Docker to keep track of orphan resources. + labels { + label = "coder.owner" + value = data.coder_workspace_owner.me.name + } + labels { + label = "coder.owner_id" + value = data.coder_workspace_owner.me.id + } + labels { + label = "coder.workspace_id" + value = data.coder_workspace.me.id + } + labels { + label = "coder.workspace_name" + value = data.coder_workspace.me.name + } +} + +resource "coder_metadata" "container_info" { + count = data.coder_workspace.me.start_count + resource_id = docker_container.workspace[0].id + item { + key = "memory" + value = docker_container.workspace[0].memory + } + item { + key = "runtime" + value = docker_container.workspace[0].runtime + } + item { + key = "region" + value = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].name + } +} diff --git a/dogfood/update-keys.sh b/dogfood/contents/update-keys.sh similarity index 97% rename from dogfood/update-keys.sh rename to dogfood/contents/update-keys.sh index 32ce65e5ca..1b57d015bf 100755 --- a/dogfood/update-keys.sh +++ b/dogfood/contents/update-keys.sh @@ -15,7 +15,7 @@ gpg_flags=( --yes ) -pushd "$PROJECT_ROOT/dogfood/files/usr/share/keyrings" +pushd "$PROJECT_ROOT/dogfood/contents/files/usr/share/keyrings" # Ansible PPA signing key curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x6125e2a8c77f2818fb7bd15b93c4a3fd7bb9c367" | diff --git a/dogfood/main.tf b/dogfood/main.tf index 58c78fbec1..178b8546af 100644 --- a/dogfood/main.tf +++ b/dogfood/main.tf @@ -1,373 +1,78 @@ terraform { required_providers { - coder = { - source = "coder/coder" - } - docker = { - source = "kreuzwerker/docker" - version = "~> 3.0.0" + coderd = { + source = "coder/coderd" } } } -locals { - // These are cluster service addresses mapped to Tailscale nodes. Ask Dean or - // Kyle for help. - docker_host = { - "" = "tcp://dogfood-ts-cdr-dev.tailscale.svc.cluster.local:2375" - "us-pittsburgh" = "tcp://dogfood-ts-cdr-dev.tailscale.svc.cluster.local:2375" - "eu-helsinki" = "tcp://reinhard-hel-cdr-dev.tailscale.svc.cluster.local:2375" - "ap-sydney" = "tcp://wolfgang-syd-cdr-dev.tailscale.svc.cluster.local:2375" - "sa-saopaulo" = "tcp://oberstein-sao-cdr-dev.tailscale.svc.cluster.local:2375" - "za-jnb" = "tcp://greenhill-jnb-cdr-dev.tailscale.svc.cluster.local:2375" - } - - repo_base_dir = data.coder_parameter.repo_base_dir.value == "~" ? "/home/coder" : replace(data.coder_parameter.repo_base_dir.value, "/^~\\//", "/home/coder/") - repo_dir = replace(module.git-clone.repo_dir, "/^~\\//", "/home/coder/") - container_name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" +// Alternative to committing a state file +import { + to = coderd_template.dogfood + id = "0d286645-29aa-4eaf-9b52-cc5d2740c90b" } -data "coder_parameter" "repo_base_dir" { - type = "string" - name = "Coder Repository Base Directory" - default = "~" - description = "The directory specified will be created (if missing) and [coder/coder](https://github.com/coder/coder) will be automatically cloned into [base directory]/coder 🪄." - mutable = true +data "coderd_organization" "default" { + is_default = true } -data "coder_parameter" "image_type" { - type = "string" - name = "Coder Image" - default = "codercom/oss-dogfood:latest" - description = "The Docker image used to run your workspace. Choose between nix and non-nix images." - option { - icon = "/icon/coder.svg" - name = "Dogfood (Default)" - value = "codercom/oss-dogfood:latest" - } - option { - icon = "/icon/nix.svg" - name = "Dogfood Nix (Experimental)" - value = "codercom/oss-dogfood-nix:latest" - } +data "coderd_user" "machine" { + username = "machine" } -data "coder_parameter" "region" { - type = "string" - name = "Region" - icon = "/emojis/1f30e.png" - default = "us-pittsburgh" - option { - icon = "/emojis/1f1fa-1f1f8.png" - name = "Pittsburgh" - value = "us-pittsburgh" - } - option { - icon = "/emojis/1f1eb-1f1ee.png" - name = "Helsinki" - value = "eu-helsinki" - } - option { - icon = "/emojis/1f1e6-1f1fa.png" - name = "Sydney" - value = "ap-sydney" - } - option { - icon = "/emojis/1f1e7-1f1f7.png" - name = "São Paulo" - value = "sa-saopaulo" - } - option { - icon = "/emojis/1f1ff-1f1e6.png" - name = "Johannesburg" - value = "za-jnb" - } +variable "CODER_TEMPLATE_NAME" { + type = string } -provider "docker" { - host = lookup(local.docker_host, data.coder_parameter.region.value) +variable "CODER_TEMPLATE_VERSION" { + type = string } -provider "coder" {} - -data "coder_external_auth" "github" { - id = "github" +variable "CODER_TEMPLATE_DIR" { + type = string } -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} - -module "slackme" { - source = "registry.coder.com/modules/slackme/coder" - version = "1.0.2" - agent_id = coder_agent.dev.id - auth_provider_id = "slack" +variable "CODER_TEMPLATE_MESSAGE" { + type = string } -module "dotfiles" { - source = "registry.coder.com/modules/dotfiles/coder" - version = "1.0.15" - agent_id = coder_agent.dev.id -} - -module "git-clone" { - source = "registry.coder.com/modules/git-clone/coder" - version = "1.0.12" - agent_id = coder_agent.dev.id - url = "https://github.com/coder/coder" - base_dir = local.repo_base_dir -} - -module "personalize" { - source = "registry.coder.com/modules/personalize/coder" - version = "1.0.2" - agent_id = coder_agent.dev.id -} - -module "code-server" { - source = "registry.coder.com/modules/code-server/coder" - version = "1.0.15" - agent_id = coder_agent.dev.id - folder = local.repo_dir - auto_install_extensions = true -} - -module "jetbrains_gateway" { - source = "registry.coder.com/modules/jetbrains-gateway/coder" - version = "1.0.13" - agent_id = coder_agent.dev.id - agent_name = "dev" - folder = local.repo_dir - jetbrains_ides = ["GO", "WS"] - default = "GO" - latest = true -} - -module "filebrowser" { - source = "registry.coder.com/modules/filebrowser/coder" - version = "1.0.8" - agent_id = coder_agent.dev.id -} - -module "coder-login" { - source = "registry.coder.com/modules/coder-login/coder" - version = "1.0.15" - agent_id = coder_agent.dev.id -} - -resource "coder_agent" "dev" { - arch = "amd64" - os = "linux" - dir = local.repo_dir - env = { - OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token, - } - startup_script_behavior = "blocking" - - # The following metadata blocks are optional. They are used to display - # information about your workspace in the dashboard. You can remove them - # if you don't want to display any information. - metadata { - display_name = "CPU Usage" - key = "cpu_usage" - order = 0 - script = "coder stat cpu" - interval = 10 - timeout = 1 - } - - metadata { - display_name = "RAM Usage" - key = "ram_usage" - order = 1 - script = "coder stat mem" - interval = 10 - timeout = 1 - } - - metadata { - display_name = "CPU Usage (Host)" - key = "cpu_usage_host" - order = 2 - script = "coder stat cpu --host" - interval = 10 - timeout = 1 - } - - metadata { - display_name = "RAM Usage (Host)" - key = "ram_usage_host" - order = 3 - script = "coder stat mem --host" - interval = 10 - timeout = 1 - } - - metadata { - display_name = "Swap Usage (Host)" - key = "swap_usage_host" - order = 4 - script = <&1 | awk ' $0 ~ "Word of the Day: [A-z]+" { print $5; exit }' - EOT - interval = 86400 - timeout = 5 - } - - startup_script = <<-EOT - set -eux -o pipefail - - # Allow synchronization between scripts. - trap 'touch /tmp/.coder-startup-script.done' EXIT - - # Start Docker service - sudo service docker start - # Install playwright dependencies - # We want to use the playwright version from site/package.json - # Check if the directory exists At workspace creation as the coder_script runs in parallel so clone might not exist yet. - while ! [[ -f "${local.repo_dir}/site/package.json" ]]; do - sleep 1 - done - cd "${local.repo_dir}/site" && pnpm install && pnpm playwright:install - EOT -} - -resource "docker_volume" "home_volume" { - name = "coder-${data.coder_workspace.me.id}-home" - # Protect the volume from being deleted due to changes in attributes. - lifecycle { - ignore_changes = all - } - # Add labels in Docker to keep track of orphan resources. - labels { - label = "coder.owner" - value = data.coder_workspace_owner.me.name - } - labels { - label = "coder.owner_id" - value = data.coder_workspace_owner.me.id - } - labels { - label = "coder.workspace_id" - value = data.coder_workspace.me.id - } - # This field becomes outdated if the workspace is renamed but can - # be useful for debugging or cleaning out dangling volumes. - labels { - label = "coder.workspace_name_at_creation" - value = data.coder_workspace.me.name - } -} - -data "docker_registry_image" "dogfood" { - name = data.coder_parameter.image_type.value -} - -resource "docker_image" "dogfood" { - name = "${data.coder_parameter.image_type.value}@${data.docker_registry_image.dogfood.sha256_digest}" - pull_triggers = [ - data.docker_registry_image.dogfood.sha256_digest, - sha1(join("", [for f in fileset(path.module, "files/*") : filesha1(f)])), - filesha1("Dockerfile"), - filesha1("Dockerfile.nix"), +resource "coderd_template" "dogfood" { + name = var.CODER_TEMPLATE_NAME + display_name = "Write Coder on Coder" + description = "The template to use when developing Coder on Coder!" + icon = "/emojis/1f3c5.png" + organization_id = "703f72a1-76f6-4f89-9de6-8a3989693fe5" + versions = [ + { + name = var.CODER_TEMPLATE_VERSION + message = var.CODER_TEMPLATE_MESSAGE + directory = var.CODER_TEMPLATE_DIR + active = true + } ] - keep_locally = true -} - -resource "docker_container" "workspace" { - count = data.coder_workspace.me.start_count - image = docker_image.dogfood.name - name = local.container_name - # Hostname makes the shell more user friendly: coder@my-workspace:~$ - hostname = data.coder_workspace.me.name - # Use the docker gateway if the access URL is 127.0.0.1 - entrypoint = ["sh", "-c", coder_agent.dev.init_script] - # CPU limits are unnecessary since Docker will load balance automatically - memory = data.coder_workspace_owner.me.name == "code-asher" ? 65536 : 32768 - runtime = "sysbox-runc" - env = [ - "CODER_AGENT_TOKEN=${coder_agent.dev.token}", - "USE_CAP_NET_ADMIN=true", - ] - host { - host = "host.docker.internal" - ip = "host-gateway" - } - volumes { - container_path = "/home/coder/" - volume_name = docker_volume.home_volume.name - read_only = false - } - capabilities { - add = ["CAP_NET_ADMIN", "CAP_SYS_NICE"] - } - # Add labels in Docker to keep track of orphan resources. - labels { - label = "coder.owner" - value = data.coder_workspace_owner.me.name - } - labels { - label = "coder.owner_id" - value = data.coder_workspace_owner.me.id - } - labels { - label = "coder.workspace_id" - value = data.coder_workspace.me.id - } - labels { - label = "coder.workspace_name" - value = data.coder_workspace.me.name - } -} - -resource "coder_metadata" "container_info" { - count = data.coder_workspace.me.start_count - resource_id = docker_container.workspace[0].id - item { - key = "memory" - value = docker_container.workspace[0].memory - } - item { - key = "runtime" - value = docker_container.workspace[0].runtime - } - item { - key = "region" - value = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].name - } + acl = { + groups = [{ + id = data.coderd_organization.default.id + role = "use" + }] + users = [{ + id = data.coderd_user.machine.id + role = "admin" + }] + } + activity_bump_ms = 10800000 + allow_user_auto_start = true + allow_user_auto_stop = true + allow_user_cancel_workspace_jobs = false + auto_start_permitted_days_of_week = ["friday", "monday", "saturday", "sunday", "thursday", "tuesday", "wednesday"] + auto_stop_requirement = { + days_of_week = ["sunday"] + weeks = 1 + } + default_ttl_ms = 28800000 + deprecation_message = null + failure_ttl_ms = 604800000 + require_active_version = true + time_til_dormant_autodelete_ms = 7776000000 + time_til_dormant_ms = 8640000000 } diff --git a/envbuilder-dogfood/main.tf b/envbuilder-dogfood/main.tf index 97134b2b8b..14d6ea0e5d 100644 --- a/envbuilder-dogfood/main.tf +++ b/envbuilder-dogfood/main.tf @@ -40,7 +40,7 @@ data "coder_parameter" "devcontainer_repo" { data "coder_parameter" "devcontainer_dir" { type = "string" name = "Devcontainer Directory" - default = "dogfood/" + default = "dogfood/contents/" description = "Directory containing a devcontainer.json relative to the repository root" mutable = true } @@ -255,7 +255,7 @@ resource "coder_agent" "dev" { sleep 1 done sudo chmod a+rw /var/run/docker.sock - + # Install playwright dependencies # We want to use the playwright version from site/package.json # Check if the directory exists At workspace creation as the coder_script runs in parallel so clone might not exist yet.