mirror of
https://github.com/rancher/os.git
synced 2025-09-06 17:22:34 +00:00
Fix DHCP hostname being overwritten
This commit is contained in:
@@ -22,7 +22,6 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||
@@ -169,32 +168,12 @@ func fetchUserData() ([]byte, datasource.Metadata, error) {
|
||||
return userDataBytes, metadata, nil
|
||||
}
|
||||
|
||||
func SetHostname(cc *rancherConfig.CloudConfig) (string, error) {
|
||||
name, _ := os.Hostname()
|
||||
if cc.Hostname != "" {
|
||||
name = cc.Hostname
|
||||
}
|
||||
if name != "" {
|
||||
//set hostname
|
||||
if err := syscall.Sethostname([]byte(name)); err != nil {
|
||||
log.WithFields(log.Fields{"err": err, "hostname": name}).Error("Error setting hostname")
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
|
||||
func executeCloudConfig() error {
|
||||
cc, err := rancherConfig.LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := SetHostname(cc); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(cc.SSHAuthorizedKeys) > 0 {
|
||||
authorizeSSHKeys("rancher", cc.SSHAuthorizedKeys, sshKeyName)
|
||||
authorizeSSHKeys("docker", cc.SSHAuthorizedKeys, sshKeyName)
|
||||
|
@@ -1,19 +1,16 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/docker/libnetwork/resolvconf"
|
||||
"github.com/rancher/netconf"
|
||||
"github.com/rancher/os/cmd/cloudinit"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/hostname"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -49,39 +46,25 @@ func Main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
hostname, _ := cloudinit.SetHostname(cfg) // ignore error
|
||||
log.Infof("Network: hostname: '%s'", hostname)
|
||||
|
||||
if _, err := resolvconf.Build("/etc/resolv.conf", cfg.Rancher.Network.Dns.Nameservers, cfg.Rancher.Network.Dns.Search, nil); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if err := hostname.SetHostnameFromCloudConfig(cfg); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if err := netconf.ApplyNetworkConfigs(&cfg.Rancher.Network); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
hostname, _ = cloudinit.SetHostname(cfg) // ignore error
|
||||
log.Infof("Network: hostname: '%s' (from DHCP, if not set by cloud-config)", hostname)
|
||||
if hostname != "" {
|
||||
hosts, err := os.Open("/etc/hosts")
|
||||
defer hosts.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
lines := bufio.NewScanner(hosts)
|
||||
hostsContent := ""
|
||||
for lines.Scan() {
|
||||
line := strings.TrimSpace(lines.Text())
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) > 0 && fields[0] == "127.0.1.1" {
|
||||
hostsContent += "127.0.1.1 " + hostname + "\n"
|
||||
continue
|
||||
}
|
||||
hostsContent += line + "\n"
|
||||
}
|
||||
if err := ioutil.WriteFile("/etc/hosts", []byte(hostsContent), 0600); err != nil {
|
||||
dhcpHostname := cfg.Hostname == ""
|
||||
if err := netconf.RunDhcp(&cfg.Rancher.Network, dhcpHostname); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if err := hostname.SyncHostname(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if f, err := os.Create(NETWORK_DONE); err != nil {
|
||||
|
@@ -71,6 +71,7 @@ type CloudConfig struct {
|
||||
SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"`
|
||||
WriteFiles []config.File `yaml:"write_files"`
|
||||
Hostname string `yaml:"hostname"`
|
||||
DefaultHostname string `yaml:"default_hostname"`
|
||||
|
||||
Rancher RancherConfig `yaml:"rancher,omitempty"`
|
||||
}
|
||||
|
62
hostname/hostname.go
Normal file
62
hostname/hostname.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package hostname
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"github.com/rancher/os/config"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func SetHostnameFromCloudConfig(cc *config.CloudConfig) error {
|
||||
var hostname string
|
||||
if cc.Hostname == "" {
|
||||
hostname = cc.DefaultHostname
|
||||
} else {
|
||||
hostname = cc.Hostname
|
||||
}
|
||||
|
||||
if hostname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// set hostname
|
||||
if err := syscall.Sethostname([]byte(hostname)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SyncHostname() error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hostname == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
hosts, err := os.Open("/etc/hosts")
|
||||
defer hosts.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := bufio.NewScanner(hosts)
|
||||
hostsContent := ""
|
||||
for lines.Scan() {
|
||||
line := strings.TrimSpace(lines.Text())
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) > 0 && fields[0] == "127.0.1.1" {
|
||||
hostsContent += "127.0.1.1 " + hostname + "\n"
|
||||
continue
|
||||
}
|
||||
hostsContent += line + "\n"
|
||||
}
|
||||
if err := ioutil.WriteFile("/etc/hosts", []byte(hostsContent), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
hostname: {{.HOSTNAME_DEFAULT}}
|
||||
default_hostname: {{.HOSTNAME_DEFAULT}}
|
||||
rancher:
|
||||
bootstrap:
|
||||
state-script:
|
||||
|
3
tests/integration/assets/test_12/cloud-config.yml
Normal file
3
tests/integration/assets/test_12/cloud-config.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
#cloud-config
|
||||
ssh_authorized_keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
4
tests/integration/assets/test_13/cloud-config.yml
Normal file
4
tests/integration/assets/test_13/cloud-config.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
#cloud-config
|
||||
hostname: rancher-test
|
||||
ssh_authorized_keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlsWAL5Rf0Wis/A7k7Tlqx0fZS60VzCZrPZYbP/wkL95jv0XzCx8bd1rZHeybblHPDNpND3BLv4qPY5DxRyexF4seGuzcJI/pOvGUGjQondeMPgDTFEo5w939gSdeTZcfXzQ0wAVhzwDbgH4zPfMzbdoo8Aiu9jkKljXw8IFju0gh+t6iKkGZCIjKT9o7zza1vGfkodhvi2V3VzPdNO28gaxZaRNtmBYUoVnGyR6nXN1Q3CJaVuh5o6GPCOqrhHNbYOFZKBpDiHbxPhVpxHQD2+8yUSGTG7WW75FfZePja5y8d0c/O5L37ZYx4AZAd3KgQYDBT2XCEJGQNawNbfpt
|
21
tests/integration/rostest/test_12_dhcp_hostname.py
Normal file
21
tests/integration/rostest/test_12_dhcp_hostname.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import pytest
|
||||
import rostest.util as u
|
||||
from rostest.util import SSH
|
||||
|
||||
ssh_command = ['./scripts/ssh', '--qemu', '--key', './tests/integration/assets/test.key']
|
||||
cloud_config_path = './tests/integration/assets/test_12/cloud-config.yml'
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def qemu(request):
|
||||
q = u.run_qemu(request, ['--cloud-config', cloud_config_path])
|
||||
u.flush_out(q.stdout)
|
||||
return q
|
||||
|
||||
|
||||
@pytest.mark.timeout(40)
|
||||
def test_dhcp_hostname(qemu):
|
||||
SSH(qemu, ssh_command).check_call('''
|
||||
hostname | grep rancher-dev
|
||||
cat /etc/hosts | grep rancher-dev
|
||||
''')
|
21
tests/integration/rostest/test_13_cloud_config_hostname.py
Normal file
21
tests/integration/rostest/test_13_cloud_config_hostname.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import pytest
|
||||
import rostest.util as u
|
||||
from rostest.util import SSH
|
||||
|
||||
ssh_command = ['./scripts/ssh', '--qemu', '--key', './tests/integration/assets/test.key']
|
||||
cloud_config_path = './tests/integration/assets/test_13/cloud-config.yml'
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def qemu(request):
|
||||
q = u.run_qemu(request, ['--cloud-config', cloud_config_path])
|
||||
u.flush_out(q.stdout)
|
||||
return q
|
||||
|
||||
|
||||
@pytest.mark.timeout(40)
|
||||
def test_cloud_config_hostname(qemu):
|
||||
SSH(qemu, ssh_command).check_call('''
|
||||
hostname | grep rancher-test
|
||||
cat /etc/hosts | grep rancher-test
|
||||
''')
|
@@ -70,7 +70,7 @@ import:
|
||||
version: v1.10.3
|
||||
|
||||
- package: github.com/rancher/netconf
|
||||
version: 6cd9ea0b3a45482c9e9aee9be9ca88c96b2f71e6
|
||||
version: 6a771a0593c146f35634c405ab9ccfec50db65e1
|
||||
|
||||
- package: github.com/ryanuber/go-glob
|
||||
version: 0067a9abd927e50aed5190662702f81231413ae0
|
||||
|
36
vendor/github.com/rancher/netconf/netconf_linux.go
generated
vendored
36
vendor/github.com/rancher/netconf/netconf_linux.go
generated
vendored
@@ -23,7 +23,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
defaultDhcpArgs = []string{"dhcpcd", "-MA4", "-e", "force_hostname=true"}
|
||||
defaultDhcpArgs = []string{"dhcpcd", "-MA4"}
|
||||
)
|
||||
|
||||
func createInterfaces(netCfg *NetworkConfig) {
|
||||
@@ -168,36 +168,48 @@ func ApplyNetworkConfigs(netCfg *NetworkConfig) error {
|
||||
return err
|
||||
}
|
||||
|
||||
dhcpLinks := map[string]string{}
|
||||
|
||||
//apply network config
|
||||
for _, link := range links {
|
||||
linkName := link.Attrs().Name
|
||||
if match, ok := findMatch(link, netCfg); ok {
|
||||
if match.DHCP {
|
||||
dhcpLinks[link.Attrs().Name] = match.DHCPArgs
|
||||
} else if err = applyInterfaceConfig(link, match); err != nil {
|
||||
if match, ok := findMatch(link, netCfg); ok && !match.DHCP {
|
||||
if err := applyInterfaceConfig(link, match); err != nil {
|
||||
log.Errorf("Failed to apply settings to %s : %v", linkName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runCmds(netCfg.PostCmds, "")
|
||||
return err
|
||||
}
|
||||
|
||||
func RunDhcp(netCfg *NetworkConfig, dhcpHostname bool) error {
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dhcpLinks := map[string]string{}
|
||||
for _, link := range links {
|
||||
if match, ok := findMatch(link, netCfg); ok && match.DHCP {
|
||||
dhcpLinks[link.Attrs().Name] = match.DHCPArgs
|
||||
}
|
||||
}
|
||||
|
||||
//run dhcp
|
||||
wg := sync.WaitGroup{}
|
||||
for iface, args := range dhcpLinks {
|
||||
wg.Add(1)
|
||||
go func(iface, args string) {
|
||||
runDhcp(netCfg, iface, args)
|
||||
runDhcp(netCfg, iface, args, dhcpHostname)
|
||||
wg.Done()
|
||||
}(iface, args)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
runCmds(netCfg.PostCmds, "")
|
||||
return err
|
||||
}
|
||||
|
||||
func runDhcp(netCfg *NetworkConfig, iface string, argstr string) {
|
||||
func runDhcp(netCfg *NetworkConfig, iface string, argstr string, dhcpHostname bool) {
|
||||
log.Infof("Running DHCP on %s", iface)
|
||||
args := []string{}
|
||||
if argstr != "" {
|
||||
@@ -215,6 +227,10 @@ func runDhcp(netCfg *NetworkConfig, iface string, argstr string) {
|
||||
args = append(args, "--nohook", "resolv.conf")
|
||||
}
|
||||
|
||||
if dhcpHostname {
|
||||
args = append(args, "-e", "force_hostname=true")
|
||||
}
|
||||
|
||||
args = append(args, iface)
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Stdout = os.Stdout
|
||||
|
Reference in New Issue
Block a user