Help us shape the future of Go! Take the 2026 Go Developer Survey

vm

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: MPL-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package vm implements the hyperv_vm resource, wrapping the vm/{get,new,set,remove}.ps1 contract via the typed hyperv.Client. CPU and memory live in nested blocks per ADR-0001.

Index

Constants

This section is empty.

Variables

View Source
var BootOrderEntryAttrTypes = map[string]attr.Type{
	"type":                types.StringType,
	"controller_type":     types.StringType,
	"controller_number":   types.Int64Type,
	"controller_location": types.Int64Type,
	"name":                types.StringType,
}

BootOrderEntryAttrTypes mirrors BootOrderEntryModel's tfsdk-tagged fields. Same role as DvdDriveAttrTypes for the boot_order list.

View Source
var BootOrderEntryListElementType = types.ObjectType{AttrTypes: BootOrderEntryAttrTypes}

BootOrderEntryListElementType is the Object element type the boot_order list holds.

View Source
var DvdDriveAttrTypes = map[string]attr.Type{
	"iso_path":            pathtype.Type,
	"controller_type":     types.StringType,
	"controller_number":   types.Int64Type,
	"controller_location": types.Int64Type,
}

DvdDriveAttrTypes mirrors DvdDriveModel's tfsdk-tagged fields. Used by the Object element type that backs the dvd_drive list, by the helpers below for ListValueFrom / ElementsAs round-trips, and by schema.go's Default empty-list value.

View Source
var DvdDriveListElementType = types.ObjectType{AttrTypes: DvdDriveAttrTypes}

DvdDriveListElementType is the Object element type the dvd_drive list holds. Computed once so all helpers share the same instance.

View Source
var HardDiskDriveAttrTypes = map[string]attr.Type{
	"path":                pathtype.Type,
	"controller_type":     types.StringType,
	"controller_number":   types.Int64Type,
	"controller_location": types.Int64Type,
}

HardDiskDriveAttrTypes mirrors HardDiskDriveModel's tfsdk tags.

View Source
var HardDiskDriveListElementType = types.ObjectType{AttrTypes: HardDiskDriveAttrTypes}

HardDiskDriveListElementType is the Object type hard_disk_drive elements use.

View Source
var NetworkAdapterAttrTypes = map[string]attr.Type{
	"name":         types.StringType,
	"switch_name":  types.StringType,
	"ip_addresses": types.ListType{ElemType: types.StringType},
	"mac_address":  mactype.Type,
	"vlan_id":      types.Int64Type,
}

NetworkAdapterAttrTypes mirrors NetworkAdapterModel's tfsdk tags.

View Source
var NetworkAdapterListElementType = types.ObjectType{AttrTypes: NetworkAdapterAttrTypes}

NetworkAdapterListElementType is the Object type network_adapter elements use.

Functions

func BootOrderListFromSlice added in v0.3.0

func BootOrderListFromSlice(ctx context.Context, slice []BootOrderEntryModel) (types.List, diag.Diagnostics)

BootOrderListFromSlice builds a types.List from a typed slice. Nil slice -> null list; empty slice -> empty list. Same rationale as DvdDriveListFromSlice.

func DvdDriveListFromSlice added in v0.3.0

func DvdDriveListFromSlice(ctx context.Context, slice []DvdDriveModel) (types.List, diag.Diagnostics)

DvdDriveListFromSlice builds a types.List from a typed slice. A nil slice becomes a null list (matching the "DvdDrives not managed" semantics on a fresh VM); an empty slice becomes an empty list (the schema's Default value when the user omits the attribute).

func HardDiskDriveListFromSlice added in v0.5.0

func HardDiskDriveListFromSlice(ctx context.Context, slice []HardDiskDriveModel) (types.List, diag.Diagnostics)

HardDiskDriveListFromSlice builds a types.List from a slice; nil -> null, empty -> empty.

func NetworkAdapterListFromSlice added in v0.5.0

func NetworkAdapterListFromSlice(ctx context.Context, slice []NetworkAdapterModel) (types.List, diag.Diagnostics)

NetworkAdapterListFromSlice builds a types.List from a slice; nil -> null, empty -> empty.

func New

func New() resource.Resource

New is the framework factory.

Types

type BootOrderEntryModel

type BootOrderEntryModel struct {
	Type               types.String `tfsdk:"type"`
	ControllerType     types.String `tfsdk:"controller_type"`
	ControllerNumber   types.Int64  `tfsdk:"controller_number"`
	ControllerLocation types.Int64  `tfsdk:"controller_location"`
	Name               types.String `tfsdk:"name"`
}

BootOrderEntryModel is one element of the `boot_order` list on a gen 2 hyperv_vm. Type discriminates between hard_disk_drive / dvd_drive entries, which carry the slot tuple, and network_adapter entries, which carry Name; unused fields for a given Type are null. Gen 1 BIOS startup order is a separate, deferred slice, and the schema validator rejects boot_order on gen 1 at plan time.

type CPUModel

type CPUModel struct {
	Count types.Int64 `tfsdk:"count"`
}

CPUModel is the nested `cpu` block. Static count only in this slice; dynamic-CPU attributes (weight, reserve, limit) attach as additional fields here in a follow-up.

type DvdDriveModel

type DvdDriveModel struct {
	IsoPath            pathtype.Path `tfsdk:"iso_path"`
	ControllerType     types.String  `tfsdk:"controller_type"`
	ControllerNumber   types.Int64   `tfsdk:"controller_number"`
	ControllerLocation types.Int64   `tfsdk:"controller_location"`
}

DvdDriveModel is one element of the `dvd_drive` list on hyperv_vm. Same slot tuple as HardDiskDriveModel (controller_type, controller_number, controller_location), but IsoPath is Optional -- an empty DVD drive (no medium loaded) is a legitimate config.

type HardDiskDriveModel

type HardDiskDriveModel struct {
	Path               pathtype.Path `tfsdk:"path"`
	ControllerType     types.String  `tfsdk:"controller_type"`
	ControllerNumber   types.Int64   `tfsdk:"controller_number"`
	ControllerLocation types.Int64   `tfsdk:"controller_location"`
}

HardDiskDriveModel is one element of the `hard_disk_drive` nested set on hyperv_vm, identifying an attached VHD (Path) at a specific controller slot (ControllerType + ControllerNumber + ControllerLocation). Path uses pathtype.Path for slash/case folding consistent with hyperv_vhd.path and hyperv_image_file.destination_path, so a forward-slash path round-trips against the bench's canonical backslash form without phantom diffs.

type MemoryModel

type MemoryModel struct {
	StartupBytes types.Int64 `tfsdk:"startup_bytes"`
	Dynamic      types.Bool  `tfsdk:"dynamic"`
	MinBytes     types.Int64 `tfsdk:"min_bytes"`
	MaxBytes     types.Int64 `tfsdk:"max_bytes"`
}

MemoryModel is the nested `memory` block. StartupBytes is required; Dynamic / MinBytes / MaxBytes opt in to Hyper-V's dynamic memory mode, following the same Optional+Computed+UseStateForUnknown pattern as state.shutdown_mode. Buffer and Priority are deferred.

type Model

type Model struct {
	ID         types.String `tfsdk:"id"`
	VMID       types.String `tfsdk:"vm_id"`
	Name       types.String `tfsdk:"name"`
	Generation types.Int64  `tfsdk:"generation"`
	// CPU and Memory are pointer-typed: ImportState briefly leaves state with only `name` set, which a value type can't represent.
	CPU    *CPUModel    `tfsdk:"cpu"`
	Memory *MemoryModel `tfsdk:"memory"`
	// HardDiskDrives is types.List, not []Struct, so an unknown plan
	// value decodes cleanly; List instead of Set works around a
	// terraform-plugin-framework v1.19 reflect-decode error on nested-set slices.
	HardDiskDrives  types.List `tfsdk:"hard_disk_drive"`
	NetworkAdapters types.List `tfsdk:"network_adapter"`
	DvdDrives       types.List `tfsdk:"dvd_drive"`
	BootOrder       types.List `tfsdk:"boot_order"`
	// SecureBoot is types.Bool, not *bool: null cleanly represents a gen-1 host with no Secure Boot concept.
	SecureBoot         types.Bool   `tfsdk:"secure_boot"`
	SecureBootTemplate types.String `tfsdk:"secure_boot_template"`
	Notes              types.String `tfsdk:"notes"`
	State              *StateModel  `tfsdk:"state"`
	IPAddresses        types.List   `tfsdk:"ip_addresses"`
	Path               types.String `tfsdk:"path"`
}

Model is the tfsdk-bound struct backing the resource state. Field tags align with schema.go attribute names; conversion to/from the typed hyperv.VM DTO lives in resource.go.

func (*Model) BootOrderEntries added in v0.3.0

func (m *Model) BootOrderEntries(ctx context.Context) ([]BootOrderEntryModel, diag.Diagnostics)

BootOrderEntries returns the typed slice underlying m.BootOrder, or nil if null/unknown. Same null-vs-empty rationale as DvdDriveModels.

func (*Model) DvdDriveModels added in v0.3.0

func (m *Model) DvdDriveModels(ctx context.Context) ([]DvdDriveModel, diag.Diagnostics)

DvdDriveModels returns the typed slice underlying m.DvdDrives, or nil if the list is null or unknown. Resource code that needs to distinguish "user explicitly set []" from "user did not set the attribute" should inspect m.DvdDrives directly via IsNull / IsUnknown -- a known-empty list returns an empty (but non-nil) slice here.

func (*Model) HardDiskDriveModels added in v0.5.0

func (m *Model) HardDiskDriveModels(ctx context.Context) ([]HardDiskDriveModel, diag.Diagnostics)

HardDiskDriveModels decodes m.HardDiskDrives, or nil if null/unknown.

func (*Model) NetworkAdapterModels added in v0.5.0

func (m *Model) NetworkAdapterModels(ctx context.Context) ([]NetworkAdapterModel, diag.Diagnostics)

NetworkAdapterModels decodes m.NetworkAdapters, or nil if null/unknown.

type NetworkAdapterModel

type NetworkAdapterModel struct {
	// Name is the slot key for diff/reconciliation; the schema validator enforces uniqueness within a VM's list at plan time.
	Name       types.String `tfsdk:"name"`
	SwitchName types.String `tfsdk:"switch_name"`
	// IPAddresses is Computed from the host, giving a multi-homed VM a per-NIC view distinct from the VM-level ip_addresses list.
	IPAddresses types.List `tfsdk:"ip_addresses"`
	// MacAddress is Optional, not Computed: Computed would mask an intentional revert to dynamic-MAC mode by copying state forward.
	MacAddress mactype.MAC `tfsdk:"mac_address"`
	// VlanID is Optional, not Computed, for the same reason as MacAddress; unset means untagged, not "not yet read."
	VlanID types.Int64 `tfsdk:"vlan_id"`
}

NetworkAdapterModel is one element of the `network_adapter` list on hyperv_vm.

type Resource

type Resource struct {
	// contains filtered or unexported fields
}

Resource implements hyperv_vm.

func (*Resource) ConfigValidators

func (r *Resource) ConfigValidators(_ context.Context) []resource.ConfigValidator

ConfigValidators rejects mode/attribute combinations at plan time so the operator gets a clear, attribute-anchored diagnostic instead of the cmdlet's opaque error at apply time.

func (*Resource) Configure

Configure stashes the typed Hyper-V client built by the provider's Configure pass. Skips when ProviderData is nil (validate-time invocation before the provider has resolved its config).

func (*Resource) Create

Create runs new.ps1 with the plan's attributes and writes the post-create read back to state.

func (*Resource) Delete

Delete runs remove.ps1. ErrNotFound is treated as success (the VM is already gone). The script hard-stops the VM first if it's running -- this is the one place the PS layer drives a power transition. Hard stop (Stop-VM -Force -TurnOff) instead of graceful for the reasons documented in the resource MarkdownDescription: graceful shutdown hangs indefinitely on guests with absent / unresponsive integration services, and destroy semantics across IaC providers consistently match the "destroy means destroy" expectation.

func (*Resource) ImportState

ImportState lets `terraform import hyperv_vm.foo my-vm` work by treating the import ID as the VM name. Read populates the rest of the attributes via Get-VM on the immediately-following refresh.

func (*Resource) Metadata

Metadata sets the resource's TF type name.

func (*Resource) Read

Read fetches the current state via get.ps1 and reconciles it: ErrNotFound triggers RemoveResource so Terraform plans recreate; other errors call AddError so a transient fault doesn't silently drop the resource from state.

func (*Resource) Schema

Schema returns the locked-in schema (see schema.go).

func (*Resource) Update

Update forwards only the fields that changed between state and plan to avoid hitting Set-VMMemory / Set-VMProcessor needlessly on a running VM (those cmdlets validate state by parameter set, not value semantics -- even a no-op call to Set-VMMemory on a running VM errors). Generation is always forwarded as the script's gen-2-only SecureBoot guard hint.

func (*Resource) UpgradeState

func (r *Resource) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader

UpgradeState bridges schema versions for hyperv_vm. Each entry maps from a SOURCE version directly to the current schema; the framework dispatches based on the on-disk version, not a chain, so each upgradeNToM helper returns the current Model in one hop. When a new schema version lands, add a new priorSchemaVX / priorModelVX / upgradeVXToV(X+1) triple here and update the existing helpers to populate any new fields.

type StateModel

type StateModel struct {
	Desired      types.String `tfsdk:"desired"`
	Current      types.String `tfsdk:"current"`
	ShutdownMode types.String `tfsdk:"shutdown_mode"`
}

StateModel is the nested `state` block on hyperv_vm. Pointer-typed for the same reason as CPU and Memory. Desired is the user-facing power-state input ("Off" | "Running"), a transition fires only when it differs from the host's actual state, and Current is the Computed readback from Hyper-V.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL