Compare commits
1 commit
master
...
evan/autor
Author | SHA1 | Date | |
---|---|---|---|
951e868622 |
|
@ -128,7 +128,8 @@ func newHostCmd() *cobra.Command {
|
|||
operation := s.Update
|
||||
if isPreview {
|
||||
operation = s.Preview
|
||||
opts.Display.JSONDisplay = true
|
||||
// we've disabled JSON for a demo of autorun
|
||||
//opts.Display.JSONDisplay = true
|
||||
}
|
||||
|
||||
// Now perform the update. This will stay alive until the user cancels the host.
|
||||
|
|
106
sdk/go/x/auto/autorun.go
Normal file
106
sdk/go/x/auto/autorun.go
Normal file
|
@ -0,0 +1,106 @@
|
|||
package auto
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
|
||||
)
|
||||
|
||||
func AutoRun(pulumiFunc pulumi.RunFunc) {
|
||||
ctx := context.Background()
|
||||
w, err := NewLocalWorkspace(ctx, WorkDir(filepath.Join(".")))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
w.SetProgram(pulumiFunc)
|
||||
|
||||
operation, stackName := parseArgs()
|
||||
|
||||
if stackName == "" {
|
||||
sSummary, err := w.Stack(ctx)
|
||||
if err != nil || sSummary == nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: no stack selected: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
stackName = sSummary.Name
|
||||
}
|
||||
|
||||
stack, err := SelectStack(ctx, stackName, w)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: unable to select stack: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
switch operation {
|
||||
case up:
|
||||
_, err = stack.Up(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
break
|
||||
case preview:
|
||||
_, err = stack.Preview(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
break
|
||||
case destroy:
|
||||
_, err = stack.Destroy(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
case refresh:
|
||||
_, err = stack.Refresh(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: program failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type op int
|
||||
|
||||
const (
|
||||
up op = iota
|
||||
preview
|
||||
refresh
|
||||
destroy
|
||||
)
|
||||
|
||||
func parseArgs() (op, string) {
|
||||
operation := up
|
||||
stack := ""
|
||||
|
||||
for _, a := range os.Args[1:] {
|
||||
stackParts := strings.Split(a, "/")
|
||||
if len(stackParts) == 3 {
|
||||
stack = a
|
||||
continue
|
||||
}
|
||||
switch a {
|
||||
case "up", "update":
|
||||
operation = up
|
||||
continue
|
||||
case "pre", "preview":
|
||||
operation = preview
|
||||
continue
|
||||
case "refresh":
|
||||
operation = refresh
|
||||
continue
|
||||
case "destroy":
|
||||
operation = destroy
|
||||
}
|
||||
}
|
||||
|
||||
return operation, stack
|
||||
}
|
|
@ -46,3 +46,27 @@ func runPulumiCommandSync(
|
|||
}
|
||||
return stdout.String(), stderr.String(), code, err
|
||||
}
|
||||
|
||||
func runPulumiCommandToStdout(
|
||||
ctx context.Context,
|
||||
workdir string,
|
||||
additionalEnv []string,
|
||||
args ...string,
|
||||
) (string, string, int, error) {
|
||||
// all commands should be run in non-interactive mode.
|
||||
// this causes commands to fail rather than prompting for input (and thus hanging indefinitely)
|
||||
args = append(args, "--non-interactive")
|
||||
cmd := exec.CommandContext(ctx, "pulumi", args...)
|
||||
cmd.Dir = workdir
|
||||
cmd.Env = append(os.Environ(), additionalEnv...)
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = &stderr
|
||||
code := unknownErrorCode
|
||||
err := cmd.Run()
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
code = exitError.ExitCode()
|
||||
}
|
||||
return stdout.String(), stderr.String(), code, err
|
||||
}
|
||||
|
|
|
@ -389,13 +389,15 @@ func (l *LocalWorkspace) ListStacks(ctx context.Context) ([]StackSummary, error)
|
|||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to unmarshal config value")
|
||||
}
|
||||
for _, s := range stacks {
|
||||
for i := range stacks {
|
||||
s := stacks[i]
|
||||
nameParts := strings.Split(s.Name, "/")
|
||||
if len(nameParts) == 1 {
|
||||
s.Name = fmt.Sprintf("%s/%s/%s", user, proj.Name.String(), s.Name)
|
||||
} else {
|
||||
s.Name = fmt.Sprintf("%s/%s/%s", nameParts[0], proj.Name.String(), nameParts[1])
|
||||
}
|
||||
stacks[i] = s
|
||||
}
|
||||
return stacks, nil
|
||||
}
|
||||
|
|
|
@ -213,18 +213,19 @@ func (s *Stack) Preview(ctx context.Context, opts ...optpreview.Option) (Preview
|
|||
return res, newAutoError(errors.Wrap(err, "failed to run preview"), stdout, stderr, code)
|
||||
}
|
||||
} else {
|
||||
args := []string{"preview", "--json", fmt.Sprintf("--exec-kind=%s", constant.ExecKindAutoLocal)}
|
||||
args := []string{"preview", fmt.Sprintf("--exec-kind=%s", constant.ExecKindAutoLocal)}
|
||||
args = append(args, sharedArgs...)
|
||||
stdout, stderr, code, err = s.runPulumiCmdSync(ctx, args...)
|
||||
stdout, stderr, code, err = s.runPulumiCmdToStdOut(ctx, args...)
|
||||
if err != nil {
|
||||
return res, newAutoError(errors.Wrap(err, "failed to run preview"), stdout, stderr, code)
|
||||
}
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(stdout), &res)
|
||||
if err != nil {
|
||||
return res, errors.Wrap(err, "unable to unmarshal preview result")
|
||||
}
|
||||
// we're just hacking things together to pipe everything to stdout for autorun mode
|
||||
// err = json.Unmarshal([]byte(stdout), &res)
|
||||
// if err != nil {
|
||||
// return res, errors.Wrap(err, "unable to unmarshal preview result")
|
||||
// }
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
@ -342,7 +343,7 @@ func (s *Stack) Refresh(ctx context.Context, opts ...optrefresh.Option) (Refresh
|
|||
}
|
||||
args = append(args, fmt.Sprintf("--exec-kind=%s", execKind))
|
||||
|
||||
stdout, stderr, code, err := s.runPulumiCmdSync(ctx, args...)
|
||||
stdout, stderr, code, err := s.runPulumiCmdToStdOut(ctx, args...)
|
||||
if err != nil {
|
||||
return res, newAutoError(errors.Wrap(err, "failed to refresh stack"), stdout, stderr, code)
|
||||
}
|
||||
|
@ -399,7 +400,7 @@ func (s *Stack) Destroy(ctx context.Context, opts ...optdestroy.Option) (Destroy
|
|||
}
|
||||
args = append(args, fmt.Sprintf("--exec-kind=%s", execKind))
|
||||
|
||||
stdout, stderr, code, err := s.runPulumiCmdSync(ctx, args...)
|
||||
stdout, stderr, code, err := s.runPulumiCmdToStdOut(ctx, args...)
|
||||
if err != nil {
|
||||
return res, newAutoError(errors.Wrap(err, "failed to destroy stack"), stdout, stderr, code)
|
||||
}
|
||||
|
@ -628,6 +629,34 @@ type DestroyResult struct {
|
|||
// secretSentinel represents the CLI response for an output marked as "secret"
|
||||
const secretSentinel = "[secret]"
|
||||
|
||||
func (s *Stack) runPulumiCmdToStdOut(ctx context.Context, args ...string) (string, string, int, error) {
|
||||
var env []string
|
||||
if s.Workspace().PulumiHome() != "" {
|
||||
homeEnv := fmt.Sprintf("%s=%s", pulumiHomeEnv, s.Workspace().PulumiHome())
|
||||
env = append(env, homeEnv)
|
||||
}
|
||||
if envvars := s.Workspace().GetEnvVars(); envvars != nil {
|
||||
for k, v := range envvars {
|
||||
e := []string{k, v}
|
||||
env = append(env, strings.Join(e, "="))
|
||||
}
|
||||
}
|
||||
additionalArgs, err := s.Workspace().SerializeArgsForOp(ctx, s.Name())
|
||||
if err != nil {
|
||||
return "", "", -1, errors.Wrap(err, "failed to exec command, error getting additional args")
|
||||
}
|
||||
args = append(args, additionalArgs...)
|
||||
stdout, stderr, errCode, err := runPulumiCommandToStdout(ctx, s.Workspace().WorkDir(), env, args...)
|
||||
if err != nil {
|
||||
return stdout, stderr, errCode, err
|
||||
}
|
||||
err = s.Workspace().PostCommandCallback(ctx, s.Name())
|
||||
if err != nil {
|
||||
return stdout, stderr, errCode, errors.Wrap(err, "command ran successfully, but error running PostCommandCallback")
|
||||
}
|
||||
return stdout, stderr, errCode, nil
|
||||
}
|
||||
|
||||
func (s *Stack) runPulumiCmdSync(ctx context.Context, args ...string) (string, string, int, error) {
|
||||
var env []string
|
||||
if s.Workspace().PulumiHome() != "" {
|
||||
|
@ -678,7 +707,7 @@ func (s *Stack) host(ctx context.Context, additionalArgs []string, parallel int)
|
|||
cmd.Env = append(os.Environ(), homeEnv)
|
||||
}
|
||||
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stdout = os.Stdout
|
||||
stderr, _ := cmd.StderrPipe()
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue