From 24574259f7c8924d5fc45c42a03b301b40a136d3 Mon Sep 17 00:00:00 2001 From: Ian Lesperance Date: Sat, 23 May 2026 18:19:40 -0400 Subject: [PATCH] Support common http_content config option --- builder/xenserver/common/common_config.go | 8 ++++---- builder/xenserver/common/config.hcl2spec.go | 2 ++ builder/xenserver/common/step_http_server.go | 14 +++++++++++--- docs/builders/iso/xenserver-iso.html.markdown | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/builder/xenserver/common/common_config.go b/builder/xenserver/common/common_config.go index 2608f2d6..f656e118 100644 --- a/builder/xenserver/common/common_config.go +++ b/builder/xenserver/common/common_config.go @@ -51,9 +51,10 @@ type CommonConfig struct { ToolsIsoName string `mapstructure:"tools_iso_name"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` + HTTPContent map[string]string `mapstructure:"http_content"` + HTTPDir string `mapstructure:"http_directory"` + HTTPPortMin uint `mapstructure:"http_port_min"` + HTTPPortMax uint `mapstructure:"http_port_max"` // SSHHostPortMin uint `mapstructure:"ssh_host_port_min"` // SSHHostPortMax uint `mapstructure:"ssh_host_port_max"` @@ -133,7 +134,6 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig c.Comm.SSHPort = 22 } - if c.OutputDir == "" { c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName) } diff --git a/builder/xenserver/common/config.hcl2spec.go b/builder/xenserver/common/config.hcl2spec.go index c5222049..60be06c8 100644 --- a/builder/xenserver/common/config.hcl2spec.go +++ b/builder/xenserver/common/config.hcl2spec.go @@ -41,6 +41,7 @@ type FlatConfig struct { RawBootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` RawDhcpWait *string `mapstructure:"dhcp_wait" cty:"dhcp_wait" hcl:"dhcp_wait"` ToolsIsoName *string `mapstructure:"tools_iso_name" cty:"tools_iso_name" hcl:"tools_iso_name"` + HTTPContent map[string]string `mapstructure:"http_content" cty:"http_content" hcl:"http_content"` HTTPDir *string `mapstructure:"http_directory" cty:"http_directory" hcl:"http_directory"` HTTPPortMin *uint `mapstructure:"http_port_min" cty:"http_port_min" hcl:"http_port_min"` HTTPPortMax *uint `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"` @@ -160,6 +161,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "boot_wait": &hcldec.AttrSpec{Name: "boot_wait", Type: cty.String, Required: false}, "dhcp_wait": &hcldec.AttrSpec{Name: "dhcp_wait", Type: cty.String, Required: false}, "tools_iso_name": &hcldec.AttrSpec{Name: "tools_iso_name", Type: cty.String, Required: false}, + "http_content": &hcldec.AttrSpec{Name: "http_content", Type: cty.Map(cty.String), Required: false}, "http_directory": &hcldec.AttrSpec{Name: "http_directory", Type: cty.String, Required: false}, "http_port_min": &hcldec.AttrSpec{Name: "http_port_min", Type: cty.Number, Required: false}, "http_port_max": &hcldec.AttrSpec{Name: "http_port_max", Type: cty.Number, Required: false}, diff --git a/builder/xenserver/common/step_http_server.go b/builder/xenserver/common/step_http_server.go index bedf3172..ec297ffa 100644 --- a/builder/xenserver/common/step_http_server.go +++ b/builder/xenserver/common/step_http_server.go @@ -10,6 +10,7 @@ import ( "net/http" "github.com/hashicorp/packer-plugin-sdk/multistep" + "github.com/hashicorp/packer-plugin-sdk/multistep/commonsteps" "github.com/hashicorp/packer-plugin-sdk/packer" ) @@ -48,12 +49,20 @@ func (snooper IPSnooper) ServeHTTP(resp http.ResponseWriter, req *http.Request) snooper.handler.ServeHTTP(resp, req) } +func (s *StepHTTPServer) Handler(config *CommonConfig) http.Handler { + if config.HTTPDir != "" { + return http.FileServer(http.Dir(config.HTTPDir)) + } + + return commonsteps.MapServer(config.HTTPContent) +} + func (s *StepHTTPServer) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { config := state.Get("commonconfig").(CommonConfig) ui := state.Get("ui").(packer.Ui) var httpPort uint = 0 - if config.HTTPDir == "" { + if config.HTTPDir == "" && len(config.HTTPContent) == 0 { // the packer provision steps assert this type is an int // so this cannot be a uint like the rest of the code state.Put("http_port", int(httpPort)) @@ -70,12 +79,11 @@ func (s *StepHTTPServer) Run(ctx context.Context, state multistep.StateBag) mult ui.Say(fmt.Sprintf("Starting HTTP server on port %d", httpPort)) // Start the HTTP server and run it in the background - fileServer := http.FileServer(http.Dir(config.HTTPDir)) server := &http.Server{ Addr: fmt.Sprintf(":%d", httpPort), Handler: IPSnooper{ ch: s.Chan, - handler: fileServer, + handler: s.Handler(&config), }, } go server.Serve(s.l) diff --git a/docs/builders/iso/xenserver-iso.html.markdown b/docs/builders/iso/xenserver-iso.html.markdown index f9e95cd2..a767b165 100644 --- a/docs/builders/iso/xenserver-iso.html.markdown +++ b/docs/builders/iso/xenserver-iso.html.markdown @@ -142,6 +142,21 @@ If you want to add multiple disk, you can do it like this: "vdi_raw" to export just the raw disk image. Set to "none" to export nothing; this is only useful with "keep_vm" set to "always" or "on_success". +- `http_content` (map[string]string) - Key/Values to serve using an HTTP server. + `http_content` works like and conflicts with `http_directory`. The keys + represent the paths and the values contents, the keys must start with a slash, + ex: `/path/to/file`. `http_content` is useful for hosting kickstart files and + so on. By default this is empty, which means no HTTP server will be started. + The address and port of the HTTP server will be available as variables in + `boot_command`. This is covered in more detail below. + Example: + ```hcl + http_content = { + "/a/b" = file("http/b") + "/foo/bar" = templatefile("${path.root}/preseed.cfg", { packages = ["nginx"] }) + } + ``` + * `http_directory` (string) - Path to a directory to serve using an HTTP server. The files in this directory will be available over HTTP which will be requestable from the virtual machine. This is useful for hosting