1
0
mirror of https://github.com/rancher/os.git synced 2025-07-16 16:11:03 +00:00

Use the partial cfg for the initial network

and release the network device from dhcp if we're not using it

Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
This commit is contained in:
Sven Dowideit 2017-03-21 10:26:52 +00:00
parent 77759afcaa
commit 59a752c306
8 changed files with 207 additions and 73 deletions

View File

@ -26,7 +26,6 @@ import (
yaml "github.com/cloudfoundry-incubator/candiedyaml" yaml "github.com/cloudfoundry-incubator/candiedyaml"
"github.com/rancher/os/cmd/control"
"github.com/rancher/os/cmd/network" "github.com/rancher/os/cmd/network"
rancherConfig "github.com/rancher/os/config" rancherConfig "github.com/rancher/os/config"
"github.com/rancher/os/config/cloudinit/config" "github.com/rancher/os/config/cloudinit/config"
@ -55,26 +54,17 @@ func Main() {
log.InitLogger() log.InitLogger()
log.Info("Running cloud-init-save") log.Info("Running cloud-init-save")
if err := control.UdevSettle(); err != nil {
log.Errorf("Failed to run udev settle: %v", err)
}
cfg := rancherConfig.LoadConfig()
network.ApplyNetworkConfig(cfg)
if err := SaveCloudConfig(); err != nil { if err := SaveCloudConfig(); err != nil {
log.Errorf("Failed to save cloud-config: %v", err) log.Errorf("Failed to save cloud-config: %v", err)
} }
// Apply any newly detected network config.
//consider putting this in a separate init phase...
cfg = rancherConfig.LoadConfig()
network.ApplyNetworkConfig(cfg)
} }
func SaveCloudConfig() error { func SaveCloudConfig() error {
log.Debugf("SaveCloudConfig") log.Debugf("SaveCloudConfig")
cfg := rancherConfig.LoadConfig() cfg := rancherConfig.LoadConfig()
log.Debugf("init: SaveCloudConfig(pre ApplyNetworkConfig): %#v", cfg.Rancher.Network)
network.ApplyNetworkConfig(cfg)
dss := getDatasources(cfg) dss := getDatasources(cfg)
if len(dss) == 0 { if len(dss) == 0 {
@ -83,6 +73,12 @@ func SaveCloudConfig() error {
} }
selectDatasource(dss) selectDatasource(dss)
// Apply any newly detected network config.
cfg = rancherConfig.LoadConfig()
log.Debugf("init: SaveCloudConfig(post ApplyNetworkConfig): %#v", cfg.Rancher.Network)
network.ApplyNetworkConfig(cfg)
return nil return nil
} }

View File

@ -354,7 +354,7 @@ func mountBootIso() error {
os.MkdirAll("/bootiso", 0755) os.MkdirAll("/bootiso", 0755)
cmd := exec.Command("mount", "-t", deviceType, deviceName, "/bootiso") cmd := exec.Command("mount", "-t", deviceType, deviceName, "/bootiso")
log.Infof("mount (%#v)", cmd) log.Debugf("mount (%#v)", cmd)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
err = cmd.Run() err = cmd.Run()

View File

@ -11,7 +11,6 @@ import (
func Main() { func Main() {
log.InitLogger() log.InitLogger()
log.Infof("Running network")
cfg := config.LoadConfig() cfg := config.LoadConfig()
ApplyNetworkConfig(cfg) ApplyNetworkConfig(cfg)
@ -20,6 +19,7 @@ func Main() {
} }
func ApplyNetworkConfig(cfg *config.CloudConfig) { func ApplyNetworkConfig(cfg *config.CloudConfig) {
log.Infof("Apply Network Config")
nameservers := cfg.Rancher.Network.DNS.Nameservers nameservers := cfg.Rancher.Network.DNS.Nameservers
search := cfg.Rancher.Network.DNS.Search search := cfg.Rancher.Network.DNS.Search
userSetDNS := len(nameservers) > 0 || len(search) > 0 userSetDNS := len(nameservers) > 0 || len(search) > 0

View File

@ -13,6 +13,8 @@ import (
"syscall" "syscall"
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
"github.com/rancher/os/cmd/control"
//networkCmd "github.com/rancher/os/cmd/network"
"github.com/rancher/os/config" "github.com/rancher/os/config"
"github.com/rancher/os/dfs" "github.com/rancher/os/dfs"
"github.com/rancher/os/log" "github.com/rancher/os/log"
@ -302,6 +304,11 @@ func RunInit() error {
log.Error(err) log.Error(err)
} }
if err := control.UdevSettle(); err != nil {
log.Errorf("Failed to run udev settle: %v", err)
}
log.Debug("init: runCloudInitServices()")
if err := runCloudInitServices(cfg); err != nil { if err := runCloudInitServices(cfg); err != nil {
log.Error(err) log.Error(err)
} }

View File

@ -193,21 +193,21 @@ func RunDhcp(netCfg *NetworkConfig, setHostname, setDNS bool) error {
return err 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{} wg := sync.WaitGroup{}
for iface, args := range dhcpLinks {
for _, link := range links {
name := link.Attrs().Name
args := ""
if match, ok := findMatch(link, netCfg); ok && match.DHCP {
args = match.DHCPArgs
} else {
args = "dhcpd --release"
}
wg.Add(1) wg.Add(1)
go func(iface, args string) { go func(iface, args string) {
runDhcp(netCfg, iface, args, setHostname, setDNS) runDhcp(netCfg, iface, args, setHostname, setDNS)
wg.Done() wg.Done()
}(iface, args) }(name, args)
} }
wg.Wait() wg.Wait()
@ -215,7 +215,6 @@ func RunDhcp(netCfg *NetworkConfig, setHostname, setDNS bool) error {
} }
func runDhcp(netCfg *NetworkConfig, iface string, argstr string, setHostname, setDNS bool) { func runDhcp(netCfg *NetworkConfig, iface string, argstr string, setHostname, setDNS bool) {
log.Infof("Running DHCP on %s", iface)
args := []string{} args := []string{}
if argstr != "" { if argstr != "" {
var err error var err error
@ -238,6 +237,7 @@ func runDhcp(netCfg *NetworkConfig, iface string, argstr string, setHostname, se
args = append(args, iface) args = append(args, iface)
cmd := exec.Command(args[0], args[1:]...) cmd := exec.Command(args[0], args[1:]...)
log.Infof("Running DHCP on %s: %s", iface, strings.Join(args, " "))
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {

View File

@ -3,11 +3,13 @@ rancher:
network: network:
interfaces: interfaces:
eth0: eth0:
dhcp: true
eth1:
address: 10.1.0.41/24 address: 10.1.0.41/24
gateway: 10.1.0.1 gateway: 10.1.0.1
mtu: 1500 mtu: 1500
dhcp: false dhcp: false
eth1: eth2:
address: 10.31.168.85/24 address: 10.31.168.85/24
gateway: 10.31.168.1 gateway: 10.31.168.1
gateway_ipv6: "fe00:1234::" gateway_ipv6: "fe00:1234::"

View File

@ -4,7 +4,7 @@ import . "gopkg.in/check.v1"
func (s *QemuSuite) TestNetworkFromUrl(c *C) { func (s *QemuSuite) TestNetworkFromUrl(c *C) {
netArgs := []string{"-net", "nic,vlan=0,model=virtio"} netArgs := []string{"-net", "nic,vlan=0,model=virtio"}
args := []string{"--append", "rancher.cloud_init.datasources=[url:https://gist.githubusercontent.com/joshwget/0bdc616cd26162ad87c535644c8b1ef6/raw/8cce947c08cf006e932b71d92ddbb96bae8e3325/gistfile1.txt]"} args := []string{"--append", "rancher.debug=true rancher.password=test-me rancher.cloud_init.datasources=[url:https://gist.githubusercontent.com/joshwget/0bdc616cd26162ad87c535644c8b1ef6/raw/8cce947c08cf006e932b71d92ddbb96bae8e3325/gistfile1.txt]"}
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
args = append(args, netArgs...) args = append(args, netArgs...)
} }

View File

@ -36,6 +36,107 @@ SCRIPT
sudo bash test-merge`) sudo bash test-merge`)
} }
func (s *QemuSuite) TestNetworkBootCfg(c *C) {
args := []string{"--append", "rancher.network.interfaces.eth1.address=10.1.0.41/24 rancher.network.interfaces.eth1.gateway=10.1.0.1 rancher.network.interfaces.eth0.dhcp=true"}
args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...)
args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...)
args = append(args, []string{"-net", "nic,vlan=0,model=virtio"}...)
s.RunQemu(c, args...)
s.CheckOutput(c,
"1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1\n"+
" link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n"+
" inet 127.0.0.1/8 scope host lo\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 ::1/128 scope host \n"+
" valid_lft forever preferred_lft forever\n"+
"2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth0\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3456/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet 10.1.0.41/24 scope global eth1\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3457/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000\n"+
"5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000\n"+
"6: docker-sys: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000\n"+
" inet 172.18.42.2/16 scope global docker-sys\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 XX::XX:XX:XX:XX/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"8: docker0: XXXXXXX......\n"+
" inet 172.17.0.1/16 scope global docker0\n"+
" valid_lft forever preferred_lft forever\n",
Equals,
"ip a | "+
"grep -v ether | "+
"sed 's/inet 10\\.0\\.2\\..*\\/24 brd/inet XX.XX.XX.XX\\/24 brd/' | "+
"sed 's/8: docker0: .*/8: docker0: XXXXXXX....../g' | "+
"sed '/inet6 fe80::5054:ff:fe12:.*\\/64/!s/inet6 .*\\/64 scope/inet6 XX::XX:XX:XX:XX\\/64 scope/'",
// fe80::18b6:9ff:fef5:be33
)
}
func (s *QemuSuite) TestNetworkBootAndCloudCfg(c *C) {
args := []string{
"--append", "rancher.network.interfaces.eth1.address=10.1.0.52/24 rancher.network.interfaces.eth1.gateway=10.1.0.1 rancher.network.interfaces.eth0.dhcp=true rancher.network.interfaces.eth3.dhcp=true",
"--cloud-config", "./tests/assets/multi_nic/cloud-config.yml",
}
args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...)
args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...)
args = append(args, []string{"-net", "nic,vlan=0,model=virtio"}...)
s.RunQemu(c, args...)
s.CheckOutput(c,
"1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1\n"+
" link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n"+
" inet 127.0.0.1/8 scope host lo\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 ::1/128 scope host \n"+
" valid_lft forever preferred_lft forever\n"+
"2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth0\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3456/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
// This shows that the boot cmdline wins over the cloud-config
// But IIRC, the cloud-init metadata wins allowing you to use ip4ll to get the hoster's metadata
// Need a test for that (presumably once we have libmachine based tests)
" inet 10.1.0.52/24 scope global eth1\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3457/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet 10.31.168.85/24 scope global eth2\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3458/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
// TODO: I think it would be better if this was dhcp: false, but it could go either way
"5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth3\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3459/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"6: docker-sys: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000\n"+
" inet 172.18.42.2/16 scope global docker-sys\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 XX::XX:XX:XX:XX/64 scope link \n"+
" valid_lft forever preferred_lft forever\n"+
"8: docker0: XXXXXXX......\n"+
" inet 172.17.0.1/16 scope global docker0\n"+
" valid_lft forever preferred_lft forever\n",
Equals,
"ip a | "+
"grep -v ether | "+
"sed 's/inet 10\\.0\\.2\\..*\\/24 brd/inet XX.XX.XX.XX\\/24 brd/' | "+
"sed 's/8: docker0: .*/8: docker0: XXXXXXX....../g' | "+
"sed '/inet6 fe80::5054:ff:fe12:.*\\/64/!s/inet6 .*\\/64 scope/inet6 XX::XX:XX:XX:XX\\/64 scope/'",
// fe80::18b6:9ff:fef5:be33
)
}
func (s *QemuSuite) TestNetworkCfg(c *C) { func (s *QemuSuite) TestNetworkCfg(c *C) {
args := []string{"--cloud-config", "./tests/assets/multi_nic/cloud-config.yml"} args := []string{"--cloud-config", "./tests/assets/multi_nic/cloud-config.yml"}
args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...) args = append(args, []string{"-net", "nic,vlan=1,model=virtio"}...)
@ -48,50 +149,78 @@ func (s *QemuSuite) TestNetworkCfg(c *C) {
// valid_lft forever preferred_lft forever // valid_lft forever preferred_lft forever
// show ip a output without mac addresses // show ip a output without mac addresses
s.CheckOutput(c, `1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 s.CheckOutput(c,
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1\n"+
inet 127.0.0.1/8 scope host lo " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n"+
valid_lft forever preferred_lft forever " inet 127.0.0.1/8 scope host lo\n"+
inet6 ::1/128 scope host " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever " inet6 ::1/128 scope host \n"+
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 " valid_lft forever preferred_lft forever\n"+
inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth0 "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
valid_lft forever preferred_lft forever " inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth0\n"+
inet 10.1.0.41/24 scope global eth0 " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever " inet6 fe80::5054:ff:fe12:3456/64 scope link \n"+
inet6 XX::XX:XX:XX:XX/64 scope link " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever "3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 " inet 10.1.0.41/24 scope global eth1\n"+
inet 10.31.168.85/24 scope global eth1 " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever " inet6 fe80::5054:ff:fe12:3457/64 scope link \n"+
inet6 XX::XX:XX:XX:XX/64 scope link " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever "4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 " inet 10.31.168.85/24 scope global eth2\n"+
inet6 XX::XX:XX:XX:XX/64 scope link " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever " inet6 fe80::5054:ff:fe12:3458/64 scope link \n"+
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 " valid_lft forever preferred_lft forever\n"+
inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth3 // TODO: I think it would be better if this was dhcp: false, but it could go either way
valid_lft forever preferred_lft forever "5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
inet6 XX::XX:XX:XX:XX/64 scope link " inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth3\n"+
valid_lft forever preferred_lft forever " valid_lft forever preferred_lft forever\n"+
6: docker-sys: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 " inet6 fe80::5054:ff:fe12:3459/64 scope link \n"+
inet 172.18.42.2/16 scope global docker-sys " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever "6: docker-sys: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000\n"+
inet6 XX::XX:XX:XX:XX/64 scope link " inet 172.18.42.2/16 scope global docker-sys\n"+
valid_lft forever preferred_lft forever " valid_lft forever preferred_lft forever\n"+
8: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default " inet6 XX::XX:XX:XX:XX/64 scope link \n"+
inet 172.17.0.1/16 scope global docker0 " valid_lft forever preferred_lft forever\n"+
valid_lft forever preferred_lft forever "8: docker0: XXXXXXX......\n"+
`, Equals, "ip a | grep -v ether | sed 's/inet 10\\.0\\.2\\..*\\/24 brd/inet XX.XX.XX.XX\\/24 brd/' | sed 's/inet6 .*\\/64 scope/inet6 XX::XX:XX:XX:XX\\/64 scope/'") " inet 172.17.0.1/16 scope global docker0\n"+
" valid_lft forever preferred_lft forever\n",
Equals,
"ip a | "+
"grep -v ether | "+
"sed 's/inet 10\\.0\\.2\\..*\\/24 brd/inet XX.XX.XX.XX\\/24 brd/' | "+
"sed 's/8: docker0: .*/8: docker0: XXXXXXX....../g' | "+
"sed '/inet6 fe80::5054:ff:fe12:.*\\/64/!s/inet6 .*\\/64 scope/inet6 XX::XX:XX:XX:XX\\/64 scope/'",
// fe80::18b6:9ff:fef5:be33
)
s.CheckOutput(c, `Kernel IP routing table s.CheckOutput(c,
Destination Gateway Genmask Flags Metric Ref Use Iface "Kernel IP routing table\n"+
0.0.0.0 10.31.168.1 0.0.0.0 UG 0 0 0 eth1 "Destination Gateway Genmask Flags Metric Ref Use Iface\n"+
0.0.0.0 10.0.2.2 0.0.0.0 UG 205 0 0 eth3 "0.0.0.0 10.1.0.1 0.0.0.0 UG 0 0 0 eth1\n"+
10.0.2.0 0.0.0.0 255.255.255.0 U 205 0 0 eth3 "0.0.0.0 10.0.2.2 0.0.0.0 UG 202 0 0 eth0\n"+
10.1.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 "0.0.0.0 10.0.2.2 0.0.0.0 UG 205 0 0 eth3\n"+
10.31.168.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 "10.0.2.0 0.0.0.0 255.255.255.0 U 202 0 0 eth0\n"+
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 "10.0.2.0 0.0.0.0 255.255.255.0 U 205 0 0 eth3\n"+
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker-sys "10.1.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1\n"+
`, Equals, "route -n") "10.31.168.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2\n"+
"172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0\n"+
"172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker-sys\n",
Equals, "route -n")
s.CheckCall(c, "sudo ros config set rancher.network.interfaces.eth3.dhcp true")
//s.CheckCall(c, "sudo netconf")
s.Reboot(c)
s.CheckOutput(c,
"5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000\n"+
" inet XX.XX.XX.XX/24 brd 10.0.2.255 scope global eth3\n"+
" valid_lft forever preferred_lft forever\n"+
" inet6 fe80::5054:ff:fe12:3459/64 scope link \n"+
" valid_lft forever preferred_lft forever\n",
Equals,
"ip a show eth3 | "+
"grep -v ether | "+
"sed 's/inet 10\\.0\\.2\\..*\\/24 brd/inet XX.XX.XX.XX\\/24 brd/' | "+
"sed '/inet6 fe80::5054:ff:fe12:.*\\/64/!s/inet6 .*\\/64 scope/inet6 XX::XX:XX:XX:XX\\/64 scope/'",
)
} }