github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/drivers/shared/hostnames/mount.go (about) 1 package hostnames 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/hashicorp/nomad/plugins/drivers" 12 ) 13 14 // GenerateEtcHostsMount writes a /etc/hosts file using the network spec's 15 // hosts configuration, and returns a mount config so that task drivers can 16 // bind-mount it into the resulting task's filesystem. The extraHosts 17 // parameter is expected to be the same format as the extra_hosts field from 18 // the Docker or containerd drivers: []string{"<hostname>:<ip address>"} 19 func GenerateEtcHostsMount(taskDir string, conf *drivers.NetworkIsolationSpec, extraHosts []string) (*drivers.MountConfig, error) { 20 if conf == nil || conf.Mode != drivers.NetIsolationModeGroup { 21 return nil, nil 22 } 23 hostsCfg := conf.HostsConfig 24 if hostsCfg == nil || hostsCfg.Address == "" || hostsCfg.Hostname == "" { 25 return nil, nil 26 } 27 28 var content strings.Builder 29 fmt.Fprintf(&content, `# this file was generated by Nomad 30 127.0.0.1 localhost 31 ::1 localhost 32 ::1 ip6-localhost ip6-loopback 33 fe00::0 ip6-localnet 34 ff00::0 ip6-mcastprefix 35 ff02::1 ip6-allnodes 36 ff02::2 ip6-allrouters 37 ff02::3 ip6-allhosts 38 39 # this entry is the IP address and hostname of the allocation 40 # shared with tasks in the task group's network 41 %s %s 42 `, hostsCfg.Address, hostsCfg.Hostname) 43 44 if len(extraHosts) > 0 { 45 content.WriteString("\n# these entries are extra hosts added by the task config") 46 for _, hostLine := range extraHosts { 47 hostsEntry := strings.SplitN(hostLine, ":", 2) 48 if len(hostsEntry) != 2 { 49 return nil, fmt.Errorf("invalid hosts entry %q", hostLine) 50 } 51 if net.ParseIP(hostsEntry[1]) == nil { 52 return nil, fmt.Errorf("invalid IP address %q", hostLine) 53 } 54 content.WriteString(fmt.Sprintf("\n%s %s", hostsEntry[1], hostsEntry[0])) 55 } 56 content.WriteString("\n") 57 } 58 59 path := filepath.Join(taskDir, "hosts") 60 61 // tasks within an alloc should be able to share and modify the file, so 62 // only write to it if it doesn't exist 63 if _, err := os.Stat(path); os.IsNotExist(err) { 64 err := ioutil.WriteFile(path, []byte(content.String()), 0644) 65 if err != nil { 66 return nil, err 67 } 68 } 69 70 // Note that we're not setting readonly. The file is in the task dir 71 // anyways, so this lets the task overwrite its own hosts file if the 72 // application knows better than Nomad here. Task drivers may override 73 // this behavior. 74 mount := &drivers.MountConfig{ 75 TaskPath: "/etc/hosts", 76 HostPath: path, 77 Readonly: false, 78 PropagationMode: "private", 79 } 80 81 return mount, nil 82 }