diff --git a/Gopkg.lock b/Gopkg.lock index 4c8ab706ed..f6077d087d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -397,7 +397,7 @@ revision = "8cba5a8e5f2816f26f9dc34b8ea968279a5a76eb" [[projects]] - digest = "1:22e399f891fccaac4700943a9465f2623bb361653d5e0d4a9974573cd5e69070" + digest = "1:54e0385cece7064d8afd967e0987e52cd8b261c8c7e22d84e8b25719d7379e74" name = "github.com/kata-containers/agent" packages = [ "pkg/types", @@ -405,7 +405,7 @@ "protocols/grpc", ] pruneopts = "NUT" - revision = "94e2a254a94a77c02280f4f84d7f82269be163ce" + revision = "3ffb7ca1067565a45ee9fbfcb109eb85e7e899af" [[projects]] branch = "master" diff --git a/Gopkg.toml b/Gopkg.toml index bde6de1c00..215cacc449 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -52,7 +52,7 @@ [[constraint]] name = "github.com/kata-containers/agent" - revision = "94e2a254a94a77c02280f4f84d7f82269be163ce" + revision = "3ffb7ca1067565a45ee9fbfcb109eb85e7e899af" [[constraint]] name = "github.com/containerd/cri-containerd" diff --git a/vendor/github.com/kata-containers/agent/protocols/client/client.go b/vendor/github.com/kata-containers/agent/protocols/client/client.go index a0431301dc..a4b0ac3db9 100644 --- a/vendor/github.com/kata-containers/agent/protocols/client/client.go +++ b/vendor/github.com/kata-containers/agent/protocols/client/client.go @@ -29,11 +29,14 @@ import ( const ( unixSocketScheme = "unix" vsockSocketScheme = "vsock" + hybridVSockScheme = "hvsock" ) var defaultDialTimeout = 15 * time.Second var defaultCloseTimeout = 5 * time.Second +var hybridVSockPort uint32 + // AgentClient is an agent gRPC client connection wrapper for agentgrpc.AgentServiceClient type AgentClient struct { agentgrpc.AgentServiceClient @@ -77,6 +80,9 @@ type dialer func(string, time.Duration) (net.Conn, error) // - unix:// // - vsock://: // - +// - hvsock://:. 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 { @@ -158,6 +164,21 @@ func parse(sock string) (string, *url.URL, error) { } 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) } @@ -190,6 +211,8 @@ func agentDialer(addr *url.URL, enableYamux bool) dialer { switch addr.Scheme { case vsockSocketScheme: d = vsockDialer + case hybridVSockScheme: + d = hybridVSockDialer case unixSocketScheme: fallthrough default: @@ -274,6 +297,18 @@ func parseGrpcVsockAddr(sock string) (uint32, uint32, error) { return uint32(cid), uint32(port), nil } +func parseGrpcHybridVSockAddr(sock string) (string, error) { + sp := strings.Split(sock, ":") + if len(sp) != 2 { + return "", grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock address: %s", sock) + } + if sp[0] != hybridVSockScheme { + return "", grpcStatus.Errorf(codes.InvalidArgument, "Invalid hybrid vsock URL scheme: %s", sock) + } + + return sp[1], 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 @@ -335,3 +370,37 @@ func vsockDialer(sock string, timeout time.Duration) (net.Conn, error) { return commonDialer(timeout, dialFunc, timeoutErr) } + +func hybridVSockDialer(sock string, timeout time.Duration) (net.Conn, error) { + udsPath, err := parseGrpcHybridVSockAddr(sock) + if err != nil { + return nil, err + } + + dialFunc := func() (net.Conn, error) { + conn, err := net.DialTimeout("unix", udsPath, timeout) + if err != nil { + return nil, err + } + // 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", hybridVSockPort))); err != nil { + conn.Close() + return nil, err + } + + // Read EOT (End of transmission) byte + eot := make([]byte, 32) + if _, err = conn.Read(eot); err != nil { + // Just close the connection, gRPC will dial again + // without errors + conn.Close() + } + + return conn, nil + } + + timeoutErr := grpcStatus.Errorf(codes.DeadlineExceeded, "timed out connecting to hybrid vsocket %s", sock) + return commonDialer(timeout, dialFunc, timeoutErr) +} diff --git a/versions.yaml b/versions.yaml index fc783f050c..2e1f13054b 100644 --- a/versions.yaml +++ b/versions.yaml @@ -76,7 +76,7 @@ assets: uscan-url: >- https://github.com/firecracker-microvm/firecracker/tags .*/v?(\d\S+)\.tar\.gz - version: "v0.17.0" + version: "v0.18.0" nemu: description: "Reduced-emulation VMM that uses KVM" diff --git a/virtcontainers/acrn.go b/virtcontainers/acrn.go index a4a431c0d0..c308055b41 100644 --- a/virtcontainers/acrn.go +++ b/virtcontainers/acrn.go @@ -547,7 +547,7 @@ func (a *acrn) addDevice(devInfo interface{}, devType deviceType) error { err = nil case types.Socket: a.acrnConfig.Devices = a.arch.appendSocket(a.acrnConfig.Devices, v) - case kataVSOCK: + case types.VSock: // Not supported. return success err = nil case Endpoint: @@ -657,3 +657,7 @@ func (a *acrn) check() error { return nil } + +func (a *acrn) generateSocket(id string, useVsock bool) (interface{}, error) { + return generateVMSocket(id, useVsock) +} diff --git a/virtcontainers/api_test.go b/virtcontainers/api_test.go index 1c76ec5683..b037b85489 100644 --- a/virtcontainers/api_test.go +++ b/virtcontainers/api_test.go @@ -121,6 +121,7 @@ func newTestSandboxConfigNoop() SandboxConfig { func newTestSandboxConfigKataAgent() SandboxConfig { sandboxConfig := newTestSandboxConfigNoop() sandboxConfig.AgentType = KataContainersAgent + sandboxConfig.AgentConfig = KataAgentConfig{} sandboxConfig.Containers = nil return sandboxConfig diff --git a/virtcontainers/fc.go b/virtcontainers/fc.go index c498d6e932..332c038cc6 100644 --- a/virtcontainers/fc.go +++ b/virtcontainers/fc.go @@ -30,7 +30,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/blang/semver" "github.com/kata-containers/runtime/virtcontainers/device/config" + fcmodels "github.com/kata-containers/runtime/virtcontainers/pkg/firecracker/client/models" "github.com/kata-containers/runtime/virtcontainers/store" "github.com/kata-containers/runtime/virtcontainers/types" "github.com/kata-containers/runtime/virtcontainers/utils" @@ -58,8 +60,17 @@ const ( // We attach a pool of placeholder drives before the guest has started, and then // patch the replace placeholder drives with drives with actual contents. fcDiskPoolSize = 8 + + defaultHybridVSocketName = "kata.hvsock" + + // This is the first usable vsock context ID. All the vsocks can use the same + // ID, since it's only used in the guest. + defaultGuestVSockCID = int64(0x3) ) +// Specify the minimum version of firecracker supported +var fcMinSupportedVersion = semver.MustParse("0.18.0") + var fcKernelParams = append(commonVirtioblkKernelRootParams, []Param{ // The boot source is the first partition of the first block device added {"pci", "off"}, @@ -261,6 +272,8 @@ func (fc *firecracker) newFireClient() *client.Firecracker { } transport := httptransport.New(client.DefaultHost, client.DefaultBasePath, client.DefaultSchemes) + transport.SetLogger(fc.Logger()) + transport.SetDebug(fc.Logger().Logger.Level == logrus.DebugLevel) transport.Transport = socketTransport httpClient.SetTransport(transport) @@ -288,6 +301,23 @@ func (fc *firecracker) vmRunning() bool { } } +func (fc *firecracker) checkVersion(vmmInfo *fcmodels.InstanceInfo) error { + if vmmInfo == nil || vmmInfo.VmmVersion == nil { + return fmt.Errorf("Unknown firecracker version") + } + + v, err := semver.Make(*vmmInfo.VmmVersion) + if err != nil { + return fmt.Errorf("Malformed firecracker version: %v", err) + } + + if v.LT(fcMinSupportedVersion) { + return fmt.Errorf("version %v is not supported. Minimum supported version of firecracker is %v", v.String(), fcMinSupportedVersion.String()) + } + + return nil +} + // waitVMM will wait for timeout seconds for the VMM to be up and running. // This does not mean that the VM is up and running. It only indicates that the VMM is up and // running and able to handle commands to setup and launch a VM @@ -301,8 +331,11 @@ func (fc *firecracker) waitVMM(timeout int) error { timeStart := time.Now() for { - _, err := fc.client().Operations.DescribeInstance(nil) + vmmInfo, err := fc.client().Operations.DescribeInstance(nil) if err == nil { + if err := fc.checkVersion(vmmInfo.Payload); err != nil { + return err + } return nil } @@ -735,28 +768,33 @@ func (fc *firecracker) resumeSandbox() error { return nil } -func (fc *firecracker) fcAddVsock(vs kataVSOCK) error { +func (fc *firecracker) fcAddVsock(hvs types.HybridVSock) error { span, _ := fc.trace("fcAddVsock") defer span.Finish() + udsPath := hvs.UdsPath + if fc.jailed { + udsPath = filepath.Join("/", defaultHybridVSocketName) + } + vsockParams := ops.NewPutGuestVsockByIDParams() vsockID := "root" - ctxID := int64(vs.contextID) + ctxID := defaultGuestVSockCID vsock := &models.Vsock{ GuestCid: &ctxID, - ID: &vsockID, + UdsPath: &udsPath, + VsockID: &vsockID, } vsockParams.SetID(vsockID) vsockParams.SetBody(vsock) - _, _, err := fc.client().Operations.PutGuestVsockByID(vsockParams) + + _, err := fc.client().Operations.PutGuestVsockByID(vsockParams) if err != nil { return err } - //Still racy. There is no way to send an fd to the firecracker - //REST API. We could release this just before we start the instance - //but even that will not eliminate the race - vs.vhostFd.Close() + return nil + } func (fc *firecracker) fcAddNetDevice(endpoint Endpoint) error { @@ -874,8 +912,8 @@ func (fc *firecracker) addDevice(devInfo interface{}, devType deviceType) error case config.BlockDrive: fc.Logger().WithField("device-type-blockdrive", devInfo).Info("Adding device") return fc.fcAddBlockDrive(v) - case kataVSOCK: - fc.Logger().WithField("device-type-vsock", devInfo).Info("Adding device") + case types.HybridVSock: + fc.Logger().WithField("device-type-hybrid-vsock", devInfo).Info("Adding device") return fc.fcAddVsock(v) default: fc.Logger().WithField("unknown-device-type", devInfo).Error("Adding device") @@ -1014,3 +1052,17 @@ func (fc *firecracker) check() error { return nil } + +func (fc *firecracker) generateSocket(id string, useVsock bool) (interface{}, error) { + if !useVsock { + return nil, fmt.Errorf("Can't start firecracker: vsocks is disabled") + } + + fc.Logger().Debug("Using hybrid-vsock endpoint") + udsPath := filepath.Join(fc.jailerRoot, defaultHybridVSocketName) + + return types.HybridVSock{ + UdsPath: udsPath, + Port: uint32(vSockPort), + }, nil +} diff --git a/virtcontainers/fc_test.go b/virtcontainers/fc_test.go new file mode 100644 index 0000000000..badcf7980a --- /dev/null +++ b/virtcontainers/fc_test.go @@ -0,0 +1,31 @@ +// Copyright (c) 2019 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package virtcontainers + +import ( + "testing" + + "github.com/kata-containers/runtime/virtcontainers/types" + "github.com/stretchr/testify/assert" +) + +func TestFCGenerateSocket(t *testing.T) { + assert := assert.New(t) + + fc := firecracker{} + i, err := fc.generateSocket("a", false) + assert.Error(err) + assert.Nil(i) + + i, err = fc.generateSocket("a", true) + assert.NoError(err) + assert.NotNil(i) + + hvsock, ok := i.(types.HybridVSock) + assert.True(ok) + assert.NotEmpty(hvsock.UdsPath) + assert.NotZero(hvsock.Port) +} diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index a65fb7ecd7..acae8b82ee 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -10,6 +10,7 @@ import ( "context" "fmt" "os" + "path/filepath" "runtime" "strconv" "strings" @@ -18,6 +19,7 @@ import ( persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api" "github.com/kata-containers/runtime/virtcontainers/store" "github.com/kata-containers/runtime/virtcontainers/types" + "github.com/kata-containers/runtime/virtcontainers/utils" ) // HypervisorType describes an hypervisor type. @@ -52,6 +54,15 @@ const ( defaultBridges = 1 defaultBlockDriver = config.VirtioSCSI + + defaultSocketName = "kata.sock" + defaultSocketDeviceID = "channel0" + defaultSocketChannelName = "agent.channel.0" + defaultSocketID = "charch0" + + // port numbers below 1024 are called privileged ports. Only a process with + // CAP_NET_BIND_SERVICE capability may bind to these port numbers. + vSockPort = 1024 ) // In some architectures the maximum number of vCPUs depends on the number of physical cores. @@ -104,6 +115,10 @@ const ( // memoryDevice is memory device type memoryDev + + // hybridVirtioVsockDev is a hybrid virtio-vsock device supported + // only on certain hypervisors, like firecracker. + hybridVirtioVsockDev ) type memoryDevice struct { @@ -659,6 +674,33 @@ func getHypervisorPid(h hypervisor) int { return pids[0] } +func generateVMSocket(id string, useVsock bool) (interface{}, error) { + if useVsock { + vhostFd, contextID, err := utils.FindContextID() + if err != nil { + return nil, err + } + + return types.VSock{ + VhostFd: vhostFd, + ContextID: contextID, + Port: uint32(vSockPort), + }, nil + } + + path, err := utils.BuildSocketPath(filepath.Join(store.RunVMStoragePath, id), defaultSocketName) + if err != nil { + return nil, err + } + + return types.Socket{ + DeviceID: defaultSocketDeviceID, + ID: defaultSocketID, + HostPath: path, + Name: defaultSocketChannelName, + }, nil +} + // hypervisor is the virtcontainers hypervisor interface. // The default hypervisor implementation is Qemu. type hypervisor interface { @@ -688,4 +730,7 @@ type hypervisor interface { save() persistapi.HypervisorState load(persistapi.HypervisorState) + + // generate the socket to communicate the host and guest + generateSocket(id string, useVsock bool) (interface{}, error) } diff --git a/virtcontainers/hypervisor_test.go b/virtcontainers/hypervisor_test.go index 3953b27fad..7cc97f2bf6 100644 --- a/virtcontainers/hypervisor_test.go +++ b/virtcontainers/hypervisor_test.go @@ -12,6 +12,8 @@ import ( "path/filepath" "testing" + ktu "github.com/kata-containers/runtime/pkg/katatestutils" + "github.com/kata-containers/runtime/virtcontainers/types" "github.com/stretchr/testify/assert" ) @@ -435,3 +437,28 @@ func genericTestRunningOnVMM(t *testing.T, data []testNestedVMMData) { assert.Equal(running, d.expected) } } + +func TestGenerateVMSocket(t *testing.T) { + assert := assert.New(t) + + s, err := generateVMSocket("a", false) + assert.NoError(err) + socket, ok := s.(types.Socket) + assert.True(ok) + assert.NotEmpty(socket.DeviceID) + assert.NotEmpty(socket.ID) + assert.NotEmpty(socket.HostPath) + assert.NotEmpty(socket.Name) + + if tc.NotValid(ktu.NeedRoot()) { + t.Skip(testDisabledAsNonRoot) + } + s, err = generateVMSocket("a", true) + assert.NoError(err) + vsock, ok := s.(types.VSock) + assert.True(ok) + defer assert.NoError(vsock.VhostFd.Close()) + assert.NotZero(vsock.VhostFd) + assert.NotZero(vsock.ContextID) + assert.NotZero(vsock.Port) +} diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 4cb104d16b..26b4ae6726 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -31,7 +31,6 @@ import ( "github.com/kata-containers/runtime/virtcontainers/pkg/uuid" "github.com/kata-containers/runtime/virtcontainers/store" "github.com/kata-containers/runtime/virtcontainers/types" - "github.com/kata-containers/runtime/virtcontainers/utils" "github.com/opencontainers/runtime-spec/specs-go" opentracing "github.com/opentracing/opentracing-go" "github.com/sirupsen/logrus" @@ -53,25 +52,17 @@ const ( ) var ( - checkRequestTimeout = 30 * time.Second - defaultRequestTimeout = 60 * time.Second - defaultKataSocketName = "kata.sock" - defaultKataChannel = "agent.channel.0" - defaultKataDeviceID = "channel0" - defaultKataID = "charch0" - errorMissingProxy = errors.New("Missing proxy pointer") - errorMissingOCISpec = errors.New("Missing OCI specification") - kataHostSharedDir = "/run/kata-containers/shared/sandboxes/" - kataGuestSharedDir = "/run/kata-containers/shared/containers/" - mountGuest9pTag = "kataShared" - kataGuestSandboxDir = "/run/kata-containers/sandbox/" - type9pFs = "9p" - typeVirtioFS = "virtio_fs" - typeVirtioFSNoCache = "none" - vsockSocketScheme = "vsock" - // port numbers below 1024 are called privileged ports. Only a process with - // CAP_NET_BIND_SERVICE capability may bind to these port numbers. - vSockPort = 1024 + checkRequestTimeout = 30 * time.Second + defaultRequestTimeout = 60 * time.Second + errorMissingProxy = errors.New("Missing proxy pointer") + errorMissingOCISpec = errors.New("Missing OCI specification") + kataHostSharedDir = "/run/kata-containers/shared/sandboxes/" + kataGuestSharedDir = "/run/kata-containers/shared/containers/" + mountGuest9pTag = "kataShared" + kataGuestSandboxDir = "/run/kata-containers/sandbox/" + type9pFs = "9p" + typeVirtioFS = "virtio_fs" + typeVirtioFSNoCache = "none" kata9pDevType = "9p" kataMmioBlkDevType = "mmioblk" kataBlkDevType = "blk" @@ -145,16 +136,6 @@ type KataAgentConfig struct { KernelModules []string } -type kataVSOCK struct { - contextID uint64 - port uint32 - vhostFd *os.File -} - -func (s *kataVSOCK) String() string { - return fmt.Sprintf("%s://%d:%d", vsockSocketScheme, s.contextID, s.port) -} - // KataAgentState is the structure describing the data stored from this // agent implementation. type KataAgentState struct { @@ -208,31 +189,6 @@ func (k *kataAgent) getSharePath(id string) string { return filepath.Join(kataHostSharedDir, id) } -func (k *kataAgent) generateVMSocket(id string, c KataAgentConfig) error { - if c.UseVSock { - // We want to go through VSOCK. The VM VSOCK endpoint will be our gRPC. - k.Logger().Debug("agent: Using vsock VM socket endpoint") - // We dont know yet the context ID - set empty vsock configuration - k.vmSocket = kataVSOCK{} - } else { - k.Logger().Debug("agent: Using unix socket form VM socket endpoint") - // We need to generate a host UNIX socket path for the emulated serial port. - kataSock, err := utils.BuildSocketPath(k.getVMPath(id), defaultKataSocketName) - if err != nil { - return err - } - - k.vmSocket = types.Socket{ - DeviceID: defaultKataDeviceID, - ID: defaultKataID, - HostPath: kataSock, - Name: defaultKataChannel, - } - } - - return nil -} - // KataAgentSetDefaultTraceConfigOptions validates agent trace options and // sets defaults. func KataAgentSetDefaultTraceConfigOptions(config *KataAgentConfig) error { @@ -303,10 +259,6 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config interface switch c := config.(type) { case KataAgentConfig: - if err := k.generateVMSocket(sandbox.id, c); err != nil { - return false, err - } - disableVMShutdown = k.handleTraceSettings(c) k.keepConn = c.LongLiveConn k.kmodules = c.KernelModules @@ -340,7 +292,9 @@ func (k *kataAgent) agentURL() (string, error) { switch s := k.vmSocket.(type) { case types.Socket: return s.HostPath, nil - case kataVSOCK: + case types.VSock: + return s.String(), nil + case types.HybridVSock: return s.String(), nil default: return "", fmt.Errorf("Invalid socket type") @@ -357,10 +311,11 @@ func (k *kataAgent) capabilities() types.Capabilities { } func (k *kataAgent) internalConfigure(h hypervisor, id, sharePath string, builtin bool, config interface{}) error { + var err error if config != nil { switch c := config.(type) { case KataAgentConfig: - if err := k.generateVMSocket(id, c); err != nil { + if k.vmSocket, err = h.generateSocket(id, c.UseVSock); err != nil { return err } k.keepConn = c.LongLiveConn @@ -388,16 +343,15 @@ func (k *kataAgent) configure(h hypervisor, id, sharePath string, builtin bool, if err != nil { return err } - case kataVSOCK: - s.vhostFd, s.contextID, err = utils.FindContextID() - if err != nil { - return err - } - s.port = uint32(vSockPort) + case types.VSock: if err = h.addDevice(s, vSockPCIDev); err != nil { return err } - k.vmSocket = s + case types.HybridVSock: + err = h.addDevice(s, hybridVirtioVsockDev) + if err != nil { + return err + } default: return vcTypes.ErrInvalidConfigType } @@ -431,7 +385,7 @@ func (k *kataAgent) createSandbox(sandbox *Sandbox) error { span, _ := k.trace("createSandbox") defer span.Finish() - return k.configure(sandbox.hypervisor, sandbox.id, k.getSharePath(sandbox.id), k.proxyBuiltIn, nil) + return k.configure(sandbox.hypervisor, sandbox.id, k.getSharePath(sandbox.id), k.proxyBuiltIn, sandbox.config.AgentConfig) } func cmdToKataProcess(cmd types.Cmd) (process *grpc.Process, err error) { diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index cba9b01437..0376823281 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -627,25 +627,6 @@ func TestAgentPathAPI(t *testing.T) { path1 = k1.getSharePath(id) path2 = k2.getSharePath(id) assert.Equal(path1, path2) - - // generateVMSocket - c := KataAgentConfig{} - err := k1.generateVMSocket(id, c) - assert.Nil(err) - err = k2.generateVMSocket(id, c) - assert.Nil(err) - assert.Equal(k1, k2) - - err = k1.generateVMSocket(id, c) - assert.Nil(err) - _, ok := k1.vmSocket.(types.Socket) - assert.True(ok) - - c.UseVSock = true - err = k2.generateVMSocket(id, c) - assert.Nil(err) - _, ok = k2.vmSocket.(kataVSOCK) - assert.True(ok) } func TestAgentConfigure(t *testing.T) { @@ -843,20 +824,19 @@ func TestKataAgentSetProxy(t *testing.T) { func TestKataGetAgentUrl(t *testing.T) { assert := assert.New(t) + var err error - k := &kataAgent{} - err := k.generateVMSocket("foobar", KataAgentConfig{}) - assert.Nil(err) + k := &kataAgent{vmSocket: types.Socket{HostPath: "/abc"}} + assert.NoError(err) url, err := k.getAgentURL() assert.Nil(err) assert.NotEmpty(url) - err = k.generateVMSocket("foobar", KataAgentConfig{UseVSock: true}) - assert.Nil(err) + k.vmSocket = types.VSock{} + assert.NoError(err) url, err = k.getAgentURL() assert.Nil(err) assert.NotEmpty(url) - } func TestKataCopyFile(t *testing.T) { diff --git a/virtcontainers/mock_hypervisor.go b/virtcontainers/mock_hypervisor.go index 86ed118258..30962e87a9 100644 --- a/virtcontainers/mock_hypervisor.go +++ b/virtcontainers/mock_hypervisor.go @@ -125,3 +125,7 @@ func (m *mockHypervisor) load(s persistapi.HypervisorState) {} func (m *mockHypervisor) check() error { return nil } + +func (m *mockHypervisor) generateSocket(id string, useVsock bool) (interface{}, error) { + return types.Socket{HostPath: "/tmp/socket", Name: "socket"}, nil +} diff --git a/virtcontainers/mock_hypervisor_test.go b/virtcontainers/mock_hypervisor_test.go index efcee1c808..799f502758 100644 --- a/virtcontainers/mock_hypervisor_test.go +++ b/virtcontainers/mock_hypervisor_test.go @@ -88,3 +88,11 @@ func TestMockHypervisorCheck(t *testing.T) { assert.NoError(t, m.check()) } + +func TestMockGenerateSocket(t *testing.T) { + var m *mockHypervisor + + i, err := m.generateSocket("a", true) + assert.NoError(t, err) + assert.NotNil(t, i) +} diff --git a/virtcontainers/pkg/firecracker/client/models/vsock.go b/virtcontainers/pkg/firecracker/client/models/vsock.go index 750d8852f6..ab84b6e3ed 100644 --- a/virtcontainers/pkg/firecracker/client/models/vsock.go +++ b/virtcontainers/pkg/firecracker/client/models/vsock.go @@ -13,7 +13,7 @@ import ( "github.com/go-openapi/validate" ) -// Vsock vsock +// Vsock Defines a vsock device, backed by a set of Unix Domain Sockets, on the host side. For host-initiated connections, Firecracker will be listening on the Unix socket identified by the path `uds_path`. Firecracker will create this socket, bind and listen on it. Host-initiated connections will be performed by connection to this socket and issuing a connection forwarding request to the desired guest-side vsock port (i.e. `CONNECT 52\n`, to connect to port 52). For guest-initiated connections, Firecracker will expect host software to be bound and listening on Unix sockets at `uds_path_`. E.g. "/path/to/host_vsock.sock_52" for port number 52. // swagger:model Vsock type Vsock struct { @@ -22,9 +22,13 @@ type Vsock struct { // Minimum: 3 GuestCid *int64 `json:"guest_cid"` - // id + // Path to UNIX domain socket, used to proxy vsock connections. // Required: true - ID *string `json:"id"` + UdsPath *string `json:"uds_path"` + + // vsock id + // Required: true + VsockID *string `json:"vsock_id"` } // Validate validates this vsock @@ -35,7 +39,11 @@ func (m *Vsock) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validateID(formats); err != nil { + if err := m.validateUdsPath(formats); err != nil { + res = append(res, err) + } + + if err := m.validateVsockID(formats); err != nil { res = append(res, err) } @@ -58,9 +66,18 @@ func (m *Vsock) validateGuestCid(formats strfmt.Registry) error { return nil } -func (m *Vsock) validateID(formats strfmt.Registry) error { +func (m *Vsock) validateUdsPath(formats strfmt.Registry) error { - if err := validate.Required("id", "body", m.ID); err != nil { + if err := validate.Required("uds_path", "body", m.UdsPath); err != nil { + return err + } + + return nil +} + +func (m *Vsock) validateVsockID(formats strfmt.Registry) error { + + if err := validate.Required("vsock_id", "body", m.VsockID); err != nil { return err } diff --git a/virtcontainers/pkg/firecracker/client/operations/create_sync_action_responses.go b/virtcontainers/pkg/firecracker/client/operations/create_sync_action_responses.go index 58cdb44d81..bb67439557 100644 --- a/virtcontainers/pkg/firecracker/client/operations/create_sync_action_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/create_sync_action_responses.go @@ -24,21 +24,18 @@ type CreateSyncActionReader struct { // ReadResponse reads a server response into the received o. func (o *CreateSyncActionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewCreateSyncActionNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewCreateSyncActionBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewCreateSyncActionDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *CreateSyncActionBadRequest) Error() string { return fmt.Sprintf("[PUT /actions][%d] createSyncActionBadRequest %+v", 400, o.Payload) } +func (o *CreateSyncActionBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *CreateSyncActionBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *CreateSyncActionDefault) Error() string { return fmt.Sprintf("[PUT /actions][%d] createSyncAction default %+v", o._statusCode, o.Payload) } +func (o *CreateSyncActionDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *CreateSyncActionDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/describe_instance_responses.go b/virtcontainers/pkg/firecracker/client/operations/describe_instance_responses.go index 3c63f9dd4a..3b21f1d321 100644 --- a/virtcontainers/pkg/firecracker/client/operations/describe_instance_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/describe_instance_responses.go @@ -24,14 +24,12 @@ type DescribeInstanceReader struct { // ReadResponse reads a server response into the received o. func (o *DescribeInstanceReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 200: result := NewDescribeInstanceOK() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - default: result := NewDescribeInstanceDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -61,6 +59,10 @@ func (o *DescribeInstanceOK) Error() string { return fmt.Sprintf("[GET /][%d] describeInstanceOK %+v", 200, o.Payload) } +func (o *DescribeInstanceOK) GetPayload() *models.InstanceInfo { + return o.Payload +} + func (o *DescribeInstanceOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.InstanceInfo) @@ -99,6 +101,10 @@ func (o *DescribeInstanceDefault) Error() string { return fmt.Sprintf("[GET /][%d] describeInstance default %+v", o._statusCode, o.Payload) } +func (o *DescribeInstanceDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *DescribeInstanceDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/get_machine_configuration_responses.go b/virtcontainers/pkg/firecracker/client/operations/get_machine_configuration_responses.go index e9bff0f89e..f73171d9c4 100644 --- a/virtcontainers/pkg/firecracker/client/operations/get_machine_configuration_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/get_machine_configuration_responses.go @@ -24,14 +24,12 @@ type GetMachineConfigurationReader struct { // ReadResponse reads a server response into the received o. func (o *GetMachineConfigurationReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 200: result := NewGetMachineConfigurationOK() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - default: result := NewGetMachineConfigurationDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -61,6 +59,10 @@ func (o *GetMachineConfigurationOK) Error() string { return fmt.Sprintf("[GET /machine-config][%d] getMachineConfigurationOK %+v", 200, o.Payload) } +func (o *GetMachineConfigurationOK) GetPayload() *models.MachineConfiguration { + return o.Payload +} + func (o *GetMachineConfigurationOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.MachineConfiguration) @@ -99,6 +101,10 @@ func (o *GetMachineConfigurationDefault) Error() string { return fmt.Sprintf("[GET /machine-config][%d] getMachineConfiguration default %+v", o._statusCode, o.Payload) } +func (o *GetMachineConfigurationDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *GetMachineConfigurationDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/get_mmds_responses.go b/virtcontainers/pkg/firecracker/client/operations/get_mmds_responses.go index 4119bf8ef3..4390227d4d 100644 --- a/virtcontainers/pkg/firecracker/client/operations/get_mmds_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/get_mmds_responses.go @@ -24,21 +24,18 @@ type GetMmdsReader struct { // ReadResponse reads a server response into the received o. func (o *GetMmdsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 200: result := NewGetMmdsOK() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewGetMmdsBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewGetMmdsDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -68,6 +65,10 @@ func (o *GetMmdsOK) Error() string { return fmt.Sprintf("[GET /mmds][%d] getMmdsOK %+v", 200, o.Payload) } +func (o *GetMmdsOK) GetPayload() interface{} { + return o.Payload +} + func (o *GetMmdsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { // response payload @@ -95,6 +96,10 @@ func (o *GetMmdsBadRequest) Error() string { return fmt.Sprintf("[GET /mmds][%d] getMmdsBadRequest %+v", 400, o.Payload) } +func (o *GetMmdsBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *GetMmdsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -133,6 +138,10 @@ func (o *GetMmdsDefault) Error() string { return fmt.Sprintf("[GET /mmds][%d] GetMmds default %+v", o._statusCode, o.Payload) } +func (o *GetMmdsDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *GetMmdsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/operations_client.go b/virtcontainers/pkg/firecracker/client/operations/operations_client.go index 94aec10b7e..960596baa5 100644 --- a/virtcontainers/pkg/firecracker/client/operations/operations_client.go +++ b/virtcontainers/pkg/firecracker/client/operations/operations_client.go @@ -48,8 +48,13 @@ func (a *Client) GetMmds(params *GetMmdsParams) (*GetMmdsOK, error) { if err != nil { return nil, err } - return result.(*GetMmdsOK), nil - + success, ok := result.(*GetMmdsOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*GetMmdsDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -76,8 +81,13 @@ func (a *Client) PatchMmds(params *PatchMmdsParams) (*PatchMmdsNoContent, error) if err != nil { return nil, err } - return result.(*PatchMmdsNoContent), nil - + success, ok := result.(*PatchMmdsNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PatchMmdsDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -104,8 +114,13 @@ func (a *Client) PutMmds(params *PutMmdsParams) (*PutMmdsNoContent, error) { if err != nil { return nil, err } - return result.(*PutMmdsNoContent), nil - + success, ok := result.(*PutMmdsNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutMmdsDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -132,8 +147,13 @@ func (a *Client) CreateSyncAction(params *CreateSyncActionParams) (*CreateSyncAc if err != nil { return nil, err } - return result.(*CreateSyncActionNoContent), nil - + success, ok := result.(*CreateSyncActionNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*CreateSyncActionDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -160,8 +180,13 @@ func (a *Client) DescribeInstance(params *DescribeInstanceParams) (*DescribeInst if err != nil { return nil, err } - return result.(*DescribeInstanceOK), nil - + success, ok := result.(*DescribeInstanceOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*DescribeInstanceDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -190,8 +215,13 @@ func (a *Client) GetMachineConfiguration(params *GetMachineConfigurationParams) if err != nil { return nil, err } - return result.(*GetMachineConfigurationOK), nil - + success, ok := result.(*GetMachineConfigurationOK) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*GetMachineConfigurationDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -220,8 +250,13 @@ func (a *Client) PatchGuestDriveByID(params *PatchGuestDriveByIDParams) (*PatchG if err != nil { return nil, err } - return result.(*PatchGuestDriveByIDNoContent), nil - + success, ok := result.(*PatchGuestDriveByIDNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PatchGuestDriveByIDDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -250,8 +285,13 @@ func (a *Client) PatchGuestNetworkInterfaceByID(params *PatchGuestNetworkInterfa if err != nil { return nil, err } - return result.(*PatchGuestNetworkInterfaceByIDNoContent), nil - + success, ok := result.(*PatchGuestNetworkInterfaceByIDNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PatchGuestNetworkInterfaceByIDDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -280,8 +320,13 @@ func (a *Client) PatchMachineConfiguration(params *PatchMachineConfigurationPara if err != nil { return nil, err } - return result.(*PatchMachineConfigurationNoContent), nil - + success, ok := result.(*PatchMachineConfigurationNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PatchMachineConfigurationDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -310,8 +355,13 @@ func (a *Client) PutGuestBootSource(params *PutGuestBootSourceParams) (*PutGuest if err != nil { return nil, err } - return result.(*PutGuestBootSourceNoContent), nil - + success, ok := result.(*PutGuestBootSourceNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutGuestBootSourceDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -340,8 +390,13 @@ func (a *Client) PutGuestDriveByID(params *PutGuestDriveByIDParams) (*PutGuestDr if err != nil { return nil, err } - return result.(*PutGuestDriveByIDNoContent), nil - + success, ok := result.(*PutGuestDriveByIDNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutGuestDriveByIDDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -370,8 +425,13 @@ func (a *Client) PutGuestNetworkInterfaceByID(params *PutGuestNetworkInterfaceBy if err != nil { return nil, err } - return result.(*PutGuestNetworkInterfaceByIDNoContent), nil - + success, ok := result.(*PutGuestNetworkInterfaceByIDNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutGuestNetworkInterfaceByIDDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -379,7 +439,7 @@ PutGuestVsockByID creates new vsock with ID specified by the id parameter If the vsock device with the specified ID already exists, its body will be updated based on the new input. May fail if update is not possible. */ -func (a *Client) PutGuestVsockByID(params *PutGuestVsockByIDParams) (*PutGuestVsockByIDCreated, *PutGuestVsockByIDNoContent, error) { +func (a *Client) PutGuestVsockByID(params *PutGuestVsockByIDParams) (*PutGuestVsockByIDNoContent, error) { // TODO: Validate the params before sending if params == nil { params = NewPutGuestVsockByIDParams() @@ -398,16 +458,15 @@ func (a *Client) PutGuestVsockByID(params *PutGuestVsockByIDParams) (*PutGuestVs Client: params.HTTPClient, }) if err != nil { - return nil, nil, err + return nil, err } - switch value := result.(type) { - case *PutGuestVsockByIDCreated: - return value, nil, nil - case *PutGuestVsockByIDNoContent: - return nil, value, nil + success, ok := result.(*PutGuestVsockByIDNoContent) + if ok { + return success, nil } - return nil, nil, nil - + // unexpected success response + unexpectedSuccess := result.(*PutGuestVsockByIDDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -434,8 +493,13 @@ func (a *Client) PutLogger(params *PutLoggerParams) (*PutLoggerNoContent, error) if err != nil { return nil, err } - return result.(*PutLoggerNoContent), nil - + success, ok := result.(*PutLoggerNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutLoggerDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } /* @@ -464,8 +528,13 @@ func (a *Client) PutMachineConfiguration(params *PutMachineConfigurationParams) if err != nil { return nil, err } - return result.(*PutMachineConfigurationNoContent), nil - + success, ok := result.(*PutMachineConfigurationNoContent) + if ok { + return success, nil + } + // unexpected success response + unexpectedSuccess := result.(*PutMachineConfigurationDefault) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) } // SetTransport changes the transport on the client diff --git a/virtcontainers/pkg/firecracker/client/operations/patch_guest_drive_by_id_responses.go b/virtcontainers/pkg/firecracker/client/operations/patch_guest_drive_by_id_responses.go index 672473f838..ba80a3e21d 100644 --- a/virtcontainers/pkg/firecracker/client/operations/patch_guest_drive_by_id_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/patch_guest_drive_by_id_responses.go @@ -24,21 +24,18 @@ type PatchGuestDriveByIDReader struct { // ReadResponse reads a server response into the received o. func (o *PatchGuestDriveByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPatchGuestDriveByIDNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPatchGuestDriveByIDBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPatchGuestDriveByIDDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PatchGuestDriveByIDBadRequest) Error() string { return fmt.Sprintf("[PATCH /drives/{drive_id}][%d] patchGuestDriveByIdBadRequest %+v", 400, o.Payload) } +func (o *PatchGuestDriveByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchGuestDriveByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PatchGuestDriveByIDDefault) Error() string { return fmt.Sprintf("[PATCH /drives/{drive_id}][%d] patchGuestDriveByID default %+v", o._statusCode, o.Payload) } +func (o *PatchGuestDriveByIDDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchGuestDriveByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/patch_guest_network_interface_by_id_responses.go b/virtcontainers/pkg/firecracker/client/operations/patch_guest_network_interface_by_id_responses.go index cb9ed11b72..652130d75a 100644 --- a/virtcontainers/pkg/firecracker/client/operations/patch_guest_network_interface_by_id_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/patch_guest_network_interface_by_id_responses.go @@ -24,21 +24,18 @@ type PatchGuestNetworkInterfaceByIDReader struct { // ReadResponse reads a server response into the received o. func (o *PatchGuestNetworkInterfaceByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPatchGuestNetworkInterfaceByIDNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPatchGuestNetworkInterfaceByIDBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPatchGuestNetworkInterfaceByIDDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PatchGuestNetworkInterfaceByIDBadRequest) Error() string { return fmt.Sprintf("[PATCH /network-interfaces/{iface_id}][%d] patchGuestNetworkInterfaceByIdBadRequest %+v", 400, o.Payload) } +func (o *PatchGuestNetworkInterfaceByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchGuestNetworkInterfaceByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PatchGuestNetworkInterfaceByIDDefault) Error() string { return fmt.Sprintf("[PATCH /network-interfaces/{iface_id}][%d] patchGuestNetworkInterfaceByID default %+v", o._statusCode, o.Payload) } +func (o *PatchGuestNetworkInterfaceByIDDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchGuestNetworkInterfaceByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/patch_machine_configuration_responses.go b/virtcontainers/pkg/firecracker/client/operations/patch_machine_configuration_responses.go index b796d056a7..f828e63c17 100644 --- a/virtcontainers/pkg/firecracker/client/operations/patch_machine_configuration_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/patch_machine_configuration_responses.go @@ -24,21 +24,18 @@ type PatchMachineConfigurationReader struct { // ReadResponse reads a server response into the received o. func (o *PatchMachineConfigurationReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPatchMachineConfigurationNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPatchMachineConfigurationBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPatchMachineConfigurationDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PatchMachineConfigurationBadRequest) Error() string { return fmt.Sprintf("[PATCH /machine-config][%d] patchMachineConfigurationBadRequest %+v", 400, o.Payload) } +func (o *PatchMachineConfigurationBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchMachineConfigurationBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PatchMachineConfigurationDefault) Error() string { return fmt.Sprintf("[PATCH /machine-config][%d] patchMachineConfiguration default %+v", o._statusCode, o.Payload) } +func (o *PatchMachineConfigurationDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchMachineConfigurationDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/patch_mmds_responses.go b/virtcontainers/pkg/firecracker/client/operations/patch_mmds_responses.go index 113c5abaa6..fe0a8e9936 100644 --- a/virtcontainers/pkg/firecracker/client/operations/patch_mmds_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/patch_mmds_responses.go @@ -24,21 +24,18 @@ type PatchMmdsReader struct { // ReadResponse reads a server response into the received o. func (o *PatchMmdsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPatchMmdsNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPatchMmdsBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPatchMmdsDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PatchMmdsBadRequest) Error() string { return fmt.Sprintf("[PATCH /mmds][%d] patchMmdsBadRequest %+v", 400, o.Payload) } +func (o *PatchMmdsBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchMmdsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PatchMmdsDefault) Error() string { return fmt.Sprintf("[PATCH /mmds][%d] PatchMmds default %+v", o._statusCode, o.Payload) } +func (o *PatchMmdsDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PatchMmdsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_guest_boot_source_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_guest_boot_source_responses.go index 3d39bebe87..5c7f604783 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_guest_boot_source_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_guest_boot_source_responses.go @@ -24,21 +24,18 @@ type PutGuestBootSourceReader struct { // ReadResponse reads a server response into the received o. func (o *PutGuestBootSourceReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutGuestBootSourceNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutGuestBootSourceBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutGuestBootSourceDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutGuestBootSourceBadRequest) Error() string { return fmt.Sprintf("[PUT /boot-source][%d] putGuestBootSourceBadRequest %+v", 400, o.Payload) } +func (o *PutGuestBootSourceBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestBootSourceBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutGuestBootSourceDefault) Error() string { return fmt.Sprintf("[PUT /boot-source][%d] putGuestBootSource default %+v", o._statusCode, o.Payload) } +func (o *PutGuestBootSourceDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestBootSourceDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_guest_drive_by_id_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_guest_drive_by_id_responses.go index 6dc8d6419f..a6909f865e 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_guest_drive_by_id_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_guest_drive_by_id_responses.go @@ -24,21 +24,18 @@ type PutGuestDriveByIDReader struct { // ReadResponse reads a server response into the received o. func (o *PutGuestDriveByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutGuestDriveByIDNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutGuestDriveByIDBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutGuestDriveByIDDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutGuestDriveByIDBadRequest) Error() string { return fmt.Sprintf("[PUT /drives/{drive_id}][%d] putGuestDriveByIdBadRequest %+v", 400, o.Payload) } +func (o *PutGuestDriveByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestDriveByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutGuestDriveByIDDefault) Error() string { return fmt.Sprintf("[PUT /drives/{drive_id}][%d] putGuestDriveByID default %+v", o._statusCode, o.Payload) } +func (o *PutGuestDriveByIDDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestDriveByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_guest_network_interface_by_id_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_guest_network_interface_by_id_responses.go index ebfbe2d604..ed4fbf7819 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_guest_network_interface_by_id_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_guest_network_interface_by_id_responses.go @@ -24,21 +24,18 @@ type PutGuestNetworkInterfaceByIDReader struct { // ReadResponse reads a server response into the received o. func (o *PutGuestNetworkInterfaceByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutGuestNetworkInterfaceByIDNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutGuestNetworkInterfaceByIDBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutGuestNetworkInterfaceByIDDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutGuestNetworkInterfaceByIDBadRequest) Error() string { return fmt.Sprintf("[PUT /network-interfaces/{iface_id}][%d] putGuestNetworkInterfaceByIdBadRequest %+v", 400, o.Payload) } +func (o *PutGuestNetworkInterfaceByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestNetworkInterfaceByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutGuestNetworkInterfaceByIDDefault) Error() string { return fmt.Sprintf("[PUT /network-interfaces/{iface_id}][%d] putGuestNetworkInterfaceByID default %+v", o._statusCode, o.Payload) } +func (o *PutGuestNetworkInterfaceByIDDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestNetworkInterfaceByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_guest_vsock_by_id_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_guest_vsock_by_id_responses.go index c9f78ca9d6..74e56f91b3 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_guest_vsock_by_id_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_guest_vsock_by_id_responses.go @@ -24,28 +24,18 @@ type PutGuestVsockByIDReader struct { // ReadResponse reads a server response into the received o. func (o *PutGuestVsockByIDReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - - case 201: - result := NewPutGuestVsockByIDCreated() - if err := result.readResponse(response, consumer, o.formats); err != nil { - return nil, err - } - return result, nil - case 204: result := NewPutGuestVsockByIDNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutGuestVsockByIDBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutGuestVsockByIDDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -58,27 +48,6 @@ func (o *PutGuestVsockByIDReader) ReadResponse(response runtime.ClientResponse, } } -// NewPutGuestVsockByIDCreated creates a PutGuestVsockByIDCreated with default headers values -func NewPutGuestVsockByIDCreated() *PutGuestVsockByIDCreated { - return &PutGuestVsockByIDCreated{} -} - -/*PutGuestVsockByIDCreated handles this case with default header values. - -Vsock created -*/ -type PutGuestVsockByIDCreated struct { -} - -func (o *PutGuestVsockByIDCreated) Error() string { - return fmt.Sprintf("[PUT /vsocks/{id}][%d] putGuestVsockByIdCreated ", 201) -} - -func (o *PutGuestVsockByIDCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - - return nil -} - // NewPutGuestVsockByIDNoContent creates a PutGuestVsockByIDNoContent with default headers values func NewPutGuestVsockByIDNoContent() *PutGuestVsockByIDNoContent { return &PutGuestVsockByIDNoContent{} @@ -86,7 +55,7 @@ func NewPutGuestVsockByIDNoContent() *PutGuestVsockByIDNoContent { /*PutGuestVsockByIDNoContent handles this case with default header values. -Vsock updated +Vsock created/updated */ type PutGuestVsockByIDNoContent struct { } @@ -117,6 +86,10 @@ func (o *PutGuestVsockByIDBadRequest) Error() string { return fmt.Sprintf("[PUT /vsocks/{id}][%d] putGuestVsockByIdBadRequest %+v", 400, o.Payload) } +func (o *PutGuestVsockByIDBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestVsockByIDBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -155,6 +128,10 @@ func (o *PutGuestVsockByIDDefault) Error() string { return fmt.Sprintf("[PUT /vsocks/{id}][%d] putGuestVsockByID default %+v", o._statusCode, o.Payload) } +func (o *PutGuestVsockByIDDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutGuestVsockByIDDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_logger_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_logger_responses.go index c986768786..b9bfebe9fb 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_logger_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_logger_responses.go @@ -24,21 +24,18 @@ type PutLoggerReader struct { // ReadResponse reads a server response into the received o. func (o *PutLoggerReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutLoggerNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutLoggerBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutLoggerDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutLoggerBadRequest) Error() string { return fmt.Sprintf("[PUT /logger][%d] putLoggerBadRequest %+v", 400, o.Payload) } +func (o *PutLoggerBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutLoggerBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutLoggerDefault) Error() string { return fmt.Sprintf("[PUT /logger][%d] putLogger default %+v", o._statusCode, o.Payload) } +func (o *PutLoggerDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutLoggerDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_machine_configuration_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_machine_configuration_responses.go index 6127fea6e3..f36aa154f3 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_machine_configuration_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_machine_configuration_responses.go @@ -24,21 +24,18 @@ type PutMachineConfigurationReader struct { // ReadResponse reads a server response into the received o. func (o *PutMachineConfigurationReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutMachineConfigurationNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutMachineConfigurationBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutMachineConfigurationDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutMachineConfigurationBadRequest) Error() string { return fmt.Sprintf("[PUT /machine-config][%d] putMachineConfigurationBadRequest %+v", 400, o.Payload) } +func (o *PutMachineConfigurationBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutMachineConfigurationBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutMachineConfigurationDefault) Error() string { return fmt.Sprintf("[PUT /machine-config][%d] putMachineConfiguration default %+v", o._statusCode, o.Payload) } +func (o *PutMachineConfigurationDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutMachineConfigurationDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/client/operations/put_mmds_responses.go b/virtcontainers/pkg/firecracker/client/operations/put_mmds_responses.go index 7b1e47b35e..1f8116d71f 100644 --- a/virtcontainers/pkg/firecracker/client/operations/put_mmds_responses.go +++ b/virtcontainers/pkg/firecracker/client/operations/put_mmds_responses.go @@ -24,21 +24,18 @@ type PutMmdsReader struct { // ReadResponse reads a server response into the received o. func (o *PutMmdsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { switch response.Code() { - case 204: result := NewPutMmdsNoContent() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return result, nil - case 400: result := NewPutMmdsBadRequest() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } return nil, result - default: result := NewPutMmdsDefault(response.Code()) if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -89,6 +86,10 @@ func (o *PutMmdsBadRequest) Error() string { return fmt.Sprintf("[PUT /mmds][%d] putMmdsBadRequest %+v", 400, o.Payload) } +func (o *PutMmdsBadRequest) GetPayload() *models.Error { + return o.Payload +} + func (o *PutMmdsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) @@ -127,6 +128,10 @@ func (o *PutMmdsDefault) Error() string { return fmt.Sprintf("[PUT /mmds][%d] PutMmds default %+v", o._statusCode, o.Payload) } +func (o *PutMmdsDefault) GetPayload() *models.Error { + return o.Payload +} + func (o *PutMmdsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { o.Payload = new(models.Error) diff --git a/virtcontainers/pkg/firecracker/firecracker-experimental.yaml b/virtcontainers/pkg/firecracker/firecracker-experimental.yaml index 1cb42891c1..e54415e007 100644 --- a/virtcontainers/pkg/firecracker/firecracker-experimental.yaml +++ b/virtcontainers/pkg/firecracker/firecracker-experimental.yaml @@ -5,8 +5,7 @@ info: The API is accessible through HTTP calls on specific URLs carrying JSON modeled data. The transport medium is a Unix Domain Socket. - This API has definitions for experimental features like vsock. - version: 0.17.0 + version: 0.18.0 termsOfService: "" contact: email: "compute-capsule@amazon.com" @@ -355,37 +354,35 @@ paths: $ref: "#/definitions/Error" /vsocks/{id}: - put: - summary: Creates new vsock with ID specified by the id parameter. - description: - If the vsock device with the specified ID already exists, its body will - be updated based on the new input. May fail if update is not possible. - operationId: putGuestVsockByID - parameters: - - name: id - in: path - description: The id of the vsock device - required: true - type: string - - name: body - in: body - description: Guest vsock properties - required: true - schema: - $ref: "#/definitions/Vsock" - responses: - 201: - description: Vsock created - 204: - description: Vsock updated - 400: - description: Vsock cannot be created due to bad input - schema: - $ref: "#/definitions/Error" - default: - description: Internal server error - schema: - $ref: "#/definitions/Error" + put: + summary: Creates new vsock with ID specified by the id parameter. + description: + If the vsock device with the specified ID already exists, its body will + be updated based on the new input. May fail if update is not possible. + operationId: putGuestVsockByID + parameters: + - name: id + in: path + description: The id of the vsock device + required: true + type: string + - name: body + in: body + description: Guest vsock properties + required: true + schema: + $ref: "#/definitions/Vsock" + responses: + 204: + description: Vsock created/updated + 400: + description: Vsock cannot be created due to bad input + schema: + $ref: "#/definitions/Error" + default: + description: Internal server error + schema: + $ref: "#/definitions/Error" definitions: BootSource: @@ -648,14 +645,28 @@ definitions: minimum: 0 Vsock: - type: object - required: - - id - - guest_cid - properties: - id: - type: string - guest_cid: - type: integer - minimum: 3 - description: Guest Vsock CID + type: object + description: + Defines a vsock device, backed by a set of Unix Domain Sockets, on the host side. + For host-initiated connections, Firecracker will be listening on the Unix socket + identified by the path `uds_path`. Firecracker will create this socket, bind and + listen on it. Host-initiated connections will be performed by connection to this + socket and issuing a connection forwarding request to the desired guest-side vsock + port (i.e. `CONNECT 52\n`, to connect to port 52). + For guest-initiated connections, Firecracker will expect host software to be + bound and listening on Unix sockets at `uds_path_`. + E.g. "/path/to/host_vsock.sock_52" for port number 52. + required: + - vsock_id + - guest_cid + - uds_path + properties: + vsock_id: + type: string + guest_cid: + type: integer + minimum: 3 + description: Guest Vsock CID + uds_path: + type: string + description: Path to UNIX domain socket, used to proxy vsock connections. diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index c8c0bb8790..2ef9eda937 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -1599,8 +1599,8 @@ func (q *qemu) addDevice(devInfo interface{}, devType deviceType) error { } case types.Socket: q.qemuConfig.Devices = q.arch.appendSocket(q.qemuConfig.Devices, v) - case kataVSOCK: - q.fds = append(q.fds, v.vhostFd) + case types.VSock: + q.fds = append(q.fds, v.VhostFd) q.qemuConfig.Devices, err = q.arch.appendVSock(q.qemuConfig.Devices, v) case Endpoint: q.qemuConfig.Devices, err = q.arch.appendNetwork(q.qemuConfig.Devices, v) @@ -2069,3 +2069,7 @@ func (q *qemu) check() error { return nil } + +func (q *qemu) generateSocket(id string, useVsock bool) (interface{}, error) { + return generateVMSocket(id, useVsock) +} diff --git a/virtcontainers/qemu_arch_base.go b/virtcontainers/qemu_arch_base.go index 4408648bc1..8889593f04 100644 --- a/virtcontainers/qemu_arch_base.go +++ b/virtcontainers/qemu_arch_base.go @@ -80,7 +80,7 @@ type qemuArch interface { appendSocket(devices []govmmQemu.Device, socket types.Socket) []govmmQemu.Device // appendVSock appends a vsock PCI to devices - appendVSock(devices []govmmQemu.Device, vsock kataVSOCK) ([]govmmQemu.Device, error) + appendVSock(devices []govmmQemu.Device, vsock types.VSock) ([]govmmQemu.Device, error) // appendNetwork appends a endpoint device to devices appendNetwork(devices []govmmQemu.Device, endpoint Endpoint) ([]govmmQemu.Device, error) @@ -451,12 +451,12 @@ func (q *qemuArchBase) appendSocket(devices []govmmQemu.Device, socket types.Soc return devices } -func (q *qemuArchBase) appendVSock(devices []govmmQemu.Device, vsock kataVSOCK) ([]govmmQemu.Device, error) { +func (q *qemuArchBase) appendVSock(devices []govmmQemu.Device, vsock types.VSock) ([]govmmQemu.Device, error) { devices = append(devices, govmmQemu.VSOCKDevice{ - ID: fmt.Sprintf("vsock-%d", vsock.contextID), - ContextID: vsock.contextID, - VHostFD: vsock.vhostFd, + ID: fmt.Sprintf("vsock-%d", vsock.ContextID), + ContextID: vsock.ContextID, + VHostFD: vsock.VhostFd, DisableModern: q.nestedRun, }, ) diff --git a/virtcontainers/qemu_test.go b/virtcontainers/qemu_test.go index 62799b9b2f..c64af10af1 100644 --- a/virtcontainers/qemu_test.go +++ b/virtcontainers/qemu_test.go @@ -274,10 +274,10 @@ func TestQemuAddDeviceKataVSOCK(t *testing.T) { }, } - vsock := kataVSOCK{ - contextID: contextID, - port: port, - vhostFd: vsockFile, + vsock := types.VSock{ + ContextID: contextID, + Port: port, + VhostFd: vsockFile, } testQemuAddDevice(t, vsock, vSockPCIDev, expectedOut) diff --git a/virtcontainers/types/sandbox.go b/virtcontainers/types/sandbox.go index 655821c11b..4e3a623789 100644 --- a/virtcontainers/types/sandbox.go +++ b/virtcontainers/types/sandbox.go @@ -7,6 +7,7 @@ package types import ( "fmt" + "os" "strings" "github.com/opencontainers/runtime-spec/specs-go" @@ -29,6 +30,11 @@ const ( StateStopped StateString = "stopped" ) +const ( + HybridVSockScheme = "hvsock" + VSockScheme = "vsock" +) + // SandboxState is a sandbox state structure type SandboxState struct { State StateString `json:"state"` @@ -161,6 +167,35 @@ func (v *Volumes) String() string { return strings.Join(volSlice, " ") } +// VSock defines a virtio-socket to communicate between +// the host and any process inside the VM. +// This kind of socket is not supported in all hypervisors. +// QEMU and NEMU support it. +type VSock struct { + ContextID uint64 + Port uint32 + VhostFd *os.File +} + +func (s *VSock) String() string { + return fmt.Sprintf("%s://%d:%d", VSockScheme, s.ContextID, s.Port) +} + +// HybridVSock defines a hybrid vsocket to communicate between +// the host and any process inside the VM. +// This is a virtio-vsock implementation based on AF_VSOCK on the +// guest side and multiple AF_UNIX sockets on the host side. +// This kind of socket is not supported in all hypervisors. +// Firecracker supports it. +type HybridVSock struct { + UdsPath string + Port uint32 +} + +func (s *HybridVSock) String() string { + return fmt.Sprintf("%s://%s:%d", HybridVSockScheme, s.UdsPath, s.Port) +} + // Socket defines a socket to communicate between // the host and any process inside the VM. type Socket struct {