Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
7a4ff3f2
Commit
7a4ff3f2
authored
Dec 22, 2013
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
builder/virtualbox: generic SSHConfig
parent
79c0c6b5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
369 additions
and
357 deletions
+369
-357
builder/virtualbox/common/ssh.go
builder/virtualbox/common/ssh.go
+59
-0
builder/virtualbox/common/ssh_config.go
builder/virtualbox/common/ssh_config.go
+80
-0
builder/virtualbox/common/ssh_config_test.go
builder/virtualbox/common/ssh_config_test.go
+186
-0
builder/virtualbox/common/step_forward_ssh.go
builder/virtualbox/common/step_forward_ssh.go
+18
-12
builder/virtualbox/iso/builder.go
builder/virtualbox/iso/builder.go
+11
-59
builder/virtualbox/iso/builder_test.go
builder/virtualbox/iso/builder_test.go
+0
-279
builder/virtualbox/ovf/builder.go
builder/virtualbox/ovf/builder.go
+12
-7
builder/virtualbox/ovf/config.go
builder/virtualbox/ovf/config.go
+3
-0
No files found.
builder/virtualbox/
iso
/ssh.go
→
builder/virtualbox/
common
/ssh.go
View file @
7a4ff3f2
package
iso
package
common
import
(
gossh
"code.google.com/p/go.crypto/ssh"
...
...
@@ -9,33 +9,33 @@ import (
"os"
)
func
ssh
Address
(
state
multistep
.
StateBag
)
(
string
,
error
)
{
func
SSH
Address
(
state
multistep
.
StateBag
)
(
string
,
error
)
{
sshHostPort
:=
state
.
Get
(
"sshHostPort"
)
.
(
uint
)
return
fmt
.
Sprintf
(
"127.0.0.1:%d"
,
sshHostPort
),
nil
}
func
sshConfig
(
state
multistep
.
StateBag
)
(
*
gossh
.
ClientConfig
,
error
)
{
config
:=
state
.
Get
(
"config"
)
.
(
*
config
)
func
SSHConfigFunc
(
config
SSHConfig
)
func
(
multistep
.
StateBag
)
(
*
gossh
.
ClientConfig
,
error
)
{
return
func
(
state
multistep
.
StateBag
)
(
*
gossh
.
ClientConfig
,
error
)
{
auth
:=
[]
gossh
.
ClientAuth
{
gossh
.
ClientAuthPassword
(
ssh
.
Password
(
config
.
SSHPassword
)),
gossh
.
ClientAuthKeyboardInteractive
(
ssh
.
PasswordKeyboardInteractive
(
config
.
SSHPassword
)),
}
auth
:=
[]
gossh
.
ClientAuth
{
gossh
.
ClientAuthPassword
(
ssh
.
Password
(
config
.
SSHPassword
)),
gossh
.
ClientAuthKeyboardInteractive
(
ssh
.
PasswordKeyboardInteractive
(
config
.
SSHPassword
)),
}
if
config
.
SSHKeyPath
!=
""
{
keyring
,
err
:=
sshKeyToKeyring
(
config
.
SSHKeyPath
)
if
err
!=
nil
{
return
nil
,
err
}
if
config
.
SSHKeyPath
!=
""
{
keyring
,
err
:=
sshKeyToKeyring
(
config
.
SSHKeyPath
)
if
err
!=
nil
{
return
nil
,
err
auth
=
append
(
auth
,
gossh
.
ClientAuthKeyring
(
keyring
))
}
auth
=
append
(
auth
,
gossh
.
ClientAuthKeyring
(
keyring
))
return
&
gossh
.
ClientConfig
{
User
:
config
.
SSHUser
,
Auth
:
auth
,
},
nil
}
return
&
gossh
.
ClientConfig
{
User
:
config
.
SSHUser
,
Auth
:
auth
,
},
nil
}
func
sshKeyToKeyring
(
path
string
)
(
gossh
.
ClientKeyring
,
error
)
{
...
...
builder/virtualbox/common/ssh_config.go
0 → 100644
View file @
7a4ff3f2
package
common
import
(
"errors"
"fmt"
"github.com/mitchellh/packer/packer"
"os"
"time"
)
type
SSHConfig
struct
{
SSHHostPortMin
uint
`mapstructure:"ssh_host_port_min"`
SSHHostPortMax
uint
`mapstructure:"ssh_host_port_max"`
SSHKeyPath
string
`mapstructure:"ssh_key_path"`
SSHPassword
string
`mapstructure:"ssh_password"`
SSHPort
uint
`mapstructure:"ssh_port"`
SSHUser
string
`mapstructure:"ssh_username"`
RawSSHWaitTimeout
string
`mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout
time
.
Duration
}
func
(
c
*
SSHConfig
)
Prepare
(
t
*
packer
.
ConfigTemplate
)
[]
error
{
if
c
.
SSHHostPortMin
==
0
{
c
.
SSHHostPortMin
=
2222
}
if
c
.
SSHHostPortMax
==
0
{
c
.
SSHHostPortMax
=
4444
}
if
c
.
SSHPort
==
0
{
c
.
SSHPort
=
22
}
if
c
.
RawSSHWaitTimeout
==
""
{
c
.
RawSSHWaitTimeout
=
"20m"
}
templates
:=
map
[
string
]
*
string
{
"ssh_key_path"
:
&
c
.
SSHKeyPath
,
"ssh_password"
:
&
c
.
SSHPassword
,
"ssh_username"
:
&
c
.
SSHUser
,
"ssh_wait_timeout"
:
&
c
.
RawSSHWaitTimeout
,
}
errs
:=
make
([]
error
,
0
)
for
n
,
ptr
:=
range
templates
{
var
err
error
*
ptr
,
err
=
t
.
Process
(
*
ptr
,
nil
)
if
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Error processing %s: %s"
,
n
,
err
))
}
}
if
c
.
SSHKeyPath
!=
""
{
if
_
,
err
:=
os
.
Stat
(
c
.
SSHKeyPath
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_key_path is invalid: %s"
,
err
))
}
else
if
_
,
err
:=
sshKeyToKeyring
(
c
.
SSHKeyPath
);
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"ssh_key_path is invalid: %s"
,
err
))
}
}
if
c
.
SSHHostPortMin
>
c
.
SSHHostPortMax
{
errs
=
append
(
errs
,
errors
.
New
(
"ssh_host_port_min must be less than ssh_host_port_max"
))
}
if
c
.
SSHUser
==
""
{
errs
=
append
(
errs
,
errors
.
New
(
"An ssh_username must be specified."
))
}
var
err
error
c
.
SSHWaitTimeout
,
err
=
time
.
ParseDuration
(
c
.
RawSSHWaitTimeout
)
if
err
!=
nil
{
errs
=
append
(
errs
,
fmt
.
Errorf
(
"Failed parsing ssh_wait_timeout: %s"
,
err
))
}
return
errs
}
builder/virtualbox/common/ssh_config_test.go
0 → 100644
View file @
7a4ff3f2
package
common
import
(
"io/ioutil"
"os"
"testing"
)
func
testSSHConfig
()
*
SSHConfig
{
return
&
SSHConfig
{
SSHUser
:
"foo"
,
}
}
func
TestSSHConfigPrepare
(
t
*
testing
.
T
)
{
c
:=
testSSHConfig
()
errs
:=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"err: %#v"
,
errs
)
}
if
c
.
SSHHostPortMin
!=
2222
{
t
.
Errorf
(
"bad min ssh host port: %d"
,
c
.
SSHHostPortMin
)
}
if
c
.
SSHHostPortMax
!=
4444
{
t
.
Errorf
(
"bad max ssh host port: %d"
,
c
.
SSHHostPortMax
)
}
if
c
.
SSHPort
!=
22
{
t
.
Errorf
(
"bad ssh port: %d"
,
c
.
SSHPort
)
}
}
func
TestSSHConfigPrepare_SSHHostPort
(
t
*
testing
.
T
)
{
var
c
*
SSHConfig
var
errs
[]
error
// Bad
c
=
testSSHConfig
()
c
.
SSHHostPortMin
=
1000
c
.
SSHHostPortMax
=
500
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
==
0
{
t
.
Fatalf
(
"bad: %#v"
,
errs
)
}
// Good
c
=
testSSHConfig
()
c
.
SSHHostPortMin
=
50
c
.
SSHHostPortMax
=
500
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %s"
,
errs
)
}
}
func
TestSSHConfigPrepare_SSHKeyPath
(
t
*
testing
.
T
)
{
var
c
*
SSHConfig
var
errs
[]
error
c
=
testSSHConfig
()
c
.
SSHKeyPath
=
""
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %#v"
,
errs
)
}
c
=
testSSHConfig
()
c
.
SSHKeyPath
=
"/i/dont/exist"
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
==
0
{
t
.
Fatal
(
"should have error"
)
}
// Test bad contents
tf
,
err
:=
ioutil
.
TempFile
(
""
,
"packer"
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
defer
os
.
Remove
(
tf
.
Name
())
defer
tf
.
Close
()
if
_
,
err
:=
tf
.
Write
([]
byte
(
"HELLO!"
));
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
c
=
testSSHConfig
()
c
.
SSHKeyPath
=
tf
.
Name
()
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
==
0
{
t
.
Fatal
(
"should have error"
)
}
// Test good contents
tf
.
Seek
(
0
,
0
)
tf
.
Truncate
(
0
)
tf
.
Write
([]
byte
(
testPem
))
c
=
testSSHConfig
()
c
.
SSHKeyPath
=
tf
.
Name
()
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %#v"
,
errs
)
}
}
func
TestSSHConfigPrepare_SSHUser
(
t
*
testing
.
T
)
{
var
c
*
SSHConfig
var
errs
[]
error
c
=
testSSHConfig
()
c
.
SSHUser
=
""
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
==
0
{
t
.
Fatalf
(
"should have error"
)
}
c
=
testSSHConfig
()
c
.
SSHUser
=
"exists"
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %#v"
,
errs
)
}
}
func
TestSSHConfigPrepare_SSHWaitTimeout
(
t
*
testing
.
T
)
{
var
c
*
SSHConfig
var
errs
[]
error
// Defaults
c
=
testSSHConfig
()
c
.
RawSSHWaitTimeout
=
""
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %#v"
,
errs
)
}
if
c
.
RawSSHWaitTimeout
!=
"20m"
{
t
.
Fatalf
(
"bad value: %s"
,
c
.
RawSSHWaitTimeout
)
}
// Test with a bad value
c
=
testSSHConfig
()
c
.
RawSSHWaitTimeout
=
"this is not good"
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
==
0
{
t
.
Fatal
(
"should have error"
)
}
// Test with a good one
c
=
testSSHConfig
()
c
.
RawSSHWaitTimeout
=
"5s"
errs
=
c
.
Prepare
(
testConfigTemplate
(
t
))
if
len
(
errs
)
>
0
{
t
.
Fatalf
(
"should not have error: %#v"
,
errs
)
}
}
const
testPem
=
`
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxd4iamvrwRJvtNDGQSIbNvvIQN8imXTRWlRY62EvKov60vqu
hh+rDzFYAIIzlmrJopvOe0clqmi3mIP9dtkjPFrYflq52a2CF5q+BdwsJXuRHbJW
LmStZUwW1khSz93DhvhmK50nIaczW63u4EO/jJb3xj+wxR1Nkk9bxi3DDsYFt8SN
AzYx9kjlEYQ/+sI4/ATfmdV9h78SVotjScupd9KFzzi76gWq9gwyCBLRynTUWlyD
2UOfJRkOvhN6/jKzvYfVVwjPSfA9IMuooHdScmC4F6KBKJl/zf/zETM0XyzIDNmH
uOPbCiljq2WoRM+rY6ET84EO0kVXbfx8uxUsqQIDAQABAoIBAQCkPj9TF0IagbM3
5BSs/CKbAWS4dH/D4bPlxx4IRCNirc8GUg+MRb04Xz0tLuajdQDqeWpr6iLZ0RKV
BvreLF+TOdV7DNQ4XE4gSdJyCtCaTHeort/aordL3l0WgfI7mVk0L/yfN1PEG4YG
E9q1TYcyrB3/8d5JwIkjabxERLglCcP+geOEJp+QijbvFIaZR/n2irlKW4gSy6ko
9B0fgUnhkHysSg49ChHQBPQ+o5BbpuLrPDFMiTPTPhdfsvGGcyCGeqfBA56oHcSF
K02Fg8OM+Bd1lb48LAN9nWWY4WbwV+9bkN3Ym8hO4c3a/Dxf2N7LtAQqWZzFjvM3
/AaDvAgBAoGBAPLD+Xn1IYQPMB2XXCXfOuJewRY7RzoVWvMffJPDfm16O7wOiW5+
2FmvxUDayk4PZy6wQMzGeGKnhcMMZTyaq2g/QtGfrvy7q1Lw2fB1VFlVblvqhoJa
nMJojjC4zgjBkXMHsRLeTmgUKyGs+fdFbfI6uejBnnf+eMVUMIdJ+6I9AoGBANCn
kWO9640dttyXURxNJ3lBr2H3dJOkmD6XS+u+LWqCSKQe691Y/fZ/ZL0Oc4Mhy7I6
hsy3kDQ5k2V0fkaNODQIFJvUqXw2pMewUk8hHc9403f4fe9cPrL12rQ8WlQw4yoC
v2B61vNczCCUDtGxlAaw8jzSRaSI5s6ax3K7enbdAoGBAJB1WYDfA2CoAQO6y9Sl
b07A/7kQ8SN5DbPaqrDrBdJziBQxukoMJQXJeGFNUFD/DXFU5Fp2R7C86vXT7HIR
v6m66zH+CYzOx/YE6EsUJms6UP9VIVF0Rg/RU7teXQwM01ZV32LQ8mswhTH20o/3
uqMHmxUMEhZpUMhrfq0isyApAoGAe1UxGTXfj9AqkIVYylPIq2HqGww7+jFmVEj1
9Wi6S6Sq72ffnzzFEPkIQL/UA4TsdHMnzsYKFPSbbXLIWUeMGyVTmTDA5c0e5XIR
lPhMOKCAzv8w4VUzMnEkTzkFY5JqFCD/ojW57KvDdNZPVB+VEcdxyAW6aKELXMAc
eHLc1nkCgYEApm/motCTPN32nINZ+Vvywbv64ZD+gtpeMNP3CLrbe1X9O+H52AXa
1jCoOldWR8i2bs2NVPcKZgdo6fFULqE4dBX7Te/uYEIuuZhYLNzRO1IKU/YaqsXG
3bfQ8hKYcSnTfE0gPtLDnqCIxTocaGLSHeG3TH9fTw+dA8FvWpUztI4=
-----END RSA PRIVATE KEY-----
`
builder/virtualbox/
iso
/step_forward_ssh.go
→
builder/virtualbox/
common
/step_forward_ssh.go
View file @
7a4ff3f2
package
iso
package
common
import
(
"fmt"
"github.com/mitchellh/multistep"
vboxcommon
"github.com/mitchellh/packer/builder/virtualbox/common"
"github.com/mitchellh/packer/packer"
"log"
"math/rand"
...
...
@@ -14,30 +13,37 @@ import (
// on the guest machine.
//
// Uses:
// driver Driver
// ui packer.Ui
// vmName string
//
// Produces:
type
stepForwardSSH
struct
{}
type
StepForwardSSH
struct
{
GuestPort
uint
HostPortMin
uint
HostPortMax
uint
}
func
(
s
*
stepForwardSSH
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
config
:=
state
.
Get
(
"config"
)
.
(
*
config
)
driver
:=
state
.
Get
(
"driver"
)
.
(
vboxcommon
.
Driver
)
func
(
s
*
StepForwardSSH
)
Run
(
state
multistep
.
StateBag
)
multistep
.
StepAction
{
driver
:=
state
.
Get
(
"driver"
)
.
(
Driver
)
ui
:=
state
.
Get
(
"ui"
)
.
(
packer
.
Ui
)
vmName
:=
state
.
Get
(
"vmName"
)
.
(
string
)
log
.
Printf
(
"Looking for available SSH port between %d and %d"
,
config
.
SSHHostPortMin
,
config
.
SSHHostPortMax
)
log
.
Printf
(
"Looking for available SSH port between %d and %d"
,
s
.
HostPortMin
,
s
.
HostPortMax
)
var
sshHostPort
uint
var
offset
uint
=
0
portRange
:=
int
(
config
.
SSHHostPortMax
-
config
.
SSH
HostPortMin
)
portRange
:=
int
(
s
.
HostPortMax
-
s
.
HostPortMin
)
if
portRange
>
0
{
// Have to check if > 0 to avoid a panic
offset
=
uint
(
rand
.
Intn
(
portRange
))
}
for
{
sshHostPort
=
offset
+
config
.
SSH
HostPortMin
sshHostPort
=
offset
+
s
.
HostPortMin
log
.
Printf
(
"Trying port: %d"
,
sshHostPort
)
l
,
err
:=
net
.
Listen
(
"tcp"
,
fmt
.
Sprintf
(
":%d"
,
sshHostPort
))
l
,
err
:=
net
.
Listen
(
"tcp"
,
fmt
.
Sprintf
(
"
127.0.0.1
:%d"
,
sshHostPort
))
if
err
==
nil
{
defer
l
.
Close
()
break
...
...
@@ -49,7 +55,7 @@ func (s *stepForwardSSH) Run(state multistep.StateBag) multistep.StepAction {
command
:=
[]
string
{
"modifyvm"
,
vmName
,
"--natpf1"
,
fmt
.
Sprintf
(
"packerssh,tcp,127.0.0.1,%d,,%d"
,
sshHostPort
,
config
.
SSH
Port
),
fmt
.
Sprintf
(
"packerssh,tcp,127.0.0.1,%d,,%d"
,
sshHostPort
,
s
.
Guest
Port
),
}
if
err
:=
driver
.
VBoxManage
(
command
...
);
err
!=
nil
{
err
:=
fmt
.
Errorf
(
"Error creating port forwarding rule: %s"
,
err
)
...
...
@@ -64,4 +70,4 @@ func (s *stepForwardSSH) Run(state multistep.StateBag) multistep.StepAction {
return
multistep
.
ActionContinue
}
func
(
s
*
s
tepForwardSSH
)
Cleanup
(
state
multistep
.
StateBag
)
{}
func
(
s
*
S
tepForwardSSH
)
Cleanup
(
state
multistep
.
StateBag
)
{}
builder/virtualbox/iso/builder.go
View file @
7a4ff3f2
...
...
@@ -8,7 +8,6 @@ import (
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer"
"log"
"os"
"strings"
"time"
)
...
...
@@ -32,6 +31,7 @@ type config struct {
common
.
PackerConfig
`mapstructure:",squash"`
vboxcommon
.
FloppyConfig
`mapstructure:",squash"`
vboxcommon
.
OutputConfig
`mapstructure:",squash"`
vboxcommon
.
SSHConfig
`mapstructure:",squash"`
BootCommand
[]
string
`mapstructure:"boot_command"`
DiskSize
uint
`mapstructure:"disk_size"`
...
...
@@ -50,12 +50,6 @@ type config struct {
ISOChecksumType
string
`mapstructure:"iso_checksum_type"`
ISOUrls
[]
string
`mapstructure:"iso_urls"`
ShutdownCommand
string
`mapstructure:"shutdown_command"`
SSHHostPortMin
uint
`mapstructure:"ssh_host_port_min"`
SSHHostPortMax
uint
`mapstructure:"ssh_host_port_max"`
SSHKeyPath
string
`mapstructure:"ssh_key_path"`
SSHPassword
string
`mapstructure:"ssh_password"`
SSHPort
uint
`mapstructure:"ssh_port"`
SSHUser
string
`mapstructure:"ssh_username"`
VBoxVersionFile
string
`mapstructure:"virtualbox_version_file"`
VBoxManage
[][]
string
`mapstructure:"vboxmanage"`
VMName
string
`mapstructure:"vm_name"`
...
...
@@ -63,11 +57,9 @@ type config struct {
RawBootWait
string
`mapstructure:"boot_wait"`
RawSingleISOUrl
string
`mapstructure:"iso_url"`
RawShutdownTimeout
string
`mapstructure:"shutdown_timeout"`
RawSSHWaitTimeout
string
`mapstructure:"ssh_wait_timeout"`
bootWait
time
.
Duration
``
shutdownTimeout
time
.
Duration
``
sshWaitTimeout
time
.
Duration
``
tpl
*
packer
.
ConfigTemplate
}
...
...
@@ -85,8 +77,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
// Accumulate any errors and warnings
errs
:=
common
.
CheckUnusedConfig
(
md
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
b
.
config
.
FloppyConfig
.
Prepare
(
b
.
config
.
tpl
)
...
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
b
.
config
.
OutputConfig
.
Prepare
(
b
.
config
.
tpl
,
&
b
.
config
.
PackerConfig
)
...
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
b
.
config
.
SSHConfig
.
Prepare
(
b
.
config
.
tpl
)
...
)
warnings
:=
make
([]
string
,
0
)
if
b
.
config
.
DiskSize
==
0
{
...
...
@@ -121,18 +115,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b
.
config
.
RawBootWait
=
"10s"
}
if
b
.
config
.
SSHHostPortMin
==
0
{
b
.
config
.
SSHHostPortMin
=
2222
}
if
b
.
config
.
SSHHostPortMax
==
0
{
b
.
config
.
SSHHostPortMax
=
4444
}
if
b
.
config
.
SSHPort
==
0
{
b
.
config
.
SSHPort
=
22
}
if
b
.
config
.
VBoxManage
==
nil
{
b
.
config
.
VBoxManage
=
make
([][]
string
,
0
)
}
...
...
@@ -160,15 +142,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
"iso_checksum_type"
:
&
b
.
config
.
ISOChecksumType
,
"iso_url"
:
&
b
.
config
.
RawSingleISOUrl
,
"shutdown_command"
:
&
b
.
config
.
ShutdownCommand
,
"ssh_key_path"
:
&
b
.
config
.
SSHKeyPath
,
"ssh_password"
:
&
b
.
config
.
SSHPassword
,
"ssh_username"
:
&
b
.
config
.
SSHUser
,
"virtualbox_version_file"
:
&
b
.
config
.
VBoxVersionFile
,
"vm_name"
:
&
b
.
config
.
VMName
,
"format"
:
&
b
.
config
.
Format
,
"boot_wait"
:
&
b
.
config
.
RawBootWait
,
"shutdown_timeout"
:
&
b
.
config
.
RawShutdownTimeout
,
"ssh_wait_timeout"
:
&
b
.
config
.
RawSSHWaitTimeout
,
}
for
n
,
ptr
:=
range
templates
{
...
...
@@ -293,42 +271,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b
.
config
.
RawShutdownTimeout
=
"5m"
}
if
b
.
config
.
RawSSHWaitTimeout
==
""
{
b
.
config
.
RawSSHWaitTimeout
=
"20m"
}
b
.
config
.
shutdownTimeout
,
err
=
time
.
ParseDuration
(
b
.
config
.
RawShutdownTimeout
)
if
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"Failed parsing shutdown_timeout: %s"
,
err
))
}
if
b
.
config
.
SSHKeyPath
!=
""
{
if
_
,
err
:=
os
.
Stat
(
b
.
config
.
SSHKeyPath
);
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"ssh_key_path is invalid: %s"
,
err
))
}
else
if
_
,
err
:=
sshKeyToKeyring
(
b
.
config
.
SSHKeyPath
);
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"ssh_key_path is invalid: %s"
,
err
))
}
}
if
b
.
config
.
SSHHostPortMin
>
b
.
config
.
SSHHostPortMax
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"ssh_host_port_min must be less than ssh_host_port_max"
))
}
if
b
.
config
.
SSHUser
==
""
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
errors
.
New
(
"An ssh_username must be specified."
))
}
b
.
config
.
sshWaitTimeout
,
err
=
time
.
ParseDuration
(
b
.
config
.
RawSSHWaitTimeout
)
if
err
!=
nil
{
errs
=
packer
.
MultiErrorAppend
(
errs
,
fmt
.
Errorf
(
"Failed parsing ssh_wait_timeout: %s"
,
err
))
}
for
i
,
args
:=
range
b
.
config
.
VBoxManage
{
for
j
,
arg
:=
range
args
{
if
err
:=
b
.
config
.
tpl
.
Validate
(
arg
);
err
!=
nil
{
...
...
@@ -382,14 +330,18 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
new
(
stepAttachISO
),
new
(
stepAttachGuestAdditions
),
new
(
vboxcommon
.
StepAttachFloppy
),
new
(
stepForwardSSH
),
&
vboxcommon
.
StepForwardSSH
{
GuestPort
:
b
.
config
.
SSHPort
,
HostPortMin
:
b
.
config
.
SSHHostPortMin
,
HostPortMax
:
b
.
config
.
SSHHostPortMax
,
},
new
(
stepVBoxManage
),
new
(
stepRun
),
new
(
stepTypeBootCommand
),
&
common
.
StepConnectSSH
{
SSHAddress
:
ssh
Address
,
SSHConfig
:
sshConfig
,
SSHWaitTimeout
:
b
.
config
.
ssh
WaitTimeout
,
SSHAddress
:
vboxcommon
.
SSH
Address
,
SSHConfig
:
vboxcommon
.
SSHConfigFunc
(
b
.
config
.
SSHConfig
)
,
SSHWaitTimeout
:
b
.
config
.
SSH
WaitTimeout
,
},
new
(
stepUploadVersion
),
new
(
stepUploadGuestAdditions
),
...
...
builder/virtualbox/iso/builder_test.go
View file @
7a4ff3f2
...
...
@@ -8,36 +8,6 @@ import (
"testing"
)
var
testPem
=
`
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxd4iamvrwRJvtNDGQSIbNvvIQN8imXTRWlRY62EvKov60vqu
hh+rDzFYAIIzlmrJopvOe0clqmi3mIP9dtkjPFrYflq52a2CF5q+BdwsJXuRHbJW
LmStZUwW1khSz93DhvhmK50nIaczW63u4EO/jJb3xj+wxR1Nkk9bxi3DDsYFt8SN
AzYx9kjlEYQ/+sI4/ATfmdV9h78SVotjScupd9KFzzi76gWq9gwyCBLRynTUWlyD
2UOfJRkOvhN6/jKzvYfVVwjPSfA9IMuooHdScmC4F6KBKJl/zf/zETM0XyzIDNmH
uOPbCiljq2WoRM+rY6ET84EO0kVXbfx8uxUsqQIDAQABAoIBAQCkPj9TF0IagbM3
5BSs/CKbAWS4dH/D4bPlxx4IRCNirc8GUg+MRb04Xz0tLuajdQDqeWpr6iLZ0RKV
BvreLF+TOdV7DNQ4XE4gSdJyCtCaTHeort/aordL3l0WgfI7mVk0L/yfN1PEG4YG
E9q1TYcyrB3/8d5JwIkjabxERLglCcP+geOEJp+QijbvFIaZR/n2irlKW4gSy6ko
9B0fgUnhkHysSg49ChHQBPQ+o5BbpuLrPDFMiTPTPhdfsvGGcyCGeqfBA56oHcSF
K02Fg8OM+Bd1lb48LAN9nWWY4WbwV+9bkN3Ym8hO4c3a/Dxf2N7LtAQqWZzFjvM3
/AaDvAgBAoGBAPLD+Xn1IYQPMB2XXCXfOuJewRY7RzoVWvMffJPDfm16O7wOiW5+
2FmvxUDayk4PZy6wQMzGeGKnhcMMZTyaq2g/QtGfrvy7q1Lw2fB1VFlVblvqhoJa
nMJojjC4zgjBkXMHsRLeTmgUKyGs+fdFbfI6uejBnnf+eMVUMIdJ+6I9AoGBANCn
kWO9640dttyXURxNJ3lBr2H3dJOkmD6XS+u+LWqCSKQe691Y/fZ/ZL0Oc4Mhy7I6
hsy3kDQ5k2V0fkaNODQIFJvUqXw2pMewUk8hHc9403f4fe9cPrL12rQ8WlQw4yoC
v2B61vNczCCUDtGxlAaw8jzSRaSI5s6ax3K7enbdAoGBAJB1WYDfA2CoAQO6y9Sl
b07A/7kQ8SN5DbPaqrDrBdJziBQxukoMJQXJeGFNUFD/DXFU5Fp2R7C86vXT7HIR
v6m66zH+CYzOx/YE6EsUJms6UP9VIVF0Rg/RU7teXQwM01ZV32LQ8mswhTH20o/3
uqMHmxUMEhZpUMhrfq0isyApAoGAe1UxGTXfj9AqkIVYylPIq2HqGww7+jFmVEj1
9Wi6S6Sq72ffnzzFEPkIQL/UA4TsdHMnzsYKFPSbbXLIWUeMGyVTmTDA5c0e5XIR
lPhMOKCAzv8w4VUzMnEkTzkFY5JqFCD/ojW57KvDdNZPVB+VEcdxyAW6aKELXMAc
eHLc1nkCgYEApm/motCTPN32nINZ+Vvywbv64ZD+gtpeMNP3CLrbe1X9O+H52AXa
1jCoOldWR8i2bs2NVPcKZgdo6fFULqE4dBX7Te/uYEIuuZhYLNzRO1IKU/YaqsXG
3bfQ8hKYcSnTfE0gPtLDnqCIxTocaGLSHeG3TH9fTw+dA8FvWpUztI4=
-----END RSA PRIVATE KEY-----
`
func
testConfig
()
map
[
string
]
interface
{}
{
return
map
[
string
]
interface
{}{
"iso_checksum"
:
"foo"
,
...
...
@@ -77,22 +47,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
t
.
Errorf
(
"bad guest OS type: %s"
,
b
.
config
.
GuestOSType
)
}
if
b
.
config
.
OutputDir
!=
"output-foo"
{
t
.
Errorf
(
"bad output dir: %s"
,
b
.
config
.
OutputDir
)
}
if
b
.
config
.
SSHHostPortMin
!=
2222
{
t
.
Errorf
(
"bad min ssh host port: %d"
,
b
.
config
.
SSHHostPortMin
)
}
if
b
.
config
.
SSHHostPortMax
!=
4444
{
t
.
Errorf
(
"bad max ssh host port: %d"
,
b
.
config
.
SSHHostPortMax
)
}
if
b
.
config
.
SSHPort
!=
22
{
t
.
Errorf
(
"bad ssh port: %d"
,
b
.
config
.
SSHPort
)
}
if
b
.
config
.
VMName
!=
"packer-foo"
{
t
.
Errorf
(
"bad vm name: %s"
,
b
.
config
.
VMName
)
}
...
...
@@ -174,39 +128,6 @@ func TestBuilderPrepare_DiskSize(t *testing.T) {
}
}
func
TestBuilderPrepare_FloppyFiles
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
delete
(
config
,
"floppy_files"
)
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"bad err: %s"
,
err
)
}
if
len
(
b
.
config
.
FloppyFiles
)
!=
0
{
t
.
Fatalf
(
"bad: %#v"
,
b
.
config
.
FloppyFiles
)
}
config
[
"floppy_files"
]
=
[]
string
{
"foo"
,
"bar"
}
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
expected
:=
[]
string
{
"foo"
,
"bar"
}
if
!
reflect
.
DeepEqual
(
b
.
config
.
FloppyFiles
,
expected
)
{
t
.
Fatalf
(
"bad: %#v"
,
b
.
config
.
FloppyFiles
)
}
}
func
TestBuilderPrepare_GuestAdditionsMode
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
...
...
@@ -613,39 +534,6 @@ func TestBuilderPrepare_ISOUrl(t *testing.T) {
}
}
func
TestBuilderPrepare_OutputDir
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
// Test with existing dir
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"packer"
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
defer
os
.
RemoveAll
(
dir
)
config
[
"output_directory"
]
=
dir
b
=
Builder
{}
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Test with a good one
config
[
"output_directory"
]
=
"i-hope-i-dont-exist"
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
}
func
TestBuilderPrepare_ShutdownCommand
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
...
...
@@ -687,173 +575,6 @@ func TestBuilderPrepare_ShutdownTimeout(t *testing.T) {
}
}
func
TestBuilderPrepare_SSHHostPort
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
// Bad
config
[
"ssh_host_port_min"
]
=
1000
config
[
"ssh_host_port_max"
]
=
500
b
=
Builder
{}
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Bad
config
[
"ssh_host_port_min"
]
=
-
500
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Good
config
[
"ssh_host_port_min"
]
=
500
config
[
"ssh_host_port_max"
]
=
1000
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
}
func
TestBuilderPrepare_sshKeyPath
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
config
[
"ssh_key_path"
]
=
""
b
=
Builder
{}
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
config
[
"ssh_key_path"
]
=
"/i/dont/exist"
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Test bad contents
tf
,
err
:=
ioutil
.
TempFile
(
""
,
"packer"
)
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
defer
os
.
Remove
(
tf
.
Name
())
defer
tf
.
Close
()
if
_
,
err
:=
tf
.
Write
([]
byte
(
"HELLO!"
));
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
config
[
"ssh_key_path"
]
=
tf
.
Name
()
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Test good contents
tf
.
Seek
(
0
,
0
)
tf
.
Truncate
(
0
)
tf
.
Write
([]
byte
(
testPem
))
config
[
"ssh_key_path"
]
=
tf
.
Name
()
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
}
func
TestBuilderPrepare_SSHUser
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
config
[
"ssh_username"
]
=
""
b
=
Builder
{}
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
config
[
"ssh_username"
]
=
"exists"
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
}
func
TestBuilderPrepare_SSHWaitTimeout
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
// Test a default boot_wait
delete
(
config
,
"ssh_wait_timeout"
)
warns
,
err
:=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
b
.
config
.
RawSSHWaitTimeout
!=
"20m"
{
t
.
Fatalf
(
"bad value: %s"
,
b
.
config
.
RawSSHWaitTimeout
)
}
// Test with a bad value
config
[
"ssh_wait_timeout"
]
=
"this is not good"
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
// Test with a good one
config
[
"ssh_wait_timeout"
]
=
"5s"
b
=
Builder
{}
warns
,
err
=
b
.
Prepare
(
config
)
if
len
(
warns
)
>
0
{
t
.
Fatalf
(
"bad: %#v"
,
warns
)
}
if
err
!=
nil
{
t
.
Fatalf
(
"should not have error: %s"
,
err
)
}
}
func
TestBuilderPrepare_VBoxManage
(
t
*
testing
.
T
)
{
var
b
Builder
config
:=
testConfig
()
...
...
builder/virtualbox/ovf/builder.go
View file @
7a4ff3f2
...
...
@@ -54,16 +54,21 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
new(stepAttachGuestAdditions),
*/
new
(
vboxcommon
.
StepAttachFloppy
),
&
vboxcommon
.
StepForwardSSH
{
GuestPort
:
b
.
config
.
SSHPort
,
HostPortMin
:
b
.
config
.
SSHHostPortMin
,
HostPortMax
:
b
.
config
.
SSHHostPortMax
,
},
/*
new(stepForwardSSH),
new(stepVBoxManage),
new(stepRun),
new(stepTypeBootCommand),
&common.StepConnectSSH{
SSHAddress: sshAddress,
SSHConfig: sshConfig,
SSHWaitTimeout: b.config.sshWaitTimeout,
},
*/
&
common
.
StepConnectSSH
{
SSHAddress
:
vboxcommon
.
SSHAddress
,
SSHConfig
:
vboxcommon
.
SSHConfigFunc
(
b
.
config
.
SSHConfig
),
SSHWaitTimeout
:
b
.
config
.
SSHWaitTimeout
,
},
/*
new(stepUploadVersion),
new(stepUploadGuestAdditions),
new(common.StepProvision),
...
...
builder/virtualbox/ovf/config.go
View file @
7a4ff3f2
...
...
@@ -11,6 +11,7 @@ type Config struct {
common
.
PackerConfig
`mapstructure:",squash"`
vboxcommon
.
FloppyConfig
`mapstructure:",squash"`
vboxcommon
.
OutputConfig
`mapstructure:",squash"`
vboxcommon
.
SSHConfig
`mapstructure:",squash"`
tpl
*
packer
.
ConfigTemplate
}
...
...
@@ -30,7 +31,9 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
// Prepare the errors
errs
:=
common
.
CheckUnusedConfig
(
md
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
c
.
FloppyConfig
.
Prepare
(
c
.
tpl
)
...
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
c
.
OutputConfig
.
Prepare
(
c
.
tpl
,
&
c
.
PackerConfig
)
...
)
errs
=
packer
.
MultiErrorAppend
(
errs
,
c
.
SSHConfig
.
Prepare
(
c
.
tpl
)
...
)
// Check for any errors.
if
errs
!=
nil
&&
len
(
errs
.
Errors
)
>
0
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment