Merge pull request #58 from gabrtv/manage_etc_hosts
feat(etc-hosts) add support for manage_etc_hosts: localhost
This commit is contained in:
		| @@ -260,3 +260,16 @@ Provide a list of objects with the following attributes: | ||||
| - **content**: Data to write at the provided `path` | ||||
| - **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>`. | ||||
|  | ||||
| ### 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 | ||||
| 		OEM   OEMRelease | ||||
| 	} | ||||
| 	WriteFiles []system.File `yaml:"write_files"` | ||||
| 	Hostname   string | ||||
| 	Users      []system.User | ||||
| 	WriteFiles     []system.File `yaml:"write_files"` | ||||
| 	Hostname       string | ||||
| 	Users          []system.User | ||||
| 	ManageEtcHosts string `yaml:"manage_etc_hosts"` | ||||
| } | ||||
|  | ||||
| func NewCloudConfig(contents string) (*CloudConfig, error) { | ||||
| @@ -154,7 +155,7 @@ func Apply(cfg CloudConfig, env *Environment) error { | ||||
| 				commands["systemd-networkd.service"] = "restart" | ||||
| 			} else { | ||||
| 				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 | ||||
| } | ||||
|   | ||||
							
								
								
									
										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") | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user