Commit 6e92e60e authored by Tom Dooner's avatar Tom Dooner

Add Rackconnect support

This adds two config options that we need in order to successfully build
our Rackspace images.

First, a boolean `rackconnect_wait` option which waits for the
RackConnect metadata to appear.

Second, an `ssh_interface` option, for rackconnect users who have more
prohibitive firewalls on the 'public' interface and want to ensure all
traffic to the server goes over the 'private' one.

Finishes #952.
parent f1970370
...@@ -95,12 +95,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -95,12 +95,15 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
SecurityGroups: b.config.SecurityGroups, SecurityGroups: b.config.SecurityGroups,
Networks: b.config.Networks, Networks: b.config.Networks,
}, },
&StepWaitForRackConnect{
Wait: b.config.RackconnectWait,
},
&StepAllocateIp{ &StepAllocateIp{
FloatingIpPool: b.config.FloatingIpPool, FloatingIpPool: b.config.FloatingIpPool,
FloatingIp: b.config.FloatingIp, FloatingIp: b.config.FloatingIp,
}, },
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: SSHAddress(csp, b.config.SSHPort), SSHAddress: SSHAddress(csp, b.config.SSHInterface, b.config.SSHPort),
SSHConfig: SSHConfig(b.config.SSHUsername), SSHConfig: SSHConfig(b.config.SSHUsername),
SSHWaitTimeout: b.config.SSHTimeout(), SSHWaitTimeout: b.config.SSHTimeout(),
}, },
......
...@@ -15,8 +15,10 @@ type RunConfig struct { ...@@ -15,8 +15,10 @@ type RunConfig struct {
RawSSHTimeout string `mapstructure:"ssh_timeout"` RawSSHTimeout string `mapstructure:"ssh_timeout"`
SSHUsername string `mapstructure:"ssh_username"` SSHUsername string `mapstructure:"ssh_username"`
SSHPort int `mapstructure:"ssh_port"` SSHPort int `mapstructure:"ssh_port"`
SSHInterface string `mapstructure:"ssh_interface"`
OpenstackProvider string `mapstructure:"openstack_provider"` OpenstackProvider string `mapstructure:"openstack_provider"`
UseFloatingIp bool `mapstructure:"use_floating_ip"` UseFloatingIp bool `mapstructure:"use_floating_ip"`
RackconnectWait bool `mapstructure:"rackconnect_wait"`
FloatingIpPool string `mapstructure:"floating_ip_pool"` FloatingIpPool string `mapstructure:"floating_ip_pool"`
FloatingIp string `mapstructure:"floating_ip"` FloatingIp string `mapstructure:"floating_ip"`
SecurityGroups []string `mapstructure:"security_groups"` SecurityGroups []string `mapstructure:"security_groups"`
...@@ -71,6 +73,7 @@ func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error { ...@@ -71,6 +73,7 @@ func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error {
"flavor": &c.Flavor, "flavor": &c.Flavor,
"ssh_timeout": &c.RawSSHTimeout, "ssh_timeout": &c.RawSSHTimeout,
"ssh_username": &c.SSHUsername, "ssh_username": &c.SSHUsername,
"ssh_interface": &c.SSHInterface,
"source_image": &c.SourceImage, "source_image": &c.SourceImage,
"openstack_provider": &c.OpenstackProvider, "openstack_provider": &c.OpenstackProvider,
"floating_ip_pool": &c.FloatingIpPool, "floating_ip_pool": &c.FloatingIpPool,
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
// SSHAddress returns a function that can be given to the SSH communicator // SSHAddress returns a function that can be given to the SSH communicator
// for determining the SSH address based on the server AccessIPv4 setting.. // for determining the SSH address based on the server AccessIPv4 setting..
func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(multistep.StateBag) (string, error) { func SSHAddress(csp gophercloud.CloudServersProvider, sshinterface string, port int) func(multistep.StateBag) (string, error) {
return func(state multistep.StateBag) (string, error) { return func(state multistep.StateBag) (string, error) {
s := state.Get("server").(*gophercloud.Server) s := state.Get("server").(*gophercloud.Server)
...@@ -25,6 +25,11 @@ func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(multistep.S ...@@ -25,6 +25,11 @@ func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(multistep.S
return "", errors.New("Error parsing SSH addresses") return "", errors.New("Error parsing SSH addresses")
} }
for pool, addresses := range ip_pools { for pool, addresses := range ip_pools {
if sshinterface != "" {
if pool != sshinterface {
continue
}
}
if pool != "" { if pool != "" {
for _, address := range addresses { for _, address := range addresses {
if address.Addr != "" && address.Version == 4 { if address.Addr != "" && address.Version == 4 {
......
package openstack
import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"time"
"github.com/mitchellh/gophercloud-fork-40444fb"
)
type StepWaitForRackConnect struct {
Wait bool
}
func (s *StepWaitForRackConnect) Run(state multistep.StateBag) multistep.StepAction {
if !s.Wait {
return multistep.ActionContinue
}
csp := state.Get("csp").(gophercloud.CloudServersProvider)
server := state.Get("server").(*gophercloud.Server)
ui := state.Get("ui").(packer.Ui)
fmt.Printf("%s", server)
ui.Say(fmt.Sprintf("Waiting for server (%s) to become RackConnect ready...", server.Id))
for {
server, err := csp.ServerById(server.Id)
if err != nil {
return multistep.ActionHalt
}
if server.Metadata["rackconnect_automation_status"] == "DEPLOYED" {
break
}
time.Sleep(2 * time.Second)
}
return multistep.ActionContinue
}
func (s *StepWaitForRackConnect) Cleanup(state multistep.StateBag) {
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment