package dnsmasq import ( "cmp" "context" "io" "isle/toolkit" "slices" "text/template" "dev.mediocregopher.com/mediocre-go-lib.git/mlog" ) // ConfDataHost describes a host which can be resolved by dnsmasq. type ConfDataHost struct { Name string IP string } // ConfData describes all the data needed to populate a dnsmasq.conf file. type ConfData struct { Resolvers []string Domain string IP string Hosts []ConfDataHost } var confTpl = template.Must(template.New("").Parse(` port=53 bind-interfaces listen-address={{ .IP }} no-resolv no-hosts user= group= {{- $domain := .Domain -}} {{- range .Hosts }} address=/{{ .Name }}.hosts.{{ $domain }}/{{ .IP }} {{ end -}} {{- range .Resolvers }} server={{ . }} {{ end -}} `)) // WriteConfFile renders a dnsmasq.conf using the given data to a new // file at the given path, returning true if the file changed or didn't // previously exist. func WriteConfFile( ctx context.Context, logger *mlog.Logger, path string, data ConfData, ) ( bool, error, ) { slices.SortFunc(data.Hosts, func(i, j ConfDataHost) int { return cmp.Or( cmp.Compare(i.IP, j.IP), cmp.Compare(i.Name, j.Name), ) }) return toolkit.WriteFileCheckChanged( ctx, logger, path, 0600, func(w io.Writer) error { return confTpl.Execute(w, data) }, ) }