func (d *Deletor) Delete( interfaceName string, containerNSPath string, sandboxName string, vxlanDeviceName string, ) error { containerNS, err := d.NamespaceOpener.OpenPath(containerNSPath) if err != nil { return fmt.Errorf("open container netns: %s", err) } err = d.Executor.Execute( commands.All( commands.InNamespace{ Namespace: containerNS, Command: commands.DeleteLink{ LinkName: interfaceName, }, }, commands.CleanupSandbox{ SandboxName: sandboxName, VxlanDeviceName: vxlanDeviceName, }, ), ) if err != nil { return err } return nil }
func (b *CommandBuilder) IdempotentlySetupBridge( vxlanName, sandboxLinkName, bridgeName string, sandboxNS namespace.Namespace, ipamResult *types.Result, ) executor.Command { return commands.InNamespace{ Namespace: sandboxNS, Command: commands.All( commands.SetLinkUp{ LinkName: sandboxLinkName, }, commands.Unless{ Condition: conditions.LinkExists{ Name: bridgeName, }, Command: commands.All( commands.CreateBridge{ Name: bridgeName, }, commands.AddAddress{ InterfaceName: bridgeName, Address: net.IPNet{ IP: ipamResult.IP4.Gateway, Mask: ipamResult.IP4.IP.Mask, }, }, commands.SetLinkUp{ LinkName: bridgeName, }, commands.SetLinkMaster{ Master: bridgeName, Slave: commands.DNS_INTERFACE_NAME, }, ), }, commands.SetLinkMaster{ Master: bridgeName, Slave: vxlanName, }, commands.SetLinkMaster{ Master: bridgeName, Slave: sandboxLinkName, }, ), } }
func (b *CommandBuilder) AddRoutes(interfaceName string, ipConfig *types.IPConfig) executor.Command { var routeCommands []executor.Command for _, route := range ipConfig.Routes { routeCommand := commands.AddRoute{ Interface: interfaceName, Destination: route.Dst, Gateway: route.GW, } if routeCommand.Gateway == nil { routeCommand.Gateway = ipConfig.Gateway } routeCommands = append(routeCommands, routeCommand) } return commands.All(routeCommands...) }
func (b *CommandBuilder) IdempotentlyCreateVxlan( vxlanName string, sandboxName string, sandboxNS namespace.Namespace, ) executor.Command { return commands.All( commands.InNamespace{ Namespace: sandboxNS, Command: commands.SetLinkUp{ LinkName: vxlanName, }, }, commands.StartMonitor{ HostNamespace: b.HostNamespace, Watcher: b.MissWatcher, SandboxName: sandboxName, VxlanLinkName: vxlanName, }, ) }
func (b *CommandBuilder) IdempotentlyCreateSandbox(sandboxName, vxlanName string, vni int, dnsAddress string) executor.Command { return commands.Unless{ Condition: conditions.SandboxExists{ Name: sandboxName, }, Command: commands.All( commands.CreateSandbox{ Name: sandboxName, }, commands.CreateVxlan{ Name: vxlanName, VNI: vni, }, commands.MoveLink{ Name: vxlanName, SandboxName: sandboxName, }, commands.StartDNSServer{ SandboxName: sandboxName, ListenAddress: dnsAddress, }, ), } }
}) }) It("should construct the correct command sequence", func() { err := deletor.Delete("some-interface-name", "/path/to/container/namespace", "sandbox-name", "some-vxlan") Expect(err).NotTo(HaveOccurred()) Expect(executor.ExecuteCallCount()).To(Equal(1)) Expect(executor.ExecuteArgsForCall(0)).To(Equal( commands.All( commands.InNamespace{ Namespace: containerNS, Command: commands.DeleteLink{ LinkName: "some-interface-name", }, }, commands.CleanupSandbox{ SandboxName: "sandbox-name", VxlanDeviceName: "some-vxlan", }, ), )) }) Context("when executing fails", func() { BeforeEach(func() { executor.ExecuteReturns(errors.New("boom")) }) It("should return the error", func() {
func (c *Creator) Setup(config CreatorConfig) (models.Container, error) { vxlanName := fmt.Sprintf("vxlan%d", config.VNI) sandboxName := fmt.Sprintf("vni-%d", config.VNI) bridgeName := fmt.Sprintf("vxlanbr%d", config.VNI) containerNS, err := c.NamespaceOpener.OpenPath(config.ContainerNsPath) if err != nil { return models.Container{}, fmt.Errorf("open container netns: %s", err) } sandboxLinkName := NameSandboxLink(config.ContainerID) var routeCommands = c.CommandBuilder.AddRoutes(config.InterfaceName, config.IPAMResult.IP4) err = c.Executor.Execute(c.CommandBuilder.IdempotentlyCreateSandbox(sandboxName, vxlanName, config.VNI, c.DNSAddress)) if err != nil { return models.Container{}, fmt.Errorf("executing command: create sandbox: %s", err) } sandbox, err := c.SandboxRepo.Get(sandboxName) if err != nil { return models.Container{}, fmt.Errorf("get sandbox: %s", err) } sandbox.Lock() defer sandbox.Unlock() sandboxNS := sandbox.Namespace() err = c.Executor.Execute( commands.All( c.CommandBuilder.IdempotentlyCreateVxlan(vxlanName, sandboxName, sandboxNS), c.CommandBuilder.SetupVeth(containerNS, sandboxLinkName, config.InterfaceName, config.IPAMResult.IP4.IP, sandboxName, routeCommands), c.CommandBuilder.IdempotentlySetupBridge(vxlanName, sandboxLinkName, bridgeName, sandboxNS, config.IPAMResult), ), ) if err != nil { return models.Container{}, err } getHardwareAddressCommand := &commands.GetHardwareAddress{ LinkName: config.InterfaceName, } command := commands.InNamespace{ Namespace: containerNS, Command: getHardwareAddressCommand, } err = c.Executor.Execute(command) if err != nil { return models.Container{}, err } return models.Container{ ID: config.ContainerID, MAC: getHardwareAddressCommand.Result.String(), IP: config.IPAMResult.IP4.IP.IP.String(), NetworkID: config.NetworkID, HostIP: c.HostIP.String(), SandboxName: sandboxName, App: config.App, }, nil }
command3 *fakes.Command all executor.Command ) BeforeEach(func() { context = &fakes.Context{} command1 = &fakes.Command{} command2 = &fakes.Command{} command3 = &fakes.Command{} command1.StringReturns("some-command 1") command2.StringReturns("some-command 2") command3.StringReturns("some-command 3") all = commands.All(command1, command2, command3) }) Describe("Execute", func() { It("creates a command wrapper that executes all commands", func() { err := all.Execute(context) Expect(err).NotTo(HaveOccurred()) Expect(command1.ExecuteCallCount()).To(Equal(1)) Expect(command1.ExecuteArgsForCall(0)).To(Equal(context)) Expect(command2.ExecuteCallCount()).To(Equal(1)) Expect(command2.ExecuteArgsForCall(0)).To(Equal(context)) Expect(command3.ExecuteCallCount()).To(Equal(1)) Expect(command3.ExecuteArgsForCall(0)).To(Equal(context))
cmd := b.IdempotentlyCreateSandbox("some-sandbox-name", "some-vxlan-name", 99, "some-dns-address") Expect(cmd).To(Equal( commands.Unless{ Condition: conditions.SandboxExists{ Name: "some-sandbox-name", }, Command: commands.All( commands.CreateSandbox{ Name: "some-sandbox-name", }, commands.CreateVxlan{ Name: "some-vxlan-name", VNI: 99, }, commands.MoveLink{ Name: "some-vxlan-name", SandboxName: "some-sandbox-name", }, commands.StartDNSServer{ SandboxName: "some-sandbox-name", ListenAddress: "some-dns-address", }, ), })) }) }) Describe("IdempotentlyCreateVxlan", func() { var sandboxNS *fakes.Namespace