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
}