mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-20 23:04:22 +01:00
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:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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...
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
473
src/runtime/virtcontainers/pkg/agent/protocols/client/client.go
Normal file
473
src/runtime/virtcontainers/pkg/agent/protocols/client/client.go
Normal 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)
|
||||
}
|
||||
15087
src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go
Normal file
15087
src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
496
src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.proto
Normal file
496
src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.proto
Normal 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 {
|
||||
}
|
||||
586
src/runtime/virtcontainers/pkg/agent/protocols/grpc/config.json
Normal file
586
src/runtime/virtcontainers/pkg/agent/protocols/grpc/config.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1026
src/runtime/virtcontainers/pkg/agent/protocols/grpc/health.pb.go
Normal file
1026
src/runtime/virtcontainers/pkg/agent/protocols/grpc/health.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
12960
src/runtime/virtcontainers/pkg/agent/protocols/grpc/oci.pb.go
Normal file
12960
src/runtime/virtcontainers/pkg/agent/protocols/grpc/oci.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
462
src/runtime/virtcontainers/pkg/agent/protocols/grpc/oci.proto
Normal file
462
src/runtime/virtcontainers/pkg/agent/protocols/grpc/oci.proto
Normal 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;
|
||||
}
|
||||
5822
src/runtime/virtcontainers/pkg/agent/protocols/grpc/ocipb_test.go
Normal file
5822
src/runtime/virtcontainers/pkg/agent/protocols/grpc/ocipb_test.go
Normal file
File diff suppressed because it is too large
Load Diff
289
src/runtime/virtcontainers/pkg/agent/protocols/grpc/utils.go
Normal file
289
src/runtime/virtcontainers/pkg/agent/protocols/grpc/utils.go
Normal 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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"
|
||||
1302
src/runtime/virtcontainers/pkg/agent/protocols/types.pb.go
Normal file
1302
src/runtime/virtcontainers/pkg/agent/protocols/types.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
48
src/runtime/virtcontainers/pkg/agent/protocols/types.proto
Normal file
48
src/runtime/virtcontainers/pkg/agent/protocols/types.proto
Normal 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;
|
||||
}
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user