diff options
Diffstat (limited to 'cmd/sbox/sbox.go')
-rw-r--r-- | cmd/sbox/sbox.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index e69a93067..6459ea175 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -27,6 +27,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "strconv" "strings" "time" @@ -51,6 +52,8 @@ const ( sandboxDirPlaceholder = "__SBOX_SANDBOX_DIR__" ) +var envVarNameRegex = regexp.MustCompile("^[a-zA-Z0-9_-]+$") + func init() { flag.StringVar(&sandboxesRoot, "sandbox-path", "", "root of temp directory to put the sandbox into") @@ -238,6 +241,48 @@ func readManifest(file string) (*sbox_proto.Manifest, error) { return &manifest, nil } +func createEnv(command *sbox_proto.Command) ([]string, error) { + env := []string{} + if command.DontInheritEnv == nil || !*command.DontInheritEnv { + env = os.Environ() + } + for _, envVar := range command.Env { + if envVar.Name == nil || !envVarNameRegex.MatchString(*envVar.Name) { + name := "nil" + if envVar.Name != nil { + name = *envVar.Name + } + return nil, fmt.Errorf("Invalid environment variable name: %q", name) + } + if envVar.State == nil { + return nil, fmt.Errorf("Must set state") + } + switch state := envVar.State.(type) { + case *sbox_proto.EnvironmentVariable_Value: + env = append(env, *envVar.Name+"="+state.Value) + case *sbox_proto.EnvironmentVariable_Unset: + if !state.Unset { + return nil, fmt.Errorf("Can't have unset set to false") + } + prefix := *envVar.Name + "=" + for i := 0; i < len(env); i++ { + if strings.HasPrefix(env[i], prefix) { + env = append(env[:i], env[i+1:]...) + i-- + } + } + case *sbox_proto.EnvironmentVariable_Inherit: + if !state.Inherit { + return nil, fmt.Errorf("Can't have inherit set to false") + } + env = append(env, *envVar.Name+"="+os.Getenv(*envVar.Name)) + default: + return nil, fmt.Errorf("Unhandled state type") + } + } + return env, nil +} + // runCommand runs a single command from a manifest. If the command references the // __SBOX_DEPFILE__ placeholder it returns the name of the depfile that was used. func runCommand(command *sbox_proto.Command, tempDir string, commandIndex int) (depFile string, err error) { @@ -313,6 +358,12 @@ func runCommand(command *sbox_proto.Command, tempDir string, commandIndex int) ( return "", fmt.Errorf("Failed to update PATH: %w", err) } } + + cmd.Env, err = createEnv(command) + if err != nil { + return "", err + } + err = cmd.Run() if err != nil { |