Пример #1
0
func (c *controller) LeaveAll(id string) error {
	c.Lock()
	sData, ok := c.sandboxes[sandbox.GenerateKey(id)]
	c.Unlock()

	if !ok {
		return fmt.Errorf("could not find sandbox for container id %s", id)
	}

	sData.Lock()
	eps := make([]*endpoint, len(sData.endpoints))
	for i, ep := range sData.endpoints {
		eps[i] = ep
	}
	sData.Unlock()

	for _, ep := range eps {
		if err := ep.Leave(id); err != nil {
			logrus.Warnf("Failed leaving endpoint id %s: %v\n", ep.ID(), err)
		}
	}

	sData.sandbox().Destroy()

	c.Lock()
	delete(c.sandboxes, sandbox.GenerateKey(id))
	c.Unlock()

	return nil
}
Пример #2
0
func TestSandboxAddEmpty(t *testing.T) {
	ctrlr := createEmptyCtrlr()
	ep := createEmptyEndpoint()

	if _, err := ctrlr.sandboxAdd(sandbox.GenerateKey("sandbox1"), true, ep); err != nil {
		t.Fatal(err)
	}

	ctrlr.sandboxRm(sandbox.GenerateKey("sandbox1"), ep)

	ctrlr.LeaveAll("sandbox1")
	if len(ctrlr.sandboxes) != 0 {
		t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
	}

	sandbox.GC()
}
Пример #3
0
func (n *network) initSandbox() error {
	n.Lock()
	n.initEpoch++
	n.Unlock()

	sbox, err := sandbox.NewSandbox(
		sandbox.GenerateKey(fmt.Sprintf("%d-", n.initEpoch)+string(n.id)), true)
	if err != nil {
		return fmt.Errorf("could not create network sandbox: %v", err)
	}

	// Add a bridge inside the namespace
	if err := sbox.AddInterface("bridge1", "br",
		sbox.InterfaceOptions().Address(bridgeIP),
		sbox.InterfaceOptions().Bridge(true)); err != nil {
		return fmt.Errorf("could not create bridge inside the network sandbox: %v", err)
	}

	vxlanName, err := createVxlan(n.vxlanID())
	if err != nil {
		return err
	}

	if err := sbox.AddInterface(vxlanName, "vxlan",
		sbox.InterfaceOptions().Master("bridge1")); err != nil {
		return fmt.Errorf("could not add vxlan interface inside the network sandbox: %v",
			err)
	}

	n.vxlanName = vxlanName

	n.setSandbox(sbox)

	n.driver.peerDbUpdateSandbox(n.id)

	var nlSock *nl.NetlinkSocket
	sbox.InvokeFunc(func() {
		nlSock, err = nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH)
		if err != nil {
			err = fmt.Errorf("failed to subscribe to neighbor group netlink messages")
		}
	})

	go n.watchMiss(nlSock)

	return nil
}
Пример #4
0
func TestSandboxAddSamePrio(t *testing.T) {
	ctrlr := createEmptyCtrlr()
	ep1 := createEmptyEndpoint()
	ep2 := createEmptyEndpoint()

	ep1.network = &network{name: "aaa"}
	ep2.network = &network{name: "bbb"}

	sKey := sandbox.GenerateKey("sandbox1")

	if _, err := ctrlr.sandboxAdd(sKey, true, ep1); err != nil {
		t.Fatal(err)
	}

	if _, err := ctrlr.sandboxAdd(sKey, true, ep2); err != nil {
		t.Fatal(err)
	}

	if ctrlr.sandboxes[sKey].endpoints[0] != ep1 {
		t.Fatal("Expected ep1 to be at the top of the heap. But did not find ep1 at the top of the heap")
	}

	ctrlr.sandboxRm(sKey, ep1)

	if ctrlr.sandboxes[sKey].endpoints[0] != ep2 {
		t.Fatal("Expected ep2 to be at the top of the heap after removing ep3. But did not find ep2 at the top of the heap")
	}

	ctrlr.sandboxRm(sKey, ep2)

	if err := ctrlr.LeaveAll("sandbox1"); err != nil {
		t.Fatal(err)
	}

	if len(ctrlr.sandboxes) != 0 {
		t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
	}

	sandbox.GC()
}
Пример #5
0
func (ep *endpoint) Join(containerID string, options ...EndpointOption) error {
	var err error

	if containerID == "" {
		return InvalidContainerIDError(containerID)
	}

	ep.joinLeaveStart()
	defer func() {
		ep.joinLeaveEnd()
	}()

	ep.Lock()
	if ep.container != nil {
		ep.Unlock()
		return ErrInvalidJoin{}
	}

	ep.container = &containerInfo{
		id: containerID,
		config: containerConfig{
			hostsPathConfig: hostsPathConfig{
				extraHosts:    []extraHost{},
				parentUpdates: []parentUpdate{},
			},
		}}

	ep.joinInfo = &endpointJoinInfo{}

	container := ep.container
	network := ep.network
	epid := ep.id

	ep.Unlock()
	defer func() {
		if err != nil {
			ep.Lock()
			ep.container = nil
			ep.Unlock()
		}
	}()

	network.Lock()
	driver := network.driver
	nid := network.id
	ctrlr := network.ctrlr
	network.Unlock()

	ep.processOptions(options...)

	sboxKey := sandbox.GenerateKey(containerID)
	if container.config.useDefaultSandBox {
		sboxKey = sandbox.GenerateKey("default")
	}

	err = driver.Join(nid, epid, sboxKey, ep, container.config.generic)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			if err = driver.Leave(nid, epid); err != nil {
				log.Warnf("driver leave failed while rolling back join: %v", err)
			}
		}
	}()

	err = ep.buildHostsFiles()
	if err != nil {
		return err
	}

	err = ep.updateParentHosts()
	if err != nil {
		return err
	}

	err = ep.setupDNS()
	if err != nil {
		return err
	}

	sb, err := ctrlr.sandboxAdd(sboxKey, !container.config.useDefaultSandBox, ep)
	if err != nil {
		return fmt.Errorf("failed sandbox add: %v", err)
	}
	defer func() {
		if err != nil {
			ctrlr.sandboxRm(sboxKey, ep)
		}
	}()

	if err := network.ctrlr.updateEndpointToStore(ep); err != nil {
		return err
	}

	container.data.SandboxKey = sb.Key()
	return nil
}
Пример #6
0
func (ep *endpoint) Join(containerID string, options ...EndpointOption) (*ContainerData, error) {
	var err error

	if containerID == "" {
		return nil, InvalidContainerIDError(containerID)
	}

	ep.joinLeaveStart()
	defer ep.joinLeaveEnd()

	ep.Lock()
	if ep.container != nil {
		ep.Unlock()
		return nil, ErrInvalidJoin{}
	}

	ep.container = &containerInfo{
		id: containerID,
		config: containerConfig{
			hostsPathConfig: hostsPathConfig{
				extraHosts:    []extraHost{},
				parentUpdates: []parentUpdate{},
			},
		}}

	ep.joinInfo = &endpointJoinInfo{}

	container := ep.container
	network := ep.network
	epid := ep.id
	joinInfo := ep.joinInfo
	ifaces := ep.iFaces

	ep.Unlock()
	defer func() {
		ep.Lock()
		if err != nil {
			ep.container = nil
		}
		ep.Unlock()
	}()

	network.Lock()
	driver := network.driver
	nid := network.id
	ctrlr := network.ctrlr
	network.Unlock()

	ep.processOptions(options...)

	sboxKey := sandbox.GenerateKey(containerID)
	if container.config.useDefaultSandBox {
		sboxKey = sandbox.GenerateKey("default")
	}

	err = driver.Join(nid, epid, sboxKey, ep, container.config.generic)
	if err != nil {
		return nil, err
	}

	err = ep.buildHostsFiles()
	if err != nil {
		return nil, err
	}

	err = ep.updateParentHosts()
	if err != nil {
		return nil, err
	}

	err = ep.setupDNS()
	if err != nil {
		return nil, err
	}

	sb, err := ctrlr.sandboxAdd(sboxKey, !container.config.useDefaultSandBox)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			ctrlr.sandboxRm(sboxKey)
		}
	}()

	for _, i := range ifaces {
		iface := &sandbox.Interface{
			SrcName: i.srcName,
			DstName: i.dstPrefix,
			Address: &i.addr,
		}
		if i.addrv6.IP.To16() != nil {
			iface.AddressIPv6 = &i.addrv6
		}
		err = sb.AddInterface(iface)
		if err != nil {
			return nil, err
		}
	}

	err = sb.SetGateway(joinInfo.gw)
	if err != nil {
		return nil, err
	}

	err = sb.SetGatewayIPv6(joinInfo.gw6)
	if err != nil {
		return nil, err
	}

	container.data.SandboxKey = sb.Key()
	cData := container.data

	return &cData, nil
}
Пример #7
0
func TestSandboxAddMultiPrio(t *testing.T) {
	ctrlr := createEmptyCtrlr()
	ep1 := createEmptyEndpoint()
	ep2 := createEmptyEndpoint()
	ep3 := createEmptyEndpoint()

	ep1.container.config.prio = 1
	ep2.container.config.prio = 2
	ep3.container.config.prio = 3

	sKey := sandbox.GenerateKey("sandbox1")

	if _, err := ctrlr.sandboxAdd(sKey, true, ep1); err != nil {
		t.Fatal(err)
	}

	if _, err := ctrlr.sandboxAdd(sKey, true, ep2); err != nil {
		t.Fatal(err)
	}

	if _, err := ctrlr.sandboxAdd(sKey, true, ep3); err != nil {
		t.Fatal(err)
	}

	if ctrlr.sandboxes[sKey].endpoints[0] != ep3 {
		t.Fatal("Expected ep3 to be at the top of the heap. But did not find ep3 at the top of the heap")
	}

	ctrlr.sandboxRm(sKey, ep3)

	if ctrlr.sandboxes[sKey].endpoints[0] != ep2 {
		t.Fatal("Expected ep2 to be at the top of the heap after removing ep3. But did not find ep2 at the top of the heap")
	}

	ctrlr.sandboxRm(sKey, ep2)

	if ctrlr.sandboxes[sKey].endpoints[0] != ep1 {
		t.Fatal("Expected ep1 to be at the top of the heap after removing ep2. But did not find ep1 at the top of the heap")
	}

	// Re-add ep3 back
	if _, err := ctrlr.sandboxAdd(sKey, true, ep3); err != nil {
		t.Fatal(err)
	}

	if ctrlr.sandboxes[sKey].endpoints[0] != ep3 {
		t.Fatal("Expected ep3 to be at the top of the heap after adding ep3 back. But did not find ep3 at the top of the heap")
	}

	ctrlr.sandboxRm(sKey, ep3)
	ctrlr.sandboxRm(sKey, ep1)

	if err := ctrlr.LeaveAll("sandbox1"); err != nil {
		t.Fatal(err)
	}

	if len(ctrlr.sandboxes) != 0 {
		t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
	}

	sandbox.GC()
}