package main import ( "fmt" "io" "net/http" "entanglement.garden/common/cloudinit" "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" ) var ( httpStaticContent = map[string][]byte{} ) func runHTTPServer(bind string) { http.ListenAndServe(bind, httphandler{}) } type httphandler struct{} func (httphandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { log := logrus.WithFields(logrus.Fields{ "method": r.Method, "path": r.URL, "remote_addr": r.RemoteAddr, }) log.Debug("handling HTTP request") switch r.Method { case http.MethodGet: resp, ok := httpStaticContent[r.URL.Path] if !ok { w.WriteHeader(http.StatusNotFound) return } if resp == nil { w.WriteHeader(http.StatusNoContent) return } _, err := w.Write(resp) if err != nil { log.WithError(err).Error("error serving HTTP response") } case http.MethodPost: body, err := io.ReadAll(r.Body) if err != nil { log.WithError(err).Error("error reading body") } r.Body.Close() log.Debug(string(body)) log.Info("VM booted") w.WriteHeader(http.StatusNoContent) wg.Done() default: w.WriteHeader(http.StatusNotFound) w.Write([]byte("not found")) } } func buildCloudConfig(i int, name string, phoneHomeURL string) error { userdata, err := yaml.Marshal(cloudinit.UserData{ Packages: argPackages, SSHAuthorizedKeys: argSSHKeys, PhoneHome: cloudinit.PhoneHome{ URL: phoneHomeURL, Post: []string{"pub_key_dsa"}, }, }) if err != nil { return err } httpStaticContent[fmt.Sprintf("/%d/user-data", i)] = append([]byte("#cloud-config\n"), userdata...) metadata, err := yaml.Marshal(cloudinit.MetaData{ InstanceID: name, LocalHostname: name, }) if err != nil { return err } httpStaticContent[fmt.Sprintf("/%d/meta-data", i)] = metadata httpStaticContent[fmt.Sprintf("/%d/vendor-data", i)] = nil return nil }