// ControlContainer control containers status
490431
func (c *Calcium) ControlContainer(ctx context.Context, IDs []string, t string) (chan *types.ControlContainerMessage, error) {
	ch := make(chan *types.ControlContainerMessage)

	go func() {
		defer close(ch)
		wg := sync.WaitGroup{}
		for _, ID := range IDs {
			container, err := c.GetContainer(ctx, ID)
			if err != nil {
				ch <- &types.ControlContainerMessage{
					ContainerID: ID,
					Error:       err,
				}
				continue
			}

			wg.Add(1)
			go func(container *types.Container) {
				defer wg.Done()
				var err error
				var message []*bytes.Buffer
				defer func() {
					if err == nil {
						log.Infof("[ControlContainer] Control container %s %s", container.ID, t)
						log.Infof("[ControlContainer] Output:\n %s", string(types.HookOutput(message)))
					}
					ch <- &types.ControlContainerMessage{
						ContainerID: container.ID,
						Error:       err,
						Hook:        message,
					}
				}()

				containerInfo, err := container.Inspect(ctx)
				if err != nil {
					return
				}

				switch t {
				case cluster.ContainerStop:
					message, err = c.doStopContainer(ctx, container, containerInfo, false)
					return
				case cluster.ContainerStart:
					message, err = c.doStartContainer(ctx, container, containerInfo)
					return
				case cluster.ContainerRestart:
					message, err = c.doStopContainer(ctx, container, containerInfo, false)
					if err != nil {
						return
					}
					m2, e2 := c.doStartContainer(ctx, container, containerInfo)
					message = append(message, m2...)
					if e2 != nil {
						err = e2
					}
					return
				default:
					err = types.ErrUnknownControlType
				}
			}(container)
		}
		wg.Wait()
	}()

	return ch, nil
}
516703
func (d *kubeDockerClient) StopContainer(id string, timeout time.Duration) error {
	ctx, cancel := d.getCustomTimeoutContext(timeout)
	defer cancel()
	err := d.client.ContainerStop(ctx, id, &timeout)
	if ctxErr := contextError(ctx); ctxErr != nil {
		return ctxErr
	}
	return err
}
1316496
func (a *HostAgent) RestartContainer(cancel <-chan interface{}, serviceID string, instanceID int) error {
	logger := plog.WithFields(log.Fields{
		"serviceid":  serviceID,
		"instanceid": instanceID,
	})

	// look up the container to get the image
	ctrName := fmt.Sprintf("%s-%d", serviceID, instanceID)
	ctr, err := docker.FindContainer(ctrName)
	if err == docker.ErrNoSuchContainer {
		// container has been deleted so we will pull when the container starts
		// again.
		logger.Debug("Container not found")
		return nil
	} else if err != nil {
		logger.WithError(err).Debug("Could not look up container")
		return err
	}

	if !ctr.IsRunning() {
		// container has stopped, so we will pull when the container starts
		// again; the event monitor will handle the stopped container
		logger.Debug("Container stopped")
		return nil
	}

	go func() {
		a.setInstanceState(serviceID, instanceID, service.StatePulling)
		for {
			// relentlessly try to pull the image
			_, _, err := a.pullImage(logger, cancel, ctr.Config.Image)
			if err != nil {
				logger.WithError(err).Debug("Could not pull the service image")
				// wait 5 seconds and try again
				select {
				case <-time.After(5 * time.Second):
				case <-cancel:
					logger.Info("Cancelled image pull")
					return
				}
				continue
			}
			logger.Debug("Pulled image")
			break
		}

		a.setInstanceState(serviceID, instanceID, service.StateStopping)
		// set the container to stop; ctr.Stop() stops the container by
		// container id and not name, so if the container was stopped or
		// deleted before the pull is successful, then this will just be a
		// no-op.  The restart of the container is handled by the delegate once
		// it is notified that the container has stopped.
		if err := ctr.Stop(45 * time.Second); err != nil {
			logger.WithError(err).Debug("Could not stop container")
		}
	}()

	return nil
}
554569
func (s *ResourceDetails) SetContainer(v *ContainerDetails) *ResourceDetails {
	s.Container = v
	return s
}
1357204
func (dh *Client) AttachContainer(containerId string, opts *AttachOptions) (e error) {
	if opts == nil {
		opts = &AttachOptions{}
	}
	rsp, e := dh.post(dh.Address + "/containers/" + containerId + "/attach" + opts.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()

	return handleMessages(rsp.Body, opts.Stdout, opts.Stderr)
}
537351
func (r *Runtime) ExecContainer(c *Container, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) error {
	impl, err := r.RuntimeImpl(c)
	if err != nil {
		return err
	}

	return impl.ExecContainer(c, cmd, stdin, stdout, stderr, tty, resize)
}
99771
func (a *HostAgent) PauseContainer(serviceID string, instanceID int) error {
	commandTimeout := time.Duration(
		config.GetOptions().MaxDFSTimeout + 1) * time.Second

	pidFile := "/pause.pid"
	kill := fmt.Sprintf(
		"if [ -f %[1]s ]; then pid=$(cat %[1]s); if [ \"$pid\" ];" +
		"then kill $pid; fi; rm -f %[1]s; fi", pidFile)

	type out struct {
		response string
		err      error
	}
	done := make(chan out, 1)

	logger := plog.WithFields(log.Fields{
		"serviceid":  serviceID,
		"instanceid": instanceID,
	})
	ctrName := fmt.Sprintf("%s-%d", serviceID, instanceID)

	// check to see if the container exists and is running
	ctr, err := docker.FindContainer(ctrName)
	if err == docker.ErrNoSuchContainer {
		// container has been deleted and the event monitor should catch this
		logger.Debug("Container not found")
		return nil
	} else if err != nil {
		logger.WithError(err).Debug("Could not look up container")
		return err
	}

	if !ctr.IsRunning() {
		// container has stopped and the event monitor should catch this
		logger.Debug("Container stopped")
		return nil
	}

	// Get the service from the client
	svc, err := a.getService(serviceID)
	if err != nil {
		logger.WithError(err).Debug("Unable to get service")
		return nil
	}

	// pause the running container
	a.setInstanceState(serviceID, instanceID, service.StatePausing)

	go func() {
		cmd := ""
		if svc.Snapshot.Pause != "" {
			cmd = svc.Snapshot.Pause + fmt.Sprintf(" & echo $! > %s; wait $!", pidFile)
		}
		output, err := attachAndRun(ctrName, cmd)
		done <- out{string(output), err}
	}()

	select {
		case result := <- done: {
			if result.err != nil {
				logger.WithError(result.err).Warn("Could not run command: %s; %s", svc.Snapshot.Pause, ctrName)
				return result.err
			}
		}
		case <- time.After(commandTimeout): {
			if _, err := attachAndRun(ctrName, kill); err != nil {
				logger.WithError(err).Warn("Error while killing pausing process.")
				return err
			}

			return fmt.Errorf("Timeout waiting for container to pause after %d seconds", commandTimeout.Seconds())
		}

	}
	logger.Debug("Paused running container")
	a.setInstanceState(serviceID, instanceID, service.StatePaused)
	return nil
}
109910
func (client *DockerClient) WaitContainer(id string) (int, error) {
	uri := fmt.Sprintf("containers/%s/wait", id)
	if data, err := client.sendRequest("POST", uri, nil, nil, nil, true); err != nil {
		return 0, err
	} else {
		var ret map[string]int
		if err := json.Unmarshal(data, &ret); err != nil {
			return 0, err
		}
		if code, ok := ret["StatusCode"]; ok {
			return code, nil
		} else {
			logger.Warnf("There is no StatusCode key inside results map, the API maybe changed, ret=%+v", ret)
			return 0, fmt.Errorf("Cannot get StatusCode from return data, %+v", ret)
		}
	}
}
813305
func (a *HostAgent) StartContainer(cancel <-chan interface{}, serviceID string, instanceID int) (*zkservice.ServiceState, <-chan time.Time, error) {
	logger := plog.WithFields(log.Fields{
		"serviceid":  serviceID,
		"instanceid": instanceID,
	})

	a.serviceCache.Invalidate(serviceID, instanceID)
	evaluatedService, tenantID, _, err := a.serviceCache.GetEvaluatedService(serviceID, instanceID)
	if err != nil {
		logger.WithError(err).Error("Failed to get service")
		return nil, nil, err
	}

	// pull the service image
	a.setInstanceState(serviceID, instanceID, service.StatePulling)
	imageUUID, imageName, err := a.pullImage(logger, cancel, evaluatedService.ImageID)
	if err != nil {
		logger.WithError(err).Debug("Could not pull the service image")
		return nil, nil, err
	}
	// Update the service with the complete image name
	evaluatedService.ImageID = imageName

	// get the container configs
	ctr, state, err := a.setupContainer(tenantID, evaluatedService, instanceID, imageUUID)
	if err != nil {
		logger.WithError(err).Debug("Could not setup container")
		return nil, nil, err
	}

	// start the container
	a.setInstanceState(serviceID, instanceID, service.StateStarting)
	ev := a.monitorContainer(logger, ctr)

	if err := ctr.Start(); err != nil {
		logger.WithError(err).Debug("Could not start container")
		ctr.CancelOnEvent(docker.Die)
		return nil, nil, err
	}
	logger.Debug("Started container")

	dctr, err := ctr.Inspect()
	if err != nil {
		logger.WithError(err).Debug("Could not inspect container")
		ctr.CancelOnEvent(docker.Die)
		return nil, nil, err
	}

	state.HostIP = a.ipaddress
	state.PrivateIP = ctr.NetworkSettings.IPAddress
	state.Started = dctr.State.StartedAt

	go a.exposeAssignedIPs(state, ctr)
	a.setInstanceState(serviceID, instanceID, service.StateRunning)
	return state, ev, nil
}
387674
func (f *RemoteRuntime) StartContainer(ctx context.Context, req *kubeapi.StartContainerRequest) (*kubeapi.StartContainerResponse, error) {
	err := f.RuntimeService.StartContainer(req.ContainerId)
	if err != nil {
		return nil, err
	}

	return &kubeapi.StartContainerResponse{}, nil
}
918563
func (s *Server) WriteContainer(c *Container) error {
	resp, err := s.UpdateContainer(c.Name, c.Writable(), "")
	if err != nil {
		return errors.Trace(err)
	}
	if err := resp.Wait(); err != nil {
		return errors.Trace(err)
	}
	return nil
}
1126213
func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContainerOpts) (Container, error) {
	ctx, done, err := c.WithLease(ctx)
	if err != nil {
		return nil, err
	}
	defer done(ctx)

	container := containers.Container{
		ID: id,
		Runtime: containers.RuntimeInfo{
			Name: c.runtime,
		},
	}
	for _, o := range opts {
		if err := o(ctx, c, &container); err != nil {
			return nil, err
		}
	}
	r, err := c.ContainerService().Create(ctx, container)
	if err != nil {
		return nil, err
	}
	return containerFromRecord(c, r), nil
}
569360
func filterContainer(c *pb.Container, filter *pb.ContainerFilter) bool {
	if filter != nil {
		if filter.State != nil {
			if c.State != filter.State.State {
				return false
			}
		}
		if filter.LabelSelector != nil {
			sel := fields.SelectorFromSet(filter.LabelSelector)
			if !sel.Matches(fields.Set(c.Labels)) {
				return false
			}
		}
	}
	return true
}
430542
func (c *ContainerServer) HasContainer(id string) bool {
	return c.state.containers.Get(id) != nil
}
1033262
func (c *Client) LoadContainer(ctx context.Context, id string) (Container, error) {
	r, err := c.ContainerService().Get(ctx, id)
	if err != nil {
		return nil, err
	}
	return containerFromRecord(c, r), nil
}
209159
func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, message string, gracePeriodOverride *int64) error {
	var containerSpec *v1.Container
	if pod != nil {
		if containerSpec = kubecontainer.GetContainerSpec(pod, containerName); containerSpec == nil {
			return fmt.Errorf("failed to get containerSpec %q(id=%q) in pod %q when killing container for reason %q",
				containerName, containerID.String(), format.Pod(pod), message)
		}
	} else {
		// Restore necessary information if one of the specs is nil.
		restoredPod, restoredContainer, err := m.restoreSpecsFromContainerLabels(containerID)
		if err != nil {
			return err
		}
		pod, containerSpec = restoredPod, restoredContainer
	}

	// From this point , pod and container must be non-nil.
	gracePeriod := int64(minimumGracePeriodInSeconds)
	switch {
	case pod.DeletionGracePeriodSeconds != nil:
		gracePeriod = *pod.DeletionGracePeriodSeconds
	case pod.Spec.TerminationGracePeriodSeconds != nil:
		gracePeriod = *pod.Spec.TerminationGracePeriodSeconds
	}

	if len(message) == 0 {
		message = fmt.Sprintf("Stopping container %s", containerSpec.Name)
	}
	m.recordContainerEvent(pod, containerSpec, containerID.ID, v1.EventTypeNormal, events.KillingContainer, message)

	// Run internal pre-stop lifecycle hook
	if err := m.internalLifecycle.PreStopContainer(containerID.ID); err != nil {
		return err
	}

	// Run the pre-stop lifecycle hooks if applicable and if there is enough time to run it
	if containerSpec.Lifecycle != nil && containerSpec.Lifecycle.PreStop != nil && gracePeriod > 0 {
		gracePeriod = gracePeriod - m.executePreStopHook(pod, containerID, containerSpec, gracePeriod)
	}
	// always give containers a minimal shutdown window to avoid unnecessary SIGKILLs
	if gracePeriod < minimumGracePeriodInSeconds {
		gracePeriod = minimumGracePeriodInSeconds
	}
	if gracePeriodOverride != nil {
		gracePeriod = *gracePeriodOverride
		klog.V(3).Infof("Killing container %q, but using %d second grace period override", containerID, gracePeriod)
	}

	klog.V(2).Infof("Killing container %q with %d second grace period", containerID.String(), gracePeriod)

	err := m.runtimeService.StopContainer(containerID.ID, gracePeriod)
	if err != nil {
		klog.Errorf("Container %q termination failed with gracePeriod %d: %v", containerID.String(), gracePeriod, err)
	} else {
		klog.V(3).Infof("Container %q exited normally", containerID.String())
	}

	m.containerRefManager.ClearRef(containerID)

	return err
}
539301
func inspectContainer(client *sshClient, container string) (*containerInfos, error) {
	// Check whether there's a container running for the service
	out, err := client.Run(fmt.Sprintf("docker inspect %s", container))
	if err != nil {
		return nil, ErrServiceUnknown
	}
	// If yes, extract various configuration options
	type inspection struct {
		State struct {
			Running bool
		}
		Mounts []struct {
			Source      string
			Destination string
		}
		Config struct {
			Env []string
		}
		HostConfig struct {
			PortBindings map[string][]map[string]string
		}
	}
	var inspects []inspection
	if err = json.Unmarshal(out, &inspects); err != nil {
		return nil, err
	}
	inspect := inspects[0]

	// Infos retrieved, parse the above into something meaningful
	infos := &containerInfos{
		running: inspect.State.Running,
		envvars: make(map[string]string),
		portmap: make(map[string]int),
		volumes: make(map[string]string),
	}
	for _, envvar := range inspect.Config.Env {
		if parts := strings.Split(envvar, "="); len(parts) == 2 {
			infos.envvars[parts[0]] = parts[1]
		}
	}
	for portname, details := range inspect.HostConfig.PortBindings {
		if len(details) > 0 {
			port, _ := strconv.Atoi(details[0]["HostPort"])
			infos.portmap[portname] = port
		}
	}
	for _, mount := range inspect.Mounts {
		infos.volumes[mount.Destination] = mount.Source
	}
	return infos, err
}