Example #1
0
// 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
}
Example #2
0
func gracefulShutdown(etcdDataSource datasource.DataSource) {
	err := etcdDataSource.RemoveInstance()
	if err != nil {
		log.Printf("\nError while removing the instance: %s\n", err)
	} else {
		fmt.Fprint(os.Stderr, "\nBlacksmith is gracefully shutdown\n")
	}
	os.Exit(0)
}
Example #3
0
func NewHTTPBooter(listenAddr net.TCPAddr, ldlinux []byte,
	ds datasource.DataSource, webPort int) (*HTTPBooter, error) {
	bootMessageVersionedTemplate := strings.Replace(bootMessageTemplate, "$VERSION", ds.Version().Version, -1)
	booter := &HTTPBooter{
		listenAddr:          listenAddr,
		ldlinux:             ldlinux,
		datasource:          ds,
		webPort:             webPort,
		bootMessageTemplate: bootMessageVersionedTemplate,
	}
	return booter, nil
}
Example #4
0
func newDHCPHandler(settings *DHCPSetting, datasource datasource.DataSource) (*DHCPHandler, error) {
	h := &DHCPHandler{
		settings:    settings,
		datasource:  datasource,
		bootMessage: fmt.Sprintf("Blacksmith (%s)", datasource.Version().Version),
	}
	return h, nil
}
Example #5
0
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
}