55 gocontext "context"
66 "fmt"
77 "io"
8+ "maps"
89 "os"
910 osExec "os/exec"
1011 "path"
@@ -18,12 +19,13 @@ import (
1819 "github.com/flanksource/commons/logger"
1920 "github.com/flanksource/commons/properties"
2021 "github.com/flanksource/commons/utils"
21- "github.com/flanksource/duty/connection"
22- "github.com/flanksource/duty/context"
23- "github.com/flanksource/duty/types"
2422 "github.com/google/uuid"
2523 "github.com/samber/lo"
2624 "github.com/samber/oops"
25+
26+ "github.com/flanksource/duty/connection"
27+ "github.com/flanksource/duty/context"
28+ "github.com/flanksource/duty/types"
2729)
2830
2931// List of env var keys that we pass on to the exec command
@@ -139,49 +141,19 @@ func Run(ctx context.Context, exec Exec) (*ExecDetails, error) {
139141
140142func RunCmd (ctx context.Context , exec Exec , cmd * osExec.Cmd ) (* ExecDetails , error ) {
141143 ctx .Logger .V (3 ).Infof ("running: %s %s" , cmd .Path , lo .Map (cmd .Args , func (arg string , _ int ) string { return strings .TrimSpace (arg ) }))
142- envParams , err := prepareEnvironment (ctx , exec )
144+ cmdCtx , err := prepareEnvironment (ctx , exec )
143145 if err != nil {
144146 return nil , ctx .Oops ().Wrap (err )
145147 }
146148
147- if exec .Chroot == "" {
148- cwd , err := os .Getwd ()
149- if err != nil {
150- return nil , ctx .Oops ().Wrap (err )
151- }
152- cmdDir := envParams .mountPoint
153- if cmdDir == "" {
154- cmdDir = path .Join (properties .String (cwd , "shell.tmp.dir" ), "shell-tmp" , uuid .New ().String ())
155- if err := os .MkdirAll (cmdDir , 0700 ); err != nil {
156- return nil , ctx .Oops ().Wrap (err )
157- }
158- }
159- cmd .Dir = cmdDir
149+ if mountPoint , err := getCmdDir (ctx , exec .Chroot , cmdCtx .mountPoint ); err != nil {
150+ return nil , ctx .Oops ().Wrap (err )
160151 } else {
161- if stat , err := os .Stat (exec .Chroot ); err != nil {
162- return nil , ctx .Oops ().Wrap (err )
163- } else if stat .IsDir () {
164- envParams .mountPoint = stat .Name ()
165- return nil , fmt .Errorf ("%s is not a directory" , exec .Chroot )
166- } else {
167- envParams .mountPoint = filepath .Dir (stat .Name ())
168- }
169- cmd .Dir = exec .Chroot
170- }
171-
172- // Set to a non-nil empty slice to prevent access to current environment variables
173- cmd .Env = []string {}
174-
175- for _ , e := range os .Environ () {
176- key , _ , ok := strings .Cut (e , "=" )
177- if _ , exists := allowedEnvVars [key ]; exists && ok {
178- cmd .Env = append (cmd .Env , e )
179- }
152+ cmdCtx .mountPoint = mountPoint
153+ cmd .Dir = mountPoint
180154 }
181155
182- if len (envParams .envs ) != 0 {
183- cmd .Env = append (cmd .Env , envParams .envs ... )
184- }
156+ cmd .Env = getEnvVar (cmdCtx .envs )
185157
186158 if setupResult , err := connection .SetupConnection (ctx , exec .Connections , cmd ); err != nil {
187159 return nil , ctx .Oops ().Wrap (err )
@@ -197,10 +169,10 @@ func RunCmd(ctx context.Context, exec Exec, cmd *osExec.Cmd) (*ExecDetails, erro
197169 }()
198170 }
199171
200- envParams .artifacts = exec .Artifacts
201- envParams .cmd = cmd
172+ cmdCtx .artifacts = exec .Artifacts
173+ cmdCtx .cmd = cmd
202174
203- return runCmd (ctx , envParams )
175+ return runCmd (ctx , cmdCtx )
204176}
205177
206178type commandContext struct {
@@ -334,11 +306,55 @@ func prepareEnvironment(ctx context.Context, exec Exec) (*commandContext, error)
334306 if extra , err := client .Clone (ctx , result .mountPoint ); err != nil {
335307 return nil , err
336308 } else {
337- for k , v := range extra {
338- result .extra [k ] = v
339- }
309+ maps .Copy (result .extra , extra )
340310 }
341311 }
342312
343313 return & result , nil
344314}
315+
316+ func getEnvVar (userSuppliedEnvs []string ) []string {
317+ // Set to a non-nil empty slice to prevent access to current environment variables
318+ env := []string {}
319+
320+ for _ , e := range os .Environ () {
321+ key , _ , ok := strings .Cut (e , "=" )
322+ if _ , exists := allowedEnvVars [key ]; exists && ok {
323+ env = append (env , e )
324+ }
325+ }
326+
327+ if len (userSuppliedEnvs ) != 0 {
328+ env = append (env , userSuppliedEnvs ... )
329+ }
330+
331+ return env
332+ }
333+
334+ func getCmdDir (ctx context.Context , chroot , mountPoint string ) (string , error ) {
335+ if chroot != "" {
336+ if stat , err := os .Stat (chroot ); err != nil {
337+ return "" , ctx .Oops ().Wrap (err )
338+ } else if ! stat .IsDir () {
339+ return "" , fmt .Errorf ("%s is not a directory" , chroot )
340+ } else {
341+ return chroot , nil
342+ }
343+ }
344+
345+ cwd , err := os .Getwd ()
346+ if err != nil {
347+ return "" , ctx .Oops ().Wrap (err )
348+ }
349+
350+ if mountPoint != "" {
351+ return mountPoint , nil
352+ }
353+
354+ cmdDir := path .Join (properties .String (cwd , "shell.tmp.dir" ), "shell-tmp" , uuid .New ().String ())
355+ if err := os .MkdirAll (cmdDir , 0700 ); err != nil {
356+ return "" , ctx .Oops ().Wrap (err )
357+ }
358+
359+ return cmdDir , nil
360+ }
0 commit comments