Merge pull request #2050 from devimc/topic/virtcontainers/fixFC018

Support Firecracker 0.18
This commit is contained in:
Eric Ernst 2019-09-23 06:52:29 -07:00 committed by GitHub
commit 22a3ca1c36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 644 additions and 280 deletions

4
Gopkg.lock generated
View File

@ -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"

View File

@ -52,7 +52,7 @@
[[constraint]]
name = "github.com/kata-containers/agent"
revision = "94e2a254a94a77c02280f4f84d7f82269be163ce"
revision = "3ffb7ca1067565a45ee9fbfcb109eb85e7e899af"
[[constraint]]
name = "github.com/containerd/cri-containerd"

View File

@ -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://<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 {
@ -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)
}

View File

@ -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"

View File

@ -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)
}

View File

@ -121,6 +121,7 @@ func newTestSandboxConfigNoop() SandboxConfig {
func newTestSandboxConfigKataAgent() SandboxConfig {
sandboxConfig := newTestSandboxConfigNoop()
sandboxConfig.AgentType = KataContainersAgent
sandboxConfig.AgentConfig = KataAgentConfig{}
sandboxConfig.Containers = nil
return sandboxConfig

View File

@ -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
}

31
virtcontainers/fc_test.go Normal file
View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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"
@ -55,10 +54,6 @@ 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/"
@ -68,10 +63,6 @@ var (
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
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) {

View File

@ -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) {

View File

@ -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
}

View File

@ -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)
}

View File

@ -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_<PORT>`. 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
}

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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"
@ -374,10 +373,8 @@ paths:
schema:
$ref: "#/definitions/Vsock"
responses:
201:
description: Vsock created
204:
description: Vsock updated
description: Vsock created/updated
400:
description: Vsock cannot be created due to bad input
schema:
@ -649,13 +646,27 @@ definitions:
Vsock:
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_<PORT>`.
E.g. "/path/to/host_vsock.sock_52" for port number 52.
required:
- id
- vsock_id
- guest_cid
- uds_path
properties:
id:
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.

View File

@ -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)
}

View File

@ -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,
},
)

View File

@ -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)

View File

@ -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 {