Separate config for shutdown step
This commit is contained in:
parent
310e10b19b
commit
228ac12366
@ -94,8 +94,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||
},
|
||||
&common.StepProvision{},
|
||||
&StepShutdown{
|
||||
Command: b.config.ShutdownCommand,
|
||||
ShutdownTimeout: b.config.ShutdownTimeout,
|
||||
config: &b.config.ShutdownConfig,
|
||||
},
|
||||
&StepCreateSnapshot{
|
||||
createSnapshot: b.config.CreateSnapshot,
|
||||
|
20
config.go
20
config.go
@ -8,7 +8,6 @@ import (
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -37,11 +36,9 @@ type Config struct {
|
||||
communicator.Config `mapstructure:",squash"`
|
||||
|
||||
// Post-processing
|
||||
ShutdownCommand string `mapstructure:"shutdown_command"`
|
||||
RawShutdownTimeout string `mapstructure:"shutdown_timeout"`
|
||||
ShutdownTimeout time.Duration
|
||||
CreateSnapshot bool `mapstructure:"create_snapshot"`
|
||||
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
||||
ShutdownConfig `mapstructure:",squash"`
|
||||
CreateSnapshot bool `mapstructure:"create_snapshot"`
|
||||
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
@ -82,16 +79,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||
}
|
||||
|
||||
errs = packer.MultiErrorAppend(errs, c.HardwareConfig.Prepare()...)
|
||||
|
||||
if c.RawShutdownTimeout != "" {
|
||||
timeout, err := time.ParseDuration(c.RawShutdownTimeout)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err))
|
||||
}
|
||||
c.ShutdownTimeout = timeout
|
||||
} else {
|
||||
c.ShutdownTimeout = 5 * time.Minute
|
||||
}
|
||||
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...)
|
||||
|
||||
if len(errs.Errors) > 0 {
|
||||
return nil, warnings, errs
|
||||
|
@ -16,8 +16,8 @@ func TestTimeout(t *testing.T) {
|
||||
raw["shutdown_timeout"] = "3m"
|
||||
conf, warns, err := NewConfig(raw)
|
||||
testConfigOk(t, warns, err)
|
||||
if conf.ShutdownTimeout != 3 * time.Minute {
|
||||
t.Fatalf("shutdown_timeout sould be equal 3 minutes")
|
||||
if conf.ShutdownConfig.Timeout != 3 * time.Minute {
|
||||
t.Fatalf("shutdown_timeout sould be equal 3 minutes, got %v", conf.ShutdownConfig.Timeout)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,31 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type StepShutdown struct{
|
||||
Command string
|
||||
ShutdownTimeout time.Duration
|
||||
type ShutdownConfig struct {
|
||||
Command string `mapstructure:"shutdown_command"`
|
||||
RawTimeout string `mapstructure:"shutdown_timeout"`
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func (c *ShutdownConfig) Prepare() []error {
|
||||
var errs []error
|
||||
|
||||
if c.RawTimeout != "" {
|
||||
timeout, err := time.ParseDuration(c.RawTimeout)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err))
|
||||
return errs
|
||||
}
|
||||
c.Timeout = timeout
|
||||
} else {
|
||||
c.Timeout = 5 * time.Minute
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type StepShutdown struct {
|
||||
config *ShutdownConfig
|
||||
}
|
||||
|
||||
func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
@ -24,22 +46,20 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
vm := state.Get("vm").(*object.VirtualMachine)
|
||||
ctx := state.Get("ctx").(context.Context)
|
||||
|
||||
ui.Say("VM shutdown...")
|
||||
ui.Say("Shut down VM...")
|
||||
|
||||
if s.Command != "" {
|
||||
if s.config.Command != "" {
|
||||
ui.Say("Gracefully halting virtual machine...")
|
||||
log.Printf("Executing shutdown command: %s", s.Command)
|
||||
log.Printf("Executing shutdown command: %s", s.config.Command)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd := &packer.RemoteCmd{
|
||||
Command: s.Command,
|
||||
Command: s.config.Command,
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
}
|
||||
if err := comm.Start(cmd); err != nil {
|
||||
err := fmt.Errorf("Failed to send shutdown command: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
state.Put("error", fmt.Errorf("Failed to send shutdown command: %s", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
} else {
|
||||
@ -47,14 +67,14 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
err := vm.ShutdownGuest(ctx)
|
||||
if err != nil {
|
||||
state.Put("error", fmt.Errorf("Could not shutdown guest: %v", err))
|
||||
state.Put("error", fmt.Errorf("Cannot shut down VM: %v", err))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the machine to actually shut down
|
||||
log.Printf("Waiting max %s for shutdown to complete", s.ShutdownTimeout)
|
||||
shutdownTimer := time.After(s.ShutdownTimeout)
|
||||
log.Printf("Waiting max %s for shutdown to complete", s.config.Timeout)
|
||||
shutdownTimer := time.After(s.config.Timeout)
|
||||
for {
|
||||
powerState, err := vm.PowerState(ctx)
|
||||
if err != nil {
|
||||
@ -81,4 +101,3 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
||||
}
|
||||
|
||||
func (s *StepShutdown) Cleanup(state multistep.StateBag) {}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user