builder/cloudstack: Support http server (#5017)
builder/cloudstack: Added docs for http server Closes hashicorp/packer#4949
This commit is contained in:
parent
7f0a404307
commit
c01f6d8708
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue