Ejemplo n.º 1
0
func (instance *LeverInstance) termContainer(kill bool) error {
	var sig dockerapi.Signal
	if kill {
		sig = dockerapi.SIGKILL
	} else {
		sig = dockerapi.SIGTERM
	}
	err := instance.docker.KillContainer(
		dockerapi.KillContainerOptions{
			ID:     instance.containerID,
			Signal: sig,
		})
	if err != nil {
		return err
	}
	exited := make(chan struct{})
	go func() {
		instance.docker.WaitContainer(instance.containerID)
		err := dockerutil.RemoveDockerContainer(
			instance.docker, instance.containerID)
		if err != nil {
			instance.logger.WithFields(
				"err", err,
				"containerID", instance.containerID,
			).Error("Error trying to remove container after it exited")
		}
		close(exited)
	}()
	if !kill {
		go func() {
			timer := time.NewTimer(10 * time.Second)
			select {
			case <-timer.C:
				instance.logger.Info(
					"Instance did not exit on term signal and had to be killed")
				instance.docker.KillContainer(
					dockerapi.KillContainerOptions{
						ID:     instance.containerID,
						Signal: dockerapi.SIGKILL,
					})
			case <-exited:
			}
		}()
	}
	return nil
}
Ejemplo n.º 2
0
// EnsureInfrastructureInitialized verifies that all the necessary
// infrastructure is registered, managed and ready to be used.
func (manager *Manager) EnsureInfrastructureInitialized(
	info *InstanceInfo) (
	envNetworkIP string, ownIP string, instanceAddr string,
	keepAlive KeepAliveFun, err error) {
	entry, err := manager.getEnvironment(info.Environment)
	if err != nil {
		return "", "", "", nil, err
	}
	defer entry.envLock.Unlock()

	instance, ok := entry.leverInstances[info.InstanceID]
	if ok {
		// Instance already managed.
		manager.logger.WithFields("leverInstanceID", info.InstanceID).Debug(
			"Instance already managed")
		keepAlive = func(
			resourceName, levResResourceID, levResSessionID string) {
			instance.KeepAlive(resourceName, levResResourceID, levResSessionID)
		}
		return entry.networkIP, entry.ownIP, instance.InstanceAddr(), keepAlive,
			nil
	}
	// Instance is new.
	manager.logger.WithFields("leverInstanceID", info.InstanceID).Debug(
		"Instance is new")
	if info.ContainerID == "" {
		// We don't have the container ID. Cannot initialize instance.
		return "", "", "", nil, fmt.Errorf("Need container ID")
	}

	// Connect the container to the env network bridge so we can talk to it
	// (forward RPCs).
	instanceIPv4, err := dockerutil.ConnectToDockerEnvNetwork(
		manager.docker, info.ContainerID, entry.networkID)
	if err != nil {
		manager.logger.WithFields(
			"err", err,
			"leverEnv", info.Environment,
			"containerID", info.ContainerID,
		).Error("Error connecting instance to env network")
		removeErr := dockerutil.RemoveDockerContainer(
			manager.docker, info.ContainerID)
		if removeErr != nil {
			manager.logger.WithFields(
				"containerID", info.ContainerID,
				"err", removeErr,
			).Error("Error trying to remove container after previous error")
		}
		return "", "", "", nil, err
	}
	instanceAddr = instanceIPv4 + ":" + core.InstanceListenPortFlag.Get()

	leverURL := &core.LeverURL{
		Environment: info.Environment,
		Service:     info.Service,
	}
	if core.IsAdmin(leverURL) {
		// Admin environment. Also connect it to the regional network.
		_, err := dockerutil.ConnectToDockerEnvNetwork(
			manager.docker, info.ContainerID, RegionalNetworkFlag.Get())
		if err != nil {
			manager.logger.WithFields(
				"err", err,
				"leverEnv", info.Environment,
				"containerID", info.ContainerID,
			).Error("Error connecting admin instance to regional network")
			removeErr := dockerutil.RemoveDockerContainer(
				manager.docker, info.ContainerID)
			if removeErr != nil {
				manager.logger.WithFields(
					"containerID", info.ContainerID,
					"err", removeErr,
				).Error(
					"Error trying to remove container after previous error")
			}
			return "", "", "", nil, err
		}
	}

	// Add the instance ID to the local serving ID map.
	manager.servingIDsLock.Lock()
	_, ok = manager.servingIDs[info.ServingID]
	if !ok {
		manager.servingIDs[info.ServingID] = make(map[string]struct{})
	}
	manager.servingIDs[info.ServingID][info.InstanceID] = struct{}{}
	manager.servingIDsLock.Unlock()

	// Start managing instance.
	instance = NewLeverInstance(
		info, instanceAddr, manager.proxyInAddr, manager.grpcPool,
		manager.docker,
		func(instanceID string, err error) {
			manager.logger.WithFields("leverInstanceID", instanceID).Debug(
				"Instance closed")
			manager.onInstanceClose(
				entry, info.Environment, instanceID, info.ServingID, err)
		})
	entry.leverInstances[info.InstanceID] = instance

	keepAlive = func(resourceName, levResResourceID, levResSessionID string) {
		instance.KeepAlive(resourceName, levResResourceID, levResSessionID)
	}
	return entry.networkIP, entry.ownIP, instanceAddr, keepAlive, nil
}