Example #1
0
func (handler *ScopesHandlersImpl) listScopes(idName string) ([]*models.ScopeConfig, error) {
	_scopes, err := handler.netCtx.Scopes(&idName)
	if err != nil {
		return nil, err
	}

	cfgs := make([]*models.ScopeConfig, len(_scopes))
	updated := make(map[uid.UID]*exec.Handle)
	for i, s := range _scopes {
		for _, e := range s.Endpoints() {
			// update the container config, if necessary
			// do not need do this for non-bridge scopes, since
			// IPAM is done by the port layer. For other
			// scopes types, like external, the network
			// may be using DHCP, in which case we need to
			// get the current IP address, and other network
			// info from the container VM.
			if s.Type() != network.BridgeScopeType {
				var h *exec.Handle
				c := e.Container().ID()
				if h = updated[c]; h == nil {
					h = exec.GetContainer(c)
					if _, err := h.Update(context.Background(), handler.handlerCtx.Session); err != nil {
						return nil, err
					}

					updated[c] = h
				}

				if err = handler.netCtx.UpdateContainer(h); err != nil {
					return nil, err
				}
			}
		}

		cfgs[i] = toScopeConfig(s)
	}

	for _, h := range updated {
		h.Close()
	}

	return cfgs, nil
}
Example #2
0
func (c *Context) RemoveContainer(h *exec.Handle, scope string) error {
	c.Lock()
	defer c.Unlock()

	if h == nil {
		return fmt.Errorf("handle is required")
	}

	if _, ok := c.containers[uid.Parse(h.ExecConfig.ID)]; ok {
		return fmt.Errorf("container is bound")
	}

	var err error
	s, err := c.resolveScope(scope)
	if err != nil {
		return err
	}

	var ne *executor.NetworkEndpoint
	ne, ok := h.ExecConfig.Networks[s.Name()]
	if !ok {
		return fmt.Errorf("container %s not part of network %s", h.ExecConfig.ID, s.Name())
	}

	// figure out if any other networks are using the NIC
	removeNIC := true
	for _, ne2 := range h.ExecConfig.Networks {
		if ne2 == ne {
			continue
		}
		if ne2.ID == ne.ID {
			removeNIC = false
			break
		}
	}

	if removeNIC {
		// ensure spec is not nil
		h.SetSpec(nil)

		var devices object.VirtualDeviceList
		backing, err := s.network.EthernetCardBackingInfo(context.Background())
		if err != nil {
			return err
		}

		d, err := devices.CreateEthernetCard("vmxnet3", backing)
		if err != nil {
			return err
		}

		devices = append(devices, d)
		spec, err := devices.ConfigSpec(types.VirtualDeviceConfigSpecOperationRemove)
		if err != nil {
			return err
		}
		h.Spec.DeviceChange = append(h.Spec.DeviceChange, spec...)
	}

	delete(h.ExecConfig.Networks, s.Name())

	return nil
}
Example #3
0
// AddContainer add a container to the specified scope, optionally specifying an ip address
// for the container in the scope
func (c *Context) AddContainer(h *exec.Handle, options *AddContainerOptions) error {
	c.Lock()
	defer c.Unlock()

	if h == nil {
		return fmt.Errorf("handle is required")
	}

	var err error
	s, err := c.resolveScope(options.Scope)
	if err != nil {
		return err
	}

	if h.ExecConfig.Networks != nil {
		if _, ok := h.ExecConfig.Networks[s.Name()]; ok {
			// already part of this scope
			return nil
		}

		// check if container is already part of an "external" scope;
		// only one "external" scope per container is allowed
		if s.Type() == ExternalScopeType {
			for name := range h.ExecConfig.Networks {
				sc, _ := c.resolveScope(name)
				if sc.Type() == ExternalScopeType {
					return fmt.Errorf("container can only be added to at most one mapped network")
				}
			}
		}
	}

	if err := h.SetSpec(nil); err != nil {
		return err
	}

	// figure out if we need to add a new NIC
	// if there is already a NIC connected to a
	// bridge network and we are adding the container
	// to a bridge network, we just reuse that
	// NIC
	var pciSlot int32
	if s.Type() == BridgeScopeType {
		for _, ne := range h.ExecConfig.Networks {
			sc, err := c.resolveScope(ne.Network.Name)
			if err != nil {
				return err
			}

			if sc.Type() != BridgeScopeType {
				continue
			}

			if ne.ID != "" {
				pciSlot = atoiOrZero(ne.ID)
				if pciSlot != 0 {
					break
				}
			}
		}
	}

	if pciSlot == 0 {
		d, err := addEthernetCard(h, s)
		if err != nil {
			return err
		}

		pciSlot = spec.VirtualDeviceSlotNumber(d)
	}

	if h.ExecConfig.Networks == nil {
		h.ExecConfig.Networks = make(map[string]*executor.NetworkEndpoint)
	}

	ne := &executor.NetworkEndpoint{
		Common: executor.Common{
			ID: strconv.Itoa(int(pciSlot)),
			// Name: this would cause NIC renaming if uncommented
		},
		Network: executor.ContainerNetwork{
			Common: executor.Common{
				Name: s.Name(),
			},
			Aliases: options.Aliases,
		},
		Ports: options.Ports,
	}

	if options.IP != nil && !options.IP.IsUnspecified() {
		ne.Static = &net.IPNet{
			IP:   *options.IP,
			Mask: s.Subnet().Mask,
		}
	}

	h.ExecConfig.Networks[s.Name()] = ne
	return nil
}