func()

in runtime/service.go [1153:1254]


func (s *service) Create(requestCtx context.Context, request *taskAPI.CreateTaskRequest) (*taskAPI.CreateTaskResponse, error) {
	logger := s.logger.WithField("task_id", request.ID)
	defer logPanicAndDie(logger)

	err := s.waitVMReady()
	if err != nil {
		logger.WithError(err).Error()
		return nil, err
	}

	logger.WithFields(logrus.Fields{
		"bundle":     request.Bundle,
		"terminal":   request.Terminal,
		"stdin":      request.Stdin,
		"stdout":     request.Stdout,
		"stderr":     request.Stderr,
		"checkpoint": request.Checkpoint,
	}).Debug("creating task")

	hostBundleDir := bundle.Dir(request.Bundle)
	vmBundleDir := bundle.VMBundleDir(request.ID)

	err = s.shimDir.CreateBundleLink(request.ID, hostBundleDir)
	if err != nil {
		err = errors.Wrap(err, "failed to create VM dir bundle link")
		logger.WithError(err).Error()
		return nil, err
	}

	err = s.shimDir.CreateAddressLink(request.ID)
	if err != nil {
		err = errors.Wrap(err, "failed to create shim address symlink")
		logger.WithError(err).Error()
		return nil, err
	}

	// We don't support a rootfs with multiple mounts, only one mount can be exposed to the
	// vm per-container
	if len(request.Rootfs) != 1 {
		return nil, errors.Errorf("can only support rootfs with exactly one mount: %+v", request.Rootfs)
	}
	rootfsMnt := request.Rootfs[0]

	err = s.containerStubHandler.Reserve(requestCtx, request.ID,
		rootfsMnt.Source, vmBundleDir.RootfsPath(), "ext4", nil, s.driveMountClient, s.machine)
	if err != nil {
		err = errors.Wrapf(err, "failed to get stub drive for task %q", request.ID)
		logger.WithError(err).Error()
		return nil, err
	}

	ociConfigBytes, err := hostBundleDir.OCIConfig().Bytes()
	if err != nil {
		return nil, err
	}

	extraData, err := s.generateExtraData(ociConfigBytes, request.Options)
	if err != nil {
		err = errors.Wrap(err, "failed to generate extra data")
		logger.WithError(err).Error()
		return nil, err
	}

	request.Options, err = ptypes.MarshalAny(extraData)
	if err != nil {
		err = errors.Wrap(err, "failed to marshal extra data")
		logger.WithError(err).Error()
		return nil, err
	}

	ioConnectorSet, err := s.newIOProxy(logger, request.Stdin, request.Stdout, request.Stderr, extraData)
	if err != nil {
		return nil, err
	}

	// override the request with the bundle dir that should be used inside the VM
	request.Bundle = vmBundleDir.RootPath()

	// The rootfs is mounted via a MountDrive call, so unset Rootfs in the request.
	// We unfortunately can't rely on just having the runc shim inside the VM do
	// the mount for us because we sometimes need to do mount retries due to our
	// requirement of patching stub drives
	request.Rootfs = nil

	resp, err := s.taskManager.CreateTask(requestCtx, request, s.agentClient, ioConnectorSet)
	if err != nil {
		err = errors.Wrap(err, "failed to create task")
		logger.WithError(err).Error()
		return nil, err
	}

	err = s.addFIFOs(request.ID, taskExecID, cio.Config{
		Stdin:  request.Stdin,
		Stdout: request.Stdout,
		Stderr: request.Stderr,
	})
	if err != nil {
		return nil, err
	}

	return resp, nil
}