Skip to content

Commit

Permalink
feat #388: Add support for paravirtualized launch volume attachment (#…
Browse files Browse the repository at this point in the history
…395)

* updated tilt-helper

1.updated tilt image golang version to 1.21.8
2.added bash to kustomize-sub.sh call

Signed-off-by: Mayank Kakani <[email protected]>

* Update types.go

Added LaunchParavirtualizedVolumeAttachment types to v1

* Update types.go

added LaunchParavirtualizedVolumeAttachment type

* Update machine.go

Added support for getParavirtualizedVolumeAttachment

* Update infrastructure.cluster.x-k8s.io_ocimachines.yaml

added launchParavirtualizedVolumeAttachment defination

* Update infrastructure.cluster.x-k8s.io_ocimachinetemplates.yaml

added launchParavirtualizedVolumeAttachment definations

* Update go.mod

Updated OCI go sdk version to  v65.81.1 to support paravirtualized volume

* Update go.sum

Updated OCI SDK version

* Update machine_test.go

added test for paravirtualized volumes

* Update machine.go

updated message "Unknown attachment type not supported"

* Update machine_test.go

updated name - "check all params together, with paravirtualized volume support"

* Fixed unittests

Fixed paravirtualized volume support unit test case

---------

Signed-off-by: Mayank Kakani <[email protected]>
  • Loading branch information
MayankKakani authored Feb 20, 2025
1 parent 14936bf commit ef5b1a3
Show file tree
Hide file tree
Showing 9 changed files with 448 additions and 7 deletions.
6 changes: 3 additions & 3 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if "default_registry" in settings:

tilt_helper_dockerfile_header = """
# Tilt image
FROM golang:1.19 as tilt-helper
FROM golang:1.21.8 as tilt-helper
# Support live reloading with Tilt
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN wget --output-document /restart.sh --quiet https://raw.githubusercontent.com/tilt-dev/rerun-process-wrapper/master/restart.sh && \
Expand Down Expand Up @@ -196,7 +196,7 @@ def base64_decode(to_decode):
return str(decode_blob)

def kustomizesub(folder):
yaml = local('hack/kustomize-sub.sh {}'.format(folder), quiet=True)
yaml = local('bash hack/kustomize-sub.sh {}'.format(folder), quiet=True)
return yaml

##############################
Expand All @@ -216,4 +216,4 @@ deploy_capi()

capoci()

waitforsystem()
waitforsystem()
31 changes: 31 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,7 @@ type VolumeType string

const (
IscsiType VolumeType = "iscsi"
ParavirtualizedType VolumeType = "paravirtualized"
)

// EncryptionInTransitTypeEnum Enum with underlying type: string
Expand All @@ -1115,6 +1116,7 @@ type LaunchVolumeAttachment struct {

// The details of iscsi volume attachment.
IscsiAttachment LaunchIscsiVolumeAttachment `json:"launchIscsiVolumeAttachment,omitempty"`
ParavirtualizedAttachment LaunchParavirtualizedVolumeAttachment `json:"launchParavirtualizedVolumeAttachment,omitempty"`
}

// LaunchIscsiVolumeAttachment specifies the iscsi volume attachments to create as part of the launch instance operation.
Expand Down Expand Up @@ -1152,6 +1154,35 @@ type LaunchIscsiVolumeAttachment struct {
EncryptionInTransitType EncryptionInTransitTypeEnum `json:"encryptionInTransitType,omitempty"`
}

// LaunchParavirtualizedVolumeAttachment specifies the paravirtualized volume attachments to create as part of the launch instance operation.
type LaunchParavirtualizedVolumeAttachment struct {
// The device name. To retrieve a list of devices for a given instance, see ListInstanceDevices.
Device *string `json:"device,omitempty"`

// A user-friendly name. Does not have to be unique, and it's changeable.
// Avoid entering confidential information.
DisplayName *string `json:"displayName,omitempty"`

// Whether the attachment was created in read-only mode.
IsReadOnly *bool `json:"isReadOnly,omitempty"`

// Whether the attachment should be created in shareable mode. If an attachment
// is created in shareable mode, then other instances can attach the same volume, provided
// that they also create their attachments in shareable mode. Only certain volume types can
// be attached in shareable mode. Defaults to false if not specified.
IsShareable *bool `json:"isShareable,omitempty"`

// The OCID of the volume. If CreateVolumeDetails is specified, this field must be omitted from the request.
VolumeId *string `json:"volumeId,omitempty"`

// LaunchCreateVolumeFromAttributes The details of the volume to create for CreateVolume operation.
LaunchCreateVolumeFromAttributes LaunchCreateVolumeFromAttributes `json:"launchCreateVolumeFromAttributes,omitempty"`

// Refer the top-level definition of isPvEncryptionInTransitEnabled.
// The default value is False.
IsPvEncryptionInTransitEnabled *bool `json:"isPvEncryptionInTransitEnabled,omitempty"`
}

// LaunchCreateVolumeFromAttributes The details of the volume to create for CreateVolume operation.
type LaunchCreateVolumeFromAttributes struct {

Expand Down
32 changes: 32 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,7 @@ type VolumeType string

const (
IscsiType VolumeType = "iscsi"
ParavirtualizedType VolumeType = "paravirtualized"
)

// EncryptionInTransitTypeEnum Enum with underlying type: string
Expand All @@ -1186,6 +1187,7 @@ type LaunchVolumeAttachment struct {

// The details of iscsi volume attachment.
IscsiAttachment LaunchIscsiVolumeAttachment `json:"launchIscsiVolumeAttachment,omitempty"`
ParavirtualizedAttachment LaunchParavirtualizedVolumeAttachment `json:"launchParavirtualizedVolumeAttachment,omitempty"`
}

// LaunchIscsiVolumeAttachment specifies the iscsi volume attachments to create as part of the launch instance operation.
Expand Down Expand Up @@ -1223,6 +1225,36 @@ type LaunchIscsiVolumeAttachment struct {
EncryptionInTransitType EncryptionInTransitTypeEnum `json:"encryptionInTransitType,omitempty"`
}

// LaunchParavirtualizedVolumeAttachment specifies the paravirtualized volume attachments to create as part of the launch instance operation.
type LaunchParavirtualizedVolumeAttachment struct {
// The device name. To retrieve a list of devices for a given instance, see ListInstanceDevices.
Device *string `json:"device,omitempty"`

// A user-friendly name. Does not have to be unique, and it's changeable.
// Avoid entering confidential information.
DisplayName *string `json:"displayName,omitempty"`

// Whether the attachment was created in read-only mode.
IsReadOnly *bool `json:"isReadOnly,omitempty"`

// Whether the attachment should be created in shareable mode. If an attachment
// is created in shareable mode, then other instances can attach the same volume, provided
// that they also create their attachments in shareable mode. Only certain volume types can
// be attached in shareable mode. Defaults to false if not specified.
IsShareable *bool `json:"isShareable,omitempty"`

// The OCID of the volume. If CreateVolumeDetails is specified, this field must be omitted from the request.
VolumeId *string `json:"volumeId,omitempty"`

// LaunchCreateVolumeFromAttributes The details of the volume to create for CreateVolume operation.
LaunchCreateVolumeFromAttributes LaunchCreateVolumeFromAttributes `json:"launchCreateVolumeFromAttributes,omitempty"`

// Refer the top-level definition of encryptionInTransitType.
// The default value is False.
IsPvEncryptionInTransitEnabled *bool `json:"isPvEncryptionInTransitEnabled,omitempty"`
}


// LaunchCreateVolumeFromAttributes The details of the volume to create for CreateVolume operation.
type LaunchCreateVolumeFromAttributes struct {

Expand Down
17 changes: 17 additions & 0 deletions cloud/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,10 @@ func (m *MachineScope) getLaunchVolumeAttachments() []core.LaunchAttachVolumeDet
for _, attachment := range volumeAttachmentsInSpec {
if attachment.Type == infrastructurev1beta2.IscsiType {
volumes = append(volumes, getIscsiVolumeAttachment(attachment.IscsiAttachment))
} else if attachment.Type == infrastructurev1beta2.ParavirtualizedType {
volumes = append(volumes, getParavirtualizedVolumeAttachment(attachment.ParavirtualizedAttachment))
} else {
m.Logger.Info("Unknown attachment type not supported")
}
}
return volumes
Expand All @@ -1017,6 +1021,19 @@ func getIscsiVolumeAttachment(attachment infrastructurev1beta2.LaunchIscsiVolume
return volumeDetails
}

func getParavirtualizedVolumeAttachment(attachment infrastructurev1beta2.LaunchParavirtualizedVolumeAttachment) core.LaunchAttachVolumeDetails {
volumeDetails := core.LaunchAttachParavirtualizedVolumeDetails{
Device: attachment.Device,
DisplayName: attachment.DisplayName,
IsShareable: attachment.IsShareable,
IsReadOnly: attachment.IsReadOnly,
VolumeId: attachment.VolumeId,
IsPvEncryptionInTransitEnabled: attachment.IsPvEncryptionInTransitEnabled,
LaunchCreateVolumeDetails: getLaunchCreateVolumeDetails(attachment.LaunchCreateVolumeFromAttributes),
}
return volumeDetails
}

func getLaunchCreateVolumeDetails(attributes infrastructurev1beta2.LaunchCreateVolumeFromAttributes) core.LaunchCreateVolumeFromAttributes {
return core.LaunchCreateVolumeFromAttributes{
SizeInGBs: attributes.SizeInGBs,
Expand Down
97 changes: 97 additions & 0 deletions cloud/scope/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,103 @@ func TestInstanceReconciliation(t *testing.T) {
OpcRetryToken: ociutil.GetOPCRetryToken("machineuid")})).Return(core.LaunchInstanceResponse{}, nil)
},
},
{
name: "check all params together, with paravirtualized volume support",
errorExpected: false,
testSpecificSetup: func(machineScope *MachineScope, computeClient *mock_compute.MockComputeClient) {
setupAllParams(ms)
ms.OCIMachine.Spec.CapacityReservationId = common.String("cap-id")
ms.OCIMachine.Spec.DedicatedVmHostId = common.String("dedicated-host-id")
ms.OCIMachine.Spec.NetworkDetails.HostnameLabel = common.String("hostname-label")
ms.OCIMachine.Spec.NetworkDetails.SubnetId = common.String("subnet-machine-id")
ms.OCIMachine.Spec.NetworkDetails.NSGIds = []string{"nsg-machine-id-1", "nsg-machine-id-2"}
// above array should take precedence
ms.OCIMachine.Spec.NetworkDetails.NSGId = common.String("nsg-machine-id")
ms.OCIMachine.Spec.NetworkDetails.SkipSourceDestCheck = common.Bool(true)
ms.OCIMachine.Spec.NetworkDetails.AssignPrivateDnsRecord = common.Bool(true)
ms.OCIMachine.Spec.NetworkDetails.DisplayName = common.String("display-name")
ms.OCIMachine.Spec.LaunchVolumeAttachment = []infrastructurev1beta2.LaunchVolumeAttachment{
{
Type: infrastructurev1beta2.ParavirtualizedType,
ParavirtualizedAttachment: infrastructurev1beta2.LaunchParavirtualizedVolumeAttachment{
Device: common.String("/dev/oci"),
IsShareable: common.Bool(true),
IsPvEncryptionInTransitEnabled: common.Bool(false),
LaunchCreateVolumeFromAttributes: infrastructurev1beta2.LaunchCreateVolumeFromAttributes{
DisplayName: common.String("test-volume"),
SizeInGBs: common.Int64(75),
VpusPerGB: common.Int64(20),
},
},
},
}
ms.OCIMachine.Spec.InstanceSourceViaImageDetails = &infrastructurev1beta2.InstanceSourceViaImageConfig{
KmsKeyId: common.String("kms-key-id"),
BootVolumeVpusPerGB: common.Int64(32),
}
computeClient.EXPECT().ListInstances(gomock.Any(), gomock.Eq(core.ListInstancesRequest{
DisplayName: common.String("name"),
CompartmentId: common.String("test"),
})).Return(core.ListInstancesResponse{}, nil)

launchDetails := core.LaunchInstanceDetails{DisplayName: common.String("name"),
CapacityReservationId: common.String("cap-id"),
DedicatedVmHostId: common.String("dedicated-host-id"),
SourceDetails: core.InstanceSourceViaImageDetails{
ImageId: common.String("image"),
BootVolumeSizeInGBs: common.Int64(120),
KmsKeyId: common.String("kms-key-id"),
BootVolumeVpusPerGB: common.Int64(32),
},
CreateVnicDetails: &core.CreateVnicDetails{
SubnetId: common.String("subnet-machine-id"),
AssignPublicIp: common.Bool(false),
DefinedTags: map[string]map[string]interface{}{},
FreeformTags: map[string]string{
ociutil.CreatedBy: ociutil.OCIClusterAPIProvider,
ociutil.ClusterResourceIdentifier: "resource_uid",
},
NsgIds: []string{"nsg-machine-id-1", "nsg-machine-id-2"},
HostnameLabel: common.String("hostname-label"),
SkipSourceDestCheck: common.Bool(true),
AssignPrivateDnsRecord: common.Bool(true),
DisplayName: common.String("display-name"),
},
LaunchVolumeAttachments: []core.LaunchAttachVolumeDetails{
core.LaunchAttachParavirtualizedVolumeDetails{
Device: common.String("/dev/oci"),
IsShareable: common.Bool(true),
IsPvEncryptionInTransitEnabled: common.Bool(false),
LaunchCreateVolumeDetails: core.LaunchCreateVolumeFromAttributes{
DisplayName: common.String("test-volume"),
SizeInGBs: common.Int64(75),
VpusPerGB: common.Int64(20),
},
},
},
Metadata: map[string]string{
"user_data": base64.StdEncoding.EncodeToString([]byte("test")),
},
Shape: common.String("shape"),
ShapeConfig: &core.LaunchInstanceShapeConfigDetails{
Ocpus: common.Float32(2),
MemoryInGBs: common.Float32(100),
BaselineOcpuUtilization: core.LaunchInstanceShapeConfigDetailsBaselineOcpuUtilization8,
},
AvailabilityDomain: common.String("ad2"),
CompartmentId: common.String("test"),
IsPvEncryptionInTransitEnabled: common.Bool(true),
DefinedTags: map[string]map[string]interface{}{},
FreeformTags: map[string]string{
ociutil.CreatedBy: ociutil.OCIClusterAPIProvider,
ociutil.ClusterResourceIdentifier: "resource_uid",
},
}
computeClient.EXPECT().LaunchInstance(gomock.Any(), gomock.Eq(core.LaunchInstanceRequest{
LaunchInstanceDetails: launchDetails,
OpcRetryToken: ociutil.GetOPCRetryToken("machineuid")})).Return(core.LaunchInstanceResponse{}, nil)
},
},
{
name: "shape config is empty",
errorExpected: false,
Expand Down
Loading

0 comments on commit ef5b1a3

Please sign in to comment.