vendor: move ttrpc proto code out of vendor

We do not really depend on the go agent generated grpc code any more.

Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
Peng Tao
2020-05-25 08:48:00 -07:00
parent f7b941b6bf
commit 6bc69760c0
62 changed files with 1539 additions and 8919 deletions

View File

@@ -10,10 +10,10 @@ import (
"syscall"
"time"
"github.com/kata-containers/agent/protocols/grpc"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
"github.com/mitchellh/mapstructure"
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/net/context"

View File

@@ -23,24 +23,24 @@ import (
"syscall"
"time"
"github.com/containerd/fifo"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
kataclient "github.com/kata-containers/agent/protocols/client"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/firecracker/client"
models "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/firecracker/client/models"
ops "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/firecracker/client/operations"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
kataclient "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/client"
"github.com/blang/semver"
"github.com/containerd/console"
"github.com/containerd/fifo"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/opencontainers/selinux/go-selinux/label"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/blang/semver"
"github.com/containerd/console"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
)
type vmmState uint8

View File

@@ -18,13 +18,12 @@ import (
"syscall"
"time"
"github.com/gogo/protobuf/proto"
aTypes "github.com/kata-containers/agent/pkg/types"
kataclient "github.com/kata-containers/agent/protocols/client"
"github.com/kata-containers/agent/protocols/grpc"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
kataclient "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/client"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
aTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
vccgroups "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/cgroups"
ns "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/nsenter"
@@ -33,6 +32,8 @@ import (
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/uuid"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/store"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/gogo/protobuf/proto"
"github.com/opencontainers/runtime-spec/specs-go"
opentracing "github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
@@ -2040,7 +2041,7 @@ func (k *kataAgent) readProcessStdout(c *Container, processID string, data []byt
defer k.disconnect()
}
return k.readProcessStream(c.id, processID, data, k.client.AgentServiceClient.ReadStdout)
return k.readProcessStream(c.id, processID, data, k.client.AgentServiceClient.ReadStdout)
}
// readStdout and readStderr are special that we cannot differentiate them with the request types...

View File

@@ -18,20 +18,19 @@ import (
"syscall"
"testing"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
"github.com/containerd/ttrpc"
gpb "github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
aTypes "github.com/kata-containers/agent/pkg/types"
pb "github.com/kata-containers/agent/protocols/grpc"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/manager"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
pb "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
aTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/mock"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/rootless"
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"

View File

@@ -9,7 +9,7 @@ import (
"syscall"
"time"
"github.com/kata-containers/agent/protocols/grpc"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"

View File

@@ -0,0 +1,473 @@
// Copyright 2017 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// gRPC client wrapper
package client
import (
"bufio"
"context"
"errors"
"fmt"
"net"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/hashicorp/yamux"
"github.com/mdlayher/vsock"
// opentracing "github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
// "google.golang.org/grpc"
"google.golang.org/grpc/codes"
grpcStatus "google.golang.org/grpc/status"
agentgrpc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
"github.com/containerd/ttrpc"
)
const (
UnixSocketScheme = "unix"
VSockSocketScheme = "vsock"
HybridVSockScheme = "hvsock"
)
var defaultDialTimeout = 15 * time.Second
var defaultCloseTimeout = 5 * time.Second
var hybridVSockPort uint32
var agentClientFields = logrus.Fields{
"name": "agent-client",
"pid": os.Getpid(),
"source": "agent-client",
}
var agentClientLog = logrus.WithFields(agentClientFields)
// AgentClient is an agent gRPC client connection wrapper for agentgrpc.AgentServiceClient
type AgentClient struct {
AgentServiceClient agentgrpc.AgentServiceService
HealthClient agentgrpc.HealthService
conn *ttrpc.Client
}
type yamuxSessionStream struct {
net.Conn
session *yamux.Session
}
func (y *yamuxSessionStream) Close() error {
waitCh := y.session.CloseChan()
timeout := time.NewTimer(defaultCloseTimeout)
if err := y.Conn.Close(); err != nil {
return err
}
if err := y.session.Close(); err != nil {
return err
}
// block until session is really closed
select {
case <-waitCh:
timeout.Stop()
case <-timeout.C:
return fmt.Errorf("timeout waiting for session close")
}
return nil
}
type dialer func(string, time.Duration) (net.Conn, error)
// NewAgentClient creates a new agent gRPC client and handles both unix and vsock addresses.
//
// Supported sock address formats are:
// - unix://<unix socket path>
// - vsock://<cid>:<port>
// - <unix socket path>
// - hvsock://<path>:<port>. Firecracker implements the virtio-vsock device
// model, and mediates communication between AF_UNIX sockets (on the host end)
// and AF_VSOCK sockets (on the guest end).
func NewAgentClient(ctx context.Context, sock string, enableYamux bool) (*AgentClient, error) {
grpcAddr, parsedAddr, err := parse(sock)
if err != nil {
return nil, err
}
var conn net.Conn
var d dialer
d = agentDialer(parsedAddr, enableYamux)
conn, err = d(grpcAddr, defaultDialTimeout)
if err != nil {
return nil, err
}
/*
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock()}
dialOpts = append(dialOpts, grpc.WithDialer(agentDialer(parsedAddr, enableYamux)))
var tracer opentracing.Tracer
span := opentracing.SpanFromContext(ctx)
// If the context contains a trace span, trace all client comms
if span != nil {
tracer = span.Tracer()
dialOpts = append(dialOpts,
grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(tracer)))
dialOpts = append(dialOpts,
grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(tracer)))
}
ctx, cancel := context.WithTimeout(ctx, defaultDialTimeout)
defer cancel()
conn, err := grpc.DialContext(ctx, grpcAddr, dialOpts...)
if err != nil {
return nil, err
}
*/
client := ttrpc.NewClient(conn)
return &AgentClient{
AgentServiceClient: agentgrpc.NewAgentServiceClient(client),
HealthClient: agentgrpc.NewHealthClient(client),
conn: client,
}, nil
}
// Close an existing connection to the agent gRPC server.
func (c *AgentClient) Close() error {
return c.conn.Close()
}
// vsock scheme is self-defined to be kept from being parsed by grpc.
// Any format starting with "scheme://" will be parsed by grpc and we lose
// all address information because vsock scheme is not supported by grpc.
// Therefore we use the format vsock:<cid>:<port> for vsock address.
//
// See https://github.com/grpc/grpc/blob/master/doc/naming.md
//
// In the long term, we should patch grpc to support vsock scheme and also
// upstream the timed vsock dialer.
func parse(sock string) (string, *url.URL, error) {
addr, err := url.Parse(sock)
if err != nil {
return "", nil, err
}
var grpcAddr string
// validate more
switch addr.Scheme {
case VSockSocketScheme:
if addr.Hostname() == "" || addr.Port() == "" || addr.Path != "" {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock scheme: %s", sock)
}
if _, err := strconv.ParseUint(addr.Hostname(), 10, 32); err != nil {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock cid: %s", sock)
}
if _, err := strconv.ParseUint(addr.Port(), 10, 32); err != nil {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock port: %s", sock)
}
grpcAddr = VSockSocketScheme + ":" + addr.Host
case UnixSocketScheme:
fallthrough
case "":
if (addr.Host == "" && addr.Path == "") || addr.Port() != "" {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid unix scheme: %s", sock)
}
if addr.Host == "" {
grpcAddr = UnixSocketScheme + ":///" + addr.Path
} else {
grpcAddr = UnixSocketScheme + ":///" + addr.Host + "/" + addr.Path
}
case HybridVSockScheme:
if addr.Path == "" {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock scheme: %s", sock)
}
hvsocket := strings.Split(addr.Path, ":")
if len(hvsocket) != 2 {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock scheme: %s", sock)
}
// Save port since agent dialer not sent the port to the hybridVSock dialer
var port uint64
if port, err = strconv.ParseUint(hvsocket[1], 10, 32); err != nil {
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock port %s: %v", sock, err)
}
hybridVSockPort = uint32(port)
grpcAddr = HybridVSockScheme + ":" + hvsocket[0]
default:
return "", nil, grpcStatus.Errorf(codes.InvalidArgument, "Invalid scheme: %s", sock)
}
return grpcAddr, addr, nil
}
// This function is meant to run in a go routine since it will send ping
// commands every second. It behaves as a heartbeat to maintain a proper
// communication state with the Yamux server in the agent.
func heartBeat(session *yamux.Session) {
if session == nil {
return
}
for {
if session.IsClosed() {
break
}
session.Ping()
// 1 Hz heartbeat
time.Sleep(time.Second)
}
}
func agentDialer(addr *url.URL, enableYamux bool) dialer {
var d dialer
switch addr.Scheme {
case VSockSocketScheme:
d = vsockDialer
case HybridVSockScheme:
d = HybridVSockDialer
case UnixSocketScheme:
fallthrough
default:
d = unixDialer
}
if !enableYamux {
return d
}
// yamux dialer
return func(sock string, timeout time.Duration) (net.Conn, error) {
conn, err := d(sock, timeout)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
conn.Close()
}
}()
var session *yamux.Session
sessionConfig := yamux.DefaultConfig()
// Disable keepAlive since we don't know how much time a container can be paused
sessionConfig.EnableKeepAlive = false
sessionConfig.ConnectionWriteTimeout = time.Second
session, err = yamux.Client(conn, sessionConfig)
if err != nil {
return nil, err
}
// Start the heartbeat in a separate go routine
go heartBeat(session)
var stream net.Conn
stream, err = session.Open()
if err != nil {
return nil, err
}
y := &yamuxSessionStream{
Conn: stream.(net.Conn),
session: session,
}
return y, nil
}
}
func unixDialer(sock string, timeout time.Duration) (net.Conn, error) {
if strings.HasPrefix(sock, "unix:") {
sock = strings.Trim(sock, "unix:")
}
dialFunc := func() (net.Conn, error) {
return net.DialTimeout("unix", sock, timeout)
}
timeoutErr := grpcStatus.Errorf(codes.DeadlineExceeded, "timed out connecting to unix socket %s", sock)
return commonDialer(timeout, dialFunc, timeoutErr)
}
func parseGrpcVsockAddr(sock string) (uint32, uint32, error) {
sp := strings.Split(sock, ":")
if len(sp) != 3 {
return 0, 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock address: %s", sock)
}
if sp[0] != VSockSocketScheme {
return 0, 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock URL scheme: %s", sp[0])
}
cid, err := strconv.ParseUint(sp[1], 10, 32)
if err != nil {
return 0, 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock cid: %s", sp[1])
}
port, err := strconv.ParseUint(sp[2], 10, 32)
if err != nil {
return 0, 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid vsock port: %s", sp[2])
}
return uint32(cid), uint32(port), nil
}
func parseGrpcHybridVSockAddr(sock string) (string, uint32, error) {
sp := strings.Split(sock, ":")
// scheme and host are required
if len(sp) < 2 {
return "", 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock address: %s", sock)
}
if sp[0] != HybridVSockScheme {
return "", 0, grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock URL scheme: %s", sock)
}
port := uint32(0)
// the third is the port
if len(sp) == 3 {
p, err := strconv.ParseUint(sp[2], 10, 32)
if err == nil {
port = uint32(p)
}
}
return sp[1], port, nil
}
// This would bypass the grpc dialer backoff strategy and handle dial timeout
// internally. Because we do not have a large number of concurrent dialers,
// it is not reasonable to have such aggressive backoffs which would kill kata
// containers boot up speed. For more information, see
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
func commonDialer(timeout time.Duration, dialFunc func() (net.Conn, error), timeoutErrMsg error) (net.Conn, error) {
t := time.NewTimer(timeout)
cancel := make(chan bool)
ch := make(chan net.Conn)
go func() {
for {
select {
case <-cancel:
// canceled or channel closed
return
default:
}
conn, err := dialFunc()
if err == nil {
// Send conn back iff timer is not fired
// Otherwise there might be no one left reading it
if t.Stop() {
ch <- conn
} else {
conn.Close()
}
return
}
}
}()
var conn net.Conn
var ok bool
select {
case conn, ok = <-ch:
if !ok {
return nil, timeoutErrMsg
}
case <-t.C:
cancel <- true
return nil, timeoutErrMsg
}
return conn, nil
}
func vsockDialer(sock string, timeout time.Duration) (net.Conn, error) {
cid, port, err := parseGrpcVsockAddr(sock)
if err != nil {
return nil, err
}
dialFunc := func() (net.Conn, error) {
return vsock.Dial(cid, port)
}
timeoutErr := grpcStatus.Errorf(codes.DeadlineExceeded, "timed out connecting to vsock %d:%d", cid, port)
return commonDialer(timeout, dialFunc, timeoutErr)
}
// HybridVSockDialer dials to a hybrid virtio socket
func HybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) {
udsPath, port, err := parseGrpcHybridVSockAddr(sock)
if err != nil {
return nil, err
}
dialFunc := func() (net.Conn, error) {
handshakeTimeout := 10 * time.Second
conn, err := net.DialTimeout("unix", udsPath, timeout)
if err != nil {
return nil, err
}
if port == 0 {
// use the port read at parse()
port = hybridVSockPort
}
// Once the connection is opened, the following command MUST BE sent,
// the hypervisor needs to know the port number where the agent is listening in order to
// create the connection
if _, err = conn.Write([]byte(fmt.Sprintf("CONNECT %d\n", port))); err != nil {
conn.Close()
return nil, err
}
errChan := make(chan error)
go func() {
reader := bufio.NewReader(conn)
response, err := reader.ReadString('\n')
if err != nil {
errChan <- err
return
}
agentClientLog.WithField("response", response).Debug("HybridVsock trivial handshake")
if strings.Contains(response, "OK") {
errChan <- nil
} else {
errChan <- errors.New("HybridVsock trivial handshake failed with malformed response code")
}
}()
select {
case err = <-errChan:
if err != nil {
conn.Close()
agentClientLog.WithField("Error", err).Debug("HybridVsock trivial handshake failed")
return nil, err
}
return conn, nil
case <-time.After(handshakeTimeout):
// Timeout: kernel vsock implementation has a race condition, where no response is given
// Instead of waiting forever for a response, timeout after a fair amount of time.
// See: https://lore.kernel.org/netdev/668b0eda8823564cd604b1663dc53fbaece0cd4e.camel@intel.com/
conn.Close()
return nil, errors.New("timeout waiting for hybrid vsocket handshake")
}
}
timeoutErr := grpcStatus.Errorf(codes.DeadlineExceeded, "timed out connecting to hybrid vsocket %s", sock)
return commonDialer(timeout, dialFunc, timeoutErr)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,496 @@
//
// Copyright 2017 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
syntax = "proto3";
package grpc;
import "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc/oci.proto";
import "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/types.proto";
import "google/protobuf/empty.proto";
// unstable
service AgentService {
// execution
rpc CreateContainer(CreateContainerRequest) returns (google.protobuf.Empty);
rpc StartContainer(StartContainerRequest) returns (google.protobuf.Empty);
// RemoveContainer will tear down an existing container by forcibly terminating
// all processes running inside that container and releasing all internal
// resources associated with it.
// RemoveContainer will wait for all processes termination before returning.
// If any process can not be killed or if it can not be killed after
// the RemoveContainerRequest timeout, RemoveContainer will return an error.
rpc RemoveContainer(RemoveContainerRequest) returns (google.protobuf.Empty);
rpc ExecProcess(ExecProcessRequest) returns (google.protobuf.Empty);
rpc SignalProcess(SignalProcessRequest) returns (google.protobuf.Empty);
rpc WaitProcess(WaitProcessRequest) returns (WaitProcessResponse); // wait & reap like waitpid(2)
rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse);
rpc UpdateContainer(UpdateContainerRequest) returns (google.protobuf.Empty);
rpc StatsContainer(StatsContainerRequest) returns (StatsContainerResponse);
rpc PauseContainer(PauseContainerRequest) returns (google.protobuf.Empty);
rpc ResumeContainer(ResumeContainerRequest) returns (google.protobuf.Empty);
// stdio
rpc WriteStdin(WriteStreamRequest) returns (WriteStreamResponse);
rpc ReadStdout(ReadStreamRequest) returns (ReadStreamResponse);
rpc ReadStderr(ReadStreamRequest) returns (ReadStreamResponse);
rpc CloseStdin(CloseStdinRequest) returns (google.protobuf.Empty);
rpc TtyWinResize(TtyWinResizeRequest) returns (google.protobuf.Empty);
// networking
rpc UpdateInterface(UpdateInterfaceRequest) returns (types.Interface);
rpc UpdateRoutes(UpdateRoutesRequest) returns (Routes);
rpc ListInterfaces(ListInterfacesRequest) returns(Interfaces);
rpc ListRoutes(ListRoutesRequest) returns (Routes);
// tracing
rpc StartTracing(StartTracingRequest) returns (google.protobuf.Empty);
rpc StopTracing(StopTracingRequest) returns (google.protobuf.Empty);
// misc (TODO: some rpcs can be replaced by hyperstart-exec)
rpc CreateSandbox(CreateSandboxRequest) returns (google.protobuf.Empty);
rpc DestroySandbox(DestroySandboxRequest) returns (google.protobuf.Empty);
rpc OnlineCPUMem(OnlineCPUMemRequest) returns (google.protobuf.Empty);
rpc ReseedRandomDev(ReseedRandomDevRequest) returns (google.protobuf.Empty);
rpc GetGuestDetails(GuestDetailsRequest) returns (GuestDetailsResponse);
rpc MemHotplugByProbe(MemHotplugByProbeRequest) returns (google.protobuf.Empty);
rpc SetGuestDateTime(SetGuestDateTimeRequest) returns (google.protobuf.Empty);
rpc CopyFile(CopyFileRequest) returns (google.protobuf.Empty);
}
message CreateContainerRequest {
string container_id = 1;
string exec_id = 2;
StringUser string_user = 3;
repeated Device devices = 4;
repeated Storage storages = 5;
Spec OCI = 6;
// This field is used to indicate if the container needs to join
// sandbox shared pid ns or create a new namespace. This field is
// meant to override the NEWPID config settings in the OCI spec.
// The agent would receive an OCI spec with PID namespace cleared
// out altogether and not just the pid ns path.
bool sandbox_pidns = 7;
}
message StartContainerRequest {
string container_id = 1;
}
message RemoveContainerRequest {
string container_id = 1;
// RemoveContainer will return an error if
// it could not kill some container processes
// after timeout seconds.
// Setting timeout to 0 means RemoveContainer will
// wait for ever.
uint32 timeout = 2;
}
message ExecProcessRequest {
string container_id = 1;
string exec_id = 2;
StringUser string_user = 3;
Process process = 4;
}
message SignalProcessRequest {
string container_id = 1;
// Special case for SignalProcess(): exec_id can be empty(""),
// which means to send the signal to all the processes including their descendants.
// Other APIs with exec_id should treat empty exec_id as an invalid request.
string exec_id = 2;
uint32 signal = 3;
}
message WaitProcessRequest {
string container_id = 1;
string exec_id = 2;
}
message WaitProcessResponse {
int32 status = 1;
}
// ListProcessesRequest contains the options used to list running processes inside the container
message ListProcessesRequest {
string container_id = 1;
string format = 2;
repeated string args = 3;
}
// ListProcessesResponse represents the list of running processes inside the container
message ListProcessesResponse {
bytes process_list = 1;
}
message UpdateContainerRequest {
string container_id = 1;
LinuxResources resources = 2;
}
message StatsContainerRequest {
string container_id = 1;
}
message PauseContainerRequest {
string container_id = 1;
}
message ResumeContainerRequest {
string container_id = 1;
}
message CpuUsage {
uint64 total_usage = 1;
repeated uint64 percpu_usage = 2;
uint64 usage_in_kernelmode = 3;
uint64 usage_in_usermode = 4;
}
message ThrottlingData {
uint64 periods = 1;
uint64 throttled_periods = 2;
uint64 throttled_time = 3;
}
message CpuStats {
CpuUsage cpu_usage = 1;
ThrottlingData throttling_data = 2;
}
message PidsStats {
uint64 current = 1;
uint64 limit = 2;
}
message MemoryData {
uint64 usage = 1;
uint64 max_usage = 2;
uint64 failcnt = 3;
uint64 limit = 4;
}
message MemoryStats {
uint64 cache = 1;
MemoryData usage = 2;
MemoryData swap_usage = 3;
MemoryData kernel_usage = 4;
bool use_hierarchy = 5;
map<string, uint64> stats = 6;
}
message BlkioStatsEntry {
uint64 major = 1;
uint64 minor = 2;
string op = 3;
uint64 value = 4;
}
message BlkioStats {
repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes transferred to and from the block device
repeated BlkioStatsEntry io_serviced_recursive = 2;
repeated BlkioStatsEntry io_queued_recursive = 3;
repeated BlkioStatsEntry io_service_time_recursive = 4;
repeated BlkioStatsEntry io_wait_time_recursive = 5;
repeated BlkioStatsEntry io_merged_recursive = 6;
repeated BlkioStatsEntry io_time_recursive = 7;
repeated BlkioStatsEntry sectors_recursive = 8;
}
message HugetlbStats {
uint64 usage = 1;
uint64 max_usage = 2;
uint64 failcnt = 3;
}
message CgroupStats {
CpuStats cpu_stats = 1;
MemoryStats memory_stats = 2;
PidsStats pids_stats = 3;
BlkioStats blkio_stats = 4;
map<string, HugetlbStats> hugetlb_stats = 5; // the map is in the format "size of hugepage: stats of the hugepage"
}
message NetworkStats {
string name = 1;
uint64 rx_bytes = 2;
uint64 rx_packets = 3;
uint64 rx_errors = 4;
uint64 rx_dropped = 5;
uint64 tx_bytes = 6;
uint64 tx_packets = 7;
uint64 tx_errors = 8;
uint64 tx_dropped = 9;
}
message StatsContainerResponse {
CgroupStats cgroup_stats = 1;
repeated NetworkStats network_stats = 2;
}
message WriteStreamRequest {
string container_id = 1;
string exec_id = 2;
bytes data = 3;
}
message WriteStreamResponse {
uint32 len = 1;
}
message ReadStreamRequest {
string container_id = 1;
string exec_id = 2;
uint32 len = 3;
}
message ReadStreamResponse {
bytes data = 1;
}
message CloseStdinRequest {
string container_id = 1;
string exec_id = 2;
}
message TtyWinResizeRequest {
string container_id = 1;
string exec_id = 2;
uint32 row = 3;
uint32 column = 4;
}
message KernelModule {
// This field is the name of the kernel module.
string name = 1;
// This field are the parameters for the kernel module which are
// whitespace-delimited key=value pairs passed to modprobe(8).
repeated string parameters = 2;
}
message CreateSandboxRequest {
string hostname = 1;
repeated string dns = 2;
repeated Storage storages = 3;
// This field means that a pause process needs to be created by the
// agent. This pid namespace of the pause process will be treated as
// a shared pid namespace. All containers created will join this shared
// pid namespace.
bool sandbox_pidns = 4;
// SandboxId identifies which sandbox is using the agent. We allow only
// one sandbox per agent and implicitly require that CreateSandbox is
// called before other sandbox/network calls.
string sandbox_id = 5;
// This field, if non-empty, designates an absolute path to a directory
// that the agent will search for OCI hooks to run within the guest.
string guest_hook_path = 6;
// This field is the list of kernel modules to be loaded in the guest kernel.
repeated KernelModule kernel_modules = 7;
}
message DestroySandboxRequest {
}
message Interfaces {
repeated types.Interface Interfaces = 1;
}
message Routes {
repeated types.Route Routes = 1;
}
message UpdateInterfaceRequest {
types.Interface interface = 1;
}
message UpdateRoutesRequest {
Routes routes = 1;
}
message ListInterfacesRequest {
}
message ListRoutesRequest {
}
message OnlineCPUMemRequest {
// Wait specifies if the caller waits for the agent to online all resources.
// If true the agent returns once all resources have been connected, otherwise all
// resources are connected asynchronously and the agent returns immediately.
bool wait = 1;
// NbCpus specifies the number of CPUs that were added and the agent has to online.
uint32 nb_cpus = 2;
// CpuOnly specifies whether only online CPU or not.
bool cpu_only = 3;
}
message ReseedRandomDevRequest {
// Data specifies the random data used to reseed the guest crng.
bytes data = 2;
}
// AgentDetails provides information to the client about the running agent.
message AgentDetails {
// Semantic version of agent (see https://semver.org).
string version = 1;
// Set if the agent is running as PID 1.
bool init_daemon = 2;
// List of available device handlers.
repeated string device_handlers = 3;
// List of available storage handlers.
repeated string storage_handlers = 4;
// Set only if the agent is built with seccomp support and the guest
// environment supports seccomp.
bool supports_seccomp = 5;
}
message GuestDetailsRequest {
// MemBlockSize asks server to return the system memory block size that can be used
// for memory hotplug alignment. Typically the server returns what's in
// /sys/devices/system/memory/block_size_bytes.
bool mem_block_size = 1;
// MemoryHotplugProbe asks server to return whether guest kernel supports memory hotplug
// via probeinterface. Typically the server will check if the path
// /sys/devices/system/memory/probe exists.
bool mem_hotplug_probe = 2;
}
message GuestDetailsResponse {
// MemBlockSizeBytes returns the system memory block size in bytes.
uint64 mem_block_size_bytes = 1;
AgentDetails agent_details = 2;
bool support_mem_hotplug_probe = 3;
}
message MemHotplugByProbeRequest {
// server needs to send the value of memHotplugProbeAddr into file /sys/devices/system/memory/probe,
// in order to notify the guest kernel about hot-add memory event
repeated uint64 memHotplugProbeAddr = 1;
}
message SetGuestDateTimeRequest {
// Sec the second since the Epoch.
int64 Sec = 1;
// Usec the microseconds portion of time since the Epoch.
int64 Usec = 2;
}
// Storage represents both the rootfs of the container, and any volume that
// could have been defined through the Mount list of the OCI specification.
message Storage {
// Driver is used to define the way the storage is passed through the
// virtual machine. It can be "9p", "blk", or something else, but for
// all cases, this will define if some extra steps are required before
// this storage gets mounted into the container.
string driver = 1;
// DriverOptions allows the caller to define a list of options such
// as block sizes, numbers of luns, ... which are very specific to
// every device and cannot be generalized through extra fields.
repeated string driver_options = 2;
// Source can be anything representing the source of the storage. This
// will be handled by the proper handler based on the Driver used.
// For instance, it can be a very simple path if the caller knows the
// name of device inside the VM, or it can be some sort of identifier
// to let the agent find the device inside the VM.
string source = 3;
// Fstype represents the filesystem that needs to be used to mount the
// storage inside the VM. For instance, it could be "xfs" for block
// device, "9p" for shared filesystem, or "tmpfs" for shared /dev/shm.
string fstype = 4;
// Options describes the additional options that might be needed to
// mount properly the storage filesytem.
repeated string options = 5;
// MountPoint refers to the path where the storage should be mounted
// inside the VM.
string mount_point = 6;
}
// Device represents only the devices that could have been defined through the
// Linux Device list of the OCI specification.
message Device {
// Id can be used to identify the device inside the VM. Some devices
// might not need it to be identified on the VM, and will rely on the
// provided VmPath instead.
string id = 1;
// Type defines the type of device described. This can be "blk",
// "scsi", "vfio", ...
// Particularly, this should be used to trigger the use of the
// appropriate device handler.
string type = 2;
// VmPath can be used by the caller to provide directly the path of
// the device as it will appear inside the VM. For some devices, the
// device id or the list of options passed might not be enough to find
// the device. In those cases, the caller should predict and provide
// this vm_path.
string vm_path = 3;
// ContainerPath defines the path where the device should be found inside
// the container. This path should match the path of the device from
// the device list listed inside the OCI spec. This is used in order
// to identify the right device in the spec and update it with the
// right options such as major/minor numbers as they appear inside
// the VM for instance. Note that an empty ctr_path should be used
// to make sure the device handler inside the agent is called, but
// no spec update needs to be performed. This has to happen for the
// case of rootfs, when a device has to be waited for after it has
// been hotplugged. An equivalent Storage entry should be defined if
// any mount needs to be performed afterwards.
string container_path = 4;
// Options allows the caller to define a list of options such as block
// sizes, numbers of luns, ... which are very specific to every device
// and cannot be generalized through extra fields.
repeated string options = 5;
}
message StringUser {
string uid = 1;
string gid = 2;
repeated string additionalGids = 3;
}
message CopyFileRequest {
// Path is the destination file in the guest. It must be absolute,
// canonical and below /run.
string path = 1;
// FileSize is the expected file size, for security reasons write operations
// are made in a temporary file, once it has the expected size, it's moved
// to the destination path.
int64 file_size = 2;
// FileMode is the file mode.
uint32 file_mode = 3;
// DirMode is the mode for the parent directories of destination path.
uint32 dir_mode = 4;
// Uid is the numeric user id.
int32 uid = 5;
// Gid is the numeric group id.
int32 gid = 6;
// Offset for the next write operation.
int64 offset = 7;
// Data to write in the destination file.
bytes data = 8;
}
message StartTracingRequest {
}
message StopTracingRequest {
}

View File

@@ -0,0 +1,586 @@
{
"ociVersion": "1.0.0",
"process": {
"user": {
"uid": 0,
"gid": 0
},
"args": [
"sh"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": "/",
"capabilities": {
"bounding": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"effective": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"inheritable": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"permitted": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"ambient": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
]
},
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
]
},
"root": {
"path": "rootfs"
},
"hostname": "mrsdalloway",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
}
],
"linux": {
"resources": {
"devices": [
{
"allow": false,
"access": "rwm"
}
],
"blockIO": {
"weight": 32,
"leafWeight": 33,
"weightDevice": [
{
"major": 10,
"minor": 11,
"weight": 64,
"leafWeight": 128
}
]
}
},
"namespaces": [
{
"type": "pid"
},
{
"type": "network"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
}
],
"seccomp": {
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": [
"SCMP_ARCH_X86_64",
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
],
"syscalls": [
{
"names": [
"accept",
"accept4",
"access",
"alarm",
"bind",
"brk",
"capget",
"capset",
"chdir",
"chmod",
"chown",
"chown32",
"clock_getres",
"clock_gettime",
"clock_nanosleep",
"close",
"connect",
"copy_file_range",
"creat",
"dup",
"dup2",
"dup3",
"epoll_create",
"epoll_create1",
"epoll_ctl",
"epoll_ctl_old",
"epoll_pwait",
"epoll_wait",
"epoll_wait_old",
"eventfd",
"eventfd2",
"execve",
"execveat",
"exit",
"exit_group",
"faccessat",
"fadvise64",
"fadvise64_64",
"fallocate",
"fanotify_mark",
"fchdir",
"fchmod",
"fchmodat",
"fchown",
"fchown32",
"fchownat",
"fcntl",
"fcntl64",
"fdatasync",
"fgetxattr",
"flistxattr",
"flock",
"fork",
"fremovexattr",
"fsetxattr",
"fstat",
"fstat64",
"fstatat64",
"fstatfs",
"fstatfs64",
"fsync",
"ftruncate",
"ftruncate64",
"futex",
"futimesat",
"getcpu",
"getcwd",
"getdents",
"getdents64",
"getegid",
"getegid32",
"geteuid",
"geteuid32",
"getgid",
"getgid32",
"getgroups",
"getgroups32",
"getitimer",
"getpeername",
"getpgid",
"getpgrp",
"getpid",
"getppid",
"getpriority",
"getrandom",
"getresgid",
"getresgid32",
"getresuid",
"getresuid32",
"getrlimit",
"get_robust_list",
"getrusage",
"getsid",
"getsockname",
"getsockopt",
"get_thread_area",
"gettid",
"gettimeofday",
"getuid",
"getuid32",
"getxattr",
"inotify_add_watch",
"inotify_init",
"inotify_init1",
"inotify_rm_watch",
"io_cancel",
"ioctl",
"io_destroy",
"io_getevents",
"ioprio_get",
"ioprio_set",
"io_setup",
"io_submit",
"ipc",
"kill",
"lchown",
"lchown32",
"lgetxattr",
"link",
"linkat",
"listen",
"listxattr",
"llistxattr",
"_llseek",
"lremovexattr",
"lseek",
"lsetxattr",
"lstat",
"lstat64",
"madvise",
"memfd_create",
"mincore",
"mkdir",
"mkdirat",
"mknod",
"mknodat",
"mlock",
"mlock2",
"mlockall",
"mmap",
"mmap2",
"mprotect",
"mq_getsetattr",
"mq_notify",
"mq_open",
"mq_timedreceive",
"mq_timedsend",
"mq_unlink",
"mremap",
"msgctl",
"msgget",
"msgrcv",
"msgsnd",
"msync",
"munlock",
"munlockall",
"munmap",
"nanosleep",
"newfstatat",
"_newselect",
"open",
"openat",
"pause",
"pipe",
"pipe2",
"poll",
"ppoll",
"prctl",
"pread64",
"preadv",
"prlimit64",
"pselect6",
"pwrite64",
"pwritev",
"read",
"readahead",
"readlink",
"readlinkat",
"readv",
"recv",
"recvfrom",
"recvmmsg",
"recvmsg",
"remap_file_pages",
"removexattr",
"rename",
"renameat",
"renameat2",
"restart_syscall",
"rmdir",
"rt_sigaction",
"rt_sigpending",
"rt_sigprocmask",
"rt_sigqueueinfo",
"rt_sigreturn",
"rt_sigsuspend",
"rt_sigtimedwait",
"rt_tgsigqueueinfo",
"sched_getaffinity",
"sched_getattr",
"sched_getparam",
"sched_get_priority_max",
"sched_get_priority_min",
"sched_getscheduler",
"sched_rr_get_interval",
"sched_setaffinity",
"sched_setattr",
"sched_setparam",
"sched_setscheduler",
"sched_yield",
"seccomp",
"select",
"semctl",
"semget",
"semop",
"semtimedop",
"send",
"sendfile",
"sendfile64",
"sendmmsg",
"sendmsg",
"sendto",
"setfsgid",
"setfsgid32",
"setfsuid",
"setfsuid32",
"setgid",
"setgid32",
"setgroups",
"setgroups32",
"setitimer",
"setpgid",
"setpriority",
"setregid",
"setregid32",
"setresgid",
"setresgid32",
"setresuid",
"setresuid32",
"setreuid",
"setreuid32",
"setrlimit",
"set_robust_list",
"setsid",
"setsockopt",
"set_thread_area",
"set_tid_address",
"setuid",
"setuid32",
"setxattr",
"shmat",
"shmctl",
"shmdt",
"shmget",
"shutdown",
"sigaltstack",
"signalfd",
"signalfd4",
"sigreturn",
"socket",
"socketcall",
"socketpair",
"splice",
"stat",
"stat64",
"statfs",
"statfs64",
"symlink",
"symlinkat",
"sync",
"sync_file_range",
"syncfs",
"sysinfo",
"syslog",
"tee",
"tgkill",
"time",
"timer_create",
"timer_delete",
"timerfd_create",
"timerfd_gettime",
"timerfd_settime",
"timer_getoverrun",
"timer_gettime",
"timer_settime",
"times",
"tkill",
"truncate",
"truncate64",
"ugetrlimit",
"umask",
"uname",
"unlink",
"unlinkat",
"utime",
"utimensat",
"utimes",
"vfork",
"vmsplice",
"wait4",
"waitid",
"waitpid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
},
{
"names": [
"personality"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 0,
"op": "SCMP_CMP_EQ"
},
{
"index": 0,
"value": 8,
"op": "SCMP_CMP_EQ"
},
{
"index": 0,
"value": 4294967295,
"op": "SCMP_CMP_EQ"
}
]
},
{
"names": [
"chroot"
],
"action": "SCMP_ACT_ALLOW"
},
{
"names": [
"clone"
],
"action": "SCMP_ACT_ALLOW",
"args": [
{
"index": 0,
"value": 2080505856,
"op": "SCMP_CMP_MASKED_EQ"
}
]
},
{
"names": [
"arch_prctl"
],
"action": "SCMP_ACT_ALLOW"
},
{
"names": [
"modify_ldt"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
//
// Copyright 2017 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
syntax = "proto3";
package grpc;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
option (gogoproto.equal_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
message CheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
message VersionCheckResponse {
string grpc_version = 1;
string agent_version = 2;
}
service Health {
rpc Check(CheckRequest) returns (HealthCheckResponse);
rpc Version(CheckRequest) returns (VersionCheckResponse);
}

View File

@@ -0,0 +1,585 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc//health.proto
package grpc
import (
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
github_com_gogo_protobuf_jsonpb "github.com/gogo/protobuf/jsonpb"
github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
proto "github.com/gogo/protobuf/proto"
math "math"
math_rand "math/rand"
testing "testing"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func TestCheckRequestProto(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, false)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &CheckRequest{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
littlefuzz := make([]byte, len(dAtA))
copy(littlefuzz, dAtA)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
if len(littlefuzz) > 0 {
fuzzamount := 100
for i := 0; i < fuzzamount; i++ {
littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))
littlefuzz = append(littlefuzz, byte(popr.Intn(256)))
}
// shouldn't panic
_ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg)
}
}
func TestCheckRequestMarshalTo(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, false)
size := p.Size()
dAtA := make([]byte, size)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
_, err := p.MarshalTo(dAtA)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &CheckRequest{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func BenchmarkCheckRequestProtoMarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*CheckRequest, 10000)
for i := 0; i < 10000; i++ {
pops[i] = NewPopulatedCheckRequest(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
if err != nil {
panic(err)
}
total += len(dAtA)
}
b.SetBytes(int64(total / b.N))
}
func BenchmarkCheckRequestProtoUnmarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
datas := make([][]byte, 10000)
for i := 0; i < 10000; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedCheckRequest(popr, false))
if err != nil {
panic(err)
}
datas[i] = dAtA
}
msg := &CheckRequest{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += len(datas[i%10000])
if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
panic(err)
}
}
b.SetBytes(int64(total / b.N))
}
func TestHealthCheckResponseProto(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, false)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &HealthCheckResponse{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
littlefuzz := make([]byte, len(dAtA))
copy(littlefuzz, dAtA)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
if len(littlefuzz) > 0 {
fuzzamount := 100
for i := 0; i < fuzzamount; i++ {
littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))
littlefuzz = append(littlefuzz, byte(popr.Intn(256)))
}
// shouldn't panic
_ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg)
}
}
func TestHealthCheckResponseMarshalTo(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, false)
size := p.Size()
dAtA := make([]byte, size)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
_, err := p.MarshalTo(dAtA)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &HealthCheckResponse{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func BenchmarkHealthCheckResponseProtoMarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*HealthCheckResponse, 10000)
for i := 0; i < 10000; i++ {
pops[i] = NewPopulatedHealthCheckResponse(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
if err != nil {
panic(err)
}
total += len(dAtA)
}
b.SetBytes(int64(total / b.N))
}
func BenchmarkHealthCheckResponseProtoUnmarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
datas := make([][]byte, 10000)
for i := 0; i < 10000; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedHealthCheckResponse(popr, false))
if err != nil {
panic(err)
}
datas[i] = dAtA
}
msg := &HealthCheckResponse{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += len(datas[i%10000])
if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
panic(err)
}
}
b.SetBytes(int64(total / b.N))
}
func TestVersionCheckResponseProto(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, false)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &VersionCheckResponse{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
littlefuzz := make([]byte, len(dAtA))
copy(littlefuzz, dAtA)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
if len(littlefuzz) > 0 {
fuzzamount := 100
for i := 0; i < fuzzamount; i++ {
littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))
littlefuzz = append(littlefuzz, byte(popr.Intn(256)))
}
// shouldn't panic
_ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg)
}
}
func TestVersionCheckResponseMarshalTo(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, false)
size := p.Size()
dAtA := make([]byte, size)
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
_, err := p.MarshalTo(dAtA)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &VersionCheckResponse{}
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
for i := range dAtA {
dAtA[i] = byte(popr.Intn(256))
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func BenchmarkVersionCheckResponseProtoMarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*VersionCheckResponse, 10000)
for i := 0; i < 10000; i++ {
pops[i] = NewPopulatedVersionCheckResponse(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
if err != nil {
panic(err)
}
total += len(dAtA)
}
b.SetBytes(int64(total / b.N))
}
func BenchmarkVersionCheckResponseProtoUnmarshal(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
datas := make([][]byte, 10000)
for i := 0; i < 10000; i++ {
dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedVersionCheckResponse(popr, false))
if err != nil {
panic(err)
}
datas[i] = dAtA
}
msg := &VersionCheckResponse{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += len(datas[i%10000])
if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
panic(err)
}
}
b.SetBytes(int64(total / b.N))
}
func TestCheckRequestJSON(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, true)
marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &CheckRequest{}
err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
}
}
func TestHealthCheckResponseJSON(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, true)
marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &HealthCheckResponse{}
err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
}
}
func TestVersionCheckResponseJSON(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, true)
marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{}
jsondata, err := marshaler.MarshalToString(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
msg := &VersionCheckResponse{}
err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)
}
}
func TestCheckRequestProtoText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, true)
dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p)
msg := &CheckRequest{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestCheckRequestProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, true)
dAtA := github_com_gogo_protobuf_proto.CompactTextString(p)
msg := &CheckRequest{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestHealthCheckResponseProtoText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, true)
dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p)
msg := &HealthCheckResponse{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestHealthCheckResponseProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, true)
dAtA := github_com_gogo_protobuf_proto.CompactTextString(p)
msg := &HealthCheckResponse{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestVersionCheckResponseProtoText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, true)
dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p)
msg := &VersionCheckResponse{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestVersionCheckResponseProtoCompactText(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, true)
dAtA := github_com_gogo_protobuf_proto.CompactTextString(p)
msg := &VersionCheckResponse{}
if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
if !p.Equal(msg) {
t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)
}
}
func TestCheckRequestSize(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedCheckRequest(popr, true)
size2 := github_com_gogo_protobuf_proto.Size(p)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
size := p.Size()
if len(dAtA) != size {
t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA))
}
if size2 != size {
t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)
}
size3 := github_com_gogo_protobuf_proto.Size(p)
if size3 != size {
t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)
}
}
func BenchmarkCheckRequestSize(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*CheckRequest, 1000)
for i := 0; i < 1000; i++ {
pops[i] = NewPopulatedCheckRequest(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += pops[i%1000].Size()
}
b.SetBytes(int64(total / b.N))
}
func TestHealthCheckResponseSize(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedHealthCheckResponse(popr, true)
size2 := github_com_gogo_protobuf_proto.Size(p)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
size := p.Size()
if len(dAtA) != size {
t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA))
}
if size2 != size {
t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)
}
size3 := github_com_gogo_protobuf_proto.Size(p)
if size3 != size {
t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)
}
}
func BenchmarkHealthCheckResponseSize(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*HealthCheckResponse, 1000)
for i := 0; i < 1000; i++ {
pops[i] = NewPopulatedHealthCheckResponse(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += pops[i%1000].Size()
}
b.SetBytes(int64(total / b.N))
}
func TestVersionCheckResponseSize(t *testing.T) {
seed := time.Now().UnixNano()
popr := math_rand.New(math_rand.NewSource(seed))
p := NewPopulatedVersionCheckResponse(popr, true)
size2 := github_com_gogo_protobuf_proto.Size(p)
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
if err != nil {
t.Fatalf("seed = %d, err = %v", seed, err)
}
size := p.Size()
if len(dAtA) != size {
t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA))
}
if size2 != size {
t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)
}
size3 := github_com_gogo_protobuf_proto.Size(p)
if size3 != size {
t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)
}
}
func BenchmarkVersionCheckResponseSize(b *testing.B) {
popr := math_rand.New(math_rand.NewSource(616))
total := 0
pops := make([]*VersionCheckResponse, 1000)
for i := 0; i < 1000; i++ {
pops[i] = NewPopulatedVersionCheckResponse(popr, false)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
total += pops[i%1000].Size()
}
b.SetBytes(int64(total / b.N))
}
func TestCheckRequestStringer(t *testing.T) {
popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
p := NewPopulatedCheckRequest(popr, false)
s1 := p.String()
s2 := fmt.Sprintf("%v", p)
if s1 != s2 {
t.Fatalf("String want %v got %v", s1, s2)
}
}
func TestHealthCheckResponseStringer(t *testing.T) {
popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
p := NewPopulatedHealthCheckResponse(popr, false)
s1 := p.String()
s2 := fmt.Sprintf("%v", p)
if s1 != s2 {
t.Fatalf("String want %v got %v", s1, s2)
}
}
func TestVersionCheckResponseStringer(t *testing.T) {
popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
p := NewPopulatedVersionCheckResponse(popr, false)
s1 := p.String()
s2 := fmt.Sprintf("%v", p)
if s1 != s2 {
t.Fatalf("String want %v got %v", s1, s2)
}
}
//These tests are generated by github.com/gogo/protobuf/plugin/testgen

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,462 @@
//
// Copyright (c) 2017 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
syntax = "proto3";
package grpc;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/wrappers.proto";
option (gogoproto.equal_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
message Spec {
// Version of the Open Container Initiative Runtime Specification with which the bundle complies.
string Version = 1;
// Process configures the container process.
Process Process = 2;
// Root configures the container's root filesystem.
Root Root = 3;
// Hostname configures the container's hostname.
string Hostname = 4;
// Mounts configures additional mounts (on top of Root).
repeated Mount Mounts = 5 [(gogoproto.nullable) = false];
// Hooks configures callbacks for container lifecycle events.
Hooks Hooks = 6;
// Annotations contains arbitrary metadata for the container.
map<string, string> Annotations = 7;
// Linux is platform-specific configuration for Linux based containers.
Linux Linux = 8;
// Solaris is platform-specific configuration for Solaris based containers.
Solaris Solaris = 9;
// Windows is platform-specific configuration for Windows based containers.
Windows Windows = 10;
}
message Process {
// Terminal creates an interactive terminal for the container.
bool Terminal = 1;
// ConsoleSize specifies the size of the console.
Box ConsoleSize = 2;
// User specifies user information for the process.
User User = 3 [(gogoproto.nullable) = false];
// Args specifies the binary and arguments for the application to execute.
repeated string Args = 4;
// Env populates the process environment for the process.
repeated string Env = 5;
// Cwd is the current working directory for the process and must be
// relative to the container's root.
string Cwd = 6;
// Capabilities are Linux capabilities that are kept for the process.
LinuxCapabilities Capabilities = 7;
// Rlimits specifies rlimit options to apply to the process.
repeated POSIXRlimit Rlimits = 8 [(gogoproto.nullable) = false];
// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
bool NoNewPrivileges = 9;
// ApparmorProfile specifies the apparmor profile for the container.
string ApparmorProfile = 10;
// Specify an oom_score_adj for the container.
int64 OOMScoreAdj = 11;
// SelinuxLabel specifies the selinux context that the container process is run as.
string SelinuxLabel = 12;
}
message Box {
// Height is the vertical dimension of a box.
uint32 Height = 1;
// Width is the horizontal dimension of a box.
uint32 Width = 2;
}
message User {
// UID is the user id.
uint32 UID = 1;
// GID is the group id.
uint32 GID = 2;
// AdditionalGids are additional group ids set for the container's process.
repeated uint32 AdditionalGids = 3;
// Username is the user name.
string Username = 4;
}
message LinuxCapabilities {
// Bounding is the set of capabilities checked by the kernel.
repeated string Bounding = 1;
// Effective is the set of capabilities checked by the kernel.
repeated string Effective = 2;
// Inheritable is the capabilities preserved across execve.
repeated string Inheritable = 3;
// Permitted is the limiting superset for effective capabilities.
repeated string Permitted = 4;
// Ambient is the ambient set of capabilities that are kept.
repeated string Ambient = 5;
}
message POSIXRlimit {
// Type of the rlimit to set
string Type = 1;
// Hard is the hard limit for the specified type
uint64 Hard = 2;
// Soft is the soft limit for the specified type
uint64 Soft = 3;
}
message Mount {
// destination is the path inside the container expect when it starts with "tmp:/"
string destination = 1;
// source is the path inside the container expect when it starts with "vm:/dev/" or "tmp:/"
// the path which starts with "vm:/dev/" refers the guest vm's "/dev",
// especially, "vm:/dev/hostfs/" refers to the shared filesystem.
// "tmp:/" is a temporary directory which is used for temporary mounts.
string source = 2;
string type = 3;
repeated string options = 4;
}
message Root {
// Path is the absolute path to the container's root filesystem.
string Path = 1;
// Readonly makes the root filesystem for the container readonly before the process is executed.
bool Readonly = 2;
}
message Hooks {
// Prestart is a list of hooks to be run before the container process is executed.
repeated Hook Prestart = 1 [(gogoproto.nullable) = false];
// Poststart is a list of hooks to be run after the container process is started.
repeated Hook Poststart = 2 [(gogoproto.nullable) = false];
// Poststop is a list of hooks to be run after the container process exits.
repeated Hook Poststop = 3 [(gogoproto.nullable) = false];
}
message Hook {
string Path = 1;
repeated string Args = 2;
repeated string Env = 3;
int64 Timeout = 4;
}
message Linux {
// UIDMapping specifies user mappings for supporting user namespaces.
repeated LinuxIDMapping UIDMappings = 1 [(gogoproto.nullable) = false];
// GIDMapping specifies group mappings for supporting user namespaces.
repeated LinuxIDMapping GIDMappings = 2 [(gogoproto.nullable) = false];
// Sysctl are a set of key value pairs that are set for the container on start
map<string, string> Sysctl = 3;
// Resources contain cgroup information for handling resource constraints
// for the container
LinuxResources Resources = 4;
// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
// The path is expected to be relative to the cgroups mountpoint.
// If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
string CgroupsPath = 5;
// Namespaces contains the namespaces that are created and/or joined by the container
repeated LinuxNamespace Namespaces = 6 [(gogoproto.nullable) = false];
// Devices are a list of device nodes that are created for the container
repeated LinuxDevice Devices = 7 [(gogoproto.nullable) = false];
// Seccomp specifies the seccomp security settings for the container.
LinuxSeccomp Seccomp = 8;
// RootfsPropagation is the rootfs mount propagation mode for the container.
string RootfsPropagation = 9;
// MaskedPaths masks over the provided paths inside the container.
repeated string MaskedPaths = 10;
// ReadonlyPaths sets the provided paths as RO inside the container.
repeated string ReadonlyPaths = 11;
// MountLabel specifies the selinux context for the mounts in the container.
string MountLabel = 12;
// IntelRdt contains Intel Resource Director Technology (RDT) information
// for handling resource constraints (e.g., L3 cache) for the container
LinuxIntelRdt IntelRdt = 13;
}
message Windows {
// Dummy string, never used.
string dummy = 1;
}
message Solaris {
// Dummy string, never used.
string dummy = 1;
}
message LinuxIDMapping {
// HostID is the starting UID/GID on the host to be mapped to 'ContainerID'
uint32 HostID = 1;
// ContainerID is the starting UID/GID in the container
uint32 ContainerID = 2;
// Size is the number of IDs to be mapped
uint32 Size = 3;
}
message LinuxNamespace {
// Type is the type of namespace
string Type = 1;
// Path is a path to an existing namespace persisted on disk that can be joined
// and is of the same type
string Path = 2;
}
message LinuxDevice {
// Path to the device.
string Path = 1;
// Device type, block, char, etc.
string Type = 2;
// Major is the device's major number.
int64 Major = 3;
// Minor is the device's minor number.
int64 Minor = 4;
// FileMode permission bits for the device.
uint32 FileMode = 5;
// UID of the device.
uint32 UID = 6;
// Gid of the device.
uint32 GID = 7;
}
message LinuxResources {
// Devices configures the device whitelist.
repeated LinuxDeviceCgroup Devices = 1 [(gogoproto.nullable) = false];
// Memory restriction configuration
LinuxMemory Memory = 2;
// CPU resource restriction configuration
LinuxCPU CPU = 3;
// Task resource restriction configuration.
LinuxPids Pids = 4;
// BlockIO restriction configuration
LinuxBlockIO BlockIO = 5;
// Hugetlb limit (in bytes)
repeated LinuxHugepageLimit HugepageLimits = 6 [(gogoproto.nullable) = false];
// Network restriction configuration
LinuxNetwork Network = 7;
}
message LinuxMemory {
// Memory limit (in bytes).
int64 Limit = 1;
// Memory reservation or soft_limit (in bytes).
int64 Reservation = 2;
// Total memory limit (memory + swap).
int64 Swap = 3;
// Kernel memory limit (in bytes).
int64 Kernel = 4;
// Kernel memory limit for tcp (in bytes)
int64 KernelTCP = 5;
// How aggressive the kernel will swap memory pages.
uint64 Swappiness = 6;
// DisableOOMKiller disables the OOM killer for out of memory conditions
bool DisableOOMKiller = 7;
}
message LinuxCPU {
// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
uint64 Shares = 1;
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
int64 Quota = 2;
// CPU period to be used for hardcapping (in usecs).
uint64 Period = 3;
// How much time realtime scheduling may use (in usecs).
int64 RealtimeRuntime = 4;
// CPU period to be used for realtime scheduling (in usecs).
uint64 RealtimePeriod = 5;
// CPUs to use within the cpuset. Default is to use any CPU available.
string Cpus = 6;
// List of memory nodes in the cpuset. Default is to use any available memory node.
string Mems = 7;
}
message LinuxWeightDevice {
// Major is the device's major number.
int64 Major = 1;
// Minor is the device's minor number.
int64 Minor = 2;
// Weight is the bandwidth rate for the device.
uint32 Weight = 3;
// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, CFQ scheduler only
uint32 LeafWeight = 4;
}
message LinuxThrottleDevice {
// Major is the device's major number.
int64 Major = 1;
// Minor is the device's minor number.
int64 Minor = 2;
// Rate is the IO rate limit per cgroup per device
uint64 Rate = 3;
}
message LinuxBlockIO {
// Specifies per cgroup weight
uint32 Weight = 1;
// Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only
uint32 LeafWeight = 2;
// Weight per cgroup per device, can override BlkioWeight
repeated LinuxWeightDevice WeightDevice = 3 [(gogoproto.nullable) = false];
// IO read rate limit per cgroup per device, bytes per second
repeated LinuxThrottleDevice ThrottleReadBpsDevice = 4 [(gogoproto.nullable) = false];
// IO write rate limit per cgroup per device, bytes per second
repeated LinuxThrottleDevice ThrottleWriteBpsDevice = 5 [(gogoproto.nullable) = false];
// IO read rate limit per cgroup per device, IO per second
repeated LinuxThrottleDevice ThrottleReadIOPSDevice = 6 [(gogoproto.nullable) = false];
// IO write rate limit per cgroup per device, IO per second
repeated LinuxThrottleDevice ThrottleWriteIOPSDevice = 7 [(gogoproto.nullable) = false];
}
message LinuxPids {
// Maximum number of PIDs. Default is "no limit".
int64 Limit = 1;
}
message LinuxDeviceCgroup {
// Allow or deny
bool Allow = 1;
// Device type, block, char, etc.
string Type = 2;
// Major is the device's major number.
int64 Major = 3;
// Minor is the device's minor number.
int64 Minor = 4;
// Cgroup access permissions format, rwm.
string Access = 5;
}
message LinuxNetwork {
// Set class identifier for container's network packets
uint32 ClassID = 1;
// Set priority of network traffic for container
repeated LinuxInterfacePriority Priorities = 2 [(gogoproto.nullable) = false];
}
message LinuxHugepageLimit {
// Pagesize is the hugepage size
string Pagesize = 1;
// Limit is the limit of "hugepagesize" hugetlb usage
uint64 Limit = 2;
}
message LinuxInterfacePriority {
// Name is the name of the network interface
string Name = 1;
// Priority for the interface
uint32 Priority = 2;
}
message LinuxSeccomp {
string DefaultAction = 1;
repeated string Architectures = 2;
repeated LinuxSyscall Syscalls = 3 [(gogoproto.nullable) = false];
}
message LinuxSeccompArg {
uint64 Index = 1;
uint64 Value = 2;
uint64 ValueTwo = 3;
string Op = 4;
}
message LinuxSyscall {
repeated string Names = 1;
string Action = 2;
repeated LinuxSeccompArg Args = 3 [(gogoproto.nullable) = false];
}
message LinuxIntelRdt {
// The schema for L3 cache id and capacity bitmask (CBM)
// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
string L3CacheSchema = 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,289 @@
//
// Copyright (c) 2017 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package grpc
import (
"reflect"
"google.golang.org/grpc/codes"
grpcStatus "google.golang.org/grpc/status"
"github.com/opencontainers/runtime-spec/specs-go"
)
func copyValue(to, from reflect.Value) error {
toKind := to.Kind()
fromKind := from.Kind()
if !from.IsValid() {
return nil
}
if toKind == reflect.Ptr {
// Handle the case of nil pointers.
if fromKind == reflect.Ptr && from.IsNil() {
return nil
}
// If the destination and the origin are both pointers, and
// if the origin is not nil, we need to allocate a new one
// for the destination.
to.Set(reflect.New(to.Type().Elem()))
if fromKind == reflect.Ptr {
return copyValue(to.Elem(), from.Elem())
}
return copyValue(to.Elem(), from)
}
// Here the destination is not a pointer.
// Let's check what's the origin.
if fromKind == reflect.Ptr {
return copyValue(to, from.Elem())
}
switch toKind {
case reflect.Struct:
return copyStructValue(to, from)
case reflect.Slice:
return copySliceValue(to, from)
case reflect.Map:
return copyMapValue(to, from)
default:
// We now are copying non pointers scalar.
// This is the leaf of the recursion.
if from.Type() != to.Type() {
if from.Type().ConvertibleTo(to.Type()) {
to.Set(from.Convert(to.Type()))
return nil
}
return grpcStatus.Errorf(codes.InvalidArgument, "Can not convert %v to %v", from.Type(), to.Type())
}
to.Set(from)
return nil
}
}
func copyMapValue(to, from reflect.Value) error {
if to.Kind() != reflect.Map && from.Kind() != reflect.Map {
return grpcStatus.Errorf(codes.InvalidArgument, "Can only copy maps into maps")
}
to.Set(reflect.MakeMap(to.Type()))
keys := from.MapKeys()
for _, k := range keys {
newValue := reflect.New(to.Type().Elem())
v := from.MapIndex(k)
if err := copyValue(newValue.Elem(), v); err != nil {
return err
}
to.SetMapIndex(k, newValue.Elem())
}
return nil
}
func copySliceValue(to, from reflect.Value) error {
if to.Kind() != reflect.Slice && from.Kind() != reflect.Slice {
return grpcStatus.Errorf(codes.InvalidArgument, "Can only copy slices into slices")
}
sliceLen := from.Len()
to.Set(reflect.MakeSlice(to.Type(), sliceLen, sliceLen))
for j := 0; j < sliceLen; j++ {
if err := copyValue(to.Index(j), from.Index(j)); err != nil {
return err
}
}
return nil
}
func copyStructSkipField(to, from reflect.Value) bool {
var grpcSolaris Solaris
var ociSolaris specs.Solaris
var grpcWindows Windows
var ociWindows specs.Windows
toType := to.Type()
grpcSolarisType := reflect.TypeOf(grpcSolaris)
ociSolarisType := reflect.TypeOf(ociSolaris)
grpcWindowsType := reflect.TypeOf(grpcWindows)
ociWindowsType := reflect.TypeOf(ociWindows)
// We skip all Windows and Solaris types
if toType == grpcSolarisType || toType == grpcWindowsType || toType == ociSolarisType || toType == ociWindowsType {
return true
}
return false
}
func structFieldName(v reflect.Value, index int) (string, error) {
if v.Kind() != reflect.Struct {
return "", grpcStatus.Errorf(codes.InvalidArgument, "Can only infer field name from structs")
}
return v.Type().Field(index).Name, nil
}
func isEmbeddedStruct(v reflect.Value, index int) bool {
if v.Kind() != reflect.Struct || index > v.Type().NumField()-1 {
return false
}
return v.Type().Field(index).Anonymous
}
func findStructField(v reflect.Value, name string) (reflect.Value, error) {
if v.Kind() != reflect.Struct {
return reflect.Value{}, grpcStatus.Errorf(codes.InvalidArgument, "Can only infer field name from structs")
}
for i := 0; i < v.NumField(); i++ {
if v.Type().Field(i).Name == name {
return v.Field(i), nil
}
}
return reflect.Value{}, grpcStatus.Errorf(codes.InvalidArgument, "Could not find field %s", name)
}
func copyStructValue(to, from reflect.Value) error {
if to.Kind() != reflect.Struct && from.Kind() != reflect.Struct {
return grpcStatus.Errorf(codes.InvalidArgument, "Can only copy structs into structs")
}
if copyStructSkipField(to, from) {
return nil
}
for i := 0; i < to.NumField(); i++ {
// If one of the field is embedded, we copy between the embedded field
// and the structure itself. The fields in the embedded field should
// be found in the parent structure.
if isEmbeddedStruct(to, i) {
if err := copyStructValue(to.Field(i), from); err != nil {
return err
}
continue
}
if isEmbeddedStruct(from, i) {
if err := copyStructValue(to, from.Field(i)); err != nil {
return err
}
continue
}
// Find the destination structure field name.
fieldName, err := structFieldName(to, i)
if err != nil {
return err
}
// Try to find the same field name in the origin structure.
// This can fail as we support copying between structures
// that optionally have embedded fields.
v, err := findStructField(from, fieldName)
if err != nil {
continue
}
if err := copyValue(to.Field(i), v); err != nil {
return err
}
}
return nil
}
func copyStruct(to interface{}, from interface{}) (err error) {
defer func() {
if r := recover(); r != nil {
err = r.(error)
}
}()
toVal := reflect.ValueOf(to)
fromVal := reflect.ValueOf(from)
if toVal.Kind() != reflect.Ptr || toVal.Elem().Kind() != reflect.Struct ||
fromVal.Kind() != reflect.Ptr || fromVal.Elem().Kind() != reflect.Struct {
return grpcStatus.Errorf(codes.InvalidArgument, "Arguments must be pointers to structures")
}
toVal = toVal.Elem()
fromVal = fromVal.Elem()
return copyStructValue(toVal, fromVal)
}
// OCItoGRPC converts an OCI specification to its gRPC representation
func OCItoGRPC(ociSpec *specs.Spec) (*Spec, error) {
s := &Spec{}
err := copyStruct(s, ociSpec)
return s, err
}
// GRPCtoOCI converts a gRPC specification back into an OCI representation
func GRPCtoOCI(grpcSpec *Spec) (*specs.Spec, error) {
s := &specs.Spec{}
err := copyStruct(s, grpcSpec)
return s, err
}
// ProcessOCItoGRPC converts an OCI process specification into its gRPC
// representation
func ProcessOCItoGRPC(ociProcess *specs.Process) (*Process, error) {
s := &Process{}
err := copyStruct(s, ociProcess)
return s, err
}
// ProcessGRPCtoOCI converts a gRPC specification back into an OCI
// representation
func ProcessGRPCtoOCI(grpcProcess *Process) (*specs.Process, error) {
s := &specs.Process{}
err := copyStruct(s, grpcProcess)
return s, err
}
// ResourcesOCItoGRPC converts an OCI LinuxResources specification into its gRPC
// representation
func ResourcesOCItoGRPC(ociResources *specs.LinuxResources) (*LinuxResources, error) {
s := &LinuxResources{}
err := copyStruct(s, ociResources)
return s, err
}
// ResourcesGRPCtoOCI converts an gRPC LinuxResources specification into its OCI
// representation
func ResourcesGRPCtoOCI(grpcResources *LinuxResources) (*specs.LinuxResources, error) {
s := &specs.LinuxResources{}
err := copyStruct(s, grpcResources)
return s, err
}

View File

@@ -0,0 +1,196 @@
//
// Copyright (c) 2017 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package grpc
import (
"encoding/json"
"io/ioutil"
"reflect"
"testing"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
)
const ociConfigFile = "config.json"
func assertProcessIsEqual(t *testing.T, ociProcess *specs.Process, grpcProcess *Process) {
assert := assert.New(t)
// Process checks: User
assert.Equal(grpcProcess.User.UID, ociProcess.User.UID)
assert.Equal(grpcProcess.User.GID, ociProcess.User.GID)
// Process checks: Capabilities
assert.Equal(grpcProcess.Capabilities.Bounding, ociProcess.Capabilities.Bounding)
assert.Equal(grpcProcess.Capabilities.Effective, ociProcess.Capabilities.Effective)
assert.Equal(grpcProcess.Capabilities.Inheritable, ociProcess.Capabilities.Inheritable)
assert.Equal(grpcProcess.Capabilities.Permitted, ociProcess.Capabilities.Permitted)
assert.Equal(grpcProcess.Capabilities.Ambient, ociProcess.Capabilities.Ambient)
}
func assertIsEqual(t *testing.T, ociSpec *specs.Spec, grpcSpec *Spec) {
assert := assert.New(t)
// Version check
assert.Equal(grpcSpec.Version, ociSpec.Version)
// Process checks:
assertProcessIsEqual(t, ociSpec.Process, grpcSpec.Process)
// Annotations checks: Annotations
assert.Equal(len(grpcSpec.Annotations), len(ociSpec.Annotations))
for k := range grpcSpec.Annotations {
assert.Equal(grpcSpec.Annotations[k], ociSpec.Annotations[k])
}
// Linux checks: Devices
assert.Equal(len(grpcSpec.Linux.Resources.Devices), len(ociSpec.Linux.Resources.Devices))
assert.Equal(len(grpcSpec.Linux.Resources.Devices), 1)
assert.Equal(grpcSpec.Linux.Resources.Devices[0].Access, "rwm")
// Linux checks: Block IO, for checking embedded structures copy
assert.NotNil(ociSpec.Linux.Resources.BlockIO.LeafWeight)
assert.NotNil(ociSpec.Linux.Resources.BlockIO.Weight)
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.Weight, *ociSpec.Linux.Resources.BlockIO.Weight)
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.LeafWeight, *ociSpec.Linux.Resources.BlockIO.LeafWeight)
assert.NotEqual(len(grpcSpec.Linux.Resources.BlockIO.WeightDevice), 0)
assert.Equal(len(grpcSpec.Linux.Resources.BlockIO.WeightDevice), len(grpcSpec.Linux.Resources.BlockIO.WeightDevice))
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.WeightDevice[0].Major, ociSpec.Linux.Resources.BlockIO.WeightDevice[0].Major)
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.WeightDevice[0].Minor, ociSpec.Linux.Resources.BlockIO.WeightDevice[0].Minor)
assert.NotNil(ociSpec.Linux.Resources.BlockIO.WeightDevice[0].LeafWeight)
assert.NotNil(ociSpec.Linux.Resources.BlockIO.WeightDevice[0].Weight)
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.WeightDevice[0].Weight, *ociSpec.Linux.Resources.BlockIO.WeightDevice[0].Weight)
assert.EqualValues(grpcSpec.Linux.Resources.BlockIO.WeightDevice[0].LeafWeight, *ociSpec.Linux.Resources.BlockIO.WeightDevice[0].LeafWeight)
// Linux checks: Namespaces
assert.Equal(len(grpcSpec.Linux.Namespaces), len(ociSpec.Linux.Namespaces))
assert.Equal(len(grpcSpec.Linux.Namespaces), 5)
for i := range grpcSpec.Linux.Namespaces {
assert.Equal(grpcSpec.Linux.Namespaces[i].Type, (string)(ociSpec.Linux.Namespaces[i].Type)) //nolint:unconvert
assert.Equal(grpcSpec.Linux.Namespaces[i].Path, (string)(ociSpec.Linux.Namespaces[i].Path)) //nolint:unconvert
}
}
func TestOCItoGRPC(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
assert.NoError(err, "Could not unmarshall OCI config file")
spec, err := OCItoGRPC(&ociSpec)
assert.NoError(err, "Could not convert OCI config file")
assertIsEqual(t, &ociSpec, spec)
}
func TestGRPCtoOCI(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
assert.NoError(err, "Could not unmarshall OCI config file")
grpcSpec, err := OCItoGRPC(&ociSpec)
assert.NoError(err, "Could not convert OCI config file")
newOciSpec, err := GRPCtoOCI(grpcSpec)
assert.NoError(err, "Could not convert gRPC structure")
assertIsEqual(t, newOciSpec, grpcSpec)
}
func TestProcessOCItoGRPC(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
assert.NoError(err, "Could not unmarshall OCI config file")
process, err := ProcessOCItoGRPC(ociSpec.Process)
assert.NoError(err, "Could not convert OCI config file")
assertProcessIsEqual(t, ociSpec.Process, process)
}
func TestProcessGRPCtoOCI(t *testing.T) {
assert := assert.New(t)
var ociSpec specs.Spec
configJSONBytes, err := ioutil.ReadFile(ociConfigFile)
assert.NoError(err, "Could not open OCI config file")
err = json.Unmarshal(configJSONBytes, &ociSpec)
assert.NoError(err, "Could not unmarshall OCI config file")
grpcProcess, err := ProcessOCItoGRPC(ociSpec.Process)
assert.NoError(err, "Could not convert OCI config file")
newOciProcess, err := ProcessGRPCtoOCI(grpcProcess)
assert.NoError(err, "Could not convert gRPC structure")
assertProcessIsEqual(t, newOciProcess, grpcProcess)
}
func testCopyValue(t *testing.T, to, from interface{}) {
assert := assert.New(t)
err := copyValue(reflect.ValueOf(to).Elem(), reflect.ValueOf(from))
assert.NoError(err, "Could not copy to %v", reflect.ValueOf(from).Kind())
assert.Equal(reflect.ValueOf(to).Elem().Interface(), reflect.ValueOf(from).Interface())
}
func TestCopyValueString(t *testing.T) {
from := "foobar"
to := new(string)
testCopyValue(t, to, from)
}
func TestCopyValueSlice(t *testing.T) {
from := []string{"foobar", "barfoo"}
to := new([]string)
testCopyValue(t, to, from)
}
func TestCopyValueStruc(t *testing.T) {
type dummyStruct struct {
S string
I int
}
from := dummyStruct{
S: "foobar",
I: 18,
}
to := new(dummyStruct)
testCopyValue(t, to, from)
}
func TestCopyValueMap(t *testing.T) {
from := map[string]string{
"key1": "value1",
"key2": "value2",
}
to := new(map[string]string)
testCopyValue(t, to, from)
}

View File

@@ -0,0 +1,11 @@
//
// Copyright 2017 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package grpc
// APIVersion specifies the version of the gRPC communications protocol used
// by Kata Containers.
const APIVersion = "0.0.1"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
//
// Copyright 2018 Intel Corporation.
//
// SPDX-License-Identifier: Apache-2.0
//
syntax = "proto3";
package types;
enum IPFamily {
v4 = 0;
v6 = 1;
}
message IPAddress {
IPFamily family = 1;
string address = 2;
string mask = 3;
}
message Interface {
string device = 1;
string name = 2;
repeated IPAddress IPAddresses = 3;
uint64 mtu = 4;
string hwAddr = 5;
// pciAddr is the PCI address in the format "bridgeAddr/deviceAddr".
// Here, bridgeAddr is the address at which the bridge is attached on the root bus,
// while deviceAddr is the address at which the network device is attached on the bridge.
string pciAddr = 6;
// Type defines the type of interface described by this structure.
// The expected values are the one that are defined by the netlink
// library, regarding each type of link. Here is a non exhaustive
// list: "veth", "macvtap", "vlan", "macvlan", "tap", ...
string type = 7;
uint32 raw_flags = 8;
}
message Route {
string dest = 1;
string gateway = 2;
string device = 3;
string source = 4;
uint32 scope = 5;
}

View File

@@ -13,8 +13,8 @@ import (
"path/filepath"
"strings"
kataclient "github.com/kata-containers/agent/protocols/client"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
kataclient "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/client"
"github.com/sirupsen/logrus"
)

View File

@@ -25,7 +25,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"github.com/kata-containers/agent/protocols/grpc"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers"