open-nomad/drivers/shared/hostnames/mount.go
Tim Gross db96e40f3a
docker: move host path for hosts file mount to alloc dir (#10823)
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.
2021-06-30 11:10:04 -04:00

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
}