From 860f7a3f5b8da5ac5a7b05c037387b28da5bd6d4 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 3 Jun 2022 19:36:54 +0000 Subject: [PATCH 1/3] example: add and document dotfiles usage --- docs/workspaces.md | 5 + .../templates/docker-with-dotfiles/README.md | 38 ++++++ .../templates/docker-with-dotfiles/main.tf | 118 ++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 examples/templates/docker-with-dotfiles/README.md create mode 100644 examples/templates/docker-with-dotfiles/main.tf diff --git a/docs/workspaces.md b/docs/workspaces.md index 06be5e14c7c77..8aa18dc129bc6 100644 --- a/docs/workspaces.md +++ b/docs/workspaces.md @@ -65,6 +65,11 @@ resources](./templates.md#persistent-and-ephemeral-resources). When a workspace is deleted, all of the workspace's resources are deleted. +## Dotfiles + +Users can install configuration from a personal [dotfiles repository](https://dotfiles.github.io) with the `coder dotfiles ` +command in their workspace. Templates can also prompt users for their dotfiles repo [(example)](../examples/templates/docker-with-dotfiles/README.md#how-it-works). + ## Updating workspaces Use the following command to update a workspace to the latest template version. diff --git a/examples/templates/docker-with-dotfiles/README.md b/examples/templates/docker-with-dotfiles/README.md new file mode 100644 index 0000000000000..540137295cf34 --- /dev/null +++ b/examples/templates/docker-with-dotfiles/README.md @@ -0,0 +1,38 @@ +--- +name: Develop in Docker with a dotfiles URL +description: Run workspaces on a Docker host using registry images +tags: [local, docker] +--- + +# docker-with-dotfiles + +This is an example for deploying workspaces with a prompt for the users' dotfiles repo URI. + +## Getting started + +Run `coder templates init` and select this template. Follow the instructions that appear. + +## How it works + +During workspace creation, Coder prompts you to specify a dotfiles URL via a Terraform variable. Once the workspace starts, the Coder agent runs `coder dotfiles` via the startup script: + +```hcl +variable "dotfiles_uri" { + description = <<-EOF + Dotfiles repo URI (optional) + + see https://dotfiles.github.io + EOF + # The codercom/enterprise-* images are only built for amd64 + default = "" +} + +resource "coder_agent" "dev" { + ... + startup_script = var.dotfiles_uri != "" ? "/tmp/tmp.coder*/coder dotfiles -y ${var.dotfiles_uri}" : null +} +``` + +# Managing images and workspaces + +Refer to the documentation in the [Docker template](../docker/README.md). diff --git a/examples/templates/docker-with-dotfiles/main.tf b/examples/templates/docker-with-dotfiles/main.tf new file mode 100644 index 0000000000000..4069de7fea14b --- /dev/null +++ b/examples/templates/docker-with-dotfiles/main.tf @@ -0,0 +1,118 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "0.4.1" + } + docker = { + source = "kreuzwerker/docker" + version = "~> 2.16.0" + } + } +} + +# Admin parameters + +# Comment this out if you are specifying a different docker +# host on the "docker" provider below. +variable "step1_docker_host_warning" { + description = <<-EOF + This template will use the Docker socket present on + the Coder host, which is not necessarily your local machine. + + You can specify a different host in the template file and + surpress this warning. + EOF + validation { + condition = contains(["Continue using /var/run/docker.sock on the Coder host"], var.step1_docker_host_warning) + error_message = "Cancelling template create." + } + + sensitive = true +} +variable "step2_arch" { + description = <<-EOF + arch: What architecture is your Docker host on? + + note: codercom/enterprise-* images are only built for amd64 + EOF + + validation { + condition = contains(["amd64", "arm64", "armv7"], var.step2_arch) + error_message = "Value must be amd64, arm64, or armv7." + } + sensitive = true +} +variable "step3_OS" { + description = <<-EOF + What operating system is your Coder host on? + EOF + + validation { + condition = contains(["MacOS", "Windows", "Linux"], var.step3_OS) + error_message = "Value must be MacOS, Windows, or Linux." + } + sensitive = true +} + +provider "docker" { + host = var.step3_OS == "Windows" ? "npipe:////.//pipe//docker_engine" : "unix:///var/run/docker.sock" +} + +provider "coder" { +} + +data "coder_workspace" "me" { +} + +variable "docker_image" { + description = "Which Docker image would you like to use for your workspace?" + # The codercom/enterprise-* images are only built for amd64 + default = "codercom/enterprise-base:ubuntu" + validation { + condition = contains(["codercom/enterprise-base:ubuntu", "codercom/enterprise-node:ubuntu", "codercom/enterprise-intellij:ubuntu"], var.docker_image) + error_message = "Invalid Docker image!" + } +} + +variable "dotfiles_uri" { + description = <<-EOF + Dotfiles repo URI (optional) + + see https://dotfiles.github.io + EOF + # The codercom/enterprise-* images are only built for amd64 + default = "" +} + +resource "coder_agent" "dev" { + arch = var.step2_arch + os = "linux" + startup_script = var.dotfiles_uri != "" ? "/tmp/tmp.coder*/coder dotfiles -y ${var.dotfiles_uri}" : null +} + +resource "docker_volume" "home_volume" { + name = "coder-${data.coder_workspace.me.owner}-${data.coder_workspace.me.name}-root" +} + +resource "docker_container" "workspace" { + count = data.coder_workspace.me.start_count + image = var.docker_image + # Uses lower() to avoid Docker restriction on container names. + name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" + # Hostname makes the shell more user friendly: coder@my-workspace:~$ + hostname = lower(data.coder_workspace.me.name) + dns = ["1.1.1.1"] + # Use the docker gateway if the access URL is 127.0.0.1 + command = ["sh", "-c", replace(coder_agent.dev.init_script, "127.0.0.1", "host.docker.internal")] + env = ["CODER_AGENT_TOKEN=${coder_agent.dev.token}"] + host { + host = "host.docker.internal" + ip = "host-gateway" + } + volumes { + container_path = "/home/coder/" + volume_name = docker_volume.home_volume.name + read_only = false + } +} From a359aa67ee5449679333cecc516e92078babc57c Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 6 Jun 2022 12:18:40 +0000 Subject: [PATCH 2/3] simplify template based on review --- .../templates/docker-with-dotfiles/main.tf | 78 ++++--------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/examples/templates/docker-with-dotfiles/main.tf b/examples/templates/docker-with-dotfiles/main.tf index 4069de7fea14b..2823930b7a2fd 100644 --- a/examples/templates/docker-with-dotfiles/main.tf +++ b/examples/templates/docker-with-dotfiles/main.tf @@ -1,3 +1,10 @@ +# Note: this example demonstrates the use of +# dotfiles with Coder templates. + +# The Docker aspect of the template only works +# with MacOS/Linux amd64 systems. See the full +# Docker example for details + terraform { required_providers { coder = { @@ -11,52 +18,8 @@ terraform { } } -# Admin parameters - -# Comment this out if you are specifying a different docker -# host on the "docker" provider below. -variable "step1_docker_host_warning" { - description = <<-EOF - This template will use the Docker socket present on - the Coder host, which is not necessarily your local machine. - - You can specify a different host in the template file and - surpress this warning. - EOF - validation { - condition = contains(["Continue using /var/run/docker.sock on the Coder host"], var.step1_docker_host_warning) - error_message = "Cancelling template create." - } - - sensitive = true -} -variable "step2_arch" { - description = <<-EOF - arch: What architecture is your Docker host on? - - note: codercom/enterprise-* images are only built for amd64 - EOF - - validation { - condition = contains(["amd64", "arm64", "armv7"], var.step2_arch) - error_message = "Value must be amd64, arm64, or armv7." - } - sensitive = true -} -variable "step3_OS" { - description = <<-EOF - What operating system is your Coder host on? - EOF - - validation { - condition = contains(["MacOS", "Windows", "Linux"], var.step3_OS) - error_message = "Value must be MacOS, Windows, or Linux." - } - sensitive = true -} - provider "docker" { - host = var.step3_OS == "Windows" ? "npipe:////.//pipe//docker_engine" : "unix:///var/run/docker.sock" + host = "unix:///var/run/docker.sock" } provider "coder" { @@ -65,29 +28,18 @@ provider "coder" { data "coder_workspace" "me" { } -variable "docker_image" { - description = "Which Docker image would you like to use for your workspace?" - # The codercom/enterprise-* images are only built for amd64 - default = "codercom/enterprise-base:ubuntu" - validation { - condition = contains(["codercom/enterprise-base:ubuntu", "codercom/enterprise-node:ubuntu", "codercom/enterprise-intellij:ubuntu"], var.docker_image) - error_message = "Invalid Docker image!" - } -} - variable "dotfiles_uri" { description = <<-EOF Dotfiles repo URI (optional) see https://dotfiles.github.io EOF - # The codercom/enterprise-* images are only built for amd64 - default = "" + default = "" } resource "coder_agent" "dev" { - arch = var.step2_arch - os = "linux" + arch = "amd64" + os = "linux" startup_script = var.dotfiles_uri != "" ? "/tmp/tmp.coder*/coder dotfiles -y ${var.dotfiles_uri}" : null } @@ -97,13 +49,11 @@ resource "docker_volume" "home_volume" { resource "docker_container" "workspace" { count = data.coder_workspace.me.start_count - image = var.docker_image + image = "codercom/enterprise-base:ubuntu" # Uses lower() to avoid Docker restriction on container names. name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" - # Hostname makes the shell more user friendly: coder@my-workspace:~$ - hostname = lower(data.coder_workspace.me.name) - dns = ["1.1.1.1"] - # Use the docker gateway if the access URL is 127.0.0.1 + dns = ["1.1.1.1"] + # Refer to Docker host when Coder is on localhost command = ["sh", "-c", replace(coder_agent.dev.init_script, "127.0.0.1", "host.docker.internal")] env = ["CODER_AGENT_TOKEN=${coder_agent.dev.token}"] host { From c35d9a558f7880f76770ffbd3ba2def4a3053059 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 8 Jun 2022 21:11:02 +0000 Subject: [PATCH 3/3] use Coder binary instead --- examples/templates/docker-with-dotfiles/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/templates/docker-with-dotfiles/main.tf b/examples/templates/docker-with-dotfiles/main.tf index 2823930b7a2fd..982751323fd3e 100644 --- a/examples/templates/docker-with-dotfiles/main.tf +++ b/examples/templates/docker-with-dotfiles/main.tf @@ -40,7 +40,7 @@ variable "dotfiles_uri" { resource "coder_agent" "dev" { arch = "amd64" os = "linux" - startup_script = var.dotfiles_uri != "" ? "/tmp/tmp.coder*/coder dotfiles -y ${var.dotfiles_uri}" : null + startup_script = var.dotfiles_uri != "" ? "coder dotfiles -y ${var.dotfiles_uri}" : null } resource "docker_volume" "home_volume" {