@@ -2,16 +2,16 @@ package provider
22
33import (
44 "context"
5+ "crypto/sha256"
6+ "encoding/hex"
57 "fmt"
6- "os"
78 "path/filepath"
89 "reflect"
910 "strings"
1011
11- "github.com/hashicorp/terraform-plugin-log/tflog"
12-
1312 "github.com/google/uuid"
1413 "github.com/hashicorp/go-cty/cty"
14+ "github.com/hashicorp/terraform-plugin-log/tflog"
1515 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1616 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1717 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -26,50 +26,34 @@ func agentResource() *schema.Resource {
2626
2727 Description : "Use this resource to associate an agent." ,
2828 CreateContext : func (ctx context.Context , resourceData * schema.ResourceData , i interface {}) diag.Diagnostics {
29- // This should be a real authentication token!
30- resourceData .SetId (uuid . NewString () )
29+ agentID := uuid . NewString ()
30+ resourceData .SetId (agentID )
3131
32- // CODER_RUNNING_WORKSPACE_AGENT_TOKEN is *only* used for prebuilds. We pass it down when we want to rebuild a prebuilt workspace
33- // but not generate a new agent token. The provisionerdserver will retrieve this token and push it down to
34- // here where it will be reused.
35- // Context: the agent token is often used in immutable attributes of workspace resource (e.g. VM/container)
36- // to initialize the agent, so if that value changes it will necessitate a replacement of that resource, thus
37- // obviating the whole point of the prebuild.
38- //
39- // The default path is for a new token to be generated on each new resource creation.
40- // TODO: add logging when the running token is actually used.
41- var token string
32+ // Most of the time, we will generate a new token for the agent.
33+ // In the case of a prebuilt workspace being claimed, we will override with
34+ // an existing token provided below.
35+ token := uuid .NewString ()
4236
37+ // If isPrebuild is true, then this workspace was built by the prebuilds system.
38+ // This does not determine whether the workspace has been claimed by a user.
39+ // At this point, it may or may not have been claimed.
4340 isPrebuild := helpers .OptionalEnv (IsPrebuildEnvironmentVariable ()) == "true"
44- if ! isPrebuild {
45- token = os .Getenv (RunningAgentTokenEnvironmentVariable ())
46- }
47-
48- allEnv := make (map [string ]interface {})
49- for _ , v := range os .Environ () {
50- split := strings .Split (v , "=" )
51- var key , val string
52- if len (split ) > 0 {
53- key = split [0 ]
54- }
55- if len (split ) > 1 {
56- val = split [1 ]
57- }
58-
59- allEnv [key ] = val
41+ // existingToken should only have been set if isPrebuild is true, because we only
42+ // reuse the token when a prebuilt workspace is being claimed.
43+ existingToken := helpers .OptionalEnv (RunningAgentTokenEnvironmentVariable (agentID ))
44+ logFields := map [string ]interface {}{
45+ "agent_id" : agentID ,
46+ "is_prebuild" : isPrebuild ,
47+ "token_provided" : existingToken != "" ,
6048 }
61-
62- allEnv ["is_prebuild" ] = fmt .Sprintf ("%v" , isPrebuild )
63-
64- if token == "" {
65- token = uuid .NewString ()
66- if ! isPrebuild {
67- tflog .Warn (ctx , "NOT USING EXISTING AGENT TOKEN" , allEnv )
68- }
49+ if isPrebuild && existingToken != "" {
50+ // check if a token was already generated for this agent.
51+ // If so, this workspace is in the process of being claimed
52+ // and we should reuse the token. If not, we use a new token as usual.
53+ tflog .Info (ctx , "using provided agent token for prebuild" , logFields )
54+ token = existingToken
6955 } else {
70- if ! isPrebuild {
71- tflog .Info (ctx , "IS USING EXISTING AGENT TOKEN" , allEnv )
72- }
56+ tflog .Info (ctx , "using a new agent token" , logFields )
7357 }
7458
7559 err := resourceData .Set ("token" , token )
@@ -517,6 +501,15 @@ func updateInitScript(resourceData *schema.ResourceData, i interface{}) diag.Dia
517501 return nil
518502}
519503
520- func RunningAgentTokenEnvironmentVariable () string {
521- return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN"
504+ // RunningAgentTokenEnvironmentVariable returns the name of the environment variable
505+ // that contains the token for the running agent. This is used for prebuilds, where
506+ // we want to reuse the same token for the next iteration of a workspace agent before
507+ // and after the workspace was claimed by a user.
508+ //
509+ // agentID is unused for now, but will be used as soon as we support multiple agents.
510+ func RunningAgentTokenEnvironmentVariable (agentID string ) string {
511+ agentID = "" // remove this once we need to support multiple agents per prebuilt workspace.
512+
513+ sum := sha256 .Sum256 ([]byte (agentID ))
514+ return "CODER_RUNNING_WORKSPACE_AGENT_TOKEN_" + hex .EncodeToString (sum [:])
522515}
0 commit comments