diff --git a/src/cmd/linuxkit/run_packet.go b/src/cmd/linuxkit/run_packet.go index 19dcc2276..144e40c12 100644 --- a/src/cmd/linuxkit/run_packet.go +++ b/src/cmd/linuxkit/run_packet.go @@ -56,7 +56,7 @@ func runPacket(args []string) { fmt.Printf("Options:\n\n") flags.PrintDefaults() } - baseURLFlag := flags.String("base-url", "", "Base URL that the kernel and initrd are served from (or "+packetBaseURL+")") + baseURLFlag := flags.String("base-url", "", "Base URL that the kernel, initrd and iPXE script are served from (or "+packetBaseURL+")") zoneFlag := flags.String("zone", packetDefaultZone, "Packet Zone (or "+packetZoneVar+")") machineFlag := flags.String("machine", packetDefaultMachine, "Packet Machine Type (or "+packetMachineVar+")") apiKeyFlag := flags.String("api-key", "", "Packet API key (or "+packetAPIKeyVar+")") @@ -80,7 +80,7 @@ func runPacket(args []string) { url := getStringValue(packetBaseURL, *baseURLFlag, "") if url == "" { - log.Fatal("Need to specify a value for --base-url where the images are hosted. This URL should contain /%s-kernel and /%s-initrd.img") + log.Fatal("Need to specify a value for --base-url where the images are hosted. This URL should contain /%s-kernel, /%s-initrd.img and /%s-packet.ipxe") } facility := getStringValue(packetZoneVar, *zoneFlag, "") plan := getStringValue(packetMachineVar, *machineFlag, defaultMachine) @@ -101,19 +101,31 @@ func runPacket(args []string) { log.Fatalf("Combination of keep=%t and console=%t makes little sense", *keepFlag, *consoleFlag) } - // Read kernel command line - var cmdline string - if c, err := ioutil.ReadFile(prefix + "-cmdline"); err != nil { - log.Fatalf("Cannot open cmdline file: %v", err) - } else { - cmdline = string(c) - } + ipxeScriptName := fmt.Sprintf("%s-packet.ipxe", name) // Serve files with a local http server var httpServer *http.Server if *serveFlag != "" { + // Read kernel command line + var cmdline string + if c, err := ioutil.ReadFile(prefix + "-cmdline"); err != nil { + log.Fatalf("Cannot open cmdline file: %v", err) + } else { + cmdline = string(c) + } + + ipxeScript := packetIPXEScript(name, url, cmdline, packetMachineToArch(*machineFlag)) + log.Debugf("Using iPXE script:\n%s\n", ipxeScript) + + // Two handlers, one for the iPXE script and one for the kernel/initrd files + mux := http.NewServeMux() + mux.HandleFunc(fmt.Sprintf("/%s", ipxeScriptName), + func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, ipxeScript) + }) fs := serveFiles{[]string{fmt.Sprintf("%s-kernel", name), fmt.Sprintf("%s-initrd.img", name)}} - httpServer = &http.Server{Addr: *serveFlag, Handler: http.FileServer(fs)} + mux.Handle("/", http.FileServer(fs)) + httpServer = &http.Server{Addr: *serveFlag, Handler: mux} go func() { log.Debugf("Listening on http://%s\n", *serveFlag) if err := httpServer.ListenAndServe(); err != nil { @@ -122,16 +134,19 @@ func runPacket(args []string) { }() } - userData := packetIPXEScript(name, url, cmdline, packetMachineToArch(*machineFlag)) - log.Debugf("Using userData of:\n%s\n", userData) - - // Make sure the URL works + // Make sure the URLs work + ipxeURL := fmt.Sprintf("%s/%s", url, ipxeScriptName) initrdURL := fmt.Sprintf("%s/%s-initrd.img", url, name) kernelURL := fmt.Sprintf("%s/%s-kernel", url, name) - log.Infof("Validating URls: %s %s", initrdURL, kernelURL) + log.Infof("Validating URL: %s", ipxeURL) + if err := validateHTTPURL(ipxeURL); err != nil { + log.Fatalf("Invalid iPXE URL %s: %v", ipxeURL, err) + } + log.Infof("Validating URL: %s", kernelURL) if err := validateHTTPURL(kernelURL); err != nil { log.Fatalf("Invalid kernel URL %s: %v", kernelURL, err) } + log.Infof("Validating URL: %s", initrdURL) if err := validateHTTPURL(initrdURL); err != nil { log.Fatalf("Invalid initrd URL %s: %v", initrdURL, err) } @@ -153,11 +168,11 @@ func runPacket(args []string) { log.Debugf("%s\n", string(b)) req := packngo.DeviceUpdateRequest{ - Hostname: hostname, - UserData: userData, - Locked: dev.Locked, - Tags: dev.Tags, - AlwaysPXE: *alwaysPXE, + Hostname: hostname, + Locked: dev.Locked, + Tags: dev.Tags, + IPXEScriptURL: ipxeURL, + AlwaysPXE: *alwaysPXE, } dev, _, err = client.Devices.Update(*deviceFlag, &req) if err != nil { @@ -169,15 +184,15 @@ func runPacket(args []string) { } else { // Create a new device req := packngo.DeviceCreateRequest{ - Hostname: hostname, - Plan: plan, - Facility: facility, - OS: osType, - BillingCycle: billing, - ProjectID: projectID, - UserData: userData, - Tags: tags, - AlwaysPXE: *alwaysPXE, + Hostname: hostname, + Plan: plan, + Facility: facility, + OS: osType, + BillingCycle: billing, + ProjectID: projectID, + Tags: tags, + IPXEScriptURL: ipxeURL, + AlwaysPXE: *alwaysPXE, } dev, _, err = client.Devices.Create(&req) if err != nil {