From bc0c71d1f08dfd21351b7f1562cb4687d1265581 Mon Sep 17 00:00:00 2001 From: Richard Case Date: Tue, 20 Dec 2022 09:03:58 +0000 Subject: [PATCH] feat: add back support for mount points This change adds back support for mounting volumes. This was initially done to support external kernel modules. Signed-off-by: Richard Case --- .../microvm/v1alpha1/microvms.swagger.json | 4 + api/types/microvm.pb.go | 37 +- api/types/microvm.proto | 4 +- buf.lock | 4 +- client/cloudinit/userdata/userdata.go | 34 +- core/application/app_test.go | 2 +- core/application/commands.go | 22 +- core/models/volumes.go | 15 + core/plans/microvm_create_update.go | 6 + core/steps/cloudinit/disk_mount.go | 142 ++++++ go.mod | 2 +- infrastructure/grpc/convert.go | 4 + .../grpc/services/microvm/v1alpha1/proto.md | 210 +++++++++ userdocs/docs/grpc/types/proto.md | 441 ++++++++++++++++++ 14 files changed, 900 insertions(+), 27 deletions(-) create mode 100644 core/steps/cloudinit/disk_mount.go create mode 100644 userdocs/docs/grpc/services/microvm/v1alpha1/proto.md create mode 100644 userdocs/docs/grpc/types/proto.md diff --git a/api/services/microvm/v1alpha1/microvms.swagger.json b/api/services/microvm/v1alpha1/microvms.swagger.json index ea725f33..6974a6a3 100644 --- a/api/services/microvm/v1alpha1/microvms.swagger.json +++ b/api/services/microvm/v1alpha1/microvms.swagger.json @@ -481,6 +481,10 @@ "type": "boolean", "description": "IsReadOnly specifies that the volume is to be mounted readonly." }, + "mountPoint": { + "type": "string", + "description": "MountPoint allows you to optionally specify a mount point for the volume. This only\napplied to additional volumes and it will use cloud-init to mount the volumes." + }, "source": { "$ref": "#/definitions/typesVolumeSource", "description": "Source is where the volume will be sourced from." diff --git a/api/types/microvm.pb.go b/api/types/microvm.pb.go index a2b3d230..c1205b27 100644 --- a/api/types/microvm.pb.go +++ b/api/types/microvm.pb.go @@ -715,6 +715,9 @@ type Volume struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // IsReadOnly specifies that the volume is to be mounted readonly. IsReadOnly bool `protobuf:"varint,2,opt,name=is_read_only,json=isReadOnly,proto3" json:"is_read_only,omitempty"` + // MountPoint allows you to optionally specify a mount point for the volume. This only + // applied to additional volumes and it will use cloud-init to mount the volumes. + MountPoint *string `protobuf:"bytes,3,opt,name=mount_point,json=mountPoint,proto3,oneof" json:"mount_point,omitempty"` // Source is where the volume will be sourced from. Source *VolumeSource `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` // PartitionID is the uuid of the boot partition. @@ -769,6 +772,13 @@ func (x *Volume) GetIsReadOnly() bool { return false } +func (x *Volume) GetMountPoint() string { + if x != nil && x.MountPoint != nil { + return *x.MountPoint + } + return "" +} + func (x *Volume) GetSource() *VolumeSource { if x != nil { return x.Source @@ -1327,21 +1337,24 @@ var file_types_microvm_proto_rawDesc = []byte{ 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x42, 0x0a, 0x0a, 0x08, - 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0xe2, 0x01, 0x0a, 0x06, 0x56, 0x6f, 0x6c, + 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0x92, 0x02, 0x0a, 0x06, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x61, - 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x6c, 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0c, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0a, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x5f, - 0x6d, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08, 0x73, 0x69, 0x7a, 0x65, - 0x49, 0x6e, 0x4d, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x6d, 0x62, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x53, 0x0a, + 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x24, 0x0a, 0x0b, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x6c, + 0x69, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x56, 0x6f, + 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x26, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x0a, 0x73, 0x69, + 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x6d, 0x62, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, + 0x52, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x4d, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0f, 0x0a, + 0x0d, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0d, + 0x0a, 0x0b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x6d, 0x62, 0x22, 0x53, 0x0a, 0x0c, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, diff --git a/api/types/microvm.proto b/api/types/microvm.proto index f9379028..4153a77c 100644 --- a/api/types/microvm.proto +++ b/api/types/microvm.proto @@ -128,11 +128,13 @@ message StaticAddress { // Volume represents the configuration for a volume to be attached to a microvm. message Volume { - reserved 3; // ID is the uinique identifier of the volume. string id = 1; // IsReadOnly specifies that the volume is to be mounted readonly. bool is_read_only = 2; + // MountPoint allows you to optionally specify a mount point for the volume. This only + // applied to additional volumes and it will use cloud-init to mount the volumes. + optional string mount_point = 3; // Source is where the volume will be sourced from. VolumeSource source = 4; // PartitionID is the uuid of the boot partition. diff --git a/buf.lock b/buf.lock index 1550d6c2..d8efa9a9 100644 --- a/buf.lock +++ b/buf.lock @@ -4,8 +4,8 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 783e4b5374fa488ab068d08af9658438 + commit: 75b4300737fb4efca0831636be94e517 - remote: buf.build owner: grpc-ecosystem repository: grpc-gateway - commit: b96615cde70c403f8075c48e56178f88 + commit: a1ecdc58eccd49aa8bea2a7a9022dc27 diff --git a/client/cloudinit/userdata/userdata.go b/client/cloudinit/userdata/userdata.go index c34a5c1c..c1889778 100644 --- a/client/cloudinit/userdata/userdata.go +++ b/client/cloudinit/userdata/userdata.go @@ -12,9 +12,41 @@ type UserData struct { RunCommands []string `yaml:"runcmd,omitempty"` // BootCommands are commands you want to run early on in the boot process. These should only // be used for commands that are need early on and running them via RunCommands is too late. - BootCommands []string `yaml:"bootcmd,omitempty"` + BootCommands []string `yaml:"bootcmd,omitempty"` + Mounts []Mount `yaml:"mounts,omitempty"` + MountDefaultFields Mount `yaml:"mount_default_fields,omitempty,flow"` } +func (u *UserData) HasMountByName(deviceName string) bool { + if len(u.Mounts) == 0 { + return false + } + + for _, mount := range u.Mounts { + if mount[0] == deviceName { + return true + } + } + + return false +} + +func (u *UserData) HasMountByMountPoint(mountPoint string) bool { + if len(u.Mounts) == 0 { + return false + } + + for _, mount := range u.Mounts { + if mount[1] == mountPoint { + return true + } + } + + return false +} + +type Mount []string + type User struct { Name string `yaml:"name"` Sudo string `yaml:"sudo,omitempty"` diff --git a/core/application/app_test.go b/core/application/app_test.go index 0819b919..59cd75e7 100644 --- a/core/application/app_test.go +++ b/core/application/app_test.go @@ -629,7 +629,7 @@ func createTestSpecWithMetadata(name, ns, uid string, metadata map[string]string { AllowMetadataRequests: true, GuestMAC: "AA:FF:00:00:00:01", - GuestDeviceName: "mmds", + GuestDeviceName: "eth0", Type: models.IfaceTypeTap, }, { diff --git a/core/application/commands.go b/core/application/commands.go index 1ddd326f..7c853635 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -19,7 +19,7 @@ import ( ) const ( - MetadataInterfaceName = "mmds" + MetadataInterfaceName = "eth0" ) func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.MicroVM, error) { @@ -192,15 +192,19 @@ func (a *app) addMetadataInterface(mvm *models.MicroVM) { } } - mvm.Spec.NetworkInterfaces = append(mvm.Spec.NetworkInterfaces, models.NetworkInterface{ - GuestDeviceName: MetadataInterfaceName, - Type: models.IfaceTypeTap, - AllowMetadataRequests: true, - GuestMAC: "AA:FF:00:00:00:01", - StaticAddress: &models.StaticAddress{ - Address: "169.254.0.1/16", + interfaces := []models.NetworkInterface{ + { + GuestDeviceName: MetadataInterfaceName, + Type: models.IfaceTypeTap, + AllowMetadataRequests: true, + GuestMAC: "AA:FF:00:00:00:01", + StaticAddress: &models.StaticAddress{ + Address: "169.254.0.1/16", + }, }, - }) + } + interfaces = append(interfaces, mvm.Spec.NetworkInterfaces...) + mvm.Spec.NetworkInterfaces = interfaces return } diff --git a/core/models/volumes.go b/core/models/volumes.go index aa104a37..7a1dac02 100644 --- a/core/models/volumes.go +++ b/core/models/volumes.go @@ -12,6 +12,9 @@ type Volume struct { PartitionID string `json:"partition_id,omitempty"` // Size is the size to resize this volume to. Size int32 `json:"size,omitempty"` + // MountPoint allows you to optionally specify a mount point for the volume. This only + // applied to additional volumes and it will use cloud-init to mount the volumes. + MountPoint string `json:"mount_point,omitempty"` } // Volumes represents a collection of volumes. @@ -28,6 +31,18 @@ func (v Volumes) GetByID(id string) *Volume { return nil } +// HasMountableVolumes returns true if any of the volumes +// have a mount point defined +func (v Volumes) HasMountableVolumes() bool { + for _, vol := range v { + if vol.MountPoint != "" { + return true + } + } + + return false +} + // VolumeSource is the source of a volume. Based loosely on the volumes in Kubernetes Pod specs. type VolumeSource struct { // Container is used to specify a source of a volume as a OCI container. diff --git a/core/plans/microvm_create_update.go b/core/plans/microvm_create_update.go index 46ef42aa..1cc184bf 100644 --- a/core/plans/microvm_create_update.go +++ b/core/plans/microvm_create_update.go @@ -3,6 +3,7 @@ package plans import ( "context" "fmt" + "github.com/weaveworks-liquidmetal/flintlock/core/steps/cloudinit" "github.com/weaveworks-liquidmetal/flintlock/core/models" "github.com/weaveworks-liquidmetal/flintlock/core/ports" @@ -63,6 +64,11 @@ func (p *microvmCreateOrUpdatePlan) Create(ctx context.Context) ([]planner.Proce if err := p.addImageSteps(ctx, p.vm, ports.ImageService); err != nil { return nil, fmt.Errorf("adding image steps: %w", err) } + if len(p.vm.Spec.AdditionalVolumes) > 0 { + if err := p.addStep(ctx, cloudinit.NewDiskMountStep(p.vm)); err != nil { + return nil, fmt.Errorf("adding mount step: %w", err) + } + } // Network interfaces if err := p.addNetworkSteps(ctx, p.vm, ports.NetworkService); err != nil { diff --git a/core/steps/cloudinit/disk_mount.go b/core/steps/cloudinit/disk_mount.go new file mode 100644 index 00000000..f3c86564 --- /dev/null +++ b/core/steps/cloudinit/disk_mount.go @@ -0,0 +1,142 @@ +package cloudinit + +import ( + "context" + "encoding/base64" + "fmt" + + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + + "github.com/weaveworks-liquidmetal/flintlock/client/cloudinit" + "github.com/weaveworks-liquidmetal/flintlock/client/cloudinit/userdata" + "github.com/weaveworks-liquidmetal/flintlock/core/models" + "github.com/weaveworks-liquidmetal/flintlock/pkg/log" + "github.com/weaveworks-liquidmetal/flintlock/pkg/planner" +) + +func NewDiskMountStep(vm *models.MicroVM) planner.Procedure { + return &diskMountStep{ + vm: vm, + } +} + +type diskMountStep struct { + vm *models.MicroVM +} + +// Name is the name of the procedure/operation. +func (s *diskMountStep) Name() string { + return "cloudinit_disk_mount" +} + +func (s *diskMountStep) ShouldDo(ctx context.Context) (bool, error) { + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "step": s.Name(), + }) + logger.Debug("checking if procedure should be run") + + if !s.vm.Spec.AdditionalVolumes.HasMountableVolumes() { + return false, nil + } + + for _, vol := range s.vm.Spec.AdditionalVolumes { + if vol.MountPoint == "" { + continue + } + + status := s.vm.Status.Volumes[vol.ID] + + if status == nil || status.Mount.Source == "" { + return true, nil + } + } + + vendorData, err := s.getVendorData() + if err != nil { + return false, fmt.Errorf("getting vendor data: %w", err) + } + if vendorData == nil { + return true, nil + } + + for _, vol := range s.vm.Spec.AdditionalVolumes { + if vol.MountPoint == "" { + continue + } + + if !vendorData.HasMountByMountPoint(vol.MountPoint) { + return true, nil + } + } + + return false, nil +} + +// Do will perform the operation/procedure. +func (s *diskMountStep) Do(ctx context.Context) ([]planner.Procedure, error) { + logger := log.GetLogger(ctx).WithFields(logrus.Fields{ + "step": s.Name(), + }) + logger.Debug("running step to mount additional disks via cloud-init") + + vendorData, err := s.getVendorData() + if err != nil { + return nil, fmt.Errorf("getting vendor data: %w", err) + } + if vendorData == nil { + vendorData = &userdata.UserData{} + } + + startingCode := int('b') + for i, vol := range s.vm.Spec.AdditionalVolumes { + if vol.MountPoint == "" { + continue + } + + device := fmt.Sprintf("vd%c", rune(startingCode+i)) // Device number is always +1 as we have the root volume first + + if !vendorData.HasMountByName(device) { + vendorData.Mounts = append(vendorData.Mounts, userdata.Mount{ + device, + vol.MountPoint, + }) + } + } + vendorData.MountDefaultFields = userdata.Mount{"None", "None", "auto", "defaults,nofail", "0", "2"} + + data, err := yaml.Marshal(vendorData) + if err != nil { + return nil, fmt.Errorf("marshalling vendor-data to yaml: %w", err) + } + dataWithHeader := append([]byte("## template: jinja\n#cloud-config\n\n"), data...) + + if s.vm.Spec.Metadata == nil { + s.vm.Spec.Metadata = map[string]string{} + } + s.vm.Spec.Metadata[cloudinit.VendorDataKey] = base64.StdEncoding.EncodeToString(dataWithHeader) + + return nil, nil +} + +func (s *diskMountStep) Verify(ctx context.Context) error { + return nil +} + +func (s *diskMountStep) getVendorData() (*userdata.UserData, error) { + vendorDataRaw, ok := s.vm.Spec.Metadata[cloudinit.VendorDataKey] + if !ok { + return nil, nil + } + + vendorData := &userdata.UserData{} + data, err := base64.StdEncoding.DecodeString(vendorDataRaw) + if err != nil { + return nil, fmt.Errorf("decoding vendor data: %w", err) + } + if marshalErr := yaml.Unmarshal(data, vendorData); marshalErr != nil { + return nil, fmt.Errorf("unmarshalling vendor-data yaml: %w", err) + } + + return vendorData, nil +} diff --git a/go.mod b/go.mod index ee11da5c..b34ec5f0 100644 --- a/go.mod +++ b/go.mod @@ -56,6 +56,7 @@ require ( github.com/weaveworks-liquidmetal/flintlock/api v0.0.0-00010101000000-000000000000 github.com/weaveworks-liquidmetal/flintlock/client v0.0.0-00010101000000-000000000000 github.com/yitsushi/file-tailor v1.0.0 + gopkg.in/yaml.v2 v2.4.0 sigs.k8s.io/yaml v1.3.0 ) @@ -133,5 +134,4 @@ require ( gopkg.in/djherbis/times.v1 v1.2.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/infrastructure/grpc/convert.go b/infrastructure/grpc/convert.go index 70c9daba..fa28cdd8 100644 --- a/infrastructure/grpc/convert.go +++ b/infrastructure/grpc/convert.go @@ -140,6 +140,10 @@ func convertVolumeToModel(volume *types.Volume) *models.Volume { } } + if volume.MountPoint != nil { + convertedVol.MountPoint = *volume.MountPoint + } + return convertedVol } diff --git a/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md b/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md new file mode 100644 index 00000000..4d6dcb11 --- /dev/null +++ b/userdocs/docs/grpc/services/microvm/v1alpha1/proto.md @@ -0,0 +1,210 @@ +# Protocol Documentation + + +## Table of Contents + +- [services/microvm/v1alpha1/microvms.proto](#services/microvm/v1alpha1/microvms.proto) + - [CreateMicroVMRequest](#microvm.services.api.v1alpha1.CreateMicroVMRequest) + - [CreateMicroVMRequest.MetadataEntry](#microvm.services.api.v1alpha1.CreateMicroVMRequest.MetadataEntry) + - [CreateMicroVMResponse](#microvm.services.api.v1alpha1.CreateMicroVMResponse) + - [DeleteMicroVMRequest](#microvm.services.api.v1alpha1.DeleteMicroVMRequest) + - [GetMicroVMRequest](#microvm.services.api.v1alpha1.GetMicroVMRequest) + - [GetMicroVMResponse](#microvm.services.api.v1alpha1.GetMicroVMResponse) + - [ListMessage](#microvm.services.api.v1alpha1.ListMessage) + - [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) + - [ListMicroVMsResponse](#microvm.services.api.v1alpha1.ListMicroVMsResponse) + + - [MicroVM](#microvm.services.api.v1alpha1.MicroVM) + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## services/microvm/v1alpha1/microvms.proto + + + + + +### CreateMicroVMRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| microvm | [flintlock.types.MicroVMSpec](#flintlock.types.MicroVMSpec) | | | +| metadata | [CreateMicroVMRequest.MetadataEntry](#microvm.services.api.v1alpha1.CreateMicroVMRequest.MetadataEntry) | repeated | | + + + + + + + + +### CreateMicroVMRequest.MetadataEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [google.protobuf.Any](#google.protobuf.Any) | | | + + + + + + + + +### CreateMicroVMResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | + + + + + + + + +### DeleteMicroVMRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| uid | [string](#string) | | | + + + + + + + + +### GetMicroVMRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| uid | [string](#string) | | | + + + + + + + + +### GetMicroVMResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | + + + + + + + + +### ListMessage + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | | | + + + + + + + + +### ListMicroVMsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| namespace | [string](#string) | | | +| name | [string](#string) | optional | | + + + + + + + + +### ListMicroVMsResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| microvm | [flintlock.types.MicroVM](#flintlock.types.MicroVM) | repeated | | + + + + + + + + + + + + + + +### MicroVM +MicroVM providers a service to create and manage the lifecycle of microvms. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| CreateMicroVM | [CreateMicroVMRequest](#microvm.services.api.v1alpha1.CreateMicroVMRequest) | [CreateMicroVMResponse](#microvm.services.api.v1alpha1.CreateMicroVMResponse) | | +| DeleteMicroVM | [DeleteMicroVMRequest](#microvm.services.api.v1alpha1.DeleteMicroVMRequest) | [.google.protobuf.Empty](#google.protobuf.Empty) | | +| GetMicroVM | [GetMicroVMRequest](#microvm.services.api.v1alpha1.GetMicroVMRequest) | [GetMicroVMResponse](#microvm.services.api.v1alpha1.GetMicroVMResponse) | | +| ListMicroVMs | [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) | [ListMicroVMsResponse](#microvm.services.api.v1alpha1.ListMicroVMsResponse) | | +| ListMicroVMsStream | [ListMicroVMsRequest](#microvm.services.api.v1alpha1.ListMicroVMsRequest) | [ListMessage](#microvm.services.api.v1alpha1.ListMessage) stream | | + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | +| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | +| double | | double | double | float | float64 | double | float | Float | +| float | | float | float | float | float32 | float | float | Float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | +| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | + diff --git a/userdocs/docs/grpc/types/proto.md b/userdocs/docs/grpc/types/proto.md new file mode 100644 index 00000000..82d36b59 --- /dev/null +++ b/userdocs/docs/grpc/types/proto.md @@ -0,0 +1,441 @@ +# Protocol Documentation + + +## Table of Contents + +- [types/microvm.proto](#types/microvm.proto) + - [ContainerVolumeSource](#flintlock.types.ContainerVolumeSource) + - [Initrd](#flintlock.types.Initrd) + - [Kernel](#flintlock.types.Kernel) + - [Kernel.CmdlineEntry](#flintlock.types.Kernel.CmdlineEntry) + - [MicroVM](#flintlock.types.MicroVM) + - [MicroVMSpec](#flintlock.types.MicroVMSpec) + - [MicroVMSpec.LabelsEntry](#flintlock.types.MicroVMSpec.LabelsEntry) + - [MicroVMSpec.MetadataEntry](#flintlock.types.MicroVMSpec.MetadataEntry) + - [MicroVMStatus](#flintlock.types.MicroVMStatus) + - [MicroVMStatus.NetworkInterfacesEntry](#flintlock.types.MicroVMStatus.NetworkInterfacesEntry) + - [MicroVMStatus.VolumesEntry](#flintlock.types.MicroVMStatus.VolumesEntry) + - [Mount](#flintlock.types.Mount) + - [NetworkInterface](#flintlock.types.NetworkInterface) + - [NetworkInterfaceStatus](#flintlock.types.NetworkInterfaceStatus) + - [NetworkOverrides](#flintlock.types.NetworkOverrides) + - [StaticAddress](#flintlock.types.StaticAddress) + - [Volume](#flintlock.types.Volume) + - [VolumeSource](#flintlock.types.VolumeSource) + - [VolumeStatus](#flintlock.types.VolumeStatus) + + - [MicroVMStatus.MicroVMState](#flintlock.types.MicroVMStatus.MicroVMState) + - [Mount.MountType](#flintlock.types.Mount.MountType) + - [NetworkInterface.IfaceType](#flintlock.types.NetworkInterface.IfaceType) + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## types/microvm.proto + + + + + +### ContainerVolumeSource +ContainerVolumeSource represents the details of a volume coming from a OCI image. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| image | [string](#string) | | Image specifies the conatiner image to use for the volume. | + + + + + + + + +### Initrd +Initrd represents the configuration for the initial ramdisk. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| image | [string](#string) | | Image is the container image to use. | +| filename | [string](#string) | optional | Filename is used to specify the name of the kernel file in the Image. Defaults to initrd | + + + + + + + + +### Kernel +Kernel represents the configuration for a kernel. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| image | [string](#string) | | Image is the container image to use. | +| cmdline | [Kernel.CmdlineEntry](#flintlock.types.Kernel.CmdlineEntry) | repeated | Cmdline is the additional kernel command line args. Each provider has its own recommended list, they will be used automatically. This field is for additional values. | +| filename | [string](#string) | optional | Filename is used to specify the name of the kernel file in the Image. | +| add_network_config | [bool](#bool) | | AddNetworkConfig if set to true indicates that the network-config kernel argument should be generated. | + + + + + + + + +### Kernel.CmdlineEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | + + + + + + + + +### MicroVM +MicroVM represents a microvm machine that is created via a provider. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| version | [int32](#int32) | | | +| spec | [MicroVMSpec](#flintlock.types.MicroVMSpec) | | Spec is the specification of the microvm. | +| status | [MicroVMStatus](#flintlock.types.MicroVMStatus) | | Status is the runtime status of the microvm. | + + + + + + + + +### MicroVMSpec +MicroVMSpec represents the specification for a microvm. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [string](#string) | | ID is the identifier of the microvm. If this empty at creation time a ID will be automatically generated. | +| namespace | [string](#string) | | Namespace is the name of the namespace the microvm belongs to. | +| labels | [MicroVMSpec.LabelsEntry](#flintlock.types.MicroVMSpec.LabelsEntry) | repeated | Labels allows you to include extra data for the microvms. | +| vcpu | [int32](#int32) | | VCPU specifies how many vcpu the machine will be allocated. | +| memory_in_mb | [int32](#int32) | | MemoryInMb is the amount of memory in megabytes that the machine will be allocated. | +| kernel | [Kernel](#flintlock.types.Kernel) | | Kernel is the details of the kernel to use . | +| initrd | [Initrd](#flintlock.types.Initrd) | optional | Initrd is the optional details of the initial ramdisk. | +| root_volume | [Volume](#flintlock.types.Volume) | | RootVolume specifies the root volume mount for the MicroVM. | +| additional_volumes | [Volume](#flintlock.types.Volume) | repeated | AdditionalVolumes specifies the volumes to be attached to the microvm. | +| interfaces | [NetworkInterface](#flintlock.types.NetworkInterface) | repeated | Interfaces specifies the network interfaces to be attached to the microvm. Device names on the guest machine are determined by the order defined in the list starting from eth1, eth2, ..., ethN. | +| metadata | [MicroVMSpec.MetadataEntry](#flintlock.types.MicroVMSpec.MetadataEntry) | repeated | Metadata allows you to specify data to be added to the metadata service. The key is the name of the metadata item and the value is the base64 encoded contents of the metadata. | +| created_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | CreatedAt indicates the time the microvm was created at. | +| updated_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | UpdatedAt indicates the time the microvm was last updated. | +| deleted_at | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | DeletedAt indicates the time the microvm was marked as deleted. | +| uid | [string](#string) | optional | UID is a globally unique identifier of the microvm. | + + + + + + + + +### MicroVMSpec.LabelsEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | + + + + + + + + +### MicroVMSpec.MetadataEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | + + + + + + + + +### MicroVMStatus +MicroVMStatus contains the runtime status of the microvm. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| state | [MicroVMStatus.MicroVMState](#flintlock.types.MicroVMStatus.MicroVMState) | | State stores information about the last known state of the vm and the spec. | +| volumes | [MicroVMStatus.VolumesEntry](#flintlock.types.MicroVMStatus.VolumesEntry) | repeated | Volumes holds the status of the volumes. | +| kernel_mount | [Mount](#flintlock.types.Mount) | | KernelMount holds the status of the kernel mount point. | +| initrd_mount | [Mount](#flintlock.types.Mount) | | InitrdMount holds the status of the initrd mount point. | +| network_interfaces | [MicroVMStatus.NetworkInterfacesEntry](#flintlock.types.MicroVMStatus.NetworkInterfacesEntry) | repeated | NetworkInterfaces holds the status of the network interfaces. | +| retry | [int32](#int32) | | Retry is a counter about how many times we retried to reconcile. | + + + + + + + + +### MicroVMStatus.NetworkInterfacesEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [NetworkInterfaceStatus](#flintlock.types.NetworkInterfaceStatus) | | | + + + + + + + + +### MicroVMStatus.VolumesEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [VolumeStatus](#flintlock.types.VolumeStatus) | | | + + + + + + + + +### Mount +Mount represents a volume mount point. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| type | [Mount.MountType](#flintlock.types.Mount.MountType) | | Type specifies the type of the mount (e.g. device or directory). | +| source | [string](#string) | | Source is the location of the mounted volume. | + + + + + + + + +### NetworkInterface + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| device_id | [string](#string) | | DeviceID is the ID of the interface. There is no relation between the ID and the name of the interface device on the quest machine. | +| type | [NetworkInterface.IfaceType](#flintlock.types.NetworkInterface.IfaceType) | | IfaceType specifies the type of network interface to create for use by the guest. | +| guest_mac | [string](#string) | optional | GuestMAC allows the specifying of a specifi MAC address to use for the interface. If not supplied a autogenerated MAC address will be used. | +| address | [StaticAddress](#flintlock.types.StaticAddress) | optional | Address is an optional static IP address to manually assign to this interface. If not supplied then DHCP will be used. | +| overrides | [NetworkOverrides](#flintlock.types.NetworkOverrides) | optional | Overrides is optional overrides applicable for network configuration. | + + + + + + + + +### NetworkInterfaceStatus + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| host_device_name | [string](#string) | | HostDeviceName is the name of the network interface used from the host. This will be a tuntap or macvtap interface. | +| index | [int32](#int32) | | Index is the index of the network interface on the host. | +| mac_address | [string](#string) | | MACAddress is the MAC address of the host interface. | + + + + + + + + +### NetworkOverrides +NetworkOverrides represents override values for a network interface. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| bridge_name | [string](#string) | optional | BridgeName is the name of the Linux bridge to attach TAP devices to. This overrides any value set at the overall flintlock level. | + + + + + + + + +### StaticAddress +StaticAddress represents a static IPv4 or IPv6 address. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| address | [string](#string) | | Address is the static IP address (IPv4 or IPv6) to assign to this interface. Must be CIDR notation. | +| gateway | [string](#string) | optional | Gateway is used to optionaly set the default gateway for IPv4 or IPv6. | +| nameservers | [string](#string) | repeated | Nameservers allows you to optionaly specify nameservers for the interface. | + + + + + + + + +### Volume +Volume represents the configuration for a volume to be attached to a microvm. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [string](#string) | | ID is the uinique identifier of the volume. | +| is_read_only | [bool](#bool) | | IsReadOnly specifies that the volume is to be mounted readonly. | +| mount_point | [string](#string) | optional | MountPoint allows you to optionally specify a mount point for the volume. This only applied to additional volumes and it will use cloud-init to mount the volumes. | +| source | [VolumeSource](#flintlock.types.VolumeSource) | | Source is where the volume will be sourced from. | +| partition_id | [string](#string) | optional | PartitionID is the uuid of the boot partition. | +| size_in_mb | [int32](#int32) | optional | Size is the size to resize this volume to. + +TODO: add rate limiting | + + + + + + + + +### VolumeSource +VolumeSource is the source of a volume. Based loosely on the volumes in Kubernetes Pod specs. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| container_source | [string](#string) | optional | Container is used to specify a source of a volume as a OCI container. + +TODO: add CSI | + + + + + + + + +### VolumeStatus + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| mount | [Mount](#flintlock.types.Mount) | | Mount represents a volume mount point. | + + + + + + + + + + +### MicroVMStatus.MicroVMState + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| PENDING | 0 | | +| CREATED | 1 | | +| FAILED | 2 | | +| DELETING | 3 | | + + + + + +### Mount.MountType + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| DEV | 0 | | +| HOSTPATH | 1 | | + + + + + +### NetworkInterface.IfaceType + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| MACVTAP | 0 | MACVTAP represents a network interface that is macvtap. | +| TAP | 1 | TAP represents a network interface that is a tap. | + + + + + + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | +| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | +| double | | double | double | float | float64 | double | float | Float | +| float | | float | float | float | float32 | float | float | Float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | +| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | +