From 6a06f8f1dd79f16e326ffa80791690d473936123 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Tue, 14 Mar 2023 23:53:15 +0000 Subject: [PATCH 1/4] Add metadata block to the agent --- docs/resources/agent.md | 14 +++++++++++++ provider/agent.go | 34 ++++++++++++++++++++++++++++++ provider/agent_test.go | 46 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 1333d5bb..99efe838 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -51,6 +51,7 @@ resource "kubernetes_pod" "dev" { - `dir` (String) The starting directory when a user creates a shell session. Defaults to $HOME. - `env` (Map of String) A mapping of environment variables to set inside the workspace. - `login_before_ready` (Boolean) This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in. +- `metadata` (Block List) Each "metadata" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases. (see [below for nested schema](#nestedblock--metadata)) - `motd_file` (String) The path to a file within the workspace containing a message to display to users when they login via SSH. A typical value would be /etc/motd. - `shutdown_script` (String) A script to run before the agent is stopped. The script should exit when it is done to signal that the workspace can be stopped. - `shutdown_script_timeout` (Number) Time in seconds until the agent lifecycle status is marked as timed out during shutdown, this happens when the shutdown script has not completed (exited) in the given time. @@ -64,4 +65,17 @@ resource "kubernetes_pod" "dev" { - `init_script` (String) Run this script on startup of an instance to initialize the agent. - `token` (String, Sensitive) Set the environment variable "CODER_AGENT_TOKEN" with this token to authenticate an agent. + +### Nested Schema for `metadata` + +Required: + +- `cmd` (String) The command that retrieves the value of this metadata item. +- `interval` (Number) The interval in seconds at which to refresh this metadata item. +- `key` (String) The key of this metadata item. + +Optional: + +- `display_name` (String) The user-facing name of this value. + diff --git a/provider/agent.go b/provider/agent.go index 4d628927..66cba46e 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -137,6 +137,40 @@ func agentResource() *schema.Resource { Optional: true, Description: "This option defines whether or not the user can (by default) login to the workspace before it is ready. Ready means that e.g. the startup_script is done and has exited. When enabled, users may see an incomplete workspace when logging in.", }, + "metadata": { + Type: schema.TypeList, + Description: "Each \"metadata\" block defines a single item consisting of a key/value pair. This feature is in alpha and may break in future releases.", + ForceNew: true, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Description: "The key of this metadata item.", + ForceNew: true, + Required: true, + }, + "display_name": { + Type: schema.TypeString, + Description: "The user-facing name of this value.", + ForceNew: true, + Optional: true, + }, + "cmd": { + Type: schema.TypeString, + Description: "The command that retrieves the value of this metadata item.", + ForceNew: true, + Required: true, + }, + "interval": { + Type: schema.TypeInt, + Description: "The interval in seconds at which to refresh this metadata item. ", + ForceNew: true, + Required: true, + }, + }, + }, + }, }, } } diff --git a/provider/agent_test.go b/provider/agent_test.go index 445ed75b..2afc764a 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -71,7 +71,7 @@ func TestAgent(t *testing.T) { }) } -func TestAgentInstance(t *testing.T) { +func TestAgent_Instance(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ Providers: map[string]*schema.Provider{ @@ -111,3 +111,47 @@ func TestAgentInstance(t *testing.T) { }}, }) } + +func TestAgent_Metadata(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + Providers: map[string]*schema.Provider{ + "coder": provider.New(), + }, + IsUnitTest: true, + Steps: []resource.TestStep{{ + Config: ` + provider "coder" { + url = "https://example.com" + } + resource "coder_agent" "dev" { + os = "linux" + arch = "amd64" + metadata { + key = "process_count" + display_name = "Process Count" + cmd = "ps aux | wc -l" + interval = 5 + } + } + `, + Check: func(state *terraform.State) error { + require.Len(t, state.Modules, 1) + require.Len(t, state.Modules[0].Resources, 1) + + resource := state.Modules[0].Resources["coder_agent.dev"] + require.NotNil(t, resource) + + t.Logf("resource: %v", resource.Primary.Attributes) + + attr := resource.Primary.Attributes + require.Equal(t, "1", attr["metadata.#"]) + require.Equal(t, "process_count", attr["metadata.0.key"]) + require.Equal(t, "Process Count", attr["metadata.0.display_name"]) + require.Equal(t, "ps aux | wc -l", attr["metadata.0.cmd"]) + require.Equal(t, "5", attr["metadata.0.interval"]) + return nil + }, + }}, + }) +} From 208a014d37fa63e4b423184d679ecc6f52913c45 Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Wed, 15 Mar 2023 15:58:46 +0000 Subject: [PATCH 2/4] Change cmd to string array --- docs/resources/agent.md | 2 +- provider/agent.go | 5 ++++- provider/agent_test.go | 7 +++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 99efe838..549bfa9c 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -70,7 +70,7 @@ resource "kubernetes_pod" "dev" { Required: -- `cmd` (String) The command that retrieves the value of this metadata item. +- `cmd` (List of String) The command that retrieves the value of this metadata item. - `interval` (Number) The interval in seconds at which to refresh this metadata item. - `key` (String) The key of this metadata item. diff --git a/provider/agent.go b/provider/agent.go index 66cba46e..8a96fa8b 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -157,10 +157,13 @@ func agentResource() *schema.Resource { Optional: true, }, "cmd": { - Type: schema.TypeString, + Type: schema.TypeList, Description: "The command that retrieves the value of this metadata item.", ForceNew: true, Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "interval": { Type: schema.TypeInt, diff --git a/provider/agent_test.go b/provider/agent_test.go index 2afc764a..f3b981f3 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -130,7 +130,7 @@ func TestAgent_Metadata(t *testing.T) { metadata { key = "process_count" display_name = "Process Count" - cmd = "ps aux | wc -l" + cmd = ["sh", "-c", "ps aux | wc -l"] interval = 5 } } @@ -148,7 +148,10 @@ func TestAgent_Metadata(t *testing.T) { require.Equal(t, "1", attr["metadata.#"]) require.Equal(t, "process_count", attr["metadata.0.key"]) require.Equal(t, "Process Count", attr["metadata.0.display_name"]) - require.Equal(t, "ps aux | wc -l", attr["metadata.0.cmd"]) + require.Equal(t, "3", attr["metadata.0.cmd.#"]) + require.Equal(t, "sh", attr["metadata.0.cmd.0"]) + require.Equal(t, "-c", attr["metadata.0.cmd.1"]) + require.Equal(t, "ps aux | wc -l", attr["metadata.0.cmd.2"]) require.Equal(t, "5", attr["metadata.0.interval"]) return nil }, From c50fa552af704daa5b9a4ac2bff98353a6b19ecb Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Wed, 15 Mar 2023 20:28:49 +0000 Subject: [PATCH 3/4] Add timeout field --- docs/resources/agent.md | 1 + provider/agent.go | 6 ++++++ provider/agent_test.go | 2 ++ 3 files changed, 9 insertions(+) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 549bfa9c..2b60fb12 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -77,5 +77,6 @@ Required: Optional: - `display_name` (String) The user-facing name of this value. +- `timeout` (Number) The maximum time the command is allowed to run in seconds. diff --git a/provider/agent.go b/provider/agent.go index 8a96fa8b..f4fa908c 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -165,6 +165,12 @@ func agentResource() *schema.Resource { Type: schema.TypeString, }, }, + "timeout": { + Type: schema.TypeInt, + Description: "The maximum time the command is allowed to run in seconds.", + ForceNew: true, + Optional: true, + }, "interval": { Type: schema.TypeInt, Description: "The interval in seconds at which to refresh this metadata item. ", diff --git a/provider/agent_test.go b/provider/agent_test.go index f3b981f3..832d0bba 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -132,6 +132,7 @@ func TestAgent_Metadata(t *testing.T) { display_name = "Process Count" cmd = ["sh", "-c", "ps aux | wc -l"] interval = 5 + timeout = 1 } } `, @@ -153,6 +154,7 @@ func TestAgent_Metadata(t *testing.T) { require.Equal(t, "-c", attr["metadata.0.cmd.1"]) require.Equal(t, "ps aux | wc -l", attr["metadata.0.cmd.2"]) require.Equal(t, "5", attr["metadata.0.interval"]) + require.Equal(t, "1", attr["metadata.0.timeout"]) return nil }, }}, From dd07581feafbb96c47b03daf5830cc2ed485820a Mon Sep 17 00:00:00 2001 From: Ammar Bandukwala Date: Thu, 23 Mar 2023 01:39:17 +0000 Subject: [PATCH 4/4] cmd -> script --- docs/resources/agent.md | 2 +- provider/agent.go | 6 +++--- provider/agent_test.go | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/resources/agent.md b/docs/resources/agent.md index 2b60fb12..9ee5c1d0 100644 --- a/docs/resources/agent.md +++ b/docs/resources/agent.md @@ -70,9 +70,9 @@ resource "kubernetes_pod" "dev" { Required: -- `cmd` (List of String) The command that retrieves the value of this metadata item. - `interval` (Number) The interval in seconds at which to refresh this metadata item. - `key` (String) The key of this metadata item. +- `script` (String) The script that retrieves the value of this metadata item. Optional: diff --git a/provider/agent.go b/provider/agent.go index f4fa908c..c5797081 100644 --- a/provider/agent.go +++ b/provider/agent.go @@ -156,9 +156,9 @@ func agentResource() *schema.Resource { ForceNew: true, Optional: true, }, - "cmd": { - Type: schema.TypeList, - Description: "The command that retrieves the value of this metadata item.", + "script": { + Type: schema.TypeString, + Description: "The script that retrieves the value of this metadata item.", ForceNew: true, Required: true, Elem: &schema.Schema{ diff --git a/provider/agent_test.go b/provider/agent_test.go index 832d0bba..2069247b 100644 --- a/provider/agent_test.go +++ b/provider/agent_test.go @@ -130,7 +130,7 @@ func TestAgent_Metadata(t *testing.T) { metadata { key = "process_count" display_name = "Process Count" - cmd = ["sh", "-c", "ps aux | wc -l"] + script = "ps aux | wc -l" interval = 5 timeout = 1 } @@ -149,10 +149,7 @@ func TestAgent_Metadata(t *testing.T) { require.Equal(t, "1", attr["metadata.#"]) require.Equal(t, "process_count", attr["metadata.0.key"]) require.Equal(t, "Process Count", attr["metadata.0.display_name"]) - require.Equal(t, "3", attr["metadata.0.cmd.#"]) - require.Equal(t, "sh", attr["metadata.0.cmd.0"]) - require.Equal(t, "-c", attr["metadata.0.cmd.1"]) - require.Equal(t, "ps aux | wc -l", attr["metadata.0.cmd.2"]) + require.Equal(t, "ps aux | wc -l", attr["metadata.0.script"]) require.Equal(t, "5", attr["metadata.0.interval"]) require.Equal(t, "1", attr["metadata.0.timeout"]) return nil