builder/cloudstack: Support http server (#5017)

builder/cloudstack: Added docs for http server
Closes hashicorp/packer#4949
This commit is contained in:
Lars Tobias Skjong-Børsting 2017-07-06 11:59:02 +02:00 committed by Sander van Harmelen
parent 7f0a404307
commit c01f6d8708
4 changed files with 86 additions and 3 deletions

View File

@ -56,7 +56,14 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
// Build the steps.
steps := []multistep.Step{
&stepPrepareConfig{},
&stepCreateInstance{},
&common.StepHTTPServer{
HTTPDir: b.config.HTTPDir,
HTTPPortMin: b.config.HTTPPortMin,
HTTPPortMax: b.config.HTTPPortMax,
},
&stepCreateInstance{
Ctx: b.config.ctx,
},
&stepSetupNetworking{},
&communicator.StepConnect{
Config: &b.config.Comm,

View File

@ -17,6 +17,7 @@ import (
// Config holds all the details needed to configure the builder.
type Config struct {
common.PackerConfig `mapstructure:",squash"`
common.HTTPConfig `mapstructure:",squash"`
Comm communicator.Config `mapstructure:",squash"`
APIURL string `mapstructure:"api_url"`
@ -64,6 +65,11 @@ func NewConfig(raws ...interface{}) (*Config, error) {
err := config.Decode(c, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &c.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"user_data",
},
},
}, raws...)
if err != nil {
return nil, err

View File

@ -2,16 +2,27 @@ package cloudstack
import (
"encoding/base64"
"errors"
"fmt"
"net"
"strings"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
"github.com/mitchellh/multistep"
"github.com/xanzy/go-cloudstack/cloudstack"
)
// userDataTemplateData represents variables for user_data interpolation
type userDataTemplateData struct {
HTTPIP string
HTTPPort uint
}
// stepCreateInstance represents a Packer build step that creates CloudStack instances.
type stepCreateInstance struct{}
type stepCreateInstance struct {
Ctx interpolate.Context
}
// Run executes the Packer build step that creates a CloudStack instance.
func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction {
@ -65,7 +76,26 @@ func (s *stepCreateInstance) Run(state multistep.StateBag) multistep.StepAction
}
if config.UserData != "" {
ud, err := getUserData(config.UserData, config.HTTPGetOnly)
httpPort := state.Get("http_port").(uint)
hostIp, err := hostIP()
if err != nil {
ui.Error(err.Error())
return multistep.ActionHalt
}
s.Ctx.Data = &userDataTemplateData{
hostIp,
httpPort,
}
renderedUserData, err := interpolate.Render(config.UserData, &s.Ctx)
if err != nil {
err := fmt.Errorf("Error rendering user_data: %s", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
ud, err := getUserData(renderedUserData, config.HTTPGetOnly)
if err != nil {
ui.Error(err.Error())
return multistep.ActionHalt
@ -159,3 +189,20 @@ func getUserData(userData string, httpGETOnly bool) (string, error) {
return ud, nil
}
func hostIP() (string, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String(), nil
}
}
}
return "", errors.New("No host IP found")
}

View File

@ -83,10 +83,24 @@ builder.
- `disk_size` (int) - The size (in GB) of the root disk of the new instance.
This option is only available when using `source_template`.
- `http_directory` (string) - Path to a directory to serve using an
HTTP server. The files in this directory will be available over HTTP that
will be requestable from the virtual machine. This is useful for hosting
kickstart files and so on. By default this is "", which means no HTTP server
will be started. The address and port of the HTTP server will be available
as variables in `user_data`. This is covered in more detail below.
- `http_get_only` (boolean) - Some cloud providers only allow HTTP GET calls to
their CloudStack API. If using such a provider, you need to set this to `true`
in order for the provider to only make GET calls and no POST calls.
- `http_port_min` and `http_port_max` (integer) - These are the minimum and
maximum port to use for the HTTP server started to serve the
`http_directory`. Because Packer often runs in parallel, Packer will choose
a randomly available port in this range to run the HTTP server. If you want
to force the HTTP server to be on one port, make this minimum and maximum
port the same. By default the values are 8000 and 9000, respectively.
- `hypervisor` (string) - The target hypervisor (e.g. `XenServer`, `KVM`) for
the new template. This option is required when using `source_iso`.
@ -123,6 +137,15 @@ builder.
- `use_local_ip_address` (boolean) - Set to `true` to indicate that the
provisioners should connect to the local IP address of the instance.
## User Data
The available variables are:
- `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server
that is started serving the directory specified by the `http_directory`
configuration parameter. If `http_directory` isn't specified, these will be
blank!
## Basic Example
Here is a basic example.