CreateContainer & CreateSandbox(

 

 

 

func (a *agentGRPC) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (resp *gpb.Empty, err error) {
        if err := a.createContainerChecks(req); err != nil {
                return emptyResp, err
        }

        // re-scan PCI bus
        // looking for hidden devices
        if err = rescanPciBus(); err != nil {
                agentLog.WithError(err).Warn("Could not rescan PCI bus")
        }

        // Some devices need some extra processing (the ones invoked with
        // --device for instance), and that's what this call is doing. It
        // updates the devices listed in the OCI spec, so that they actually
        // match real devices inside the VM. This step is necessary since we
        // cannot predict everything from the caller.
        if err = addDevices(ctx, req.Devices, req.OCI, a.sandbox); err != nil {
                return emptyResp, err
        }

        // Both rootfs and volumes (invoked with --volume for instance) will
        // be processed the same way. The idea is to always mount any provided
        // storage to the specified MountPoint, so that it will match what's
        // inside oci.Mounts.
        // After all those storages have been processed, no matter the order
        // here, the agent will rely on libcontainer (using the oci.Mounts
        // list) to bind mount all of them inside the container.
        mountList, err := addStorages(ctx, req.Storages, a.sandbox)
        if err != nil {
                return emptyResp, err
        }

        ctr := &container{
                id:              req.ContainerId,
                processes:       make(map[string]*process),
                mounts:          mountList,
                useSandboxPidNs: req.SandboxPidns,
                agentPidNs:      req.AgentPidns,
                ctx:             ctx,
        }

        // In case the container creation failed, make sure we cleanup
        // properly by rolling back the actions previously performed.
        defer func() {
                if err != nil {
                        a.rollbackFailingContainerCreation(ctr)
                }
        }()

        // Add the nvdimm root partition to the device cgroup to prevent access
        updateDeviceCgroupForGuestRootfs(req.OCI)

        // Convert the spec to an actual OCI specification structure.
        ociSpec, err := pb.GRPCtoOCI(req.OCI)
        if err != nil {
                return emptyResp, err
        }

        if err := a.handleCPUSet(ociSpec); err != nil {
                return emptyResp, err
        }

        if err := a.applyNetworkSysctls(ociSpec); err != nil {
                return emptyResp, err
        }

        if a.sandbox.guestHooksPresent {
                // Add any custom OCI hooks to the spec
                a.sandbox.addGuestHooks(ociSpec)

                // write the OCI spec to a file so that hooks can read it
                err = writeSpecToFile(ociSpec, req.ContainerId)
                if err != nil {
                        return emptyResp, err
                }

                // Change cwd because libcontainer assumes the bundle path is the cwd:
                // https://github.com/opencontainers/runc/blob/v1.0.0-rc5/libcontainer/specconv/spec_linux.go#L157
                oldcwd, err := changeToBundlePath(ociSpec, req.ContainerId)
                if err != nil {
                        return emptyResp, err
                }
                defer os.Chdir(oldcwd)
        }

        // Convert the OCI specification into a libcontainer configuration.
        config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{
                CgroupName:   req.ContainerId,
                NoNewKeyring: true,
                Spec:         ociSpec,
                NoPivotRoot:  a.sandbox.noPivotRoot,
        })
        if err != nil {
                return emptyResp, err
        }

        // apply rlimits
        config.Rlimits = posixRlimitsToRlimits(ociSpec.Process.Rlimits)

        // Update libcontainer configuration for specific cases not handled
        // by the specconv converter.
        if err = a.updateContainerConfig(ociSpec, config, ctr); err != nil {
                return emptyResp, err
        }

        return a.finishCreateContainer(ctr, req, config)
}

 

 

func (a *agentGRPC) CreateSandbox(ctx context.Context, req *pb.CreateSandboxRequest) (*gpb.Empty, error) {
        if a.sandbox.running {
                return emptyResp, grpcStatus.Error(codes.AlreadyExists, "Sandbox already started, impossible to start again")
        }

        a.sandbox.hostname = req.Hostname
        a.sandbox.containers = make(map[string]*container)
        a.sandbox.network.ifaces = make(map[string]*types.Interface)
        a.sandbox.network.dns = req.Dns
        a.sandbox.running = true
        a.sandbox.sandboxPidNs = req.SandboxPidns
        a.sandbox.storages = make(map[string]*sandboxStorage)
        a.sandbox.guestHooks = &specs.Hooks{}
        a.sandbox.guestHooksPresent = false

        for _, m := range req.KernelModules {
                if err := loadKernelModule(m); err != nil {
                        return emptyResp, err
                }
        }

        if req.GuestHookPath != "" {
                a.sandbox.scanGuestHooks(req.GuestHookPath)
        }

        if req.SandboxId != "" {
                a.sandbox.id = req.SandboxId
                agentLog = agentLog.WithField("sandbox", a.sandbox.id)
        }

        // Set up shared UTS and IPC namespaces
        if err := a.sandbox.setupSharedNamespaces(ctx); err != nil {
                return emptyResp, err
        }

        if req.SandboxPidns {
                if err := a.sandbox.setupSharedPidNs(); err != nil {
                        return emptyResp, err
                }
        }

        mountList, err := addStorages(ctx, req.Storages, a.sandbox)
        if err != nil {
                return emptyResp, err
        }

        a.sandbox.mounts = mountList

        if err := setupDNS(a.sandbox.network.dns); err != nil {
                return emptyResp, err
        }

        return emptyResp, nil
}

 

posted on 2020-12-02 10:19  tycoon3  阅读(259)  评论(0)    收藏  举报

导航