Skip to content

Commit

Permalink
provisioner/salt-masterless: Wait for operations to complete
Browse files Browse the repository at this point in the history
Previously the provisioner did not wait until the Salt operation had completed before returning, causing some operations not to be applied, and causing the output to get swallowed.

Now we wait until the remote work is complete, and copy output into the Terraform log in a similar way as is done for other provisioners.
  • Loading branch information
subbarao authored and apparentlymart committed Dec 5, 2017
1 parent fe33661 commit 44cb98e
Showing 1 changed file with 70 additions and 5 deletions.
75 changes: 70 additions & 5 deletions builtin/provisioners/salt-masterless/resource_provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
"context"
"errors"
"fmt"
"io"
"os"
"path/filepath"

"github.com/hashicorp/terraform/communicator"
"github.com/hashicorp/terraform/communicator/remote"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
linereader "github.com/mitchellh/go-linereader"
)

type provisionFn func(terraform.UIOutput, communicator.Communicator) error
Expand Down Expand Up @@ -139,14 +141,46 @@ func applyFn(ctx context.Context) error {
}
o.Output(fmt.Sprintf("Downloading saltstack bootstrap to /tmp/install_salt.sh"))
if err = comm.Start(cmd); err != nil {
return fmt.Errorf("Unable to download Salt: %s", err)
err = fmt.Errorf("Unable to download Salt: %s", err)
}

if err == nil {
cmd.Wait()
if cmd.ExitStatus != 0 {
err = fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus)
}
}

outR, outW := io.Pipe()
errR, errW := io.Pipe()
outDoneCh := make(chan struct{})
errDoneCh := make(chan struct{})
go copyOutput(o, outR, outDoneCh)
go copyOutput(o, errR, errDoneCh)
cmd = &remote.Cmd{
Command: fmt.Sprintf("%s /tmp/install_salt.sh %s", p.sudo("sh"), p.BootstrapArgs),
Stdout: outW,
Stderr: errW,
}

o.Output(fmt.Sprintf("Installing Salt with command %s", cmd.Command))
if err = comm.Start(cmd); err != nil {
return fmt.Errorf("Unable to install Salt: %s", err)
err = fmt.Errorf("Unable to install Salt: %s", err)
}

if err == nil {
cmd.Wait()
if cmd.ExitStatus != 0 {
err = fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus)
}
}
// Wait for output to clean up
outW.Close()
errW.Close()
<-outDoneCh
<-errDoneCh
if err != nil {
return err
}
}

Expand Down Expand Up @@ -212,17 +246,39 @@ func applyFn(ctx context.Context) error {
}
}

outR, outW := io.Pipe()
errR, errW := io.Pipe()
outDoneCh := make(chan struct{})
errDoneCh := make(chan struct{})

go copyOutput(o, outR, outDoneCh)
go copyOutput(o, errR, errDoneCh)
o.Output(fmt.Sprintf("Running: salt-call --local %s", p.CmdArgs))
cmd := &remote.Cmd{Command: p.sudo(fmt.Sprintf("salt-call --local %s", p.CmdArgs))}
cmd := &remote.Cmd{
Command: p.sudo(fmt.Sprintf("salt-call --local %s", p.CmdArgs)),
Stdout: outW,
Stderr: errW,
}
if err = comm.Start(cmd); err != nil || cmd.ExitStatus != 0 {
if err == nil {
err = fmt.Errorf("Bad exit status: %d", cmd.ExitStatus)
}

return fmt.Errorf("Error executing salt-call: %s", err)
err = fmt.Errorf("Error executing salt-call: %s", err)
}
if err == nil {
cmd.Wait()
if cmd.ExitStatus != 0 {
err = fmt.Errorf("Script exited with non-zero exit status: %d", cmd.ExitStatus)
}
}
// Wait for output to clean up
outW.Close()
errW.Close()
<-outDoneCh
<-errDoneCh

return nil
return err
}

// Prepends sudo to supplied command if config says to
Expand Down Expand Up @@ -466,3 +522,12 @@ func decodeConfig(d *schema.ResourceData) (*provisioner, error) {

return p, nil
}

func copyOutput(
o terraform.UIOutput, r io.Reader, doneCh chan<- struct{}) {
defer close(doneCh)
lr := linereader.New(r)
for line := range lr.Ch {
o.Output(line)
}
}

0 comments on commit 44cb98e

Please sign in to comment.