db96e40f3a
In Nomad 1.1.1 we generate a hosts file based on the Nomad-owned network namespace, rather than using the default hosts file from the pause container. This hosts file should be shared between tasks in the same allocation so that tasks can update the file and have the results propagated between tasks.
83 lines
2.5 KiB
Go
83 lines
2.5 KiB
Go
package hostnames
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/nomad/plugins/drivers"
|
|
)
|
|
|
|
// GenerateEtcHostsMount writes a /etc/hosts file using the network spec's
|
|
// hosts configuration, and returns a mount config so that task drivers can
|
|
// bind-mount it into the resulting task's filesystem. The extraHosts
|
|
// parameter is expected to be the same format as the extra_hosts field from
|
|
// the Docker or containerd drivers: []string{"<hostname>:<ip address>"}
|
|
func GenerateEtcHostsMount(taskDir string, conf *drivers.NetworkIsolationSpec, extraHosts []string) (*drivers.MountConfig, error) {
|
|
if conf == nil || conf.Mode != drivers.NetIsolationModeGroup {
|
|
return nil, nil
|
|
}
|
|
hostsCfg := conf.HostsConfig
|
|
if hostsCfg == nil || hostsCfg.Address == "" || hostsCfg.Hostname == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
var content strings.Builder
|
|
fmt.Fprintf(&content, `# this file was generated by Nomad
|
|
127.0.0.1 localhost
|
|
::1 localhost
|
|
::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
|
|
|
|
# this entry is the IP address and hostname of the allocation
|
|
# shared with tasks in the task group's network
|
|
%s %s
|
|
`, hostsCfg.Address, hostsCfg.Hostname)
|
|
|
|
if len(extraHosts) > 0 {
|
|
content.WriteString("\n# these entries are extra hosts added by the task config")
|
|
for _, hostLine := range extraHosts {
|
|
hostsEntry := strings.SplitN(hostLine, ":", 2)
|
|
if len(hostsEntry) != 2 {
|
|
return nil, fmt.Errorf("invalid hosts entry %q", hostLine)
|
|
}
|
|
if net.ParseIP(hostsEntry[1]) == nil {
|
|
return nil, fmt.Errorf("invalid IP address %q", hostLine)
|
|
}
|
|
content.WriteString(fmt.Sprintf("\n%s %s", hostsEntry[1], hostsEntry[0]))
|
|
}
|
|
content.WriteString("\n")
|
|
}
|
|
|
|
path := filepath.Join(taskDir, "hosts")
|
|
|
|
// tasks within an alloc should be able to share and modify the file, so
|
|
// only write to it if it doesn't exist
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
err := ioutil.WriteFile(path, []byte(content.String()), 0644)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Note that we're not setting readonly. The file is in the task dir
|
|
// anyways, so this lets the task overwrite its own hosts file if the
|
|
// application knows better than Nomad here. Task drivers may override
|
|
// this behavior.
|
|
mount := &drivers.MountConfig{
|
|
TaskPath: "/etc/hosts",
|
|
HostPath: path,
|
|
Readonly: false,
|
|
PropagationMode: "private",
|
|
}
|
|
|
|
return mount, nil
|
|
}
|