enclave_runtime.go 2.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
package runtime // import "github.com/opencontainers/runc/libenclave/internal/runtime"

import (
	"github.com/opencontainers/runc/libenclave/configs"
	core "github.com/opencontainers/runc/libenclave/internal/runtime/core"
	pal "github.com/opencontainers/runc/libenclave/internal/runtime/pal"
	"github.com/sirupsen/logrus"
	"os"
	"os/exec"
)

type EnclaveRuntime interface {
	Name() string
	Load(path string) error
	Init(args string, logLevel string) error
	Attest() error
	Exec(cmd []string, envp []string, stdio [3]*os.File) (int32, error)
	Kill(sig int, pid int) error
	Destroy() error
}

type EnclaveRuntimeWrapper struct {
	runtime EnclaveRuntime
}

func StartInitialization(config *configs.InitEnclaveConfig, logLevel string) (*EnclaveRuntimeWrapper, error) {
	logrus.Debugf("enclave init config retrieved: %+v", config)

	var (
		runtime EnclaveRuntime
		err     error
	)
	runtime, err = core.StartInitialization(config)
	if err != nil {
		runtime, err = pal.StartInitialization(config)
		if err != nil {
			return nil, err
		}
	}

	logrus.Infof("Loading enclave runtime %s", config.Path)
	err = runtime.Load(config.Path)
	if err != nil {
		return nil, err
	}
	name := runtime.Name()

	logrus.Infof("Initializing enclave runtime %s", name)
	err = runtime.Init(config.Args, logLevel)
	if err != nil {
		return nil, err
	}

	rt := &EnclaveRuntimeWrapper{
		runtime: runtime,
	}
	return rt, nil
}

func (rt *EnclaveRuntimeWrapper) LaunchAttestation() error {
	logrus.Debugf("attesting enclave runtime %s", rt.runtime.Name())

	return rt.runtime.Attest()
}

func (rt *EnclaveRuntimeWrapper) ExecutePayload(cmd []string, envp []string, stdio [3]*os.File) (int32, error) {
	logrus.Debugf("enclave runtime %s executing payload with commandline %s", rt.runtime.Name(), cmd)

	// The executable may not exist in container at all according
	// to the design of enclave runtime, such as Occlum, which uses
	// an invisible filesystem to the container. In this case, the
	// lookup will fail.
	if fullPath, err := exec.LookPath(cmd[0]); err == nil {
		cmd[0] = fullPath
	}
	return rt.runtime.Exec(cmd, envp, stdio)
}

func (rt *EnclaveRuntimeWrapper) KillPayload(sig int, pid int) error {
	if pid != -1 {
		logrus.Debugf("enclave runtime %s killing payload %d with signal %d", rt.runtime.Name(), pid, sig)
	} else {
		logrus.Debugf("enclave runtime %s killing all payloads with signal %d", rt.runtime.Name(), sig)
	}

	return rt.runtime.Kill(sig, pid)
}

func (rt *EnclaveRuntimeWrapper) DestroyInstance() error {
	logrus.Debugf("Destroying enclave runtime %s", rt.runtime.Name())

	return rt.runtime.Destroy()
}