commit
2a883c59e7
|
@ -69,7 +69,10 @@ func (c *Communicator) Upload(dst string, r io.Reader, fi *os.FileInfo) error {
|
||||||
return fmt.Errorf("Error preparing shell script: %s", err)
|
return fmt.Errorf("Error preparing shell script: %s", err)
|
||||||
}
|
}
|
||||||
defer os.Remove(tf.Name())
|
defer os.Remove(tf.Name())
|
||||||
io.Copy(tf, r)
|
|
||||||
|
if _, err := io.Copy(tf, r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
cpCmd, err := c.CmdWrapper(fmt.Sprintf("cp %s %s", tf.Name(), dst))
|
cpCmd, err := c.CmdWrapper(fmt.Sprintf("cp %s %s", tf.Name(), dst))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package chroot
|
package chroot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// StepChrootProvision provisions the instance within a chroot.
|
// StepChrootProvision provisions the instance within a chroot.
|
||||||
type StepChrootProvision struct {
|
type StepChrootProvision struct {
|
||||||
mounts []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepChrootProvision) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepChrootProvision) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (s *StepMountDevice) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui.Say("Mounting the root device...")
|
ui.Say("Mounting the root device...")
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
|
|
||||||
// build mount options from mount_options config, usefull for nouuid options
|
// build mount options from mount_options config, useful for nouuid options
|
||||||
// or other specific device type settings for mount
|
// or other specific device type settings for mount
|
||||||
opts := ""
|
opts := ""
|
||||||
if len(s.MountOptions) > 0 {
|
if len(s.MountOptions) > 0 {
|
||||||
|
|
|
@ -2,15 +2,15 @@ package chroot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StepPrepareDevice finds an available device and sets it.
|
// StepPrepareDevice finds an available device and sets it.
|
||||||
type StepPrepareDevice struct {
|
type StepPrepareDevice struct {
|
||||||
mounts []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepPrepareDevice) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepPrepareDevice) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (c *AccessConfig) Config() (*aws.Config, error) {
|
||||||
func (c *AccessConfig) Region() (string, error) {
|
func (c *AccessConfig) Region() (string, error) {
|
||||||
if c.RawRegion != "" {
|
if c.RawRegion != "" {
|
||||||
if !c.SkipValidation {
|
if !c.SkipValidation {
|
||||||
if valid := ValidateRegion(c.RawRegion); valid == false {
|
if valid := ValidateRegion(c.RawRegion); !valid {
|
||||||
return "", fmt.Errorf("Not a valid region: %s", c.RawRegion)
|
return "", fmt.Errorf("Not a valid region: %s", c.RawRegion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ func (c *AccessConfig) Region() (string, error) {
|
||||||
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
|
func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
var errs []error
|
var errs []error
|
||||||
if c.RawRegion != "" && !c.SkipValidation {
|
if c.RawRegion != "" && !c.SkipValidation {
|
||||||
if valid := ValidateRegion(c.RawRegion); valid == false {
|
if valid := ValidateRegion(c.RawRegion); !valid {
|
||||||
errs = append(errs, fmt.Errorf("Unknown region: %s", c.RawRegion))
|
errs = append(errs, fmt.Errorf("Unknown region: %s", c.RawRegion))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,5 +115,5 @@ func GetInstanceMetaData(path string) (contents []byte, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return []byte(body), err
|
return body, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
|
|
||||||
if !c.AMISkipRegionValidation {
|
if !c.AMISkipRegionValidation {
|
||||||
// Verify the region is real
|
// Verify the region is real
|
||||||
if valid := ValidateRegion(region); valid == false {
|
if valid := ValidateRegion(region); !valid {
|
||||||
errs = append(errs, fmt.Errorf("Unknown region: %s", region))
|
errs = append(errs, fmt.Errorf("Unknown region: %s", region))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,10 +90,7 @@ func (c *CLIConfig) Prepare(name string) error {
|
||||||
c.SourceProfile = c.ProfileName
|
c.SourceProfile = c.ProfileName
|
||||||
}
|
}
|
||||||
c.profileCred, err = credsFromName(c.SourceProfile)
|
c.profileCred, err = credsFromName(c.SourceProfile)
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CLIConfig) getSessionName(rawName string) (string, error) {
|
func (c *CLIConfig) getSessionName(rawName string) (string, error) {
|
||||||
|
|
|
@ -163,7 +163,7 @@ func WaitForState(conf *StateChangeConf) (i interface{}, err error) {
|
||||||
log.Printf("Waiting for state to become: %s", conf.Target)
|
log.Printf("Waiting for state to become: %s", conf.Target)
|
||||||
|
|
||||||
sleepSeconds := SleepSeconds()
|
sleepSeconds := SleepSeconds()
|
||||||
maxTicks := int(TimeoutSeconds()/sleepSeconds) + 1
|
maxTicks := TimeoutSeconds()/sleepSeconds + 1
|
||||||
notfoundTick := 0
|
notfoundTick := 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (s *StepCreateEncryptedAMICopy) Run(state multistep.StateBag) multistep.Ste
|
||||||
// Encrypt boot not set, so skip step
|
// Encrypt boot not set, so skip step
|
||||||
if !s.EncryptBootVolume {
|
if !s.EncryptBootVolume {
|
||||||
if kmsKeyId != "" {
|
if kmsKeyId != "" {
|
||||||
log.Printf(fmt.Sprintf("Ignoring KMS Key ID: %s, encrypted=false", kmsKeyId))
|
log.Printf("Ignoring KMS Key ID: %s, encrypted=false", kmsKeyId)
|
||||||
}
|
}
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,10 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
|
||||||
Target: "cancelled",
|
Target: "cancelled",
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForState(&stateChange)
|
_, err := WaitForState(&stateChange)
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,6 +362,9 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
|
||||||
Target: "terminated",
|
Target: "terminated",
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForState(&stateChange)
|
_, err := WaitForState(&stateChange)
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We loop and retry this a few times because sometimes the security
|
// We loop and retry this a few times because sometimes the security
|
||||||
// group isn't available immediately because AWS resources are eventaully
|
// group isn't available immediately because AWS resources are eventually
|
||||||
// consistent.
|
// consistent.
|
||||||
ui.Say(fmt.Sprintf(
|
ui.Say(fmt.Sprintf(
|
||||||
"Authorizing access to port %d the temporary security group...",
|
"Authorizing access to port %d the temporary security group...",
|
||||||
|
|
|
@ -85,7 +85,7 @@ func (s *StepSourceAMIInfo) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(imageResp.Images) > 1 && s.AmiFilters.MostRecent == false {
|
if len(imageResp.Images) > 1 && !s.AmiFilters.MostRecent {
|
||||||
err := fmt.Errorf("Your query returned more than one result. Please try a more specific search, or set most_recent to true.")
|
err := fmt.Errorf("Your query returned more than one result. Please try a more specific search, or set most_recent to true.")
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
|
|
|
@ -84,11 +84,11 @@ func checkTags() builderT.TestCheckFunc {
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error retreiving Snapshots for AMI Artifcat (%#v) in Tags Test: %s", artifact, err)
|
return fmt.Errorf("Error retrieving Snapshots for AMI Artifact (%#v) in Tags Test: %s", artifact, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(resp.Snapshots) == 0 {
|
if len(resp.Snapshots) == 0 {
|
||||||
return fmt.Errorf("No Snapshots found for AMI Artifcat (%#v) in Tags Test", artifact)
|
return fmt.Errorf("No Snapshots found for AMI Artifact (%#v) in Tags Test", artifact)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the snapshots, check the tags
|
// Grab the snapshots, check the tags
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
|
|
||||||
type StepGetCertificate struct {
|
type StepGetCertificate struct {
|
||||||
client *AzureClient
|
client *AzureClient
|
||||||
template string
|
|
||||||
get func(keyVaultName string, secretName string) (string, error)
|
get func(keyVaultName string, secretName string) (string, error)
|
||||||
say func(message string)
|
say func(message string)
|
||||||
error func(e error)
|
error func(e error)
|
||||||
|
|
|
@ -18,5 +18,5 @@ func GlueStrings(a, b string) string {
|
||||||
shift++
|
shift++
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(a[:shift]) + b
|
return a[:shift] + b
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestBMPStringDecode(t *testing.T) {
|
||||||
|
|
||||||
func TestBMPString(t *testing.T) {
|
func TestBMPString(t *testing.T) {
|
||||||
str, err := bmpString("")
|
str, err := bmpString("")
|
||||||
if bytes.Compare(str, []byte{0, 0}) != 0 {
|
if !bytes.Equal(str, []byte{0, 0}) {
|
||||||
t.Errorf("expected empty string to return double 0, but found: % x", str)
|
t.Errorf("expected empty string to return double 0, but found: % x", str)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -44,7 +44,7 @@ func TestBMPString(t *testing.T) {
|
||||||
|
|
||||||
// Example from https://tools.ietf.org/html/rfc7292#appendix-B
|
// Example from https://tools.ietf.org/html/rfc7292#appendix-B
|
||||||
str, err = bmpString("Beavis")
|
str, err = bmpString("Beavis")
|
||||||
if bytes.Compare(str, []byte{0x00, 0x42, 0x00, 0x65, 0x00, 0x61, 0x00, 0x0076, 0x00, 0x69, 0x00, 0x73, 0x00, 0x00}) != 0 {
|
if !bytes.Equal(str, []byte{0x00, 0x42, 0x00, 0x65, 0x00, 0x61, 0x00, 0x0076, 0x00, 0x69, 0x00, 0x73, 0x00, 0x00}) {
|
||||||
t.Errorf("expected 'Beavis' to return 0x00 0x42 0x00 0x65 0x00 0x61 0x00 0x76 0x00 0x69 0x00 0x73 0x00 0x00, but found: % x", str)
|
t.Errorf("expected 'Beavis' to return 0x00 0x42 0x00 0x65 0x00 0x61 0x00 0x76 0x00 0x69 0x00 0x73 0x00 0x00, but found: % x", str)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -54,7 +54,7 @@ func TestBMPString(t *testing.T) {
|
||||||
// some characters from the "Letterlike Symbols Unicode block"
|
// some characters from the "Letterlike Symbols Unicode block"
|
||||||
tst := "\u2115 - Double-struck N"
|
tst := "\u2115 - Double-struck N"
|
||||||
str, err = bmpString(tst)
|
str, err = bmpString(tst)
|
||||||
if bytes.Compare(str, []byte{0x21, 0x15, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x2d, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x75, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x4e, 0x00, 0x00}) != 0 {
|
if !bytes.Equal(str, []byte{0x21, 0x15, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x2d, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x75, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x4e, 0x00, 0x00}) {
|
||||||
t.Errorf("expected '%s' to return 0x21 0x15 0x00 0x20 0x00 0x2d 0x00 0x20 0x00 0x44 0x00 0x6f 0x00 0x75 0x00 0x62 0x00 0x6c 0x00 0x65 0x00 0x2d 0x00 0x73 0x00 0x74 0x00 0x72 0x00 0x75 0x00 0x63 0x00 0x6b 0x00 0x20 0x00 0x4e 0x00 0x00, but found: % x", tst, str)
|
t.Errorf("expected '%s' to return 0x21 0x15 0x00 0x20 0x00 0x2d 0x00 0x20 0x00 0x44 0x00 0x6f 0x00 0x75 0x00 0x62 0x00 0x6c 0x00 0x65 0x00 0x2d 0x00 0x73 0x00 0x74 0x00 0x72 0x00 0x75 0x00 0x63 0x00 0x6b 0x00 0x20 0x00 0x4e 0x00 0x00, but found: % x", tst, str)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -47,7 +47,7 @@ func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error)
|
||||||
if psLen := int(decrypted[len(decrypted)-1]); psLen > 0 && psLen <= cbc.BlockSize() {
|
if psLen := int(decrypted[len(decrypted)-1]); psLen > 0 && psLen <= cbc.BlockSize() {
|
||||||
m := decrypted[:len(decrypted)-psLen]
|
m := decrypted[:len(decrypted)-psLen]
|
||||||
ps := decrypted[len(decrypted)-psLen:]
|
ps := decrypted[len(decrypted)-psLen:]
|
||||||
if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 {
|
if !bytes.Equal(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) {
|
||||||
return nil, ErrDecryption
|
return nil, ErrDecryption
|
||||||
}
|
}
|
||||||
decrypted = m
|
decrypted = m
|
||||||
|
@ -87,7 +87,7 @@ func TestPbDecrypterFor(t *testing.T) {
|
||||||
expectedM := []byte{185, 73, 135, 249, 137, 1, 122, 247}
|
expectedM := []byte{185, 73, 135, 249, 137, 1, 122, 247}
|
||||||
cbc.CryptBlocks(M, M)
|
cbc.CryptBlocks(M, M)
|
||||||
|
|
||||||
if bytes.Compare(M, expectedM) != 0 {
|
if !bytes.Equal(M, expectedM) {
|
||||||
t.Errorf("expected M to be '%d', but found '%d", expectedM, M)
|
t.Errorf("expected M to be '%d', but found '%d", expectedM, M)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ func TestPbDecrypt(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error decrypting C=%x: %v", c, err)
|
t.Errorf("error decrypting C=%x: %v", c, err)
|
||||||
}
|
}
|
||||||
if bytes.Compare(m, e) != 0 {
|
if !bytes.Equal(m, e) {
|
||||||
t.Errorf("expected C=%x to be decoded to M=%x, but found %x", c, e, m)
|
t.Errorf("expected C=%x to be decoded to M=%x, but found %x", c, e, m)
|
||||||
}
|
}
|
||||||
case error:
|
case error:
|
||||||
|
|
|
@ -12,7 +12,7 @@ func TestThatPBKDFWorksCorrectlyForLongKeys(t *testing.T) {
|
||||||
password, _ := bmpString("sesame")
|
password, _ := bmpString("sesame")
|
||||||
key := pbkdf(salt, password, 2048)
|
key := pbkdf(salt, password, 2048)
|
||||||
|
|
||||||
if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); bytes.Compare(key, expected) != 0 {
|
if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); !bytes.Equal(key, expected) {
|
||||||
t.Fatalf("expected key '% x', but found '% x'", key, expected)
|
t.Fatalf("expected key '% x', but found '% x'", key, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,23 +30,6 @@ type contentInfo struct {
|
||||||
Content asn1.RawValue `asn1:"tag:0,explicit,optional"`
|
Content asn1.RawValue `asn1:"tag:0,explicit,optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type encryptedData struct {
|
|
||||||
Version int
|
|
||||||
EncryptedContentInfo encryptedContentInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type encryptedContentInfo struct {
|
|
||||||
ContentType asn1.ObjectIdentifier
|
|
||||||
ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
|
|
||||||
EncryptedContent []byte `asn1:"tag:0,optional"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i encryptedContentInfo) GetAlgorithm() pkix.AlgorithmIdentifier {
|
|
||||||
return i.ContentEncryptionAlgorithm
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i encryptedContentInfo) GetData() []byte { return i.EncryptedContent }
|
|
||||||
|
|
||||||
type safeBag struct {
|
type safeBag struct {
|
||||||
Id asn1.ObjectIdentifier
|
Id asn1.ObjectIdentifier
|
||||||
Value asn1.RawValue `asn1:"tag:0,explicit"`
|
Value asn1.RawValue `asn1:"tag:0,explicit"`
|
||||||
|
|
|
@ -44,7 +44,7 @@ func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
return nil, fmt.Errorf("Error loading configured private key file: %s", err)
|
return nil, fmt.Errorf("Error loading configured private key file: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
signer, err := ssh.ParsePrivateKey(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/digitalocean/godo"
|
"github.com/digitalocean/godo"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"io/ioutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type stepCreateDroplet struct {
|
type stepCreateDroplet struct {
|
||||||
|
@ -41,7 +42,7 @@ func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
Slug: c.Image,
|
Slug: c.Image,
|
||||||
},
|
},
|
||||||
SSHKeys: []godo.DropletCreateSSHKey{
|
SSHKeys: []godo.DropletCreateSSHKey{
|
||||||
{ID: int(sshKeyId)},
|
{ID: sshKeyId},
|
||||||
},
|
},
|
||||||
PrivateNetworking: c.PrivateNetworking,
|
PrivateNetworking: c.PrivateNetworking,
|
||||||
UserData: userData,
|
UserData: userData,
|
||||||
|
|
|
@ -99,7 +99,7 @@ func TestUploadDownload(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestLargeDownload verifies that files are the apporpriate size after being
|
// TestLargeDownload verifies that files are the appropriate size after being
|
||||||
// downloaded. This is to identify and fix the race condition in #2793. You may
|
// downloaded. This is to identify and fix the race condition in #2793. You may
|
||||||
// need to use github.com/cbednarski/rerun to verify since this problem occurs
|
// need to use github.com/cbednarski/rerun to verify since this problem occurs
|
||||||
// only intermittently.
|
// only intermittently.
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (c *AwsAccessConfig) config(region string) (*aws.Config, error) {
|
||||||
// or an error.
|
// or an error.
|
||||||
func (c *AwsAccessConfig) EcrGetLogin(ecrUrl string) (string, string, error) {
|
func (c *AwsAccessConfig) EcrGetLogin(ecrUrl string) (string, string, error) {
|
||||||
|
|
||||||
exp := regexp.MustCompile("(?:http://|https://|)([0-9]*)\\.dkr\\.ecr\\.(.*)\\.amazonaws\\.com.*")
|
exp := regexp.MustCompile(`(?:http://|https://|)([0-9]*)\.dkr\.ecr\.(.*)\.amazonaws\.com.*`)
|
||||||
splitUrl := exp.FindStringSubmatch(ecrUrl)
|
splitUrl := exp.FindStringSubmatch(ecrUrl)
|
||||||
if len(splitUrl) != 3 {
|
if len(splitUrl) != 3 {
|
||||||
return "", "", fmt.Errorf("Failed to parse the ECR URL: %s it should be on the form <account number>.dkr.ecr.<region>.amazonaws.com", ecrUrl)
|
return "", "", fmt.Errorf("Failed to parse the ECR URL: %s it should be on the form <account number>.dkr.ecr.<region>.amazonaws.com", ecrUrl)
|
||||||
|
|
|
@ -54,7 +54,6 @@ type Config struct {
|
||||||
Zone string `mapstructure:"zone"`
|
Zone string `mapstructure:"zone"`
|
||||||
|
|
||||||
Account AccountFile
|
Account AccountFile
|
||||||
privateKeyBytes []byte
|
|
||||||
stateTimeout time.Duration
|
stateTimeout time.Duration
|
||||||
imageAlreadyExists bool
|
imageAlreadyExists bool
|
||||||
ctx interpolate.Context
|
ctx interpolate.Context
|
||||||
|
|
|
@ -12,8 +12,6 @@ import (
|
||||||
// stepInstanceInfo represents a Packer build step that gathers GCE instance info.
|
// stepInstanceInfo represents a Packer build step that gathers GCE instance info.
|
||||||
type StepInstanceInfo struct {
|
type StepInstanceInfo struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
|
|
||||||
info int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes the Packer build step that gathers GCE instance info.
|
// Run executes the Packer build step that gathers GCE instance info.
|
||||||
|
|
|
@ -254,7 +254,7 @@ func (d *HypervPS4Driver) verifyPSVersion() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionOutput := strings.TrimSpace(string(cmdOut))
|
versionOutput := strings.TrimSpace(cmdOut)
|
||||||
log.Printf("%s output: %s", versionCmd, versionOutput)
|
log.Printf("%s output: %s", versionCmd, versionOutput)
|
||||||
|
|
||||||
ver, err := strconv.ParseInt(versionOutput, 10, 32)
|
ver, err := strconv.ParseInt(versionOutput, 10, 32)
|
||||||
|
@ -283,7 +283,7 @@ func (d *HypervPS4Driver) verifyPSHypervModule() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := strings.TrimSpace(string(cmdOut))
|
res := strings.TrimSpace(cmdOut)
|
||||||
|
|
||||||
if res == "False" {
|
if res == "False" {
|
||||||
err := fmt.Errorf("%s", "PS Hyper-V module is not loaded. Make sure Hyper-V feature is on.")
|
err := fmt.Errorf("%s", "PS Hyper-V module is not loaded. Make sure Hyper-V feature is on.")
|
||||||
|
@ -305,7 +305,7 @@ func (d *HypervPS4Driver) verifyHypervPermissions() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := strings.TrimSpace(string(cmdOut))
|
res := strings.TrimSpace(cmdOut)
|
||||||
|
|
||||||
if res == "False" {
|
if res == "False" {
|
||||||
isAdmin, _ := powershell.IsCurrentUserAnAdministrator()
|
isAdmin, _ := powershell.IsCurrentUserAnAdministrator()
|
||||||
|
|
|
@ -2,11 +2,12 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StepConfigureIp struct {
|
type StepConfigureIp struct {
|
||||||
|
@ -35,7 +36,7 @@ func (s *StepConfigureIp) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
ip = strings.TrimSpace(string(cmdOut))
|
ip = strings.TrimSpace(cmdOut)
|
||||||
|
|
||||||
if ip != "False" {
|
if ip != "False" {
|
||||||
break
|
break
|
||||||
|
|
|
@ -3,18 +3,18 @@ package common
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const port string = "13000"
|
const port string = "13000"
|
||||||
|
|
||||||
type StepPollingInstalation struct {
|
type StepPollingInstalation struct {
|
||||||
step int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAction {
|
func (s *StepPollingInstalation) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
|
@ -2,10 +2,11 @@ package openstack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ber_encoded_key = `
|
var ber_encoded_key = `
|
||||||
|
@ -71,7 +72,7 @@ mKMH6Gf6COfSIbLuejdzSOUAmjkFpm+nwBkka1eHdAy4ALn9wNQz3w==
|
||||||
func TestBerToDer(t *testing.T) {
|
func TestBerToDer(t *testing.T) {
|
||||||
_, err := exec.LookPath("openssl")
|
_, err := exec.LookPath("openssl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Skipf("OpenSSL not availible skippint test.")
|
t.Skipf("OpenSSL not available skipping test.")
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := new(bytes.Buffer)
|
msg := new(bytes.Buffer)
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepA
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Paralells Tools path on the host machine
|
// Get the Parallels Tools path on the host machine
|
||||||
parallelsToolsPath := state.Get("parallels_tools_path").(string)
|
parallelsToolsPath := state.Get("parallels_tools_path").(string)
|
||||||
|
|
||||||
// Attach the guest additions to the computer
|
// Attach the guest additions to the computer
|
||||||
|
|
|
@ -47,7 +47,7 @@ func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepA
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Paralells Tools path on the host machine
|
// Get the Parallels Tools path on the host machine
|
||||||
parallelsToolsPath := state.Get("parallels_tools_path").(string)
|
parallelsToolsPath := state.Get("parallels_tools_path").(string)
|
||||||
|
|
||||||
f, err := os.Open(parallelsToolsPath)
|
f, err := os.Open(parallelsToolsPath)
|
||||||
|
|
|
@ -90,7 +90,7 @@ func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
_, errs := b.Prepare(config)
|
_, errs := b.Prepare(config)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
// Create the driver that we'll use to communicate with Parallels
|
// Create the driver that we'll use to communicate with Parallels
|
||||||
driver, err := parallelscommon.NewDriver()
|
driver, err := parallelscommon.NewDriver()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed creating Paralles driver: %s", err)
|
return nil, fmt.Errorf("Failed creating Parallels driver: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the state.
|
// Set up the state.
|
||||||
|
|
|
@ -87,7 +87,7 @@ func TestNewConfig_InvalidFloppies(t *testing.T) {
|
||||||
c["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
c["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
||||||
_, _, errs := NewConfig(c)
|
_, _, errs := NewConfig(c)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"github.com/profitbricks/profitbricks-sdk-go"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"github.com/profitbricks/profitbricks-sdk-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stepCreateServer struct{}
|
type stepCreateServer struct{}
|
||||||
|
@ -71,7 +72,11 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
if datacenter.StatusCode > 299 {
|
if datacenter.StatusCode > 299 {
|
||||||
if datacenter.StatusCode > 299 {
|
if datacenter.StatusCode > 299 {
|
||||||
var restError RestError
|
var restError RestError
|
||||||
json.Unmarshal([]byte(datacenter.Response), &restError)
|
err := json.Unmarshal([]byte(datacenter.Response), &restError)
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(fmt.Sprintf("Error decoding json response: %s", err.Error()))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
if len(restError.Messages) > 0 {
|
if len(restError.Messages) > 0 {
|
||||||
ui.Error(restError.Messages[0].Message)
|
ui.Error(restError.Messages[0].Message)
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,7 +88,7 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
||||||
err := s.waitTillProvisioned(datacenter.Headers.Get("Location"), *c)
|
err := s.waitTillProvisioned(datacenter.Headers.Get("Location"), *c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Error occured while creating a datacenter %s", err.Error()))
|
ui.Error(fmt.Sprintf("Error occurred while creating a datacenter %s", err.Error()))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +102,13 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
})
|
})
|
||||||
|
|
||||||
if lan.StatusCode > 299 {
|
if lan.StatusCode > 299 {
|
||||||
ui.Error(fmt.Sprintf("Error occured %s", parseErrorMessage(lan.Response)))
|
ui.Error(fmt.Sprintf("Error occurred %s", parseErrorMessage(lan.Response)))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.waitTillProvisioned(lan.Headers.Get("Location"), *c)
|
err = s.waitTillProvisioned(lan.Headers.Get("Location"), *c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Error occured while creating a LAN %s", err.Error()))
|
ui.Error(fmt.Sprintf("Error occurred while creating a LAN %s", err.Error()))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,13 +122,13 @@ func (s *stepCreateServer) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
})
|
})
|
||||||
|
|
||||||
if lan.StatusCode > 299 {
|
if lan.StatusCode > 299 {
|
||||||
ui.Error(fmt.Sprintf("Error occured %s", parseErrorMessage(nic.Response)))
|
ui.Error(fmt.Sprintf("Error occurred %s", parseErrorMessage(nic.Response)))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.waitTillProvisioned(nic.Headers.Get("Location"), *c)
|
err = s.waitTillProvisioned(nic.Headers.Get("Location"), *c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Error occured while creating a NIC %s", err.Error()))
|
ui.Error(fmt.Sprintf("Error occurred while creating a NIC %s", err.Error()))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,9 +151,11 @@ func (s *stepCreateServer) Cleanup(state multistep.StateBag) {
|
||||||
|
|
||||||
if dcId, ok := state.GetOk("datacenter_id"); ok {
|
if dcId, ok := state.GetOk("datacenter_id"); ok {
|
||||||
resp := profitbricks.DeleteDatacenter(dcId.(string))
|
resp := profitbricks.DeleteDatacenter(dcId.(string))
|
||||||
s.checkForErrors(resp)
|
if err := s.checkForErrors(resp); err != nil {
|
||||||
err := s.waitTillProvisioned(resp.Headers.Get("Location"), *c)
|
ui.Error(fmt.Sprintf(
|
||||||
if err != nil {
|
"Error deleting Virtual Data Center. Please destroy it manually: %s", err))
|
||||||
|
}
|
||||||
|
if err := s.waitTillProvisioned(resp.Headers.Get("Location"), *c); err != nil {
|
||||||
ui.Error(fmt.Sprintf(
|
ui.Error(fmt.Sprintf(
|
||||||
"Error deleting Virtual Data Center. Please destroy it manually: %s", err))
|
"Error deleting Virtual Data Center. Please destroy it manually: %s", err))
|
||||||
}
|
}
|
||||||
|
@ -182,7 +189,7 @@ func (d *stepCreateServer) setPB(username string, password string, url string) {
|
||||||
|
|
||||||
func (d *stepCreateServer) checkForErrors(instance profitbricks.Resp) error {
|
func (d *stepCreateServer) checkForErrors(instance profitbricks.Resp) error {
|
||||||
if instance.StatusCode > 299 {
|
if instance.StatusCode > 299 {
|
||||||
return errors.New(fmt.Sprintf("Error occured %s", string(instance.Body)))
|
return errors.New(fmt.Sprintf("Error occurred %s", string(instance.Body)))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@ package profitbricks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"time"
|
||||||
"fmt"
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"github.com/profitbricks/profitbricks-sdk-go"
|
"github.com/profitbricks/profitbricks-sdk-go"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type stepTakeSnapshot struct{}
|
type stepTakeSnapshot struct{}
|
||||||
|
@ -29,7 +28,10 @@ func (s *stepTakeSnapshot) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
||||||
if snapshot.StatusCode > 299 {
|
if snapshot.StatusCode > 299 {
|
||||||
var restError RestError
|
var restError RestError
|
||||||
json.Unmarshal([]byte(snapshot.Response), &restError)
|
if err := json.Unmarshal([]byte(snapshot.Response), &restError); err != nil {
|
||||||
|
ui.Error(err.Error())
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
if len(restError.Messages) > 0 {
|
if len(restError.Messages) > 0 {
|
||||||
ui.Error(restError.Messages[0].Message)
|
ui.Error(restError.Messages[0].Message)
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,13 +49,6 @@ func (s *stepTakeSnapshot) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
func (s *stepTakeSnapshot) Cleanup(state multistep.StateBag) {
|
func (s *stepTakeSnapshot) Cleanup(state multistep.StateBag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stepTakeSnapshot) checkForErrors(instance profitbricks.Resp) error {
|
|
||||||
if instance.StatusCode > 299 {
|
|
||||||
return errors.New(fmt.Sprintf("Error occured %s", string(instance.Body)))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *stepTakeSnapshot) waitTillProvisioned(path string, config Config) {
|
func (d *stepTakeSnapshot) waitTillProvisioned(path string, config Config) {
|
||||||
d.setPB(config.PBUsername, config.PBPassword, config.PBUrl)
|
d.setPB(config.PBUsername, config.PBPassword, config.PBUrl)
|
||||||
waitCount := 50
|
waitCount := 50
|
||||||
|
|
|
@ -301,11 +301,11 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
_, errs := b.Prepare(config)
|
_, errs := b.Prepare(config)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -2,11 +2,12 @@ package qemu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This step configures the VM to enable the VNC server.
|
// This step configures the VM to enable the VNC server.
|
||||||
|
@ -28,7 +29,7 @@ func (stepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
// best.
|
// best.
|
||||||
msg := fmt.Sprintf("Looking for available port between %d and %d on %s", config.VNCPortMin, config.VNCPortMax, config.VNCBindAddress)
|
msg := fmt.Sprintf("Looking for available port between %d and %d on %s", config.VNCPortMin, config.VNCPortMax, config.VNCBindAddress)
|
||||||
ui.Say(msg)
|
ui.Say(msg)
|
||||||
log.Printf(msg)
|
log.Print(msg)
|
||||||
var vncPort uint
|
var vncPort uint
|
||||||
portRange := int(config.VNCPortMax - config.VNCPortMin)
|
portRange := int(config.VNCPortMax - config.VNCPortMin)
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package qemu
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// stepWaitForShutdown waits for the shutdown of the currently running
|
|
||||||
// qemu VM.
|
|
||||||
type stepWaitForShutdown struct {
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stepWaitForShutdown) Run(state multistep.StateBag) multistep.StepAction {
|
|
||||||
driver := state.Get("driver").(Driver)
|
|
||||||
ui := state.Get("ui").(packer.Ui)
|
|
||||||
|
|
||||||
stopCh := make(chan struct{})
|
|
||||||
defer close(stopCh)
|
|
||||||
|
|
||||||
cancelCh := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
if _, ok := state.GetOk(multistep.StateCancelled); ok {
|
|
||||||
close(cancelCh)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-stopCh:
|
|
||||||
return
|
|
||||||
case <-time.After(100 * time.Millisecond):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
ui.Say(s.Message)
|
|
||||||
driver.WaitForShutdown(cancelCh)
|
|
||||||
return multistep.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stepWaitForShutdown) Cleanup(state multistep.StateBag) {}
|
|
|
@ -59,7 +59,7 @@ func (c *AccessConfig) CreateTritonClient() (*cloudapi.Client, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userauth, err := auth.NewAuth(c.Account, string(keyData), "rsa-sha256")
|
userauth, err := auth.NewAuth(c.Account, keyData, "rsa-sha256")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ func CommHost(host string) func(multistep.StateBag) (string, error) {
|
||||||
|
|
||||||
func SSHPort(state multistep.StateBag) (int, error) {
|
func SSHPort(state multistep.StateBag) (int, error) {
|
||||||
sshHostPort := state.Get("sshHostPort").(int)
|
sshHostPort := state.Get("sshHostPort").(int)
|
||||||
return int(sshHostPort), nil
|
return sshHostPort, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
|
|
|
@ -2,9 +2,10 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This step starts the virtual machine.
|
// This step starts the virtual machine.
|
||||||
|
@ -29,7 +30,7 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
||||||
ui.Say("Starting the virtual machine...")
|
ui.Say("Starting the virtual machine...")
|
||||||
guiArgument := "gui"
|
guiArgument := "gui"
|
||||||
if s.Headless == true {
|
if s.Headless {
|
||||||
vrdpIpRaw, vrdpIpOk := state.GetOk("vrdpIp")
|
vrdpIpRaw, vrdpIpOk := state.GetOk("vrdpIp")
|
||||||
vrdpPortRaw, vrdpPortOk := state.GetOk("vrdpPort")
|
vrdpPortRaw, vrdpPortOk := state.GetOk("vrdpPort")
|
||||||
|
|
||||||
|
|
|
@ -126,11 +126,11 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
_, errs := b.Prepare(config)
|
_, errs := b.Prepare(config)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -42,10 +42,10 @@ func TestNewConfig_FloppyFiles(t *testing.T) {
|
||||||
|
|
||||||
func TestNewConfig_InvalidFloppies(t *testing.T) {
|
func TestNewConfig_InvalidFloppies(t *testing.T) {
|
||||||
c := testConfig(t)
|
c := testConfig(t)
|
||||||
c["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
c["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||||
_, _, errs := NewConfig(c)
|
_, _, errs := NewConfig(c)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -127,11 +127,11 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
_, errs := b.Prepare(config)
|
_, errs := b.Prepare(config)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package iso
|
package iso
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OutputDir is an interface type that abstracts the creation and handling
|
// OutputDir is an interface type that abstracts the creation and handling
|
||||||
// of the output directory for VMware-based products. The abstraction is made
|
// of the output directory for VMware-based products. The abstraction is made
|
||||||
// so that the output directory can be properly made on remote (ESXi) based
|
// so that the output directory can be properly made on remote (ESXi) based
|
||||||
|
@ -17,50 +12,3 @@ type OutputDir interface {
|
||||||
RemoveAll() error
|
RemoveAll() error
|
||||||
SetOutputDir(string)
|
SetOutputDir(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// localOutputDir is an OutputDir implementation where the directory
|
|
||||||
// is on the local machine.
|
|
||||||
type localOutputDir struct {
|
|
||||||
dir string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) DirExists() (bool, error) {
|
|
||||||
_, err := os.Stat(d.dir)
|
|
||||||
return err == nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) ListFiles() ([]string, error) {
|
|
||||||
files := make([]string, 0, 10)
|
|
||||||
|
|
||||||
visit := func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !info.IsDir() {
|
|
||||||
files = append(files, path)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return files, filepath.Walk(d.dir, visit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) MkdirAll() error {
|
|
||||||
return os.MkdirAll(d.dir, 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) Remove(path string) error {
|
|
||||||
return os.Remove(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) RemoveAll() error {
|
|
||||||
return os.RemoveAll(d.dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) SetOutputDir(path string) {
|
|
||||||
d.dir = path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *localOutputDir) String() string {
|
|
||||||
return d.dir
|
|
||||||
}
|
|
||||||
|
|
|
@ -56,11 +56,11 @@ func TestBuilderPrepare_FloppyFiles(t *testing.T) {
|
||||||
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig(t)
|
config := testConfig(t)
|
||||||
config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
|
config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
_, errs := b.Prepare(config)
|
_, errs := b.Prepare(config)
|
||||||
if errs == nil {
|
if errs == nil {
|
||||||
t.Fatalf("Non existant floppies should trigger multierror")
|
t.Fatalf("Nonexistent floppies should trigger multierror")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs.(*packer.MultiError).Errors) != 2 {
|
if len(errs.(*packer.MultiError).Errors) != 2 {
|
||||||
|
|
|
@ -211,8 +211,8 @@ func (c BuildCommand) Run(args []string) int {
|
||||||
|
|
||||||
c.Ui.Error("\n==> Some builds didn't complete successfully and had errors:")
|
c.Ui.Error("\n==> Some builds didn't complete successfully and had errors:")
|
||||||
for name, err := range errors {
|
for name, err := range errors {
|
||||||
// Create a UI for the machine readable stuff to be targetted
|
// Create a UI for the machine readable stuff to be targeted
|
||||||
ui := &packer.TargettedUi{
|
ui := &packer.TargetedUI{
|
||||||
Target: name,
|
Target: name,
|
||||||
Ui: c.Ui,
|
Ui: c.Ui,
|
||||||
}
|
}
|
||||||
|
@ -226,8 +226,8 @@ func (c BuildCommand) Run(args []string) int {
|
||||||
if len(artifacts.m) > 0 {
|
if len(artifacts.m) > 0 {
|
||||||
c.Ui.Say("\n==> Builds finished. The artifacts of successful builds are:")
|
c.Ui.Say("\n==> Builds finished. The artifacts of successful builds are:")
|
||||||
for name, buildArtifacts := range artifacts.m {
|
for name, buildArtifacts := range artifacts.m {
|
||||||
// Create a UI for the machine readable stuff to be targetted
|
// Create a UI for the machine readable stuff to be targeted
|
||||||
ui := &packer.TargettedUi{
|
ui := &packer.TargetedUI{
|
||||||
Target: name,
|
Target: name,
|
||||||
Ui: c.Ui,
|
Ui: c.Ui,
|
||||||
}
|
}
|
||||||
|
|
20
commands.go
20
commands.go
|
@ -1,9 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/mitchellh/packer/command"
|
"github.com/mitchellh/packer/command"
|
||||||
"github.com/mitchellh/packer/version"
|
"github.com/mitchellh/packer/version"
|
||||||
|
@ -68,20 +65,3 @@ func init() {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeShutdownCh creates an interrupt listener and returns a channel.
|
|
||||||
// A message will be sent on the channel for every interrupt received.
|
|
||||||
func makeShutdownCh() <-chan struct{} {
|
|
||||||
resultCh := make(chan struct{})
|
|
||||||
|
|
||||||
signalCh := make(chan os.Signal, 4)
|
|
||||||
signal.Notify(signalCh, os.Interrupt)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
<-signalCh
|
|
||||||
resultCh <- struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return resultCh
|
|
||||||
}
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ func (d *DownloadClient) VerifyChecksum(path string) (bool, error) {
|
||||||
log.Printf("Verifying checksum of %s", path)
|
log.Printf("Verifying checksum of %s", path)
|
||||||
d.config.Hash.Reset()
|
d.config.Hash.Reset()
|
||||||
io.Copy(d.config.Hash, f)
|
io.Copy(d.config.Hash, f)
|
||||||
return bytes.Compare(d.config.Hash.Sum(nil), d.config.Checksum) == 0, nil
|
return bytes.Equal(d.config.Hash.Sum(nil), d.config.Checksum), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPDownloader is an implementation of Downloader that downloads
|
// HTTPDownloader is an implementation of Downloader that downloads
|
||||||
|
|
|
@ -23,7 +23,7 @@ func (c *FloppyConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range c.FloppyFiles {
|
for _, path := range c.FloppyFiles {
|
||||||
if strings.IndexAny(path, "*?[") >= 0 {
|
if strings.ContainsAny(path, "*?[") {
|
||||||
_, err = filepath.Glob(path)
|
_, err = filepath.Glob(path)
|
||||||
} else {
|
} else {
|
||||||
_, err = os.Stat(path)
|
_, err = os.Stat(path)
|
||||||
|
@ -38,7 +38,7 @@ func (c *FloppyConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range c.FloppyDirectories {
|
for _, path := range c.FloppyDirectories {
|
||||||
if strings.IndexAny(path, "*?[") >= 0 {
|
if strings.ContainsAny(path, "*?[") {
|
||||||
_, err = filepath.Glob(path)
|
_, err = filepath.Glob(path)
|
||||||
} else {
|
} else {
|
||||||
_, err = os.Stat(path)
|
_, err = os.Stat(path)
|
||||||
|
|
|
@ -721,7 +721,7 @@ $vm.Uptime.TotalSeconds
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uptime, err := strconv.ParseUint(strings.TrimSpace(string(cmdOut)), 10, 64)
|
uptime, err := strconv.ParseUint(strings.TrimSpace(cmdOut), 10, 64)
|
||||||
|
|
||||||
return uptime, err
|
return uptime, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ param([string]$moduleName)
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := strings.TrimSpace(string(cmdOut))
|
res := strings.TrimSpace(cmdOut)
|
||||||
|
|
||||||
if res == powerShellFalse {
|
if res == powerShellFalse {
|
||||||
err := fmt.Errorf("PowerShell %s module is not loaded. Make sure %s feature is on.", moduleName, moduleName)
|
err := fmt.Errorf("PowerShell %s module is not loaded. Make sure %s feature is on.", moduleName, moduleName)
|
||||||
|
|
|
@ -56,7 +56,7 @@ func TestRetry(t *testing.T) {
|
||||||
return false, nil
|
return false, nil
|
||||||
})
|
})
|
||||||
if numTries != expectedTries {
|
if numTries != expectedTries {
|
||||||
t.Fatalf("Unsuccessul retry function should have been called %d times. Only called %d times.", expectedTries, numTries)
|
t.Fatalf("Unsuccessful retry function should have been called %d times. Only called %d times.", expectedTries, numTries)
|
||||||
}
|
}
|
||||||
if err != RetryExhaustedError {
|
if err != RetryExhaustedError {
|
||||||
t.Fatalf("Unsuccessful retry function should have returned a retry exhausted error. Actual error: %s", err)
|
t.Fatalf("Unsuccessful retry function should have returned a retry exhausted error. Actual error: %s", err)
|
||||||
|
|
|
@ -2,10 +2,6 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/go-fs"
|
|
||||||
"github.com/mitchellh/go-fs/fat"
|
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -13,6 +9,11 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mitchellh/go-fs"
|
||||||
|
"github.com/mitchellh/go-fs/fat"
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StepCreateFloppy will create a floppy disk with the given files.
|
// StepCreateFloppy will create a floppy disk with the given files.
|
||||||
|
@ -96,7 +97,7 @@ func (s *StepCreateFloppy) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
// Utility functions for walking through a directory grabbing all files flatly
|
// Utility functions for walking through a directory grabbing all files flatly
|
||||||
globFiles := func(files []string, list chan string) {
|
globFiles := func(files []string, list chan string) {
|
||||||
for _, filename := range files {
|
for _, filename := range files {
|
||||||
if strings.IndexAny(filename, "*?[") >= 0 {
|
if strings.ContainsAny(filename, "*?[") {
|
||||||
matches, _ := filepath.Glob(filename)
|
matches, _ := filepath.Glob(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -173,7 +174,7 @@ func (s *StepCreateFloppy) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui.Message("Collecting paths from floppy_dirs")
|
ui.Message("Collecting paths from floppy_dirs")
|
||||||
var pathqueue []string
|
var pathqueue []string
|
||||||
for _, filename := range s.Directories {
|
for _, filename := range s.Directories {
|
||||||
if strings.IndexAny(filename, "*?[") >= 0 {
|
if strings.ContainsAny(filename, "*?[") {
|
||||||
matches, err := filepath.Glob(filename)
|
matches, err := filepath.Glob(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", fmt.Errorf("Error adding path %s to floppy: %s", filename, err))
|
state.Put("error", fmt.Errorf("Error adding path %s to floppy: %s", filename, err))
|
||||||
|
|
|
@ -250,7 +250,7 @@ func (c *comm) newSession() (session *ssh.Session, err error) {
|
||||||
|
|
||||||
func (c *comm) reconnect() (err error) {
|
func (c *comm) reconnect() (err error) {
|
||||||
if c.conn != nil {
|
if c.conn != nil {
|
||||||
c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the conn and client to nil since we'll recreate it
|
// Set the conn and client to nil since we'll recreate it
|
||||||
|
@ -620,14 +620,10 @@ func (c *comm) scpDownloadSession(path string, output io.Writer) error {
|
||||||
|
|
||||||
fmt.Fprint(w, "\x00")
|
fmt.Fprint(w, "\x00")
|
||||||
|
|
||||||
if err := checkSCPStatus(stdoutR); err != nil {
|
return checkSCPStatus(stdoutR)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if !strings.Contains(path, " ") {
|
||||||
}
|
|
||||||
|
|
||||||
if strings.Index(path, " ") == -1 {
|
|
||||||
return c.scpSession("scp -vf "+path, scpFunc)
|
return c.scpSession("scp -vf "+path, scpFunc)
|
||||||
}
|
}
|
||||||
return c.scpSession("scp -vf "+strconv.Quote(path), scpFunc)
|
return c.scpSession("scp -vf "+strconv.Quote(path), scpFunc)
|
||||||
|
@ -805,11 +801,7 @@ func scpUploadFile(dst string, src io.Reader, w io.Writer, r *bufio.Reader, fi *
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(w, "\x00")
|
fmt.Fprint(w, "\x00")
|
||||||
if err := checkSCPStatus(r); err != nil {
|
return checkSCPStatus(r)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func scpUploadDirProtocol(name string, w io.Writer, r *bufio.Reader, f func() error, fi os.FileInfo) error {
|
func scpUploadDirProtocol(name string, w io.Writer, r *bufio.Reader, f func() error, fi os.FileInfo) error {
|
||||||
|
@ -830,11 +822,7 @@ func scpUploadDirProtocol(name string, w io.Writer, r *bufio.Reader, f func() er
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(w, "E")
|
fmt.Fprintln(w, "E")
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func scpUploadDir(root string, fs []os.FileInfo, w io.Writer, r *bufio.Reader) error {
|
func scpUploadDir(root string, fs []os.FileInfo, w io.Writer, r *bufio.Reader) error {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package ssh
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An implementation of ssh.KeyboardInteractiveChallenge that simply sends
|
// An implementation of ssh.KeyboardInteractiveChallenge that simply sends
|
||||||
|
@ -19,7 +20,7 @@ func PasswordKeyboardInteractive(password string) ssh.KeyboardInteractiveChallen
|
||||||
// Just send the password back for all questions
|
// Just send the password back for all questions
|
||||||
answers := make([]string, len(questions))
|
answers := make([]string, len(questions))
|
||||||
for i := range answers {
|
for i := range answers {
|
||||||
answers[i] = string(password)
|
answers[i] = password
|
||||||
}
|
}
|
||||||
|
|
||||||
return answers, nil
|
return answers, nil
|
||||||
|
|
|
@ -155,13 +155,8 @@ func (c *config) discover(path string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.discoverSingle(
|
return c.discoverSingle(
|
||||||
filepath.Join(path, "packer-provisioner-*"), &c.Provisioners)
|
filepath.Join(path, "packer-provisioner-*"), &c.Provisioners)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *config) discoverSingle(glob string, m *map[string]string) error {
|
func (c *config) discoverSingle(glob string, m *map[string]string) error {
|
||||||
|
|
2
main.go
2
main.go
|
@ -187,8 +187,6 @@ func wrappedMain() int {
|
||||||
Ui: ui,
|
Ui: ui,
|
||||||
}
|
}
|
||||||
|
|
||||||
//setupSignalHandlers(env)
|
|
||||||
|
|
||||||
cli := &cli.CLI{
|
cli := &cli.CLI{
|
||||||
Args: args,
|
Args: args,
|
||||||
Commands: Commands,
|
Commands: Commands,
|
||||||
|
|
|
@ -56,7 +56,7 @@ type Build interface {
|
||||||
Run(Ui, Cache) ([]Artifact, error)
|
Run(Ui, Cache) ([]Artifact, error)
|
||||||
|
|
||||||
// Cancel will cancel a running build. This will block until the build
|
// Cancel will cancel a running build. This will block until the build
|
||||||
// is actually completely cancelled.
|
// is actually completely canceled.
|
||||||
Cancel()
|
Cancel()
|
||||||
|
|
||||||
// SetDebug will enable/disable debug mode. Debug mode is always
|
// SetDebug will enable/disable debug mode. Debug mode is always
|
||||||
|
@ -210,8 +210,8 @@ func (b *coreBuild) Run(originalUi Ui, cache Cache) ([]Artifact, error) {
|
||||||
hook := &DispatchHook{Mapping: hooks}
|
hook := &DispatchHook{Mapping: hooks}
|
||||||
artifacts := make([]Artifact, 0, 1)
|
artifacts := make([]Artifact, 0, 1)
|
||||||
|
|
||||||
// The builder just has a normal Ui, but targetted
|
// The builder just has a normal Ui, but targeted
|
||||||
builderUi := &TargettedUi{
|
builderUi := &TargetedUI{
|
||||||
Target: b.Name(),
|
Target: b.Name(),
|
||||||
Ui: originalUi,
|
Ui: originalUi,
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ PostProcessorRunSeqLoop:
|
||||||
for _, ppSeq := range b.postProcessors {
|
for _, ppSeq := range b.postProcessors {
|
||||||
priorArtifact := builderArtifact
|
priorArtifact := builderArtifact
|
||||||
for i, corePP := range ppSeq {
|
for i, corePP := range ppSeq {
|
||||||
ppUi := &TargettedUi{
|
ppUi := &TargetedUI{
|
||||||
Target: fmt.Sprintf("%s (%s)", b.Name(), corePP.processorType),
|
Target: fmt.Sprintf("%s (%s)", b.Name(), corePP.processorType),
|
||||||
Ui: originalUi,
|
Ui: originalUi,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ type Builder interface {
|
||||||
// Prepare is responsible for configuring the builder and validating
|
// Prepare is responsible for configuring the builder and validating
|
||||||
// that configuration. Any setup should be done in this method. Note that
|
// that configuration. Any setup should be done in this method. Note that
|
||||||
// NO side effects should take place in prepare, it is meant as a state
|
// NO side effects should take place in prepare, it is meant as a state
|
||||||
// setup only. Calling Prepare is not necessarilly followed by a Run.
|
// setup only. Calling Prepare is not necessarily followed by a Run.
|
||||||
//
|
//
|
||||||
// The parameters to Prepare are a set of interface{} values of the
|
// The parameters to Prepare are a set of interface{} values of the
|
||||||
// configuration. These are almost always `map[string]interface{}`
|
// configuration. These are almost always `map[string]interface{}`
|
||||||
|
@ -24,7 +24,7 @@ type Builder interface {
|
||||||
// configuration.
|
// configuration.
|
||||||
//
|
//
|
||||||
// Prepare should return a list of warnings along with any errors
|
// Prepare should return a list of warnings along with any errors
|
||||||
// that occured while preparing.
|
// that occurred while preparing.
|
||||||
Prepare(...interface{}) ([]string, error)
|
Prepare(...interface{}) ([]string, error)
|
||||||
|
|
||||||
// Run is where the actual build should take place. It takes a Build and a Ui.
|
// Run is where the actual build should take place. It takes a Build and a Ui.
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"net/rpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// rpcDial makes a TCP connection to a remote RPC server and returns
|
|
||||||
// the client. This will set the connection up properly so that keep-alives
|
|
||||||
// are set and so on and should be used to make all RPC connections within
|
|
||||||
// this package.
|
|
||||||
func rpcDial(address string) (*rpc.Client, error) {
|
|
||||||
tcpConn, err := tcpDial(address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an RPC client around our connection
|
|
||||||
return rpc.NewClient(tcpConn), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// tcpDial connects via TCP to the designated address.
|
|
||||||
func tcpDial(address string) (*net.TCPConn, error) {
|
|
||||||
conn, err := net.Dial("tcp", address)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set a keep-alive so that the connection stays alive even when idle
|
|
||||||
tcpConn := conn.(*net.TCPConn)
|
|
||||||
tcpConn.SetKeepAlive(true)
|
|
||||||
return tcpConn, nil
|
|
||||||
}
|
|
|
@ -183,9 +183,7 @@ func (m *muxBroker) timeoutWait(id uint32, p *muxBrokerPending) {
|
||||||
// If we timed out, then check if we have a channel in the buffer,
|
// If we timed out, then check if we have a channel in the buffer,
|
||||||
// and if so, close it.
|
// and if so, close it.
|
||||||
if timeout {
|
if timeout {
|
||||||
select {
|
s := <-p.ch
|
||||||
case s := <-p.ch:
|
|
||||||
s.Close()
|
s.Close()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An implementation of packer.PostProcessor where the PostProcessor is actually
|
// An implementation of packer.PostProcessor where the PostProcessor is actually
|
||||||
|
@ -15,7 +16,6 @@ type postProcessor struct {
|
||||||
// PostProcessorServer wraps a packer.PostProcessor implementation and makes it
|
// PostProcessorServer wraps a packer.PostProcessor implementation and makes it
|
||||||
// exportable as part of a Golang RPC server.
|
// exportable as part of a Golang RPC server.
|
||||||
type PostProcessorServer struct {
|
type PostProcessorServer struct {
|
||||||
client *rpc.Client
|
|
||||||
mux *muxBroker
|
mux *muxBroker
|
||||||
p packer.PostProcessor
|
p packer.PostProcessor
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,11 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
var endpointId uint64
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultArtifactEndpoint string = "Artifact"
|
DefaultArtifactEndpoint string = "Artifact"
|
||||||
DefaultBuildEndpoint = "Build"
|
DefaultBuildEndpoint = "Build"
|
||||||
|
@ -140,18 +137,3 @@ func (s *Server) Serve() {
|
||||||
rpcCodec := codec.GoRpc.ServerCodec(stream, h)
|
rpcCodec := codec.GoRpc.ServerCodec(stream, h)
|
||||||
s.server.ServeCodec(rpcCodec)
|
s.server.ServeCodec(rpcCodec)
|
||||||
}
|
}
|
||||||
|
|
||||||
// registerComponent registers a single Packer RPC component onto
|
|
||||||
// the RPC server. If id is true, then a unique ID number will be appended
|
|
||||||
// onto the end of the endpoint.
|
|
||||||
//
|
|
||||||
// The endpoint name is returned.
|
|
||||||
func registerComponent(server *rpc.Server, name string, rcvr interface{}, id bool) string {
|
|
||||||
endpoint := name
|
|
||||||
if id {
|
|
||||||
log.Printf("%s.%d", endpoint, atomic.AddUint64(&endpointId, 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
server.RegisterName(endpoint, rcvr)
|
|
||||||
return endpoint
|
|
||||||
}
|
|
||||||
|
|
16
packer/ui.go
16
packer/ui.go
|
@ -46,12 +46,12 @@ type ColoredUi struct {
|
||||||
Ui Ui
|
Ui Ui
|
||||||
}
|
}
|
||||||
|
|
||||||
// TargettedUi is a UI that wraps another UI implementation and modifies
|
// TargetedUI is a UI that wraps another UI implementation and modifies
|
||||||
// the output to indicate a specific target. Specifically, all Say output
|
// the output to indicate a specific target. Specifically, all Say output
|
||||||
// is prefixed with the target name. Message output is not prefixed but
|
// is prefixed with the target name. Message output is not prefixed but
|
||||||
// is offset by the length of the target so that output is lined up properly
|
// is offset by the length of the target so that output is lined up properly
|
||||||
// with Say output. Machine-readable output has the proper target set.
|
// with Say output. Machine-readable output has the proper target set.
|
||||||
type TargettedUi struct {
|
type TargetedUI struct {
|
||||||
Target string
|
Target string
|
||||||
Ui Ui
|
Ui Ui
|
||||||
}
|
}
|
||||||
|
@ -132,28 +132,28 @@ func (u *ColoredUi) supportsColors() bool {
|
||||||
return cygwin
|
return cygwin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) Ask(query string) (string, error) {
|
func (u *TargetedUI) Ask(query string) (string, error) {
|
||||||
return u.Ui.Ask(u.prefixLines(true, query))
|
return u.Ui.Ask(u.prefixLines(true, query))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) Say(message string) {
|
func (u *TargetedUI) Say(message string) {
|
||||||
u.Ui.Say(u.prefixLines(true, message))
|
u.Ui.Say(u.prefixLines(true, message))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) Message(message string) {
|
func (u *TargetedUI) Message(message string) {
|
||||||
u.Ui.Message(u.prefixLines(false, message))
|
u.Ui.Message(u.prefixLines(false, message))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) Error(message string) {
|
func (u *TargetedUI) Error(message string) {
|
||||||
u.Ui.Error(u.prefixLines(true, message))
|
u.Ui.Error(u.prefixLines(true, message))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) Machine(t string, args ...string) {
|
func (u *TargetedUI) Machine(t string, args ...string) {
|
||||||
// Prefix in the target, then pass through
|
// Prefix in the target, then pass through
|
||||||
u.Ui.Machine(fmt.Sprintf("%s,%s", u.Target, t), args...)
|
u.Ui.Machine(fmt.Sprintf("%s,%s", u.Target, t), args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *TargettedUi) prefixLines(arrow bool, message string) string {
|
func (u *TargetedUI) prefixLines(arrow bool, message string) string {
|
||||||
arrowText := "==>"
|
arrowText := "==>"
|
||||||
if !arrow {
|
if !arrow {
|
||||||
arrowText = strings.Repeat(" ", len(arrowText))
|
arrowText = strings.Repeat(" ", len(arrowText))
|
||||||
|
|
|
@ -97,9 +97,9 @@ func TestColoredUi_noColorEnv(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTargettedUi(t *testing.T) {
|
func TestTargetedUI(t *testing.T) {
|
||||||
bufferUi := testUi()
|
bufferUi := testUi()
|
||||||
targettedUi := &TargettedUi{
|
targettedUi := &TargetedUI{
|
||||||
Target: "foo",
|
Target: "foo",
|
||||||
Ui: bufferUi,
|
Ui: bufferUi,
|
||||||
}
|
}
|
||||||
|
@ -142,11 +142,11 @@ func TestColoredUi_ImplUi(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTargettedUi_ImplUi(t *testing.T) {
|
func TestTargetedUI_ImplUi(t *testing.T) {
|
||||||
var raw interface{}
|
var raw interface{}
|
||||||
raw = &TargettedUi{}
|
raw = &TargetedUI{}
|
||||||
if _, ok := raw.(Ui); !ok {
|
if _, ok := raw.(Ui); !ok {
|
||||||
t.Fatalf("TargettedUi must implement Ui")
|
t.Fatalf("TargetedUI must implement Ui")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ type Config struct {
|
||||||
Name string `mapstructure:"ami_name"`
|
Name string `mapstructure:"ami_name"`
|
||||||
Description string `mapstructure:"ami_description"`
|
Description string `mapstructure:"ami_description"`
|
||||||
Users []string `mapstructure:"ami_users"`
|
Users []string `mapstructure:"ami_users"`
|
||||||
Groups []string `mapstrcuture:"ami_groups"`
|
Groups []string `mapstructure:"ami_groups"`
|
||||||
|
|
||||||
ctx interpolate.Context
|
ctx interpolate.Context
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ type PostProcessor struct {
|
||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point for configuration parisng when we've defined
|
// Entry point for configuration parsing when we've defined
|
||||||
func (p *PostProcessor) Configure(raws ...interface{}) error {
|
func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
p.config.ctx.Funcs = awscommon.TemplateFuncs
|
p.config.ctx.Funcs = awscommon.TemplateFuncs
|
||||||
err := config.Decode(&p.config, &config.DecodeOpts{
|
err := config.Decode(&p.config, &config.DecodeOpts{
|
||||||
|
@ -74,7 +74,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
||||||
// Check we have AWS access variables defined somewhere
|
// Check we have AWS access variables defined somewhere
|
||||||
errs = packer.MultiErrorAppend(errs, p.config.AccessConfig.Prepare(&p.config.ctx)...)
|
errs = packer.MultiErrorAppend(errs, p.config.AccessConfig.Prepare(&p.config.ctx)...)
|
||||||
|
|
||||||
// define all our required paramaters
|
// define all our required parameters
|
||||||
templates := map[string]*string{
|
templates := map[string]*string{
|
||||||
"s3_bucket_name": &p.config.S3Bucket,
|
"s3_bucket_name": &p.config.S3Bucket,
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
|
|
||||||
ui.Message(fmt.Sprintf("Started import of s3://%s/%s, task id %s", p.config.S3Bucket, p.config.S3Key, *import_start.ImportTaskId))
|
ui.Message(fmt.Sprintf("Started import of s3://%s/%s, task id %s", p.config.S3Bucket, p.config.S3Key, *import_start.ImportTaskId))
|
||||||
|
|
||||||
// Wait for import process to complete, this takess a while
|
// Wait for import process to complete, this takes a while
|
||||||
ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId))
|
ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId))
|
||||||
|
|
||||||
stateChange := awscommon.StateChangeConf{
|
stateChange := awscommon.StateChangeConf{
|
||||||
|
@ -239,7 +239,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
return nil, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err)
|
return nil, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ec2conn.DeregisterImage(&ec2.DeregisterImageInput{
|
_, err = ec2conn.DeregisterImage(&ec2.DeregisterImageInput{
|
||||||
ImageId: &createdami,
|
ImageId: &createdami,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply atttributes for AMI specified in config
|
// Apply attributes for AMI specified in config
|
||||||
// (duped from builder/amazon/common/step_modify_ami_attributes.go)
|
// (duped from builder/amazon/common/step_modify_ami_attributes.go)
|
||||||
options := make(map[string]*ec2.ModifyImageAttributeInput)
|
options := make(map[string]*ec2.ModifyImageAttributeInput)
|
||||||
if p.config.Description != "" {
|
if p.config.Description != "" {
|
||||||
|
|
|
@ -9,7 +9,6 @@ const BuilderId = "packer.post-processor.compress"
|
||||||
|
|
||||||
type Artifact struct {
|
type Artifact struct {
|
||||||
Path string
|
Path string
|
||||||
files []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Artifact) BuilderId() string {
|
func (a *Artifact) BuilderId() string {
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (s *stepUpload) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Message("Box succesfully uploaded")
|
ui.Message("Box successfully uploaded")
|
||||||
|
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@ package vagrantcloud
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stepVerifyUpload struct {
|
type stepVerifyUpload struct {
|
||||||
|
@ -88,8 +89,8 @@ func (s *stepVerifyUpload) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Message(fmt.Sprintf("Upload succesfully verified with token %s", providerCheck.HostedToken))
|
ui.Message(fmt.Sprintf("Upload successfully verified with token %s", providerCheck.HostedToken))
|
||||||
log.Printf("Box succesfully verified %s == %s", upload.Token, providerCheck.HostedToken)
|
log.Printf("Box successfully verified %s == %s", upload.Token, providerCheck.HostedToken)
|
||||||
|
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
case <-time.After(600 * time.Second):
|
case <-time.After(600 * time.Second):
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestAWSProvider_ArtifactId(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
result := `aws.region_config "us-east-1", ami: "ami-1234"`
|
result := `aws.region_config "us-east-1", ami: "ami-1234"`
|
||||||
if strings.Index(vagrantfile, result) == -1 {
|
if !strings.Contains(vagrantfile, result) {
|
||||||
t.Fatalf("wrong substitution: %s", vagrantfile)
|
t.Fatalf("wrong substitution: %s", vagrantfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,11 +31,11 @@ func TestDigitalOceanProvider_ArtifactId(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
image := `digital_ocean.image = "42"`
|
image := `digital_ocean.image = "42"`
|
||||||
if strings.Index(vagrantfile, image) == -1 {
|
if !strings.Contains(vagrantfile, image) {
|
||||||
t.Fatalf("wrong image substitution: %s", vagrantfile)
|
t.Fatalf("wrong image substitution: %s", vagrantfile)
|
||||||
}
|
}
|
||||||
region := `digital_ocean.region = "San Francisco"`
|
region := `digital_ocean.region = "San Francisco"`
|
||||||
if strings.Index(vagrantfile, region) == -1 {
|
if !strings.Contains(vagrantfile, region) {
|
||||||
t.Fatalf("wrong region substitution: %s", vagrantfile)
|
t.Fatalf("wrong region substitution: %s", vagrantfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,7 +355,9 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri
|
||||||
go repeat(stderr)
|
go repeat(stderr)
|
||||||
|
|
||||||
log.Printf("Executing Ansible: %s", strings.Join(cmd.Args, " "))
|
log.Printf("Executing Ansible: %s", strings.Join(cmd.Args, " "))
|
||||||
cmd.Start()
|
if err := cmd.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -54,7 +54,7 @@ func scpUploadSession(opts []byte, rest string, in io.Reader, out io.Writer, com
|
||||||
// directory on the remote side, but ansible only sends files, so there's no
|
// directory on the remote side, but ansible only sends files, so there's no
|
||||||
// need to set targetIsDir, because it can be safely assumed that rest is
|
// need to set targetIsDir, because it can be safely assumed that rest is
|
||||||
// intended to be a file, and whatever names are used in 'C' commands are
|
// intended to be a file, and whatever names are used in 'C' commands are
|
||||||
// irrelavant.
|
// irrelevant.
|
||||||
state := &scpUploadState{target: rest, srcRoot: d, comm: comm}
|
state := &scpUploadState{target: rest, srcRoot: d, comm: comm}
|
||||||
|
|
||||||
fmt.Fprintf(out, scpOK) // signal the client to start the transfer.
|
fmt.Fprintf(out, scpOK) // signal the client to start the transfer.
|
||||||
|
@ -104,8 +104,7 @@ func (state *scpDownloadState) FileProtocol(path string, info os.FileInfo, in *b
|
||||||
size := info.Size()
|
size := info.Size()
|
||||||
perms := fmt.Sprintf("C%04o", info.Mode().Perm())
|
perms := fmt.Sprintf("C%04o", info.Mode().Perm())
|
||||||
fmt.Fprintln(out, perms, size, info.Name())
|
fmt.Fprintln(out, perms, size, info.Name())
|
||||||
err := scpResponse(in)
|
if err := scpResponse(in); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +193,7 @@ func (state *scpUploadState) FileProtocol(in *bufio.Reader, out io.Writer) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = scpResponse(in)
|
if err := scpResponse(in); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +258,9 @@ type scpDownloadState struct {
|
||||||
func (state *scpDownloadState) Protocol(in *bufio.Reader, out io.Writer) error {
|
func (state *scpDownloadState) Protocol(in *bufio.Reader, out io.Writer) error {
|
||||||
r := bufio.NewReader(in)
|
r := bufio.NewReader(in)
|
||||||
// read the byte sent by the other side to start the transfer
|
// read the byte sent by the other side to start the transfer
|
||||||
scpResponse(r)
|
if err := scpResponse(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return filepath.Walk(state.srcRoot, func(path string, info os.FileInfo, err error) error {
|
return filepath.Walk(state.srcRoot, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -321,7 +321,7 @@ func scpResponse(r *bufio.Reader) error {
|
||||||
|
|
||||||
// 1 is a warning. Anything higher (really just 2) is an error.
|
// 1 is a warning. Anything higher (really just 2) is an error.
|
||||||
if code > 1 {
|
if code > 1 {
|
||||||
return errors.New(string(message))
|
return errors.New(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("WARNING:", err)
|
log.Println("WARNING:", err)
|
||||||
|
|
|
@ -319,20 +319,6 @@ func (p *Provisioner) Cancel() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provisioner) uploadDirectory(ui packer.Ui, comm packer.Communicator, dst string, src string) error {
|
|
||||||
if err := p.createDir(ui, comm, dst); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure there is a trailing "/" so that the directory isn't
|
|
||||||
// created on the other side.
|
|
||||||
if src[len(src)-1] != '/' {
|
|
||||||
src = src + "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
return comm.UploadDir(dst, src, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, remotePath string, localPath string) error {
|
func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, remotePath string, localPath string) error {
|
||||||
ui.Message(fmt.Sprintf("Uploading %s...", localPath))
|
ui.Message(fmt.Sprintf("Uploading %s...", localPath))
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ func (p *Provisioner) ProvisionDownload(ui packer.Ui, comm packer.Communicator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if the src was a dir, download the dir
|
// if the src was a dir, download the dir
|
||||||
if strings.HasSuffix(src, "/") || strings.IndexAny(src, "*?[") >= 0 {
|
if strings.HasSuffix(src, "/") || strings.ContainsAny(src, "*?[") {
|
||||||
return comm.DownloadDir(src, dst, nil)
|
return comm.DownloadDir(src, dst, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -317,7 +317,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
||||||
|
|
||||||
// Create an error and log it
|
// Create an error and log it
|
||||||
err = fmt.Errorf("Retryable error: %s", err)
|
err = fmt.Errorf("Retryable error: %s", err)
|
||||||
log.Printf(err.Error())
|
log.Print(err.Error())
|
||||||
|
|
||||||
// Check if we timed out, otherwise we retry. It is safe to
|
// Check if we timed out, otherwise we retry. It is safe to
|
||||||
// retry since the only error case above is if the command
|
// retry since the only error case above is if the command
|
||||||
|
|
|
@ -348,7 +348,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
||||||
|
|
||||||
// Create an error and log it
|
// Create an error and log it
|
||||||
err = fmt.Errorf("Retryable error: %s", err)
|
err = fmt.Errorf("Retryable error: %s", err)
|
||||||
log.Printf(err.Error())
|
log.Print(err.Error())
|
||||||
|
|
||||||
// Check if we timed out, otherwise we retry. It is safe to
|
// Check if we timed out, otherwise we retry. It is safe to
|
||||||
// retry since the only error case above is if the command
|
// retry since the only error case above is if the command
|
||||||
|
|
|
@ -116,7 +116,7 @@ var waitForRestart = func(p *Provisioner, comm packer.Communicator) error {
|
||||||
cmd = &packer.RemoteCmd{Command: trycommand}
|
cmd = &packer.RemoteCmd{Command: trycommand}
|
||||||
err = cmd.StartWithUi(comm, ui)
|
err = cmd.StartWithUi(comm, ui)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Couldnt execute, we asume machine is rebooting already
|
// Couldn't execute, we assume machine is rebooting already
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if cmd.ExitStatus == 1115 || cmd.ExitStatus == 1190 {
|
if cmd.ExitStatus == 1115 || cmd.ExitStatus == 1190 {
|
||||||
|
@ -175,8 +175,8 @@ var waitForCommunicator = func(p *Provisioner) error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-p.cancel:
|
case <-p.cancel:
|
||||||
log.Println("Communicator wait cancelled, exiting loop")
|
log.Println("Communicator wait canceled, exiting loop")
|
||||||
return fmt.Errorf("Communicator wait cancelled")
|
return fmt.Errorf("Communicator wait canceled")
|
||||||
case <-time.After(retryableSleep):
|
case <-time.After(retryableSleep):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
||||||
|
|
||||||
// Create an error and log it
|
// Create an error and log it
|
||||||
err = fmt.Errorf("Retryable error: %s", err)
|
err = fmt.Errorf("Retryable error: %s", err)
|
||||||
log.Printf(err.Error())
|
log.Print(err.Error())
|
||||||
|
|
||||||
// Check if we timed out, otherwise we retry. It is safe to
|
// Check if we timed out, otherwise we retry. It is safe to
|
||||||
// retry since the only error case above is if the command
|
// retry since the only error case above is if the command
|
||||||
|
|
|
@ -319,7 +319,7 @@ func TestRetryable(t *testing.T) {
|
||||||
err := p.Prepare(config)
|
err := p.Prepare(config)
|
||||||
err = p.retryable(retryMe)
|
err = p.retryable(retryMe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("should not have error retrying funuction")
|
t.Fatalf("should not have error retrying function")
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -327,7 +327,7 @@ func TestRetryable(t *testing.T) {
|
||||||
err = p.Prepare(config)
|
err = p.Prepare(config)
|
||||||
err = p.retryable(retryMe)
|
err = p.retryable(retryMe)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("should have error retrying funuction")
|
t.Fatalf("should have error retrying function")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ func TestProvision_Cancel(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
<-waitDone
|
<-waitDone
|
||||||
|
|
||||||
// Expect interupt error
|
// Expect interrupt error
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("should have error")
|
t.Fatal("should have error")
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,11 +150,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if errs != nil {
|
|
||||||
return errs
|
return errs
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function takes the inline scripts, concatenates them
|
// This function takes the inline scripts, concatenates them
|
||||||
|
@ -270,7 +266,7 @@ func (p *Provisioner) retryable(f func() error) error {
|
||||||
|
|
||||||
// Create an error and log it
|
// Create an error and log it
|
||||||
err = fmt.Errorf("Retryable error: %s", err)
|
err = fmt.Errorf("Retryable error: %s", err)
|
||||||
log.Printf(err.Error())
|
log.Print(err.Error())
|
||||||
|
|
||||||
// Check if we timed out, otherwise we retry. It is safe to
|
// Check if we timed out, otherwise we retry. It is safe to
|
||||||
// retry since the only error case above is if the command
|
// retry since the only error case above is if the command
|
||||||
|
|
39
signal.go
39
signal.go
|
@ -1,39 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/mitchellh/packer/packer"
|
|
||||||
"github.com/mitchellh/packer/packer/plugin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Prepares the signal handlers so that we handle interrupts properly.
|
|
||||||
// The signal handler exists in a goroutine.
|
|
||||||
func setupSignalHandlers(ui packer.Ui) {
|
|
||||||
ch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(ch, os.Interrupt)
|
|
||||||
signal.Notify(ch, syscall.SIGTERM)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
// First interrupt. We mostly ignore this because it allows the
|
|
||||||
// plugins time to cleanup.
|
|
||||||
<-ch
|
|
||||||
log.Println("First interrupt. Ignoring to allow plugins to clean up.")
|
|
||||||
|
|
||||||
ui.Error("Interrupt signal received. Cleaning up...")
|
|
||||||
|
|
||||||
// Second interrupt. Go down hard.
|
|
||||||
<-ch
|
|
||||||
log.Println("Second interrupt. Exiting now.")
|
|
||||||
|
|
||||||
ui.Error("Interrupt signal received twice. Forcefully exiting now.")
|
|
||||||
|
|
||||||
// Force kill all the plugins, but mark that we're killing them
|
|
||||||
// first so that we don't get panics everywhere.
|
|
||||||
plugin.CleanupClients()
|
|
||||||
os.Exit(1)
|
|
||||||
}()
|
|
||||||
}
|
|
|
@ -154,7 +154,6 @@ type renderWalker struct {
|
||||||
csKey []reflect.Value
|
csKey []reflect.Value
|
||||||
csData interface{}
|
csData interface{}
|
||||||
sliceIndex int
|
sliceIndex int
|
||||||
unknownKeys []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// renderWalkerFunc is the callback called by interpolationWalk.
|
// renderWalkerFunc is the callback called by interpolationWalk.
|
||||||
|
@ -281,34 +280,3 @@ func (w *renderWalker) Primitive(v reflect.Value) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *renderWalker) removeCurrent() {
|
|
||||||
// Append the key to the unknown keys
|
|
||||||
w.unknownKeys = append(w.unknownKeys, strings.Join(w.key, "."))
|
|
||||||
|
|
||||||
for i := 1; i <= len(w.cs); i++ {
|
|
||||||
c := w.cs[len(w.cs)-i]
|
|
||||||
switch c.Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
// Zero value so that we delete the map key
|
|
||||||
var val reflect.Value
|
|
||||||
|
|
||||||
// Get the key and delete it
|
|
||||||
k := w.csData.(reflect.Value)
|
|
||||||
c.SetMapIndex(k, val)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("No container found for removeCurrent")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *renderWalker) replaceCurrent(v reflect.Value) {
|
|
||||||
c := w.cs[len(w.cs)-2]
|
|
||||||
switch c.Kind() {
|
|
||||||
case reflect.Map:
|
|
||||||
// Get the key and delete it
|
|
||||||
k := w.csKey[len(w.csKey)-1]
|
|
||||||
c.SetMapIndex(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue