feat(etc-hosts) add support for manage_etc_hosts: localhost
This feature is based on https://github.com/number5/cloud-init/blob/master/doc/examples/cloud-config.txt#L447:L482
This commit is contained in:
parent
23d02363ee
commit
4d02e1da8e
@ -260,3 +260,16 @@ Provide a list of objects with the following attributes:
|
|||||||
- **content**: Data to write at the provided `path`
|
- **content**: Data to write at the provided `path`
|
||||||
- **permissions**: String representing file permissions in octal notation (i.e. '0644')
|
- **permissions**: String representing file permissions in octal notation (i.e. '0644')
|
||||||
- **owner**: User and group that should own the file written to disk. This is equivalent to the `<user>:<group>` argument to `chown <user>:<group> <path>`.
|
- **owner**: User and group that should own the file written to disk. This is equivalent to the `<user>:<group>` argument to `chown <user>:<group> <path>`.
|
||||||
|
|
||||||
|
### manage_etc_hosts
|
||||||
|
|
||||||
|
Have coreos-cloudinit manage your /etc/hosts file for local name resolution.
|
||||||
|
The only supported value is "localhost" which will cause your system's hostname
|
||||||
|
to resolve to "127.0.0.1". This is helpful when the host does not have DNS
|
||||||
|
infrastructure in place to resolve its own hostname, for example, when using Vagrant.
|
||||||
|
|
||||||
|
```
|
||||||
|
#cloud-config
|
||||||
|
|
||||||
|
manage_etc_hosts: localhost
|
||||||
|
```
|
||||||
|
@ -17,9 +17,10 @@ type CloudConfig struct {
|
|||||||
Units []system.Unit
|
Units []system.Unit
|
||||||
OEM OEMRelease
|
OEM OEMRelease
|
||||||
}
|
}
|
||||||
WriteFiles []system.File `yaml:"write_files"`
|
WriteFiles []system.File `yaml:"write_files"`
|
||||||
Hostname string
|
Hostname string
|
||||||
Users []system.User
|
Users []system.User
|
||||||
|
ManageEtcHosts string `yaml:"manage_etc_hosts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCloudConfig(contents string) (*CloudConfig, error) {
|
func NewCloudConfig(contents string) (*CloudConfig, error) {
|
||||||
@ -154,7 +155,7 @@ func Apply(cfg CloudConfig, env *Environment) error {
|
|||||||
commands["systemd-networkd.service"] = "restart"
|
commands["systemd-networkd.service"] = "restart"
|
||||||
} else {
|
} else {
|
||||||
if unit.Command != "" {
|
if unit.Command != "" {
|
||||||
commands[unit.Name] = unit.Command
|
commands[unit.Name] = unit.Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,5 +170,15 @@ func Apply(cfg CloudConfig, env *Environment) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.ManageEtcHosts != "" {
|
||||||
|
|
||||||
|
if err := WriteEtcHosts(cfg.ManageEtcHosts, env.Root()); err != nil {
|
||||||
|
log.Fatalf("Failed to write /etc/hosts to filesystem: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Wrote /etc/hosts file to filesystem")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
44
initialize/manage_etc_hosts.go
Normal file
44
initialize/manage_etc_hosts.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/coreos/coreos-cloudinit/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
const DefaultIpv4Address = "127.0.0.1"
|
||||||
|
|
||||||
|
func generateEtcHosts(option string) (out string, err error) {
|
||||||
|
if option != "localhost" {
|
||||||
|
return "", errors.New("Invalid option to manage_etc_hosts")
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the operating system hostname
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s %s", DefaultIpv4Address, hostname), nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write an /etc/hosts file
|
||||||
|
func WriteEtcHosts(option string, root string) error {
|
||||||
|
|
||||||
|
etcHosts, err := generateEtcHosts(option)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file := system.File{
|
||||||
|
Path: path.Join(root, "etc", "hosts"),
|
||||||
|
RawFilePermissions: "0644",
|
||||||
|
Content: etcHosts,
|
||||||
|
}
|
||||||
|
|
||||||
|
return system.WriteFile(&file)
|
||||||
|
}
|
76
initialize/manage_etc_hosts_test.go
Normal file
76
initialize/manage_etc_hosts_test.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package initialize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCloudConfigManageEtcHosts(t *testing.T) {
|
||||||
|
contents := `
|
||||||
|
manage_etc_hosts: localhost
|
||||||
|
`
|
||||||
|
cfg, err := NewCloudConfig(contents)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Encountered unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
manageEtcHosts := cfg.ManageEtcHosts
|
||||||
|
|
||||||
|
if manageEtcHosts != "localhost" {
|
||||||
|
t.Errorf("ManageEtcHosts value is %q, expected 'localhost'", manageEtcHosts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManageEtcHostsInvalidValue(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create tempdir: %v", err)
|
||||||
|
}
|
||||||
|
defer rmdir(dir)
|
||||||
|
|
||||||
|
if err := WriteEtcHosts("invalid", dir); err == nil {
|
||||||
|
t.Fatalf("WriteEtcHosts succeeded with invalid value: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEtcHostsWrittenToDisk(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to create tempdir: %v", err)
|
||||||
|
}
|
||||||
|
defer rmdir(dir)
|
||||||
|
|
||||||
|
if err := WriteEtcHosts("localhost", dir); err != nil {
|
||||||
|
t.Fatalf("WriteEtcHosts failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fullPath := path.Join(dir, "etc", "hosts")
|
||||||
|
|
||||||
|
fi, err := os.Stat(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to stat file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Mode() != os.FileMode(0644) {
|
||||||
|
t.Errorf("File has incorrect mode: %v", fi.Mode())
|
||||||
|
}
|
||||||
|
|
||||||
|
contents, err := ioutil.ReadFile(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to read expected file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to read OS hostname: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expect := fmt.Sprintf("%s %s", DefaultIpv4Address, hostname)
|
||||||
|
|
||||||
|
if string(contents) != expect {
|
||||||
|
t.Fatalf("File has incorrect contents")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user