From b0986a5f7f09863ae4663ca64e9dfe158cf47263 Mon Sep 17 00:00:00 2001 From: Nitesh Konkar Date: Mon, 28 Jan 2019 23:42:20 +0530 Subject: [PATCH 1/2] ppc64le: Fix vCPU hotplug issue ppc64le qemu does not need threadID and socketID parameters when hotplugging. Fixes: #1155 Signed-off-by: Nitesh Konkar niteshkonkar@in.ibm.com --- virtcontainers/qemu.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index e4d4ff78a8..487f91ba67 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -1077,6 +1077,11 @@ func (q *qemu) hotplugAddCPUs(amount uint32) (uint32, error) { return 0, fmt.Errorf("failed to query hotpluggable CPUs: %v", err) } + machine, err := q.arch.machine() + if err != nil { + return 0, fmt.Errorf("failed to query machine type: %v", err) + } + var hotpluggedVCPUs uint32 for _, hc := range hotpluggableVCPUs { // qom-path is the path to the CPU, non-empty means that this CPU is already in use @@ -1090,6 +1095,13 @@ func (q *qemu) hotplugAddCPUs(amount uint32) (uint32, error) { socketID := fmt.Sprintf("%d", hc.Properties.Socket) coreID := fmt.Sprintf("%d", hc.Properties.Core) threadID := fmt.Sprintf("%d", hc.Properties.Thread) + + // If CPU type is IBM pSeries, we do not set socketID and threadID + if machine.Type == "pseries" { + socketID = "" + threadID = "" + } + if err := q.qmpMonitorCh.qmp.ExecuteCPUDeviceAdd(q.qmpMonitorCh.ctx, driver, cpuID, socketID, coreID, threadID, romFile); err != nil { // don't fail, let's try with other CPU continue From b1c666730e6b2e00fa982626926c33636a4537c0 Mon Sep 17 00:00:00 2001 From: Nitesh Konkar Date: Mon, 28 Jan 2019 23:38:54 +0530 Subject: [PATCH 2/2] vendor: Update govmm vendoring Shortlog: 78d079d Merge pull request #84 from nitkon/master 4692f6b qmp: Conditionally pass threadID and socketID when CPU device add b9c8f76 Merge pull request #85 from markdryan/fix-travis 1f51b43 Update the versions of Go used to build GoVMM ad310f9 Fix staticcheck S1023 932fdc7 Fix staticcheck S1023 cb2ce93 Fix staticcheck S1008 f0172cd Fix staticcheck (S1002) 5f2e630 Fix staticcheck (S1025) 4beea51 Fix staticcheck (ST1005) errors Fixes: #1155 Signed-off-by: Nitesh Konkar niteshkonkar@in.ibm.com --- Gopkg.lock | 8 +- Gopkg.toml | 2 +- .../firecracker-go-sdk/command_builder.go | 155 ----- .../firecracker-go-sdk/doc.go | 29 - .../firecracker-go-sdk/drives.go | 65 -- .../firecracker-go-sdk/firecracker.go | 150 ----- .../firecracker-go-sdk/handlers.go | 237 ------- .../firecracker-go-sdk/machine.go | 607 ------------------ .../firecracker-go-sdk/opts.go | 49 -- .../firecracker-go-sdk/pointer_helpers.go | 46 -- .../firecracker-go-sdk/swagger.go | 22 - vendor/github.com/intel/govmm/qemu/image.go | 8 +- vendor/github.com/intel/govmm/qemu/qemu.go | 80 +-- vendor/github.com/intel/govmm/qemu/qmp.go | 51 +- 14 files changed, 69 insertions(+), 1440 deletions(-) delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/command_builder.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/doc.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/drives.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/firecracker.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/handlers.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/machine.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/opts.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/pointer_helpers.go delete mode 100644 vendor/github.com/firecracker-microvm/firecracker-go-sdk/swagger.go diff --git a/Gopkg.lock b/Gopkg.lock index d36d090841..974a33b677 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -204,10 +204,9 @@ version = "v0.3.3" [[projects]] - digest = "1:58b18038f51b6f79865fd00e3d883949c9507ede577cd9c4e743ed56cc454122" + digest = "1:351337e3b022de09e72306f1f9711314cc4bd407c15e8d328e218c655fd55731" name = "github.com/firecracker-microvm/firecracker-go-sdk" packages = [ - ".", "client", "client/models", "client/operations", @@ -377,11 +376,11 @@ revision = "3520598351bb3500a49ae9563f5539666ae0a27c" [[projects]] - digest = "1:15f0da05538e2445b354c620555231448849b7ece222c45578668d0dfd6bec93" + digest = "1:270961b1d5e664d4939ffae00b990e256d92bb5039cae69208211a84c72fe5f5" name = "github.com/intel/govmm" packages = ["qemu"] pruneopts = "NUT" - revision = "737f03de595e216116264cc74a58e5f2a1df789a" + revision = "78d079db6d1f3e32e3ed7578a54baa6257b058a7" [[projects]] digest = "1:590bfb6f8d5741fa38bb3022f55588fb7e06389f6b7b6692a965e0e5a4363fb1" @@ -699,7 +698,6 @@ "github.com/containernetworking/plugins/pkg/ns", "github.com/dlespiau/covertool/pkg/cover", "github.com/docker/go-units", - "github.com/firecracker-microvm/firecracker-go-sdk", "github.com/firecracker-microvm/firecracker-go-sdk/client", "github.com/firecracker-microvm/firecracker-go-sdk/client/models", "github.com/firecracker-microvm/firecracker-go-sdk/client/operations", diff --git a/Gopkg.toml b/Gopkg.toml index 4af6a00602..a54834ed5d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -52,7 +52,7 @@ [[constraint]] name = "github.com/intel/govmm" - revision = "737f03de595e216116264cc74a58e5f2a1df789a" + revision = "78d079db6d1f3e32e3ed7578a54baa6257b058a7" [[constraint]] name = "github.com/kata-containers/agent" diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/command_builder.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/command_builder.go deleted file mode 100644 index bb78923532..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/command_builder.go +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -package firecracker - -import ( - "context" - "io" - "os" - "os/exec" -) - -var defaultFirecrackerVMMCommandBuilder = VMCommandBuilder{}. - WithBin("firecracker"). - WithStdin(os.Stdin). - WithStdout(os.Stdout). - WithStderr(os.Stderr) - -// VMCommandBuilder is a utility for building an exec.Cmd that represents how to -// start the Firecracker VMM. -type VMCommandBuilder struct { - bin string - args []string - socketPath string - stdin io.Reader - stdout io.Writer - stderr io.Writer -} - -// Args returns all args that will be passed to exec.Command -func (b VMCommandBuilder) Args() []string { - return b.args -} - -// WithArgs specifies which arguments to pass through to the -// firecracker exec.Command -func (b VMCommandBuilder) WithArgs(args []string) VMCommandBuilder { - b.args = args - return b -} - -// AddArgs will append the provided args to the given command -func (b VMCommandBuilder) AddArgs(args ...string) VMCommandBuilder { - b.args = append(b.args, args...) - return b -} - -// Bin return the bin that was set -func (b VMCommandBuilder) Bin() string { - return b.bin -} - -// WithBin specifies which binary for firecracker to use -func (b VMCommandBuilder) WithBin(bin string) VMCommandBuilder { - b.bin = bin - return b -} - -// SocketPath returns the specified socket path -func (b VMCommandBuilder) SocketPath() []string { - if len(b.socketPath) == 0 { - return nil - } - - return []string{ - "--api-sock", - b.socketPath, - } -} - -// WithSocketPath specifies the socket path to be used when -// creating the firecracker exec.Command -func (b VMCommandBuilder) WithSocketPath(path string) VMCommandBuilder { - b.socketPath = path - return b -} - -// Stdout will return the stdout that will be used when creating -// the firecracker exec.Command -func (b VMCommandBuilder) Stdout() io.Writer { - return b.stdout -} - -// WithStdout specifies which io.Writer to use in place of the -// os.Stdout in the firecracker exec.Command. -func (b VMCommandBuilder) WithStdout(stdout io.Writer) VMCommandBuilder { - b.stdout = stdout - return b -} - -// Stderr will return the stderr that will be used when creating -// the firecracker exec.Command -func (b VMCommandBuilder) Stderr() io.Writer { - return b.stderr -} - -// WithStderr specifies which io.Writer to use in place of the -// os.Stderr in the firecracker exec.Command. -func (b VMCommandBuilder) WithStderr(stderr io.Writer) VMCommandBuilder { - b.stderr = stderr - return b -} - -// Stdin will return the stdin that will be used when creating -// the firecracker exec.Command -func (b VMCommandBuilder) Stdin() io.Reader { - return b.stdin -} - -// WithStdin specifies which io.Reader to use in place of the -// os.Stdin in the firecracker exec.Command. -func (b VMCommandBuilder) WithStdin(stdin io.Reader) VMCommandBuilder { - b.stdin = stdin - return b -} - -// Build will build a firecracker command using the specific arguments -// specified in the builder. -func (b VMCommandBuilder) Build(ctx context.Context) *exec.Cmd { - args := []string{} - if socketPath := b.SocketPath(); socketPath != nil { - args = append(args, socketPath...) - } - if v := b.Args(); v != nil { - args = append(args, v...) - } - - cmd := exec.CommandContext( - ctx, - b.Bin(), - args..., - ) - - if stdout := b.Stdout(); stdout != nil { - cmd.Stdout = stdout - } - if stderr := b.Stderr(); stderr != nil { - cmd.Stderr = stderr - } - if stdin := b.Stdin(); stdin != nil { - cmd.Stdin = stdin - } - - return cmd -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/doc.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/doc.go deleted file mode 100644 index f522c0666c..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/doc.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -/* -Package firecracker provides a library to interact with the Firecracker API. - -Firecracker is an open-source virtualization technology that is purpose-built -for creating and managing secure, multi-tenant containers and functions-based -services. See https://firecracker-microvm.github.io/ for more details. - -This library requires Go 1.11 and can be used with Go modules. - -BUG(aws): There are some Firecracker features that are not yet supported by the -SDK. These are tracked as GitHub issues with the firecracker-feature label: -https://github.com/firecracker-microvm/firecracker-go-sdk/issues?q=is%3Aissue+is%3Aopen+label%3Afirecracker-feature - -This library is licensed under the Apache 2.0 License. -*/ -package firecracker diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/drives.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/drives.go deleted file mode 100644 index 37c262b5cf..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/drives.go +++ /dev/null @@ -1,65 +0,0 @@ -package firecracker - -import ( - "strconv" - - models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" -) - -const rootDriveName = "root-drive" - -// DrivesBuilder is a builder that will build an array of drives used to set up -// the firecracker microVM. The DriveID will be an incrementing number starting -// at one -type DrivesBuilder struct { - rootDrive models.Drive - drives []models.Drive -} - -// NewDrivesBuilder will return a new DrivesBuilder with a given rootfs. -func NewDrivesBuilder(rootDrivePath string) DrivesBuilder { - return DrivesBuilder{}.WithRootDrive(rootDrivePath) -} - -// DriveOpt represents an optional function used to allow for specific -// customization of the models.Drive structure. -type DriveOpt func(*models.Drive) - -// WithRootDrive will set the given builder with the a new root path. The root -// drive will be set to read and write by default. -func (b DrivesBuilder) WithRootDrive(rootDrivePath string, opts ...DriveOpt) DrivesBuilder { - b.rootDrive = models.Drive{ - DriveID: String(rootDriveName), - PathOnHost: &rootDrivePath, - IsRootDevice: Bool(true), - IsReadOnly: Bool(false), - } - - for _, opt := range opts { - opt(&b.rootDrive) - } - - return b -} - -// AddDrive will add a new drive to the given builder. -func (b DrivesBuilder) AddDrive(path string, readOnly bool, opts ...DriveOpt) DrivesBuilder { - drive := models.Drive{ - DriveID: String(strconv.Itoa(len(b.drives))), - PathOnHost: &path, - IsRootDevice: Bool(false), - IsReadOnly: &readOnly, - } - - for _, opt := range opts { - opt(&drive) - } - - b.drives = append(b.drives, drive) - return b -} - -// Build will construct an array of drives with the root drive at the very end. -func (b DrivesBuilder) Build() []models.Drive { - return append(b.drives, b.rootDrive) -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/firecracker.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/firecracker.go deleted file mode 100644 index 958a272747..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/firecracker.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -package firecracker - -import ( - "context" - "net" - "net/http" - "time" - - "github.com/go-openapi/strfmt" - "github.com/sirupsen/logrus" - - "github.com/firecracker-microvm/firecracker-go-sdk/client" - models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" - ops "github.com/firecracker-microvm/firecracker-go-sdk/client/operations" - httptransport "github.com/go-openapi/runtime/client" -) - -const firecrackerRequestTimeout = 500 * time.Millisecond - -// FirecrackerClient is a client for interacting with the Firecracker API -type FirecrackerClient struct { - client *client.Firecracker -} - -// NewFirecrackerClient creates a FirecrackerClient -func NewFirecrackerClient(socketPath string, logger *logrus.Entry, debug bool) *FirecrackerClient { - httpClient := client.NewHTTPClient(strfmt.NewFormats()) - - socketTransport := &http.Transport{ - DialContext: func(ctx context.Context, network, path string) (net.Conn, error) { - addr, err := net.ResolveUnixAddr("unix", socketPath) - if err != nil { - return nil, err - } - - return net.DialUnix("unix", nil, addr) - }, - } - - transport := httptransport.New(client.DefaultHost, client.DefaultBasePath, client.DefaultSchemes) - transport.Transport = socketTransport - - if debug { - transport.SetDebug(debug) - } - - if logger != nil { - transport.SetLogger(logger) - } - - httpClient.SetTransport(transport) - - return &FirecrackerClient{client: httpClient} -} - -func (f *FirecrackerClient) PutLogger(ctx context.Context, logger *models.Logger) (*ops.PutLoggerNoContent, error) { - timeout, cancel := context.WithTimeout(ctx, firecrackerRequestTimeout) - defer cancel() - - loggerParams := ops.NewPutLoggerParamsWithContext(timeout) - loggerParams.SetBody(logger) - - return f.client.Operations.PutLogger(loggerParams) -} - -func (f *FirecrackerClient) PutMachineConfiguration(ctx context.Context, cfg *models.MachineConfiguration) (*ops.PutMachineConfigurationNoContent, error) { - timeout, cancel := context.WithTimeout(ctx, firecrackerRequestTimeout) - defer cancel() - - mc := ops.NewPutMachineConfigurationParamsWithContext(timeout) - mc.SetBody(cfg) - - return f.client.Operations.PutMachineConfiguration(mc) -} - -func (f *FirecrackerClient) PutGuestBootSource(ctx context.Context, source *models.BootSource) (*ops.PutGuestBootSourceNoContent, error) { - timeout, cancel := context.WithTimeout(ctx, firecrackerRequestTimeout) - defer cancel() - - bootSource := ops.NewPutGuestBootSourceParamsWithContext(timeout) - bootSource.SetBody(source) - - return f.client.Operations.PutGuestBootSource(bootSource) -} - -func (f *FirecrackerClient) PutGuestNetworkInterfaceByID(ctx context.Context, ifaceID string, ifaceCfg *models.NetworkInterface) (*ops.PutGuestNetworkInterfaceByIDNoContent, error) { - timeout, cancel := context.WithTimeout(ctx, firecrackerRequestTimeout) - defer cancel() - - cfg := ops.NewPutGuestNetworkInterfaceByIDParamsWithContext(timeout) - cfg.SetBody(ifaceCfg) - cfg.SetIfaceID(ifaceID) - - return f.client.Operations.PutGuestNetworkInterfaceByID(cfg) -} - -func (f *FirecrackerClient) PutGuestDriveByID(ctx context.Context, driveID string, drive *models.Drive) (*ops.PutGuestDriveByIDNoContent, error) { - timeout, cancel := context.WithTimeout(ctx, 250*time.Millisecond) - defer cancel() - - params := ops.NewPutGuestDriveByIDParamsWithContext(timeout) - params.SetDriveID(driveID) - params.SetBody(drive) - - return f.client.Operations.PutGuestDriveByID(params) -} - -func (f *FirecrackerClient) PutGuestVsockByID(ctx context.Context, vsockID string, vsock *models.Vsock) (*ops.PutGuestVsockByIDCreated, *ops.PutGuestVsockByIDNoContent, error) { - params := ops.NewPutGuestVsockByIDParams() - params.SetContext(ctx) - params.SetID(vsockID) - params.SetBody(vsock) - return f.client.Operations.PutGuestVsockByID(params) -} - -func (f *FirecrackerClient) CreateSyncAction(ctx context.Context, info *models.InstanceActionInfo) (*ops.CreateSyncActionNoContent, error) { - params := ops.NewCreateSyncActionParams() - params.SetContext(ctx) - params.SetInfo(info) - - return f.client.Operations.CreateSyncAction(params) -} - -func (f *FirecrackerClient) PutMmds(ctx context.Context, metadata interface{}) (*ops.PutMmdsNoContent, error) { - params := ops.NewPutMmdsParams() - params.SetContext(ctx) - params.SetBody(metadata) - - return f.client.Operations.PutMmds(params) -} - -func (f *FirecrackerClient) GetMachineConfig() (*ops.GetMachineConfigOK, error) { - p := ops.NewGetMachineConfigParams() - p.SetTimeout(firecrackerRequestTimeout) - - return f.client.Operations.GetMachineConfig(p) -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/handlers.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/handlers.go deleted file mode 100644 index f7f1bd0c96..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/handlers.go +++ /dev/null @@ -1,237 +0,0 @@ -package firecracker - -import ( - "context" -) - -// Handler name constants -const ( - StartVMMHandlerName = "fcinit.StartVMM" - BootstrapLoggingHandlerName = "fcinit.BootstrapLogging" - CreateMachineHandlerName = "fcinit.CreateMachine" - CreateBootSourceHandlerName = "fcinit.CreateBootSource" - AttachDrivesHandlerName = "fcinit.AttachDrives" - CreateNetworkInterfacesHandlerName = "fcinit.CreateNetworkInterfaces" - AddVsocksHandlerName = "fcinit.AddVsocks" - SetMetadataHandlerName = "fcinit.SetMetadata" - - ValidateCfgHandlerName = "validate.Cfg" -) - -// StartVMMHandler is a named handler that will handle starting of the VMM. -// This handler will also set the exit channel on completion. -var StartVMMHandler = Handler{ - Name: StartVMMHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.startVMM(ctx) - }, -} - -// BootstrapLoggingHandler is a named handler that will set up fifo logging of -// firecracker process. -var BootstrapLoggingHandler = Handler{ - Name: BootstrapLoggingHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - if err := m.setupLogging(ctx); err != nil { - m.logger.Warnf("setupLogging() returned %s. Continuing anyway.", err) - } else { - m.logger.Debugf("setup logging: success") - } - - return nil - }, -} - -// CreateMachineHandler is a named handler that will "create" the machine and -// upload any necessary configuration to the firecracker process. -var CreateMachineHandler = Handler{ - Name: CreateMachineHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.createMachine(ctx) - }, -} - -// CreateBootSourceHandler is a named handler that will set up the booting -// process of the firecracker process. -var CreateBootSourceHandler = Handler{ - Name: CreateBootSourceHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.createBootSource(ctx, m.cfg.KernelImagePath, m.cfg.KernelArgs) - }, -} - -// AttachDrivesHandler is a named handler that will attach all drives for the -// firecracker process. -var AttachDrivesHandler = Handler{ - Name: AttachDrivesHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.attachDrives(ctx, m.cfg.Drives...) - }, -} - -// CreateNetworkInterfacesHandler is a named handler that sets up network -// interfaces to the firecracker process. -var CreateNetworkInterfacesHandler = Handler{ - Name: CreateNetworkInterfacesHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.createNetworkInterfaces(ctx, m.cfg.NetworkInterfaces...) - }, -} - -// AddVsocksHandler is a named handler that adds vsocks to the firecracker -// process. -var AddVsocksHandler = Handler{ - Name: AddVsocksHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.addVsocks(ctx, m.cfg.VsockDevices...) - }, -} - -// NewSetMetadataHandler is a named handler that puts the metadata into the -// firecracker process. -func NewSetMetadataHandler(metadata interface{}) Handler { - return Handler{ - Name: SetMetadataHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - return m.SetMetadata(ctx, m.Metadata) - }, - } -} - -var defaultValidationHandlerList = HandlerList{}.Append( - Handler{ - Name: ValidateCfgHandlerName, - Fn: func(ctx context.Context, m *Machine) error { - // ensure that the configuration is valid for the - // FcInit handlers. - return m.cfg.Validate() - }, - }, -) - -var defaultFcInitHandlerList = HandlerList{}.Append( - StartVMMHandler, - BootstrapLoggingHandler, - CreateMachineHandler, - CreateBootSourceHandler, - AttachDrivesHandler, - CreateNetworkInterfacesHandler, - AddVsocksHandler, -) - -var defaultHandlers = Handlers{ - Validation: defaultValidationHandlerList, - FcInit: defaultFcInitHandlerList, -} - -// Handler represents a named handler that contains a name and a function which -// is used to execute during the initialization process of a machine. -type Handler struct { - Name string - Fn func(context.Context, *Machine) error -} - -// Handlers is a container that houses categories of handler lists. -type Handlers struct { - Validation HandlerList - FcInit HandlerList -} - -// Run will execute all handlers in the Handlers object by flattening the lists -// into a single list and running. -func (h Handlers) Run(ctx context.Context, m *Machine) error { - l := HandlerList{}.Append( - h.Validation.list..., - ).Append( - h.FcInit.list..., - ) - - return l.Run(ctx, m) -} - -// HandlerList represents a list of named handler that can be used to execute a -// flow of instructions for a given machine. -type HandlerList struct { - list []Handler -} - -// Append will append a new handler to the handler list. -func (l HandlerList) Append(handlers ...Handler) HandlerList { - l.list = append(l.list, handlers...) - - return l -} - -// Len return the length of the given handler list -func (l HandlerList) Len() int { - return len(l.list) -} - -// Has will iterate through the handler list and check to see if the the named -// handler exists. -func (l HandlerList) Has(name string) bool { - for _, h := range l.list { - if h.Name == name { - return true - } - } - - return false -} - -// Swap will replace all elements of the given name with the new handler. -func (l HandlerList) Swap(handler Handler) HandlerList { - newList := HandlerList{} - for _, h := range l.list { - if h.Name == handler.Name { - newList.list = append(newList.list, handler) - continue - } - - newList.list = append(newList.list, h) - } - - return newList -} - -// Swappend will either append, if there isn't an element within the handler -// list, otherwise it will replace all elements with the given name. -func (l HandlerList) Swappend(handler Handler) HandlerList { - if l.Has(handler.Name) { - return l.Swap(handler) - } - - return l.Append(handler) -} - -// Remove will return an updated handler with all instances of the specific -// named handler being removed. -func (l HandlerList) Remove(name string) HandlerList { - newList := HandlerList{} - for _, h := range l.list { - if h.Name != name { - newList.list = append(newList.list, h) - } - } - - return newList -} - -// Clear clears all named handler in the list. -func (l HandlerList) Clear() HandlerList { - l.list = l.list[0:0] - return l -} - -// Run will execute each instruction in the handler list. If an error occurs in -// any of the handlers, then the list will halt execution and return the error. -func (l HandlerList) Run(ctx context.Context, m *Machine) error { - for _, handler := range l.list { - m.logger.Debugf("Running handler %s", handler.Name) - if err := handler.Fn(ctx, m); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/machine.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/machine.go deleted file mode 100644 index c19f0a7f80..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/machine.go +++ /dev/null @@ -1,607 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -package firecracker - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "os/exec" - "os/signal" - "strconv" - "syscall" - "time" - - models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" - ops "github.com/firecracker-microvm/firecracker-go-sdk/client/operations" - log "github.com/sirupsen/logrus" -) - -const ( - userAgent = "firecracker-go-sdk" -) - -// Firecracker is an interface that can be used to mock -// out an Firecracker agent for testing purposes. -type Firecracker interface { - PutLogger(ctx context.Context, logger *models.Logger) (*ops.PutLoggerNoContent, error) - PutMachineConfiguration(ctx context.Context, cfg *models.MachineConfiguration) (*ops.PutMachineConfigurationNoContent, error) - PutGuestBootSource(ctx context.Context, source *models.BootSource) (*ops.PutGuestBootSourceNoContent, error) - PutGuestNetworkInterfaceByID(ctx context.Context, ifaceID string, ifaceCfg *models.NetworkInterface) (*ops.PutGuestNetworkInterfaceByIDNoContent, error) - PutGuestDriveByID(ctx context.Context, driveID string, drive *models.Drive) (*ops.PutGuestDriveByIDNoContent, error) - PutGuestVsockByID(ctx context.Context, vsockID string, vsock *models.Vsock) (*ops.PutGuestVsockByIDCreated, *ops.PutGuestVsockByIDNoContent, error) - CreateSyncAction(ctx context.Context, info *models.InstanceActionInfo) (*ops.CreateSyncActionNoContent, error) - PutMmds(ctx context.Context, metadata interface{}) (*ops.PutMmdsNoContent, error) - GetMachineConfig() (*ops.GetMachineConfigOK, error) -} - -// Config is a collection of user-configurable VMM settings -type Config struct { - // SocketPath defines the file path where the Firecracker control socket - // should be created. - SocketPath string - - // LogFifo defines the file path where the Firecracker log named-pipe should - // be located. - LogFifo string - - // LogLevel defines the verbosity of Firecracker logging. Valid values are - // "Error", "Warning", "Info", and "Debug", and are case-sensitive. - LogLevel string - - // MetricsFifo defines the file path where the Firecracker metrics - // named-pipe should be located. - MetricsFifo string - - // KernelImagePath defines the file path where the kernel image is located. - // The kernel image must be an uncompressed ELF image. - KernelImagePath string - - // KernelArgs defines the command-line arguments that should be passed to - // the kernel. - KernelArgs string - - // Drives specifies BlockDevices that should be made available to the - // microVM. - Drives []models.Drive - - // NetworkInterfaces specifies the tap devices that should be made available - // to the microVM. - NetworkInterfaces []NetworkInterface - - // FifoLogWriter is an io.Writer that is used to redirect the contents of the - // fifo log to the writer. - FifoLogWriter io.Writer - - // VsockDevices specifies the vsock devices that should be made available to - // the microVM. - VsockDevices []VsockDevice - - // Debug enables debug-level logging for the SDK. - Debug bool - - // MachineCfg represents the firecracker microVM process configuration - MachineCfg models.MachineConfiguration - - // DisableValidation allows for easier mock testing by disabling the - // validation of configuration performed by the SDK. - DisableValidation bool -} - -// Validate will ensure that the required fields are set and that -// the fields are valid values. -func (cfg *Config) Validate() error { - if cfg.DisableValidation { - return nil - } - - if _, err := os.Stat(cfg.KernelImagePath); err != nil { - return fmt.Errorf("failed to stat kernal image path, %q: %v", cfg.KernelImagePath, err) - } - - rootPath := "" - for _, drive := range cfg.Drives { - if BoolValue(drive.IsRootDevice) { - rootPath = StringValue(drive.PathOnHost) - break - } - } - - if _, err := os.Stat(rootPath); err != nil { - return fmt.Errorf("failed to stat host path, %q: %v", rootPath, err) - } - - // Check the non-existence of some files: - if _, err := os.Stat(cfg.SocketPath); err == nil { - return fmt.Errorf("socket %s already exists", cfg.SocketPath) - } - - return nil -} - -// Machine is the main object for manipulating Firecracker microVMs -type Machine struct { - cfg Config - client Firecracker - cmd *exec.Cmd - logger *log.Entry - machineConfig models.MachineConfiguration // The actual machine config as reported by Firecracker - - // Metadata is the associated metadata that will be sent to the firecracker - // process - Metadata interface{} - errCh chan error - Handlers Handlers -} - -// Logger returns a logrus logger appropriate for logging hypervisor messages -func (m *Machine) Logger() *log.Entry { - return m.logger.WithField("subsystem", userAgent) -} - -// NetworkInterface represents a Firecracker microVM's network interface. -type NetworkInterface struct { - // MacAddress defines the MAC address that should be assigned to the network - // interface inside the microVM. - MacAddress string - // HostDevName defines the file path of the tap device on the host. - HostDevName string - // AllowMMDS makes the Firecracker MMDS available on this network interface. - AllowMDDS bool -} - -// VsockDevice represents a vsock connection between the host and the guest -// microVM. -type VsockDevice struct { - // Path defines the filesystem path of the vsock device on the host. - Path string - // CID defines the 32-bit Context Identifier for the vsock device. See - // the vsock(7) manual page for more information. - CID uint32 -} - -// SocketPath returns the filesystem path to the socket used for VMM -// communication -func (m Machine) socketPath() string { - return m.cfg.SocketPath -} - -// LogFile returns the filesystem path of the VMM log -func (m Machine) LogFile() string { - return m.cfg.LogFifo -} - -// LogLevel returns the VMM log level. -func (m Machine) LogLevel() string { - return m.cfg.LogLevel -} - -// NewMachine initializes a new Machine instance and performs validation of the -// provided Config. -func NewMachine(ctx context.Context, cfg Config, opts ...Opt) (*Machine, error) { - if err := cfg.Validate(); err != nil { - return nil, err - } - - m := &Machine{} - logger := log.New() - - if cfg.Debug { - logger.SetLevel(log.DebugLevel) - } - - m.logger = log.NewEntry(logger) - m.cmd = defaultFirecrackerVMMCommandBuilder. - WithSocketPath(cfg.SocketPath). - Build(ctx) - m.Handlers = defaultHandlers - - for _, opt := range opts { - opt(m) - } - - if m.client == nil { - m.client = NewFirecrackerClient(cfg.SocketPath, m.logger, cfg.Debug) - } - - m.cfg = cfg - - m.logger.Debug("Called NewMachine()") - return m, nil -} - -// Start will iterate through the handler list and call each handler. If an -// error occurred during handler execution, that error will be returned. If the -// handlers succeed, then this will start the VMM instance. -func (m *Machine) Start(ctx context.Context) error { - m.logger.Debug("Called Machine.Start()") - if err := m.Handlers.Run(ctx, m); err != nil { - return err - } - - return m.StartInstance(ctx) -} - -// Wait will wait until the firecracker process has finished -func (m *Machine) Wait(ctx context.Context) error { - select { - case <-ctx.Done(): - return ctx.Err() - case err := <-m.errCh: - return err - } -} - -func (m *Machine) addVsocks(ctx context.Context, vsocks ...VsockDevice) error { - for _, dev := range m.cfg.VsockDevices { - if err := m.addVsock(ctx, dev); err != nil { - return err - } - } - return nil -} - -func (m *Machine) createNetworkInterfaces(ctx context.Context, ifaces ...NetworkInterface) error { - for id, iface := range ifaces { - if err := m.createNetworkInterface(ctx, iface, id+1); err != nil { - return err - } - m.logger.Debugf("createNetworkInterface returned for %s", iface.HostDevName) - } - - return nil -} - -func (m *Machine) attachDrives(ctx context.Context, drives ...models.Drive) error { - for _, dev := range drives { - if err := m.attachDrive(ctx, dev); err != nil { - m.logger.Errorf("While attaching drive %s, got error %s", StringValue(dev.PathOnHost), err) - return err - } - m.logger.Debugf("attachDrive returned for %s", StringValue(dev.PathOnHost)) - } - - return nil -} - -// startVMM starts the firecracker vmm process and configures logging. -func (m *Machine) startVMM(ctx context.Context) error { - m.logger.Printf("Called startVMM(), setting up a VMM on %s", m.cfg.SocketPath) - - m.errCh = make(chan error) - - err := m.cmd.Start() - if err != nil { - m.logger.Errorf("Failed to start VMM: %s", err) - return err - } - m.logger.Debugf("VMM started socket path is %s", m.cfg.SocketPath) - - go func() { - if err := m.cmd.Wait(); err != nil { - m.logger.Warnf("firecracker exited: %s", err.Error()) - } else { - m.logger.Printf("firecracker exited: status=0") - } - - os.Remove(m.cfg.SocketPath) - os.Remove(m.cfg.LogFifo) - os.Remove(m.cfg.MetricsFifo) - m.errCh <- err - }() - - // Set up a signal handler and pass INT, QUIT, and TERM through to firecracker - vmchan := make(chan error) - sigchan := make(chan os.Signal) - signal.Notify(sigchan, os.Interrupt, - syscall.SIGQUIT, - syscall.SIGTERM, - syscall.SIGHUP, - syscall.SIGABRT) - m.logger.Debugf("Setting up signal handler") - go func() { - select { - case sig := <-sigchan: - m.logger.Printf("Caught signal %s", sig) - m.cmd.Process.Signal(sig) - case err = <-vmchan: - m.errCh <- err - } - }() - - // Wait for firecracker to initialize: - err = m.waitForSocket(3*time.Second, m.errCh) - if err != nil { - msg := fmt.Sprintf("Firecracker did not create API socket %s: %s", m.cfg.SocketPath, err) - err = errors.New(msg) - return err - } - - m.logger.Debugf("returning from startVMM()") - return nil -} - -//StopVMM stops the current VMM. -func (m *Machine) StopVMM() error { - return m.stopVMM() -} - -func (m *Machine) stopVMM() error { - if m.cmd != nil && m.cmd.Process != nil { - log.Debug("stopVMM(): sending sigterm to firecracker") - return m.cmd.Process.Signal(syscall.SIGTERM) - } - log.Debug("stopVMM(): no firecracker process running, not sending a signal") - - // don't return an error if the process isn't even running - return nil -} - -// createFifos sets up the firecracker logging and metrics FIFOs -func createFifos(logFifo, metricsFifo string) error { - log.Debugf("Creating FIFO %s", logFifo) - if err := syscall.Mkfifo(logFifo, 0700); err != nil { - return fmt.Errorf("Failed to create log fifo: %v", err) - } - - log.Debugf("Creating metric FIFO %s", metricsFifo) - if err := syscall.Mkfifo(metricsFifo, 0700); err != nil { - return fmt.Errorf("Failed to create metric fifo: %v", err) - } - return nil -} - -func (m *Machine) setupLogging(ctx context.Context) error { - if len(m.cfg.LogFifo) == 0 || len(m.cfg.MetricsFifo) == 0 { - // No logging configured - m.logger.Printf("VMM logging and metrics disabled.") - return nil - } - - if err := createFifos(m.cfg.LogFifo, m.cfg.MetricsFifo); err != nil { - m.logger.Errorf("Unable to set up logging: %s", err) - return err - } - - m.logger.Debug("Created metrics and logging fifos.") - - l := models.Logger{ - LogFifo: m.cfg.LogFifo, - Level: m.cfg.LogLevel, - MetricsFifo: m.cfg.MetricsFifo, - ShowLevel: true, - ShowLogOrigin: false, - } - - _, err := m.client.PutLogger(ctx, &l) - if err != nil { - return err - } - - m.logger.Debugf("Configured VMM logging to %s, metrics to %s", - m.cfg.LogFifo, - m.cfg.MetricsFifo, - ) - - if m.cfg.FifoLogWriter != nil { - if err := captureFifoToFile(m.logger, m.cfg.LogFifo, m.cfg.FifoLogWriter); err != nil { - return err - } - } - - return nil -} - -func captureFifoToFile(logger *log.Entry, fifoPath string, fifo io.Writer) error { - // create the fifo pipe which will be used - // to write its contents to a file. - fifoPipe, err := os.OpenFile(fifoPath, os.O_RDONLY, 0600) - if err != nil { - return fmt.Errorf("Failed to open fifo path at %q: %v", fifoPath, err) - } - - if err := syscall.Unlink(fifoPath); err != nil { - logger.Warnf("Failed to unlink %s", fifoPath) - } - - logger.Debugf("Capturing %q to writer", fifoPath) - - // Uses a go routine to do a non-blocking io.Copy. The fifo - // file should be closed when the appication has finished, since - // the forked firecracker application will be closed resulting - // in the pipe to return an io.EOF - go func() { - defer fifoPipe.Close() - - if _, err := io.Copy(fifo, fifoPipe); err != nil { - logger.Warnf("io.Copy failed to copy contents of fifo pipe: %v", err) - } - }() - - return nil -} - -func (m *Machine) createMachine(ctx context.Context) error { - resp, err := m.client.PutMachineConfiguration(ctx, &m.cfg.MachineCfg) - if err != nil { - m.logger.Errorf("PutMachineConfiguration returned %s", resp.Error()) - return err - } - - m.logger.Debug("PutMachineConfiguration returned") - err = m.refreshMachineConfig() - if err != nil { - log.Errorf("Unable to inspect Firecracker MachineConfig. Continuing anyway. %s", err) - } - m.logger.Debug("createMachine returning") - return err -} - -func (m *Machine) createBootSource(ctx context.Context, imagePath, kernelArgs string) error { - bsrc := models.BootSource{ - KernelImagePath: &imagePath, - BootArgs: kernelArgs, - } - - resp, err := m.client.PutGuestBootSource(ctx, &bsrc) - if err == nil { - m.logger.Printf("PutGuestBootSource: %s", resp.Error()) - } - - return err -} - -func (m *Machine) createNetworkInterface(ctx context.Context, iface NetworkInterface, iid int) error { - ifaceID := strconv.Itoa(iid) - m.logger.Printf("Attaching NIC %s (hwaddr %s) at index %s", iface.HostDevName, iface.MacAddress, ifaceID) - - ifaceCfg := models.NetworkInterface{ - IfaceID: &ifaceID, - GuestMac: iface.MacAddress, - HostDevName: iface.HostDevName, - AllowMmdsRequests: iface.AllowMDDS, - } - - resp, err := m.client.PutGuestNetworkInterfaceByID(ctx, ifaceID, &ifaceCfg) - if err == nil { - m.logger.Printf("PutGuestNetworkInterfaceByID: %s", resp.Error()) - } - - return err -} - -// attachDrive attaches a secondary block device -func (m *Machine) attachDrive(ctx context.Context, dev models.Drive) error { - var err error - hostPath := StringValue(dev.PathOnHost) - - _, err = os.Stat(hostPath) - if err != nil { - return err - } - - log.Infof("Attaching drive %s, slot %s, root %t.", hostPath, StringValue(dev.DriveID), BoolValue(dev.IsRootDevice)) - respNoContent, err := m.client.PutGuestDriveByID(ctx, StringValue(dev.DriveID), &dev) - if err == nil { - m.logger.Printf("Attached drive %s: %s", hostPath, respNoContent.Error()) - } else { - m.logger.Errorf("Attach drive failed: %s: %s", hostPath, err) - } - return err -} - -// addVsock adds a vsock to the instance -func (m *Machine) addVsock(ctx context.Context, dev VsockDevice) error { - vsockCfg := models.Vsock{ - GuestCid: int64(dev.CID), - ID: &dev.Path, - } - resp, _, err := m.client.PutGuestVsockByID(ctx, dev.Path, &vsockCfg) - if err != nil { - return err - } - m.logger.Debugf("Attach vsock %s successful: %s", dev.Path, resp.Error()) - return nil -} - -// StartInstance starts the Firecracker microVM -func (m *Machine) StartInstance(ctx context.Context) error { - return m.startInstance(ctx) -} - -func (m *Machine) startInstance(ctx context.Context) error { - info := models.InstanceActionInfo{ - ActionType: models.InstanceActionInfoActionTypeInstanceStart, - } - - resp, err := m.client.CreateSyncAction(ctx, &info) - if err == nil { - m.logger.Printf("startInstance successful: %s", resp.Error()) - } else { - m.logger.Errorf("Starting instance: %s", err) - } - return err -} - -// EnableMetadata will append or replace the metadata handler. -func (m *Machine) EnableMetadata(metadata interface{}) { - m.Handlers.FcInit = m.Handlers.FcInit.Swappend(NewSetMetadataHandler(metadata)) -} - -// SetMetadata sets the machine's metadata for MDDS -func (m *Machine) SetMetadata(ctx context.Context, metadata interface{}) error { - respnocontent, err := m.client.PutMmds(ctx, metadata) - - if err == nil { - var message string - if respnocontent != nil { - message = respnocontent.Error() - } - m.logger.Printf("SetMetadata successful: %s", message) - } else { - m.logger.Errorf("Setting metadata: %s", err) - } - return err -} - -// refreshMachineConfig synchronizes our cached representation of the machine configuration -// with that reported by the Firecracker API -func (m *Machine) refreshMachineConfig() error { - resp, err := m.client.GetMachineConfig() - if err != nil { - return err - } - - m.logger.Infof("refreshMachineConfig: %s", resp.Error()) - m.machineConfig = *resp.Payload - return nil -} - -// waitForSocket waits for the given file to exist -func (m *Machine) waitForSocket(timeout time.Duration, exitchan chan error) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - done := make(chan error) - ticker := time.NewTicker(10 * time.Millisecond) - - go func() { - for { - select { - case <-ctx.Done(): - done <- ctx.Err() - return - case err := <-exitchan: - done <- err - return - case <-ticker.C: - if _, err := os.Stat(m.cfg.SocketPath); err != nil { - continue - } - - // Send test HTTP request to make sure socket is available - if _, err := m.client.GetMachineConfig(); err != nil { - continue - } - - done <- nil - return - } - } - }() - - return <-done -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/opts.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/opts.go deleted file mode 100644 index d02b4ea60c..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/opts.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -package firecracker - -import ( - "os/exec" - - "github.com/sirupsen/logrus" -) - -// Opt represents a functional option to help modify functionality of a Machine. -type Opt func(*Machine) - -// WithClient will use the client in place rather than the client constructed -// during bootstrapping of the machine. This option is useful for mocking out -// tests. -func WithClient(client Firecracker) Opt { - return func(machine *Machine) { - machine.client = client - } -} - -// WithLogger will allow for the Machine to use the provided logger. -func WithLogger(logger *logrus.Entry) Opt { - return func(machine *Machine) { - machine.logger = logger - } -} - -// WithProcessRunner will allow for a specific command to be run instead of the -// default firecracker command. -// For example, this could be used to instead call the jailer instead of -// firecracker directly. -func WithProcessRunner(cmd *exec.Cmd) Opt { - return func(machine *Machine) { - machine.cmd = cmd - } -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/pointer_helpers.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/pointer_helpers.go deleted file mode 100644 index 6dd58f0276..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/pointer_helpers.go +++ /dev/null @@ -1,46 +0,0 @@ -package firecracker - -// BoolValue will return a boolean value. If the pointer is nil, then false -// will be returned. -func BoolValue(b *bool) bool { - if b == nil { - return false - } - - return *b -} - -// Bool will return a pointer value of the given parameter. -func Bool(b bool) *bool { - return &b -} - -// StringValue will return a string value. If the pointer is nil, then an empty -// string will be returned. -func StringValue(str *string) string { - if str == nil { - return "" - } - - return *str -} - -// String will return a pointer value of the given parameter. -func String(str string) *string { - return &str -} - -// Int64 will return a pointer value of the given parameter. -func Int64(v int64) *int64 { - return &v -} - -// Int64Value will return an int64 value. If the pointer is nil, then zero will -// be returned. -func Int64Value(v *int64) int64 { - if v == nil { - return 0 - } - - return *v -} diff --git a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/swagger.go b/vendor/github.com/firecracker-microvm/firecracker-go-sdk/swagger.go deleted file mode 100644 index fd762acd78..0000000000 --- a/vendor/github.com/firecracker-microvm/firecracker-go-sdk/swagger.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"). You may -// not use this file except in compliance with the License. A copy of the -// License is located at -// -// http://aws.amazon.com/apache2.0/ -// -// or in the "license" file accompanying this file. This file is distributed -// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -// express or implied. See the License for the specific language governing -// permissions and limitations under the License. - -//go:generate find ./client ! -name swagger.yaml -type f -delete - -// --skip-validation is used in the command-lines below to remove the network dependency that the swagger generator has -// in attempting to validate that the email address specified in the yaml file is valid. - -//go:generate docker run --rm --net=none -v $PWD:/work -w /work quay.io/goswagger/swagger generate model -f ./client/swagger.yaml --model-package=client/models --client-package=client --copyright-file=COPYRIGHT_HEADER --skip-validation -//go:generate docker run --rm --net=none -v $PWD:/work -w /work quay.io/goswagger/swagger generate client -f ./client/swagger.yaml --model-package=client/models --client-package=client --copyright-file=COPYRIGHT_HEADER --skip-validation - -package firecracker diff --git a/vendor/github.com/intel/govmm/qemu/image.go b/vendor/github.com/intel/govmm/qemu/image.go index de12333c45..ddee0670e1 100644 --- a/vendor/github.com/intel/govmm/qemu/image.go +++ b/vendor/github.com/intel/govmm/qemu/image.go @@ -51,18 +51,18 @@ func CreateCloudInitISO(ctx context.Context, scratchDir, isoPath string, err := os.MkdirAll(dataDirPath, 0750) if err != nil { - return fmt.Errorf("Unable to create config drive directory %s : %v", + return fmt.Errorf("unable to create config drive directory %s : %v", dataDirPath, err) } err = ioutil.WriteFile(metaDataPath, metaData, 0644) if err != nil { - return fmt.Errorf("Unable to create %s : %v", metaDataPath, err) + return fmt.Errorf("unable to create %s : %v", metaDataPath, err) } err = ioutil.WriteFile(userDataPath, userData, 0644) if err != nil { - return fmt.Errorf("Unable to create %s : %v", userDataPath, err) + return fmt.Errorf("unable to create %s : %v", userDataPath, err) } cmd := exec.CommandContext(ctx, "xorriso", "-as", "mkisofs", "-R", "-V", "config-2", @@ -70,7 +70,7 @@ func CreateCloudInitISO(ctx context.Context, scratchDir, isoPath string, cmd.SysProcAttr = attr err = cmd.Run() if err != nil { - return fmt.Errorf("Unable to create cloudinit iso image %v", err) + return fmt.Errorf("unable to create cloudinit iso image %v", err) } return nil diff --git a/vendor/github.com/intel/govmm/qemu/qemu.go b/vendor/github.com/intel/govmm/qemu/qemu.go index 8bd6afbef0..9703018d57 100644 --- a/vendor/github.com/intel/govmm/qemu/qemu.go +++ b/vendor/github.com/intel/govmm/qemu/qemu.go @@ -260,7 +260,7 @@ func (fsdev FSDevice) QemuParams(config *Config) []string { var deviceParams []string var qemuParams []string - deviceParams = append(deviceParams, fmt.Sprintf("%s", fsdev.Driver)) + deviceParams = append(deviceParams, string(fsdev.Driver)) if s := fsdev.Driver.disableModern(fsdev.DisableModern); s != "" { deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } @@ -346,7 +346,7 @@ func (cdev CharDevice) QemuParams(config *Config) []string { var deviceParams []string var qemuParams []string - deviceParams = append(deviceParams, fmt.Sprintf("%s", cdev.Driver)) + deviceParams = append(deviceParams, string(cdev.Driver)) if s := cdev.Driver.disableModern(cdev.DisableModern); s != "" { deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } @@ -534,7 +534,7 @@ func (netdev NetDevice) QemuNetdevParams(config *Config) []string { netdevParams = append(netdevParams, netdev.Type.QemuNetdevParam()) netdevParams = append(netdevParams, fmt.Sprintf(",id=%s", netdev.ID)) - if netdev.VHost == true { + if netdev.VHost { netdevParams = append(netdevParams, ",vhost=on") if len(netdev.VhostFDs) > 0 { var fdParams []string @@ -627,7 +627,7 @@ func (dev SerialDevice) QemuParams(config *Config) []string { var deviceParams []string var qemuParams []string - deviceParams = append(deviceParams, fmt.Sprintf("%s", dev.Driver)) + deviceParams = append(deviceParams, string(dev.Driver)) if s := dev.Driver.disableModern(dev.DisableModern); s != "" { deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } @@ -705,16 +705,16 @@ func (blkdev BlockDevice) QemuParams(config *Config) []string { var deviceParams []string var qemuParams []string - deviceParams = append(deviceParams, fmt.Sprintf("%s", blkdev.Driver)) + deviceParams = append(deviceParams, string(blkdev.Driver)) if s := blkdev.Driver.disableModern(blkdev.DisableModern); s != "" { deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } deviceParams = append(deviceParams, fmt.Sprintf(",drive=%s", blkdev.ID)) - if blkdev.SCSI == false { + if !blkdev.SCSI { deviceParams = append(deviceParams, ",scsi=off") } - if blkdev.WCE == false { + if !blkdev.WCE { deviceParams = append(deviceParams, ",config-wce=off") } @@ -842,11 +842,7 @@ type VFIODevice struct { // Valid returns true if the VFIODevice structure is valid and complete. func (vfioDev VFIODevice) Valid() bool { - if vfioDev.BDF == "" { - return false - } - - return true + return vfioDev.BDF != "" } // QemuParams returns the qemu parameters built out of this vfio device. @@ -889,11 +885,7 @@ type SCSIController struct { // Valid returns true if the SCSIController structure is valid and complete. func (scsiCon SCSIController) Valid() bool { - if scsiCon.ID == "" { - return false - } - - return true + return scsiCon.ID != "" } // QemuParams returns the qemu parameters built out of this SCSIController device. @@ -910,7 +902,7 @@ func (scsiCon SCSIController) QemuParams(config *Config) []string { devParams = append(devParams, fmt.Sprintf("addr=%s", scsiCon.Addr)) } if s := driver.disableModern(scsiCon.DisableModern); s != "" { - devParams = append(devParams, fmt.Sprintf("%s", s)) + devParams = append(devParams, s) } if scsiCon.IOThread != "" { devParams = append(devParams, fmt.Sprintf("iothread=%s", scsiCon.IOThread)) @@ -1057,7 +1049,7 @@ func (vsock VSOCKDevice) QemuParams(config *Config) []string { var qemuParams []string driver := VHostVSock - deviceParams = append(deviceParams, fmt.Sprintf("%s", driver)) + deviceParams = append(deviceParams, string(driver)) if s := driver.disableModern(vsock.DisableModern); s != "" { deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } @@ -1094,11 +1086,7 @@ type RngDevice struct { // Valid returns true if the RngDevice structure is valid and complete. func (v RngDevice) Valid() bool { - if v.ID == "" { - return false - } - - return true + return v.ID != "" } // QemuParams returns the qemu parameters built out of the RngDevice. @@ -1174,7 +1162,7 @@ func (b BalloonDevice) QemuParams(_ *Config) []string { deviceParams = append(deviceParams, "deflate-on-oom=off") } if s := driver.disableModern(b.DisableModern); s != "" { - deviceParams = append(deviceParams, fmt.Sprintf("%s", s)) + deviceParams = append(deviceParams, string(s)) } qemuParams = append(qemuParams, "-device") qemuParams = append(qemuParams, strings.Join(deviceParams, ",")) @@ -1184,11 +1172,7 @@ func (b BalloonDevice) QemuParams(_ *Config) []string { // Valid returns true if the balloonDevice structure is valid and complete. func (b BalloonDevice) Valid() bool { - if b.ID == "" { - return false - } - - return true + return b.ID != "" } // RTCBaseType is the qemu RTC base time type. @@ -1523,15 +1507,15 @@ func (config *Config) appendCPUModel() { func (config *Config) appendQMPSockets() { for _, q := range config.QMPSockets { - if q.Valid() == false { + if !q.Valid() { continue } qmpParams := append([]string{}, fmt.Sprintf("%s:", q.Type)) - qmpParams = append(qmpParams, fmt.Sprintf("%s", q.Name)) - if q.Server == true { + qmpParams = append(qmpParams, q.Name) + if q.Server { qmpParams = append(qmpParams, ",server") - if q.NoWait == true { + if q.NoWait { qmpParams = append(qmpParams, ",nowait") } } @@ -1543,7 +1527,7 @@ func (config *Config) appendQMPSockets() { func (config *Config) appendDevices() { for _, d := range config.Devices { - if d.Valid() == false { + if !d.Valid() { continue } @@ -1611,7 +1595,7 @@ func (config *Config) appendCPUs() error { } func (config *Config) appendRTC() { - if config.RTC.Valid() == false { + if !config.RTC.Valid() { return } @@ -1663,7 +1647,7 @@ func (config *Config) appendKernel() { } func (config *Config) appendMemoryKnobs() { - if config.Knobs.HugePages == true { + if config.Knobs.HugePages { if config.Memory.Size != "" { dimmName := "dimm1" objMemParam := "memory-backend-file,id=" + dimmName + ",size=" + config.Memory.Size + ",mem-path=/dev/hugepages,share=on,prealloc=on" @@ -1675,7 +1659,7 @@ func (config *Config) appendMemoryKnobs() { config.qemuParams = append(config.qemuParams, "-numa") config.qemuParams = append(config.qemuParams, numaMemParam) } - } else if config.Knobs.MemPrealloc == true { + } else if config.Knobs.MemPrealloc { if config.Memory.Size != "" { dimmName := "dimm1" objMemParam := "memory-backend-ram,id=" + dimmName + ",size=" + config.Memory.Size + ",prealloc=on" @@ -1687,11 +1671,11 @@ func (config *Config) appendMemoryKnobs() { config.qemuParams = append(config.qemuParams, "-numa") config.qemuParams = append(config.qemuParams, numaMemParam) } - } else if config.Knobs.FileBackedMem == true { + } else if config.Knobs.FileBackedMem { if config.Memory.Size != "" && config.Memory.Path != "" { dimmName := "dimm1" objMemParam := "memory-backend-file,id=" + dimmName + ",size=" + config.Memory.Size + ",mem-path=" + config.Memory.Path - if config.Knobs.FileBackedMemShared == true { + if config.Knobs.FileBackedMemShared { objMemParam += ",share=on" } numaMemParam := "node,memdev=" + dimmName @@ -1706,45 +1690,45 @@ func (config *Config) appendMemoryKnobs() { } func (config *Config) appendKnobs() { - if config.Knobs.NoUserConfig == true { + if config.Knobs.NoUserConfig { config.qemuParams = append(config.qemuParams, "-no-user-config") } - if config.Knobs.NoDefaults == true { + if config.Knobs.NoDefaults { config.qemuParams = append(config.qemuParams, "-nodefaults") } - if config.Knobs.NoGraphic == true { + if config.Knobs.NoGraphic { config.qemuParams = append(config.qemuParams, "-nographic") } - if config.Knobs.Daemonize == true { + if config.Knobs.Daemonize { config.qemuParams = append(config.qemuParams, "-daemonize") } config.appendMemoryKnobs() - if config.Knobs.Realtime == true { + if config.Knobs.Realtime { config.qemuParams = append(config.qemuParams, "-realtime") // This path is redundant as the default behaviour is locked memory // Realtime today does not control any other feature even though // other features may be added in the future // https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg03330.html - if config.Knobs.Mlock == true { + if config.Knobs.Mlock { config.qemuParams = append(config.qemuParams, "mlock=on") } else { config.qemuParams = append(config.qemuParams, "mlock=off") } } else { // In order to turn mlock off we need the -realtime option as well - if config.Knobs.Mlock == false { + if !config.Knobs.Mlock { //Enable realtime anyway just to get the right swapping behaviour config.qemuParams = append(config.qemuParams, "-realtime") config.qemuParams = append(config.qemuParams, "mlock=off") } } - if config.Knobs.Stopped == true { + if config.Knobs.Stopped { config.qemuParams = append(config.qemuParams, "-S") } } diff --git a/vendor/github.com/intel/govmm/qemu/qmp.go b/vendor/github.com/intel/govmm/qemu/qmp.go index 6e4d4f3559..9b21d96480 100644 --- a/vendor/github.com/intel/govmm/qemu/qmp.go +++ b/vendor/github.com/intel/govmm/qemu/qmp.go @@ -329,14 +329,14 @@ func (q *QMP) errorDesc(errorData interface{}) (string, error) { // convert error to json data, err := json.Marshal(errorData) if err != nil { - return "", fmt.Errorf("Unable to extract error information: %v", err) + return "", fmt.Errorf("unable to extract error information: %v", err) } // see: https://github.com/qemu/qemu/blob/stable-2.12/qapi/qmp-dispatch.c#L125 var qmpErr map[string]string // convert json to qmpError if err = json.Unmarshal(data, &qmpErr); err != nil { - return "", fmt.Errorf("Unable to convert json to qmpError: %v", err) + return "", fmt.Errorf("unable to convert json to qmpError: %v", err) } return qmpErr["desc"], nil @@ -404,7 +404,7 @@ func (q *QMP) writeNextQMPCommand(cmdQueue *list.List) { encodedCmd, err := json.Marshal(&cmdData) if err != nil { cmd.res <- qmpResult{ - err: fmt.Errorf("Unable to marhsall command %s: %v", + err: fmt.Errorf("unable to marhsall command %s: %v", cmd.name, err), } cmdQueue.Remove(cmdEl) @@ -419,7 +419,7 @@ func (q *QMP) writeNextQMPCommand(cmdQueue *list.List) { if err != nil { cmd.res <- qmpResult{ - err: fmt.Errorf("Unable to write command to qmp socket %v", err), + err: fmt.Errorf("unable to write command to qmp socket %v", err), } cmdQueue.Remove(cmdEl) } @@ -525,7 +525,7 @@ func (q *QMP) mainLoop() { } /* #nosec */ _ = q.conn.Close() - _ = <-fromVMCh + <-fromVMCh failOutstandingCommands(cmdQueue) close(q.disconnectedCh) }() @@ -689,12 +689,12 @@ func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh case <-ctx.Done(): q.Shutdown() <-disconnectedCh - return nil, nil, fmt.Errorf("Canceled by caller") + return nil, nil, fmt.Errorf("canceled by caller") case <-disconnectedCh: - return nil, nil, fmt.Errorf("Lost connection to VM") + return nil, nil, fmt.Errorf("lost connection to VM") case q.version = <-connectedCh: if q.version == nil { - return nil, nil, fmt.Errorf("Failed to find QMP version information") + return nil, nil, fmt.Errorf("failed to find QMP version information") } } @@ -860,7 +860,7 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive } if !isSCSIDriver { - return fmt.Errorf("Invalid SCSI driver provided %s", driver) + return fmt.Errorf("invalid SCSI driver provided %s", driver) } args := map[string]interface{}{ @@ -1144,14 +1144,21 @@ func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsd // ExecuteCPUDeviceAdd adds a CPU to a QEMU instance using the device_add command. // driver is the CPU model, cpuID must be a unique ID to identify the CPU, socketID is the socket number within // node/board the CPU belongs to, coreID is the core number within socket the CPU belongs to, threadID is the -// thread number within core the CPU belongs to. +// thread number within core the CPU belongs to. Note that socketID and threadID are not a requirement for +// architecures like ppc64le. func (q *QMP) ExecuteCPUDeviceAdd(ctx context.Context, driver, cpuID, socketID, coreID, threadID, romfile string) error { args := map[string]interface{}{ - "driver": driver, - "id": cpuID, - "socket-id": socketID, - "core-id": coreID, - "thread-id": threadID, + "driver": driver, + "id": cpuID, + "core-id": coreID, + } + + if socketID != "" { + args["socket-id"] = socketID + } + + if threadID != "" { + args["thread-id"] = threadID } if isVirtioPCI[DeviceDriver(driver)] { @@ -1171,13 +1178,13 @@ func (q *QMP) ExecuteQueryHotpluggableCPUs(ctx context.Context) ([]HotpluggableC // convert response to json data, err := json.Marshal(response) if err != nil { - return nil, fmt.Errorf("Unable to extract CPU information: %v", err) + return nil, fmt.Errorf("unable to extract CPU information: %v", err) } var cpus []HotpluggableCPU // convert json to []HotpluggableCPU if err = json.Unmarshal(data, &cpus); err != nil { - return nil, fmt.Errorf("Unable to convert json to hotpluggable CPU: %v", err) + return nil, fmt.Errorf("unable to convert json to hotpluggable CPU: %v", err) } return cpus, nil @@ -1211,7 +1218,7 @@ func (q *QMP) ExecQueryMemoryDevices(ctx context.Context) ([]MemoryDevices, erro // convert response to json data, err := json.Marshal(response) if err != nil { - return nil, fmt.Errorf("Unable to extract memory devices information: %v", err) + return nil, fmt.Errorf("unable to extract memory devices information: %v", err) } var memoryDevices []MemoryDevices @@ -1235,7 +1242,7 @@ func (q *QMP) ExecQueryCpus(ctx context.Context) ([]CPUInfo, error) { // convert response to json data, err := json.Marshal(response) if err != nil { - return nil, fmt.Errorf("Unable to extract memory devices information: %v", err) + return nil, fmt.Errorf("unable to extract memory devices information: %v", err) } var cpuInfo []CPUInfo @@ -1259,7 +1266,7 @@ func (q *QMP) ExecQueryCpusFast(ctx context.Context) ([]CPUInfoFast, error) { // convert response to json data, err := json.Marshal(response) if err != nil { - return nil, fmt.Errorf("Unable to extract memory devices information: %v", err) + return nil, fmt.Errorf("unable to extract memory devices information: %v", err) } var cpuInfoFast []CPUInfoFast @@ -1434,12 +1441,12 @@ func (q *QMP) ExecuteQueryMigration(ctx context.Context) (MigrationStatus, error data, err := json.Marshal(response) if err != nil { - return MigrationStatus{}, fmt.Errorf("Unable to extract migrate status information: %v", err) + return MigrationStatus{}, fmt.Errorf("unable to extract migrate status information: %v", err) } var status MigrationStatus if err = json.Unmarshal(data, &status); err != nil { - return MigrationStatus{}, fmt.Errorf("Unable to convert migrate status information: %v", err) + return MigrationStatus{}, fmt.Errorf("unable to convert migrate status information: %v", err) } return status, nil