Example #1
0
// registerLinks writes the links to a file.
func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *containertypes.HostConfig) error {
	if hostConfig == nil || hostConfig.NetworkMode.IsUserDefined() {
		return nil
	}

	for _, l := range hostConfig.Links {
		name, alias, err := runconfigopts.ParseLink(l)
		if err != nil {
			return err
		}
		child, err := daemon.GetContainer(name)
		if err != nil {
			//An error from daemon.GetContainer() means this name could not be found
			return fmt.Errorf("Could not get container for %s", name)
		}
		for child.HostConfig.NetworkMode.IsContainer() {
			parts := strings.SplitN(string(child.HostConfig.NetworkMode), ":", 2)
			child, err = daemon.GetContainer(parts[1])
			if err != nil {
				return fmt.Errorf("Could not get container for %s", parts[1])
			}
		}
		if child.HostConfig.NetworkMode.IsHost() {
			return runconfig.ErrConflictHostNetworkAndLinks
		}
		if err := daemon.registerLink(container, child, alias); err != nil {
			return err
		}
	}

	// After we load all the links into the daemon
	// set them to nil on the hostconfig
	return container.WriteHostConfig()
}
func (daemon *Daemon) allocateNetwork(container *container.Container) error {
	controller := daemon.netController

	// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
	if err := controller.SandboxDestroy(container.ID); err != nil {
		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
	}

	updateSettings := false
	if len(container.NetworkSettings.Networks) == 0 {
		if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
			return nil
		}

		err := daemon.updateContainerNetworkSettings(container, nil)
		if err != nil {
			return err
		}
		updateSettings = true
	}

	for n, nConf := range container.NetworkSettings.Networks {
		if err := daemon.connectToNetwork(container, n, nConf, updateSettings); err != nil {
			return err
		}
	}

	return container.WriteHostConfig()
}
Example #3
0
// migrateLegacySqliteLinks migrates sqlite links to use links from HostConfig
// when sqlite links were used, hostConfig.Links was set to nil
func (daemon *Daemon) migrateLegacySqliteLinks(db *graphdb.Database, container *container.Container) error {
	// if links is populated (or an empty slice), then this isn't using sqlite links and can be skipped
	if container.HostConfig == nil || container.HostConfig.Links != nil {
		return nil
	}

	logrus.Debugf("migrating legacy sqlite link info for container: %s", container.ID)

	fullName := container.Name
	if fullName[0] != '/' {
		fullName = "/" + fullName
	}

	// don't use a nil slice, this ensures that the check above will skip once the migration has completed
	links := []string{}
	children, err := db.Children(fullName, 0)
	if err != nil {
		if !strings.Contains(err.Error(), "Cannot find child for") {
			return err
		}
		// else continue... it's ok if we didn't find any children, it'll just be nil and we can continue the migration
	}

	for _, child := range children {
		c, err := daemon.GetContainer(child.Entity.ID())
		if err != nil {
			return err
		}

		links = append(links, c.Name+":"+child.Edge.Name)
	}

	container.HostConfig.Links = links
	return container.WriteHostConfig()
}
Example #4
0
func (daemon *Daemon) allocateNetwork(container *container.Container) error {
	controller := daemon.netController

	if daemon.netController == nil {
		return nil
	}

	// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
	if err := controller.SandboxDestroy(container.ID); err != nil {
		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
	}

	updateSettings := false
	if len(container.NetworkSettings.Networks) == 0 {
		if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
			return nil
		}

		err := daemon.updateContainerNetworkSettings(container, nil)
		if err != nil {
			return err
		}
		updateSettings = true
	}

	// always connect default network first since only default
	// network mode support link and we need do some setting
	// on sandbox initialize for link, but the sandbox only be initialized
	// on first network connecting.
	defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName()
	if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok {
		cleanOperationalData(nConf)
		if err := daemon.connectToNetwork(container, defaultNetName, nConf.EndpointSettings, updateSettings); err != nil {
			return err
		}

	}
	var (
		networks  []string
		epConfigs []*network.EndpointSettings
	)

	for n, epConf := range container.NetworkSettings.Networks {
		if n == defaultNetName {
			continue
		}

		networks = append(networks, n)
		epConfigs = append(epConfigs, epConf)
	}

	for i, epConf := range epConfigs {
		cleanOperationalData(epConf)
		if err := daemon.connectToNetwork(container, networks[i], epConf.EndpointSettings, updateSettings); err != nil {
			return err
		}
	}

	return container.WriteHostConfig()
}
Example #5
0
func (daemon *Daemon) allocateNetwork(container *container.Container) error {
	start := time.Now()
	controller := daemon.netController

	if daemon.netController == nil {
		return nil
	}

	// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
	if err := controller.SandboxDestroy(container.ID); err != nil {
		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
	}

	updateSettings := false
	if len(container.NetworkSettings.Networks) == 0 {
		if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
			return nil
		}

		daemon.updateContainerNetworkSettings(container, nil)
		updateSettings = true
	}

	// always connect default network first since only default
	// network mode support link and we need do some setting
	// on sandbox initialize for link, but the sandbox only be initialized
	// on first network connecting.
	defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName()
	if nConf, ok := container.NetworkSettings.Networks[defaultNetName]; ok {
		cleanOperationalData(nConf)
		if err := daemon.connectToNetwork(container, defaultNetName, nConf.EndpointSettings, updateSettings); err != nil {
			return err
		}

	}

	// the intermediate map is necessary because "connectToNetwork" modifies "container.NetworkSettings.Networks"
	networks := make(map[string]*network.EndpointSettings)
	for n, epConf := range container.NetworkSettings.Networks {
		if n == defaultNetName {
			continue
		}

		networks[n] = epConf
	}

	for netName, epConf := range networks {
		cleanOperationalData(epConf)
		if err := daemon.connectToNetwork(container, netName, epConf.EndpointSettings, updateSettings); err != nil {
			return err
		}
	}

	if err := container.WriteHostConfig(); err != nil {
		return err
	}
	networkActions.WithValues("allocate").UpdateSince(start)
	return nil
}
func (daemon *Daemon) allocateNetwork(container *container.Container) error {
	controller := daemon.netController

	// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
	if err := controller.SandboxDestroy(container.ID); err != nil {
		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
	}

	updateSettings := false
	if len(container.NetworkSettings.Networks) == 0 {
		mode := container.HostConfig.NetworkMode
		if container.Config.NetworkDisabled || mode.IsContainer() {
			return nil
		}

		networkName := mode.NetworkName()
		if mode.IsDefault() {
			networkName = controller.Config().Daemon.DefaultNetwork
		}
		if mode.IsUserDefined() {
			n, err := daemon.FindNetwork(networkName)
			if err != nil {
				return err
			}
			networkName = n.Name()
		}
		container.NetworkSettings.Networks = make(map[string]*networktypes.EndpointSettings)
		container.NetworkSettings.Networks[networkName] = new(networktypes.EndpointSettings)
		updateSettings = true
	}

	for n := range container.NetworkSettings.Networks {
		if err := daemon.connectToNetwork(container, n, updateSettings); err != nil {
			return err
		}
	}

	return container.WriteHostConfig()
}
Example #7
0
//分配网络的主要代码。
func (daemon *Daemon) allocateNetwork(container *container.Container) error {

	//controller是一个libnetwork.NetworkController的接口,主要有如下方法:
	/*
			    type NetworkController interface {
			// ID provides an unique identity for the controller
			ID() string

			// Config method returns the bootup configuration for the controller
			Config() config.Config

			// Create a new network. The options parameter carries network specific options.
			NewNetwork(networkType, name string, options ...NetworkOption) (Network, error)

			// Networks returns the list of Network(s) managed by this controller.
			Networks() []Network

			// WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
			WalkNetworks(walker NetworkWalker)

			// NetworkByName returns the Network which has the passed name. If not found, the error ErrNoSuchNetwork is returned.
			NetworkByName(name string) (Network, error)

			// NetworkByID returns the Network which has the passed id. If not found, the error ErrNoSuchNetwork is returned.
			NetworkByID(id string) (Network, error)

			// NewSandbox cretes a new network sandbox for the passed container id
			NewSandbox(containerID string, options ...SandboxOption) (Sandbox, error)

			// Sandboxes returns the list of Sandbox(s) managed by this controller.
			Sandboxes() []Sandbox

			// WlakSandboxes uses the provided function to walk the Sandbox(s) managed by this controller.
			WalkSandboxes(walker SandboxWalker)

			// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
			SandboxByID(id string) (Sandbox, error)

			// SandboxDestroy destroys a sandbox given a container ID
			SandboxDestroy(id string) error

			// Stop network controller
			Stop()

			// ReloadCondfiguration updates the controller configuration
			ReloadConfiguration(cfgOptions ...config.Option) error
		}
	*/
	controller := daemon.netController

	if daemon.netController == nil {
		return nil
	}

	// Cleanup any stale sandbox left over due to ungraceful daemon shutdown
	//清除sandbox的相关信息,这个时候容器就没有IP地址了
	if err := controller.SandboxDestroy(container.ID); err != nil {
		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
	}

	updateSettings := false
	if len(container.NetworkSettings.Networks) == 0 {
		if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
			return nil
		}

		err := daemon.updateContainerNetworkSettings(container, nil)
		if err != nil {
			return err
		}
		updateSettings = true
	}

	//容器可能添加了多个网络,因此需要对每一网络进行连接。
	//其中,n代表网络的名字或者id,nConf代表网络的配置。
	for n, nConf := range container.NetworkSettings.Networks {
		if err := daemon.connectToNetwork(container, n, nConf, updateSettings); err != nil {
			return err
		}
	}

	//更新/var/lib/docker/containers/XXX/hosts文件,即容器的/etc/hosts文件。
	return container.WriteHostConfig()
}