Skip to content

Commit

Permalink
feat: add support to import OVF template from URL in supervisor build…
Browse files Browse the repository at this point in the history
…er plugin

This change is to add configurable optional steps on supervisor builder to allow
users to import OVF template to Supervisor namespaces via packer builder
vsphere supervisor plugin.
  • Loading branch information
ericvmw committed May 15, 2024
1 parent ec5d9c8 commit 700650e
Show file tree
Hide file tree
Showing 16 changed files with 1,252 additions and 150 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ main
dist/*
.docs/*
.vscode/*
.idea/*
packer-plugin-vsphere
crash.log
41 changes: 39 additions & 2 deletions .web-docs/components/builder/vsphere-supervisor/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
Type: `vsphere-supervisor`
Artifact BuilderId: `vsphere.supervisor`

This builder deploys and publishes new VMs to a vSphere Supervisor cluster using VM Service.
This builder imports VM images, deploys and publishes new VMs to a vSphere Supervisor cluster using VM Service.
If you are new to VM Service, please refer to [Deploying and Managing Virtual Machines in vSphere with Tanzu
](https://docs.vmware.com/en/VMware-vSphere/8.0/vsphere-with-tanzu-services-workloads/GUID-F81E3535-C275-4DDE-B35F-CE759EA3B4A0.html) for more information.

- It uses a kubeconfig file to connect to the vSphere Supervisor cluster.
- It uses the [VM image registry operator API](https://github.com/vmware-tanzu/image-registry-operator-api/) to import VM images from remote HTTPs URLs to vSphere Supervisor clusters.
- It uses the [VM-Operator API](https://vm-operator.readthedocs.io/en/latest/concepts/) to deploy and configure the source VM.
- It uses the Packer provisioners to customize the VM after establishing a successful connection.
- It publishes the customized VM as a new VM image to the designated content library in vSphere.
Expand All @@ -22,11 +23,16 @@ Example Packer template:

```hcl
source "vsphere-supervisor" "example-vm" {
import_source_url = "<remote URL to import image from, optional, e.g. 'https://example.com/example.ovf'>"
import_source_ssl_certificate = "<SSL certificate of the remote HTTPS server, optional, e.g. '-----BEGIN CERTIFICATE-----xxxxx-----END CERTIFICATE-----'>"
import_target_location_name = "<target location / content library for the imported image, optional, e.g. 'cl-6066c61f7931c5ef9'>"
import_target_image_type = "<target image type, optional, e.g. 'OVF'>"
image_name = "<Image name of the source VM, e.g. 'ubuntu-impish-21.10-cloudimg'>"
class_name = "<VM class that describes the virtual hardware settings, e.g. 'best-effort-large'>"
storage_class = "<Storage class that provides the backing storage for volume, e.g. 'wcplocal-storage-profile'>"
bootstrap_provider = "<CloudInit, Sysprep, or vAppConfig to customize the guest OS>"
bootstrap_data_file = "<Path to the file containing the bootstrap data for guest OS customization>"
publish_location_name = "<target location / content library for the published image, optional, e.g. 'cl-6066c61f7931c5ef9'>"
}
build {
Expand All @@ -41,11 +47,16 @@ build {
"builders": [
{
"type": "vsphere-supervisor",
"import_source_url": "<remote URL to import image from, optional, e.g. 'https://example.com/example.ovf'>",
"import_source_ssl_certificate": "<SSL certificate of the remote HTTPS server, optional, e.g. '-----BEGIN CERTIFICATE-----xxxxx-----END CERTIFICATE-----'>",
"import_target_location_name": "<target location / content library for the import image, optional, e.g. 'cl-6066c61f7931c5ef9'>",
"import_target_image_type": "<target image type, optional, e.g. 'OVF'>",
"image_name": "<Image name of the source VM, e.g. 'ubuntu-impish-21.10-cloudimg'>",
"class_name": "<VM class that describes the virtual hardware settings, e.g. 'best-effort-large'>",
"storage_class": "<Storage class that provides the backing storage for volume, e.g. 'wcplocal-storage-profile'>",
"bootstrap_provider": "<CloudInit, Sysprep, or vAppConfig to customize the guest OS>",
"bootstrap_data_file": "<Path to the file containing the bootstrap data for guest OS customization>"
"bootstrap_data_file": "<Path to the file containing the bootstrap data for guest OS customization>",
"publish_location_name": "<target location / content library for the published image, optional, e.g. 'cl-6066c61f7931c5ef9'>"
}
]
}
Expand Down Expand Up @@ -83,6 +94,32 @@ There are various configuration options available for each step in this builder.
<!-- End of code generated from the comments of the ConnectSupervisorConfig struct in builder/vsphere/supervisor/step_connect_supervisor.go; -->


#### Source VM Image Import Validation

<!-- Code generated from the comments of the ValidateImportConfig struct in builder/vsphere/supervisor/step_validate_import.go; DO NOT EDIT MANUALLY -->

- `import_source_url` (string) - The remote URL where the to-be-imported image is hosted, the URL must start with `https`.

- `import_source_ssl_certificate` (string) - The SSL certificate of the remote HTTPs server that hosts the to-be-imported image.

- `import_target_location_name` (string) - Name of a writable & import-allowed ContentLibrary resource in the namespace where the image will be imported to.

- `import_target_image_type` (string) - The type of the imported image. If not specified, the default type of OVF is assumed.

<!-- End of code generated from the comments of the ValidateImportConfig struct in builder/vsphere/supervisor/step_validate_import.go; -->


#### Source VM Image Importing

<!-- Code generated from the comments of the ImportImageConfig struct in builder/vsphere/supervisor/step_import_image.go; DO NOT EDIT MANUALLY -->

- `import_request_name` (string) - The name of the image import request. If not specified, the name defaults to `packer-vsphere-supervisor-import-req-<random-suffix>`.

- `watch_import_timeout_sec` (int) - The timeout in seconds to wait for the image to be imported. If not specified, it defaults to `600`.

<!-- End of code generated from the comments of the ImportImageConfig struct in builder/vsphere/supervisor/step_import_image.go; -->


#### Source VM Creation

<!-- Code generated from the comments of the CreateSourceConfig struct in builder/vsphere/supervisor/step_create_source.go; DO NOT EDIT MANUALLY -->
Expand Down
16 changes: 16 additions & 0 deletions builder/vsphere/supervisor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,22 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
&StepValidatePublish{
Config: &b.config.ValidatePublishConfig,
},
)

// conditionally add steps to validate import spec and import images from source URL as VM image.
if b.config.ValidateImportConfig.ImportSourceURL != "" {
steps = append(steps,
&StepValidateImport{
Config: &b.config.ValidateImportConfig,
},
&StepImportImage{
ImportImageConfig: &b.config.ImportImageConfig,
CreateSourceConfig: &b.config.CreateSourceConfig,
},
)
}

steps = append(steps,
// Create a source VM and other related resources in Supervisor cluster.
&StepCreateSource{
Config: &b.config.CreateSourceConfig,
Expand Down
4 changes: 4 additions & 0 deletions builder/vsphere/supervisor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ type Config struct {
CommunicatorConfig communicator.Config `mapstructure:",squash"`
ValidatePublishConfig `mapstructure:",squash"`
ConnectSupervisorConfig `mapstructure:",squash"`
ValidateImportConfig `mapstructure:",squash"`
ImportImageConfig `mapstructure:",squash"`
CreateSourceConfig `mapstructure:",squash"`
WatchSourceConfig `mapstructure:",squash"`
PublishSourceConfig `mapstructure:",squash"`
Expand Down Expand Up @@ -62,6 +64,8 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
errs = packersdk.MultiErrorAppend(errs, c.CommunicatorConfig.Prepare(&c.ctx)...)
errs = packersdk.MultiErrorAppend(errs, c.ConnectSupervisorConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.ValidatePublishConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.ValidateImportConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.ImportImageConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.CreateSourceConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.WatchSourceConfig.Prepare()...)
errs = packersdk.MultiErrorAppend(errs, c.PublishSourceConfig.Prepare()...)
Expand Down
Loading

0 comments on commit 700650e

Please sign in to comment.