// ReplaceContainer replace containers with same resource
491206
func (c *Calcium) ReplaceContainer(ctx context.Context, opts *types.ReplaceOptions) (chan *types.ReplaceContainerMessage, error) {
	if len(opts.IDs) == 0 {
		oldContainers, err := c.ListContainers(ctx, &types.ListContainersOptions{
			Appname: opts.Name, Entrypoint: opts.Entrypoint.Name, Nodename: opts.Nodename,
		})
		if err != nil {
			return nil, err
		}
		for _, container := range oldContainers {
			opts.IDs = append(opts.IDs, container.ID)
		}
	}
	ch := make(chan *types.ReplaceContainerMessage)
	go func() {
		defer close(ch)
		// 并发控制
		step := opts.Count
		wg := sync.WaitGroup{}
		defer wg.Wait()
		for index, ID := range opts.IDs {
			container, containerJSON, containerLock, err := c.doLockAndGetContainer(ctx, ID)
			if err != nil {
				log.Errorf("[ReplaceContainer] Get container %s failed %v", ID, err)
				continue
			}
			if opts.Podname != "" && container.Podname != opts.Podname {
				log.Warnf("[ReplaceContainer] Skip not in pod container %s", container.ID)
				c.doUnlock(containerLock, container.ID)
				continue
			}

			log.Infof("[ReplaceContainer] Replace old container %s", container.ID)
			wg.Add(1)

			go func(replaceOpts types.ReplaceOptions, container *types.Container, containerJSON *enginetypes.VirtualizationInfo, containerLock lock.DistributedLock, index int) {
				defer wg.Done()
				defer c.doUnlock(containerLock, container.ID)
				// 使用复制之后的配置
				// 停老的，起新的
				replaceOpts.Memory = container.Memory
				replaceOpts.CPUQuota = container.Quota
				replaceOpts.SoftLimit = container.SoftLimit
				// 覆盖 podname 如果做全量更新的话
				replaceOpts.Podname = container.Podname
				// 继承网络配置
				if replaceOpts.NetworkInherit {
					log.Infof("[ReplaceContainer] Inherit old container network configuration mode %v", containerJSON.Networks)
					replaceOpts.NetworkMode = ""
					replaceOpts.Networks = containerJSON.Networks
				}

				createMessage, removeMessage, err := c.doReplaceContainer(
					ctx, container, containerJSON, &replaceOpts, index,
				)
				ch <- &types.ReplaceContainerMessage{
					Create: createMessage,
					Remove: removeMessage,
					Error:  err,
				}
				if err != nil {
					log.Errorf("[ReplaceContainer] Replace and remove failed %v, old container restarted", err)
					return
				}
				log.Infof("[ReplaceContainer] Replace and remove success %s", container.ID)
				// 传 opts 的值，产生一次复制
			}(*opts, container, containerJSON, containerLock, index)
			if (index+1)%step == 0 {
				wg.Wait()
			}
		}
	}()

	return ch, nil
}
420150
func (s *wfScope) replaceMap() map[string]string {
	replaceMap := make(map[string]string)
	for key, val := range s.scope {
		valStr, ok := val.(string)
		if ok {
			replaceMap[key] = valStr
		}
	}
	return replaceMap
}
75237
func (s *Server) removeContainer(event string) {
	safeMap.RLock()
	appPath := safeMap.data[event]
	safeMap.RUnlock()

	if appPath != "" {
		keyPath := fmt.Sprintf("/deis/services/%s", appPath)
		log.Printf("stopped %s\n", keyPath)
		s.removeEtcd(keyPath, false)
	}
}
1374876
func (runtime *CRIRuntime) RemoveContainers(containers []string) error {
	errs := []error{}
	for _, container := range containers {
		out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "stopp", container).CombinedOutput()
		if err != nil {
			// don't stop on errors, try to remove as many containers as possible
			errs = append(errs, errors.Wrapf(err, "failed to stop running pod %s: output: %s, error", container, string(out)))
		} else {
			out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "rmp", container).CombinedOutput()
			if err != nil {
				errs = append(errs, errors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out)))
			}
		}
	}
	return errorsutil.NewAggregate(errs)
}
385264
func (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error {
	query := url.Values{}
	query.Set("path", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.
	// Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
	if !options.AllowOverwriteDirWithFile {
		query.Set("noOverwriteDirNonDir", "true")
	}

	if options.CopyUIDGID {
		query.Set("copyUIDGID", "true")
	}

	apiPath := "/containers/" + containerID + "/archive"

	response, err := cli.putRaw(ctx, apiPath, query, content, nil)
	defer ensureReaderClosed(response)
	if err != nil {
		return wrapResponseError(err, response, "container:path", containerID+":"+dstPath)
	}

	// TODO this code converts non-error status-codes (e.g., "204 No Content") into an error; verify if this is the desired behavior
	if response.statusCode != http.StatusOK {
		return fmt.Errorf("unexpected status code from daemon: %d", response.statusCode)
	}

	return nil
}
1001447
func (s *Server) UpdateContainerResources(ctx context.Context, req *pb.UpdateContainerResourcesRequest) (resp *pb.UpdateContainerResourcesResponse, err error) {
	const operation = "update_container_resources"
	defer func() {
		recordOperation(operation, time.Now())
		recordError(operation, err)
	}()
	logrus.Debugf("UpdateContainerResources %+v", req)

	c, err := s.GetContainerFromShortID(req.GetContainerId())
	if err != nil {
		return nil, err
	}
	state := c.State()
	if !(state.Status == oci.ContainerStateRunning || state.Status == oci.ContainerStateCreated) {
		return nil, fmt.Errorf("container %s is not running or created state: %s", c.ID(), state.Status)
	}

	resources := toOCIResources(req.GetLinux())
	if err := s.Runtime().UpdateContainer(c, resources); err != nil {
		return nil, err
	}
	return &pb.UpdateContainerResourcesResponse{}, 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
}
285668
func (r *runtimeOCI) UpdateContainer(c *Container, res *rspec.LinuxResources) error {
	cmd := exec.Command(r.path, rootFlag, r.root, "update", "--resources", "-", c.id)
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if v, found := os.LookupEnv("XDG_RUNTIME_DIR"); found {
		cmd.Env = append(cmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", v))
	}
	jsonResources, err := json.Marshal(res)
	if err != nil {
		return err
	}
	cmd.Stdin = bytes.NewReader(jsonResources)

	if err := cmd.Run(); err != nil {
		return fmt.Errorf("updating resources for container %q failed: %v %v (%v)", c.id, stderr.String(), stdout.String(), err)
	}
	return nil
}
715223
func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
	container, err := OpenContainer(id)
	if err != nil {
		if IsNotExist(err) {
			return ErrComputeSystemDoesNotExist
		}
		return getInnerError(err)
	}
	defer container.Close()
	err = container.Modify(request)
	if err != nil {
		if IsNotSupported(err) {
			return ErrPlatformNotSupported
		}
		return getInnerError(err)
	}

	return nil
}
535925
func (r *RemoteRuntimeService) RemoveContainer(containerID string) error {
	ctx, cancel := getContextWithTimeout(r.timeout)
	defer cancel()

	r.logReduction.ClearID(containerID)
	_, err := r.runtimeClient.RemoveContainer(ctx, &runtimeapi.RemoveContainerRequest{
		ContainerId: containerID,
	})
	if err != nil {
		klog.Errorf("RemoveContainer %q from runtime service failed: %v", containerID, err)
		return err
	}

	return nil
}
208604
func (_m *APIClient) CopyToContainer(ctx context.Context, _a1 string, path string, content io.Reader, options types.CopyToContainerOptions) error {
	ret := _m.Called(ctx, _a1, path, content, options)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, io.Reader, types.CopyToContainerOptions) error); ok {
		r0 = rf(ctx, _a1, path, content, options)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}
920004
func (l *location) RemoveContainer(id string) error {
	stowCont, err := l.Container(id)
	if err != nil {
		return err
	}

	return stowCont.(*container).bucket.Delete()
}
1296012
func (v *Vibranium) RemoveContainer(opts *pb.RemoveContainerOptions, stream pb.CoreRPC_RemoveContainerServer) error {
	v.taskAdd("RemoveContainer", true)
	defer v.taskDone("RemoveContainer", true)

	ids := opts.GetIds()
	force := opts.GetForce()

	if len(ids) == 0 {
		return types.ErrNoContainerIDs
	}

	//这里不能让 client 打断 remove
	ch, err := v.cluster.RemoveContainer(context.Background(), ids, force)
	if err != nil {
		return err
	}

	for m := range ch {
		if err = stream.Send(toRPCRemoveContainerMessage(m)); err != nil {
			v.logUnsentMessages("RemoveContainer", m)
		}
	}

	return err
}
429110
func (r *Runtime) DeleteContainer(c *Container) error {
	impl, err := r.RuntimeImpl(c)
	if err != nil {
		return err
	}

	defer delete(r.runtimeImplList, c.ID())

	return impl.DeleteContainer(c)
}
1069699
func (client *Client) ReplaceSystemDisk(args *ReplaceSystemDiskArgs) (diskId string, err error) {
	response := ReplaceSystemDiskResponse{}
	err = client.Invoke("ReplaceSystemDisk", args, &response)
	if err != nil {
		return "", err
	}
	return response.DiskId, nil
}
332809
func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error {
	items := make(map[string]interface{}, len(list))
	ts := c.clock.Now()
	for _, item := range list {
		key, err := c.keyFunc(item)
		if err != nil {
			return KeyError{item, err}
		}
		items[key] = &TimestampedEntry{item, ts}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Replace(items, resourceVersion)
	return nil
}
1042434
func (s *Preset) SetContainer(v string) *Preset {
	s.Container = &v
	return s
}