add better logging and error handling to ansible provisioner (#3477)

This commit is contained in:
Billie Cleek 2016-08-24 10:53:39 -07:00 committed by Rickard von Essen
parent b7da7768df
commit 023f2edde8
1 changed files with 54 additions and 26 deletions

View File

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"log"
"net"
"github.com/mitchellh/packer/packer"
@ -100,62 +101,71 @@ func (c *adapter) handleSession(newChannel ssh.NewChannel) error {
for req := range in {
switch req.Type {
case "pty-req":
log.Println("ansible provisioner pty-req request")
// accept pty-req requests, but don't actually do anything. Necessary for OpenSSH and sudo.
req.Reply(true, nil)
case "env":
req.Reply(true, nil)
req, err := newEnvRequest(req)
if err != nil {
c.ui.Error(err.Error())
req.Reply(false, nil)
continue
}
env = append(env, req.Payload)
case "exec":
log.Printf("new env request: %s", req.Payload)
req.Reply(true, nil)
case "exec":
req, err := newExecRequest(req)
if err != nil {
c.ui.Error(err.Error())
req.Reply(false, nil)
close(done)
continue
}
if len(req.Payload) > 0 {
cmd := &packer.RemoteCmd{
Stdin: channel,
Stdout: channel,
Stderr: channel.Stderr(),
Command: string(req.Payload),
}
log.Printf("new exec request: %s", req.Payload)
if err := c.comm.Start(cmd); err != nil {
c.ui.Error(err.Error())
close(done)
return
}
go func(cmd *packer.RemoteCmd, channel ssh.Channel) {
cmd.Wait()
exitStatus := make([]byte, 4)
binary.BigEndian.PutUint32(exitStatus, uint32(cmd.ExitStatus))
channel.SendRequest("exit-status", false, exitStatus)
close(done)
}(cmd, channel)
if len(req.Payload) == 0 {
req.Reply(false, nil)
close(done)
return
}
cmd := &packer.RemoteCmd{
Stdin: channel,
Stdout: channel,
Stderr: channel.Stderr(),
Command: string(req.Payload),
}
if err := c.comm.Start(cmd); err != nil {
c.ui.Error(err.Error())
req.Reply(false, nil)
close(done)
return
}
go func(cmd *packer.RemoteCmd, channel ssh.Channel) {
cmd.Wait()
exitStatus := make([]byte, 4)
binary.BigEndian.PutUint32(exitStatus, uint32(cmd.ExitStatus))
channel.SendRequest("exit-status", false, exitStatus)
close(done)
}(cmd, channel)
req.Reply(true, nil)
case "subsystem":
req, err := newSubsystemRequest(req)
if err != nil {
c.ui.Error(err.Error())
req.Reply(false, nil)
continue
}
log.Printf("new subsystem request: %s", req.Payload)
switch req.Payload {
case "sftp":
c.ui.Say("starting sftp subsystem")
req.Reply(true, nil)
sftpCmd := c.sftpCmd
if len(sftpCmd) == 0 {
sftpCmd = "/usr/lib/sftp-server -e"
@ -167,16 +177,22 @@ func (c *adapter) handleSession(newChannel ssh.NewChannel) error {
Command: sftpCmd,
}
c.ui.Say("starting sftp subsystem")
if err := c.comm.Start(cmd); err != nil {
c.ui.Error(err.Error())
req.Reply(false, nil)
close(done)
return
}
req.Reply(true, nil)
go func() {
cmd.Wait()
close(done)
}()
default:
c.ui.Error(fmt.Sprintf("unsupported subsystem requested: %s", req.Payload))
req.Reply(false, nil)
}
@ -205,6 +221,10 @@ type envRequestPayload struct {
Value string
}
func (p envRequestPayload) String() string {
return fmt.Sprintf("%s=%s", p.Name, p.Value)
}
func newEnvRequest(raw *ssh.Request) (*envRequest, error) {
r := new(envRequest)
r.Request = raw
@ -238,6 +258,10 @@ type execRequest struct {
type execRequestPayload string
func (p execRequestPayload) String() string {
return string(p)
}
func newExecRequest(raw *ssh.Request) (*execRequest, error) {
r := new(execRequest)
r.Request = raw
@ -260,6 +284,10 @@ type subsystemRequest struct {
type subsystemRequestPayload string
func (p subsystemRequestPayload) String() string {
return string(p)
}
func newSubsystemRequest(raw *ssh.Request) (*subsystemRequest, error) {
r := new(subsystemRequest)
r.Request = raw