Skip to content
Permalink
Browse files

allow enabling of ipv6 through env.bosh.ipv6.enable=true

Signed-off-by: dmitriy kalinin <dkalinin@pivotal.io>
  • Loading branch information...
cunnie committed May 12, 2017
1 parent c35146e commit 0962dce7801616f89ba2cd559e97b532379ba594
@@ -81,6 +81,10 @@ func (boot bootstrap) Run() (err error) {
return bosherr.WrapError(err, "Settings user password")
}

if err = boot.platform.SetupIPv6(settings.Env.Bosh.IPv6); err != nil {
return bosherr.WrapError(err, "Setting up IPv6")
}

if err = boot.platform.SetupHostname(settings.AgentID); err != nil {
return bosherr.WrapError(err, "Setting up hostname")
}
@@ -152,6 +152,14 @@ func init() {
})
})

It("sets up ipv6", func() {
settingsService.Settings.Env.Bosh.IPv6.Enable = true

err := bootstrap()
Expect(err).NotTo(HaveOccurred())
Expect(platform.SetupIPv6Config).To(Equal(boshsettings.IPv6{Enable: true}))
})

It("sets up hostname", func() {
settingsService.Settings.AgentID = "foo-bar-baz-123"

@@ -147,6 +147,10 @@ func (p dummyPlatform) SaveDNSRecords(dnsRecords boshsettings.DNSRecords, hostna
return p.fs.WriteFileString(etcHostsPath, dnsRecordsContents.String())
}

func (p dummyPlatform) SetupIPv6(config boshsettings.IPv6) error {
return nil
}

func (p dummyPlatform) SetupHostname(hostname string) (err error) {
return
}
@@ -48,6 +48,9 @@ type FakePlatform struct {
UserPasswords map[string]string
SetupHostnameHostname string

SetupIPv6Config boshsettings.IPv6
SetupIPv6Error error

SaveDNSRecordsError error
SaveDNSRecordsHostname string
SaveDNSRecordsDNSRecords boshsettings.DNSRecords
@@ -276,6 +279,11 @@ func (p *FakePlatform) SaveDNSRecords(dnsRecords boshsettings.DNSRecords, hostna
return p.SaveDNSRecordsError
}

func (p *FakePlatform) SetupIPv6(config boshsettings.IPv6) error {
p.SetupIPv6Config = config
return p.SetupIPv6Error
}

func (p *FakePlatform) SetupHostname(hostname string) (err error) {
p.SetupHostnameHostname = hostname
return
@@ -465,6 +465,10 @@ func (p linux) SaveDNSRecords(dnsRecords boshsettings.DNSRecords, hostname strin
return nil
}

func (p linux) SetupIPv6(config boshsettings.IPv6) error {
return p.netManager.SetupIPv6(config, nil)
}

func (p linux) SetupHostname(hostname string) error {
if !p.state.Linux.HostsConfigured {
_, _, _, err := p.cmdRunner.RunCommand("hostname", hostname)
@@ -2993,6 +2993,19 @@ unit: sectors
})
})

Describe("SetupIPv6", func() {
It("delegates to the NetManager", func() {
netManager.SetupIPv6Err = errors.New("fake-err")

err := platform.SetupIPv6(boshsettings.IPv6{Enable: true})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))

Expect(netManager.SetupIPv6Config).To(Equal(boshsettings.IPv6{Enable: true}))
Expect(netManager.SetupIPv6StopCh).To(BeNil())
})
})

Describe("SetupNetworking", func() {
It("delegates to the NetManager", func() {
networks := boshsettings.Networks{}
@@ -50,6 +50,8 @@ func NewCentosNetManager(
}
}

func (net centosNetManager) SetupIPv6(_ boshsettings.IPv6, _ <-chan struct{}) error { return nil }

func (net centosNetManager) SetupNetworking(networks boshsettings.Networks, errCh chan error) error {
nonVipNetworks := boshsettings.Networks{}
for networkName, networkSettings := range networks {
@@ -10,13 +10,23 @@ type FakeManager struct {
SetupNetworkingNetworks boshsettings.Networks
SetupNetworkingErr error

SetupIPv6Config boshsettings.IPv6
SetupIPv6StopCh <-chan struct{}
SetupIPv6Err error

GetConfiguredNetworkInterfacesInterfaces []string
GetConfiguredNetworkInterfacesErr error

SetupDhcpNetworks boshsettings.Networks
SetupDhcpErr error
}

func (net *FakeManager) SetupIPv6(config boshsettings.IPv6, stopCh <-chan struct{}) error {
net.SetupIPv6Config = config
net.SetupIPv6StopCh = stopCh
return net.SetupIPv6Err
}

func (net *FakeManager) SetupNetworking(networks boshsettings.Networks, errCh chan error) error {
net.SetupNetworkingNetworks = networks
return net.SetupNetworkingErr
@@ -12,4 +12,6 @@ type Manager interface {

// Returns the list of interfaces that have configurations for them present
GetConfiguredNetworkInterfaces() ([]string, error)

SetupIPv6(boshsettings.IPv6, <-chan struct{}) error
}
@@ -85,6 +85,59 @@ func (net UbuntuNetManager) ComputeNetworkConfig(networks boshsettings.Networks)
return staticConfigs, dhcpConfigs, dnsServers, nil
}

func (net UbuntuNetManager) SetupIPv6(config boshsettings.IPv6, stopCh <-chan struct{}) error {
const (
grubConfPath = "/boot/grub/grub.conf"
grubIPv6DisableOpt = "ipv6.disable=1"
)

if !config.Enable {
return nil
}

grubConf, err := net.fs.ReadFileString(grubConfPath)
if err != nil {
return bosherr.WrapError(err, "Reading grub")
}

if strings.Contains(grubConf, grubIPv6DisableOpt) {
grubConf = strings.Replace(grubConf, grubIPv6DisableOpt, "", -1)

err = net.fs.WriteFileString(grubConfPath, grubConf)
if err != nil {
return bosherr.WrapError(err, "Writing grub.conf")
}

net.logger.Info(UbuntuNetManagerLogTag, "Rebooting to enable IPv6 in kernel")

_, _, _, err = net.cmdRunner.RunCommand("shutdown", "-r", "now")
if err != nil {
return bosherr.WrapError(err, "Rebooting for IPv6")
}

// Wait here for the OS to reboot the machine
<-stopCh

return nil
}

ipv6Sysctls := []string{
"net.ipv6.conf.all.accept_ra=1",
"net.ipv6.conf.default.accept_ra=1",
"net.ipv6.conf.all.disable_ipv6=0",
"net.ipv6.conf.default.disable_ipv6=0",
}

for _, sysctl := range ipv6Sysctls {
_, _, _, err := net.cmdRunner.RunCommand("sysctl", sysctl)
if err != nil {
return bosherr.WrapError(err, "Running IPv6 sysctl")
}
}

return nil
}

func (net UbuntuNetManager) SetupNetworking(networks boshsettings.Networks, errCh chan error) error {
if networks.IsPreconfigured() {
// Note in this case IPs are not broadcasted
@@ -914,4 +914,139 @@ iface ethstatic inet static
})
})
})

Describe("SetupIPv6", func() {
var (
config boshsettings.IPv6
stopCh chan struct{}
)

BeforeEach(func() {
config = boshsettings.IPv6{}
stopCh = make(chan struct{}, 1)
})

act := func() error { return netManager.SetupIPv6(config, stopCh) }

Context("when grub.conf disables IPv6", func() {
BeforeEach(func() {
err := fs.WriteFileString("/boot/grub/grub.conf", "before ipv6.disable=1 after")
Expect(err).ToNot(HaveOccurred())
})

Context("when IPv6 is enabled by the user", func() {
BeforeEach(func() {
config.Enable = true
})

It("removes ipv6.disable=1 from grub.conf", func() {
stopCh <- struct{}{}
Expect(act()).ToNot(HaveOccurred())
Expect(fs.ReadFileString("/boot/grub/grub.conf")).To(Equal("before after"))
})

It("reboots after changing grub.conf and continue waiting until reboot event succeeds", func() {
stopCh <- struct{}{}
Expect(act()).ToNot(HaveOccurred())
Expect(cmdRunner.RunCommands).To(Equal([][]string{{"shutdown", "-r", "now"}}))
})

It("returns an error if it fails to read grub.conf", func() {
fs.ReadFileError = errors.New("fake-err")

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})

It("returns an error if update to grub.conf fails", func() {
fs.WriteFileError = errors.New("fake-err")

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})

It("returns an error if shutdown fails", func() {
cmdRunner.AddCmdResult("shutdown -r now", fakesys.FakeCmdResult{
Error: errors.New("fake-err"),
})

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})
})

Context("when IPv6 is NOT enabled by the user", func() {
BeforeEach(func() {
config.Enable = false
})

It("does not change grub.conf", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(fs.ReadFileString("/boot/grub/grub.conf")).To(Equal("before ipv6.disable=1 after"))
})

It("does not reboot and does not set sysctl", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(cmdRunner.RunCommands).To(BeEmpty())
})
})
})

Context("when grub.conf allows IPv6", func() {
BeforeEach(func() {
err := fs.WriteFileString("/boot/grub/grub.conf", "before after")
Expect(err).ToNot(HaveOccurred())
})

Context("when IPv6 is enabled by the user", func() {
BeforeEach(func() {
config.Enable = true
})

It("does not change grub.conf", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(fs.ReadFileString("/boot/grub/grub.conf")).To(Equal("before after"))
})

It("does not reboot but sets IPv6 sysctl", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(cmdRunner.RunCommands).To(Equal([][]string{
{"sysctl", "net.ipv6.conf.all.accept_ra=1"},
{"sysctl", "net.ipv6.conf.default.accept_ra=1"},
{"sysctl", "net.ipv6.conf.all.disable_ipv6=0"},
{"sysctl", "net.ipv6.conf.default.disable_ipv6=0"},
}))
})

It("fails if the underlying sysctl fails", func() {
cmdRunner.AddCmdResult("sysctl net.ipv6.conf.all.accept_ra=1", fakesys.FakeCmdResult{
Error: errors.New("fake-err"),
})

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})
})

Context("when IPv6 is NOT enabled by the user", func() {
BeforeEach(func() {
config.Enable = false
})

It("does not change grub.conf", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(fs.ReadFileString("/boot/grub/grub.conf")).To(Equal("before after"))
})

It("does not reboot and does not set sysctl", func() {
Expect(act()).ToNot(HaveOccurred())
Expect(cmdRunner.RunCommands).To(BeEmpty())
})
})
})
})
}
@@ -119,6 +119,8 @@ func (net WindowsNetManager) ComputeNetworkConfig(networks boshsettings.Networks

}

func (net WindowsNetManager) SetupIPv6(_ boshsettings.IPv6, _ <-chan struct{}) error { return nil }

func (net WindowsNetManager) SetupNetworking(networks boshsettings.Networks, errCh chan error) error {
nonVipNetworks := boshsettings.Networks{}
for networkName, networkSettings := range networks {
@@ -43,6 +43,7 @@ type Platform interface {
SetupRootDisk(ephemeralDiskPath string) (err error)
SetupSSH(publicKey []string, username string) (err error)
SetUserPassword(user, encryptedPwd string) (err error)
SetupIPv6(boshsettings.IPv6) error
SetupHostname(hostname string) (err error)
SetupNetworking(networks boshsettings.Networks) (err error)
SetupLogrotate(groupName, basePath, size string) (err error)
@@ -171,6 +171,10 @@ func (p WindowsPlatform) SaveDNSRecords(dnsRecords boshsettings.DNSRecords, host
return
}

func (p WindowsPlatform) SetupIPv6(config boshsettings.IPv6) error {
return nil
}

func (p WindowsPlatform) SetupHostname(hostname string) (err error) {
return
}
@@ -202,13 +202,19 @@ type BoshEnv struct {
Mbus struct {
Cert CertKeyPair `json:"cert"`
} `json:"mbus"`

IPv6 IPv6 `json:"ipv6"`
}

type CertKeyPair struct {
PrivateKey string `json:"private_key"`
Certificate string `json:"certificate"`
}

type IPv6 struct {
Enable bool `json:"enable"`
}

type DNSRecords struct {
Version uint64 `json:"Version"`
Records [][2]string `json:"records"`
Oops, something went wrong.

0 comments on commit 0962dce

Please sign in to comment.
You can’t perform that action at this time.