diff --git a/Gopkg.lock b/Gopkg.lock index 4b88d09ed0..3bfa0de53d 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" @@ -701,7 +700,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 96fcb32796..7cf7a7d688 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 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