builder/digitalocean: add configurable "event_delay" for sleeps
This commit is contained in:
parent
c12e9ff9a8
commit
1e17e90acd
|
@ -31,10 +31,12 @@ type config struct {
|
|||
SSHUsername string `mapstructure:"ssh_username"`
|
||||
SSHPort uint `mapstructure:"ssh_port"`
|
||||
SSHTimeout time.Duration
|
||||
EventDelay time.Duration
|
||||
|
||||
PackerDebug bool `mapstructure:"packer_debug"`
|
||||
|
||||
RawSSHTimeout string `mapstructure:"ssh_timeout"`
|
||||
RawEventDelay string `mapstructure:"event_delay"`
|
||||
}
|
||||
|
||||
type Builder struct {
|
||||
|
@ -88,6 +90,12 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
|||
b.config.RawSSHTimeout = "1m"
|
||||
}
|
||||
|
||||
if b.config.RawEventDelay == "" {
|
||||
// Default to 5 second delays after creating events
|
||||
// to allow DO to process
|
||||
b.config.RawEventDelay = "5s"
|
||||
}
|
||||
|
||||
// A list of errors on the configuration
|
||||
errs := make([]error, 0)
|
||||
|
||||
|
@ -100,12 +108,19 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
|||
if b.config.APIKey == "" {
|
||||
errs = append(errs, errors.New("an api_key must be specified"))
|
||||
}
|
||||
|
||||
timeout, err := time.ParseDuration(b.config.RawSSHTimeout)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Failed parsing ssh_timeout: %s", err))
|
||||
}
|
||||
b.config.SSHTimeout = timeout
|
||||
|
||||
delay, err := time.ParseDuration(b.config.RawEventDelay)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Failed parsing event_delay: %s", err))
|
||||
}
|
||||
b.config.EventDelay = delay
|
||||
|
||||
if len(errs) > 0 {
|
||||
return &packer.MultiError{errs}
|
||||
}
|
||||
|
|
|
@ -220,6 +220,38 @@ func TestBuilderPrepare_SSHTimeout(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_EventDelay(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test default
|
||||
err := b.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.RawEventDelay != "5s" {
|
||||
t.Errorf("invalid: %d", b.config.RawEventDelay)
|
||||
}
|
||||
|
||||
// Test set
|
||||
config["event_delay"] = "10s"
|
||||
b = Builder{}
|
||||
err = b.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test bad
|
||||
config["event_delay"] = "tubes"
|
||||
b = Builder{}
|
||||
err = b.Prepare(config)
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_SnapshotName(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -49,6 +50,7 @@ func (s *stepCreateDroplet) Cleanup(state map[string]interface{}) {
|
|||
|
||||
client := state["client"].(*DigitalOceanClient)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
c := state["config"].(config)
|
||||
|
||||
// Destroy the droplet we just created
|
||||
ui.Say("Destroying droplet...")
|
||||
|
@ -56,7 +58,8 @@ func (s *stepCreateDroplet) Cleanup(state map[string]interface{}) {
|
|||
// Sleep arbitrarily before sending destroy request
|
||||
// Otherwise we get "pending event" errors, even though there isn't
|
||||
// one.
|
||||
time.Sleep(5 * time.Second)
|
||||
log.Printf("Sleeping for %v, event_delay", c.RawEventDelay)
|
||||
time.Sleep(c.EventDelay)
|
||||
|
||||
err := client.DestroyDroplet(s.dropletId)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package digitalocean
|
|||
import (
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -10,13 +11,15 @@ type stepPowerOff struct{}
|
|||
|
||||
func (s *stepPowerOff) Run(state map[string]interface{}) multistep.StepAction {
|
||||
client := state["client"].(*DigitalOceanClient)
|
||||
c := state["config"].(config)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
dropletId := state["droplet_id"].(uint)
|
||||
|
||||
// Sleep arbitrarily before sending power off request
|
||||
// Otherwise we get "pending event" errors, even though there isn't
|
||||
// one.
|
||||
time.Sleep(3 * time.Second)
|
||||
log.Printf("Sleeping for %v, event_delay", c.RawEventDelay)
|
||||
time.Sleep(c.EventDelay)
|
||||
|
||||
// Poweroff the droplet so it can be snapshot
|
||||
err := client.PowerOffDroplet(dropletId)
|
||||
|
|
Loading…
Reference in New Issue