package cluster import ( "bytes" "fmt" "strings" "text/template" ) type hostsFile struct { Ring0 []hostsEntry Ring1 []hostsEntry } type hostsEntry struct { Addr string Names []string } var hostsTemplate = template.Must(template.New("hosts").Funcs(template.FuncMap{ "StringsJoin": strings.Join, }).Parse(`127.0.0.1 localhost # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts {{range .Ring1 -}} {{.Addr}} {{StringsJoin .Names " "}} {{end}} {{range .Ring0 -}} {{.Addr}} {{StringsJoin .Names " "}} {{end -}} `)) // WriteHosts rewrites all hosts files on the tree func (m *Cluster) WriteHosts() error { var err error m.ForEachZone(func(z *Zone) bool { err = z.WriteHosts() return err != nil }) return err } // WriteHosts rewrites all hosts files in the zone func (z *Zone) WriteHosts() error { var err error s := z.Hosts() z.ForEachMachine(func(p *Machine) bool { err = p.WriteStringFile(s, "hosts") return err != nil }) return err } // WriteHosts rewrites the hosts file func (p *Machine) WriteHosts() error { s := p.zone.Hosts() return p.WriteStringFile(s, "hosts") } func (z *Zone) genHosts(out *hostsFile, p *Machine) { var names []string ip, _ := RingOneAddress(p.zone.ID, p.ID) names = append(names, p.Name) if p.CephMonitor { names = append(names, fmt.Sprintf("%s-%s", p.zone.Name, "ceph")) names = append(names, fmt.Sprintf("%s-%s", p.zone.Name, "k3s")) if z.ID == p.zone.ID { names = append(names, "ceph") names = append(names, "k3s") } } entry := hostsEntry{ Addr: ip.String(), Names: names, } out.Ring1 = append(out.Ring1, entry) if p.IsGateway() { var s string ip, _ = RingZeroAddress(p.zone.ID, p.ID) s = fmt.Sprintf("%s-%v", p.Name, 0) entry = hostsEntry{ Addr: ip.String(), Names: []string{s}, } out.Ring0 = append(out.Ring0, entry) } } // Hosts renders the /etc/hosts to be used on this zone func (z *Zone) Hosts() string { var buf bytes.Buffer var out hostsFile z.zones.ForEachZone(func(z2 *Zone) bool { z2.ForEachMachine(func(p *Machine) bool { z.genHosts(&out, p) return false }) return false }) if err := hostsTemplate.Execute(&buf, &out); err != nil { panic(err) } return buf.String() }