// StartDHCP ListenAndServe for dhcp on port 67, binds on interface=ifName if it's // not empty func StartDHCP(ifName string, serverIP net.IP, datasource datasource.DataSource) error { handler := &Handler{ ifName: ifName, serverIP: serverIP, datasource: datasource, bootMessage: fmt.Sprintf("Blacksmith (%s)", datasource.SelfInfo().Version), } log.WithFields(log.Fields{ "where": "dhcp.StartDHCP", "action": "announce", }).Infof("Listening on %s:67 (interface: %s)", serverIP.String(), ifName) var err error if ifName != "" { err = dhcp4.ListenAndServeIf(ifName, handler) } else { err = dhcp4.ListenAndServe(handler) } // https://groups.google.com/forum/#!topic/coreos-user/Qbn3OdVtrZU if len(datasource.ClusterName()) > 50 { // 63 - 12(mac) - 1(.) log.WithField("where", "dhcp.StartDHCP").Warn( "Warning: ClusterName is too long. It may break the behaviour of the DHCP clients") } rand.Seed(time.Now().UTC().UnixNano()) return err }
func executeTemplate(rootTemplte *template.Template, templateName string, ds datasource.DataSource, machineInterface datasource.MachineInterface, webServerAddr string) (string, error) { template := rootTemplte.Lookup(templateName) if template == nil { return "", fmt.Errorf("template with name=%s wasn't found for root=%v", templateName, rootTemplte) } mac := machineInterface.Mac().String() buf := new(bytes.Buffer) template.Funcs(map[string]interface{}{ "V": func(key string) string { value, err := machineInterface.GetVariable(key) if err != nil { log.WithField("where", "templating.executeTemplate").WithError(err).Warn( "error while GetVariable") } return value }, "b64": func(text string) string { return base64.StdEncoding.EncodeToString([]byte(text)) }, "b64template": func(templateName string) string { text, err := executeTemplate(rootTemplte, templateName, ds, machineInterface, webServerAddr) if err != nil { log.WithField("where", "templating.executeTemplate").WithError(err).Warnf( "error while executeTemplate(templateName=%s machine=%s)", templateName, mac) return "" } return base64.StdEncoding.EncodeToString([]byte(text)) }, }) etcdMembers, _ := ds.EtcdMembers() machine, err := machineInterface.Machine(false, nil) if err != nil { return "", err } data := struct { Mac string IP string Hostname string Domain string WebServerAddr string EtcdEndpoints string }{ mac, machine.IP.String(), machineInterface.Hostname(), ds.ClusterName(), webServerAddr, etcdMembers, } err = template.ExecuteTemplate(buf, templateName, &data) if err != nil { return "", err } str := buf.String() str = strings.Trim(str, "\n") return str, nil }