Documentation
¶
Overview ¶
Package hyperv is the typed Go wrapper over the connection layer. It concatenates the embedded preamble to each script body, marshals Go DTOs into PowerShell input JSON, and unmarshals PowerShell output JSON back into typed structs, mapping errors from the structured envelope (Write-HypervError) to the typed errors in errors.go. Resources never touch connection.Runner directly — they go through this Client.
Index ¶
- Variables
- func ComputeFileSHA256(path string) (string, error)
- type AttachDvdDriveInput
- type AttachHardDiskInput
- type AttachNetworkAdapterInput
- type BootOrderEntry
- type Client
- func (c *Client) AttachDvdDrive(ctx context.Context, in AttachDvdDriveInput) error
- func (c *Client) AttachHardDisk(ctx context.Context, in AttachHardDiskInput) error
- func (c *Client) AttachNetworkAdapter(ctx context.Context, in AttachNetworkAdapterInput) error
- func (c *Client) CopyHostFile(ctx context.Context, in CopyHostFileInput) (*ImageFile, error)
- func (c *Client) DetachDvdDrive(ctx context.Context, in DetachDvdDriveInput) error
- func (c *Client) DetachHardDisk(ctx context.Context, in DetachHardDiskInput) error
- func (c *Client) DetachNetworkAdapter(ctx context.Context, in DetachNetworkAdapterInput) error
- func (c *Client) GetImageFile(ctx context.Context, path string) (*ImageFile, error)
- func (c *Client) GetNatStaticMapping(ctx context.Context, in GetNatStaticMappingInput) (*NatStaticMapping, error)
- func (c *Client) GetVHD(ctx context.Context, path string) (*VHD, error)
- func (c *Client) GetVM(ctx context.Context, name string) (*VM, error)
- func (c *Client) GetVMHost(ctx context.Context) (*VMHost, error)
- func (c *Client) GetVMSwitch(ctx context.Context, name, natName string) (*VMSwitch, error)
- func (c *Client) ListVHDsByPrefix(ctx context.Context, parentDir, prefix string) ([]VHDPath, error)
- func (c *Client) ListVMSwitchesByPrefix(ctx context.Context, prefix string) ([]VMSwitchName, error)
- func (c *Client) ListVMsByPrefix(ctx context.Context, prefix string) ([]VMName, error)
- func (c *Client) NewImageFileFromBytes(ctx context.Context, in NewImageFileFromBytesInput) (*ImageFile, error)
- func (c *Client) NewImageFileFromHostPath(ctx context.Context, destinationPath string) (*ImageFile, error)
- func (c *Client) NewImageFileFromLocalPath(ctx context.Context, in NewImageFileFromLocalPathInput) (*ImageFile, error)
- func (c *Client) NewImageFileFromURL(ctx context.Context, in NewImageFileFromURLInput) (*ImageFile, error)
- func (c *Client) NewNatStaticMapping(ctx context.Context, in NewNatStaticMappingInput) (*NatStaticMapping, error)
- func (c *Client) NewVHDDifferencing(ctx context.Context, in NewVHDDifferencingInput) (*VHD, error)
- func (c *Client) NewVHDDynamic(ctx context.Context, in NewVHDDynamicInput) (*VHD, error)
- func (c *Client) NewVHDFixed(ctx context.Context, in NewVHDFixedInput) (*VHD, error)
- func (c *Client) NewVM(ctx context.Context, in NewVMInput) (*VM, error)
- func (c *Client) NewVMSwitch(ctx context.Context, in NewVMSwitchInput) (*VMSwitch, error)
- func (c *Client) RemoveImageFile(ctx context.Context, in RemoveImageFileInput) error
- func (c *Client) RemoveNatStaticMapping(ctx context.Context, in RemoveNatStaticMappingInput) error
- func (c *Client) RemoveVHD(ctx context.Context, path string) error
- func (c *Client) RemoveVM(ctx context.Context, name string) error
- func (c *Client) RemoveVMSwitch(ctx context.Context, name, natName string) error
- func (c *Client) ResizeVHD(ctx context.Context, path string, sizeBytes int64) (*VHD, error)
- func (c *Client) RunScript(ctx context.Context, script string, stdinJSON []byte) (connection.Result, error)
- func (c *Client) SetBootOrder(ctx context.Context, in SetBootOrderInput) error
- func (c *Client) SetNatStaticMapping(ctx context.Context, in SetNatStaticMappingInput) (*NatStaticMapping, error)
- func (c *Client) SetVM(ctx context.Context, in SetVMInput) (*VM, error)
- func (c *Client) SetVMState(ctx context.Context, in SetVMStateInput) (*VM, error)
- func (c *Client) SetVMSwitch(ctx context.Context, in SetVMSwitchInput) (*VMSwitch, error)
- func (c *Client) StatImageFile(ctx context.Context, path string) (*ImageFile, error)
- func (c *Client) SweepImageFiles(ctx context.Context, parentDir, prefix string) ([]string, error)
- func (c *Client) SweepNetNats(ctx context.Context, prefix string) ([]string, error)
- type ClientOption
- type CopyHostFileInput
- type DetachDvdDriveInput
- type DetachHardDiskInput
- type DetachNetworkAdapterInput
- type DvdDrive
- type GetNatStaticMappingInput
- type HardDiskDrive
- type ImageFile
- type NatStaticMapping
- type NatStaticMappingFirewallInput
- type NetworkAdapter
- type NewImageFileFromBytesInput
- type NewImageFileFromLocalPathInput
- type NewImageFileFromURLInput
- type NewNatStaticMappingInput
- type NewVHDDifferencingInput
- type NewVHDDynamicInput
- type NewVHDFixedInput
- type NewVMInput
- type NewVMSwitchInput
- type RemoveImageFileInput
- type RemoveNatStaticMappingInput
- type SetBootOrderEntryInput
- type SetBootOrderInput
- type SetNatStaticMappingInput
- type SetVMInput
- type SetVMStateInput
- type SetVMSwitchInput
- type VHD
- type VHDPath
- type VM
- type VMHost
- type VMName
- type VMSwitch
- type VMSwitchName
Constants ¶
This section is empty.
Variables ¶
var ( ErrNotFound = errors.New("hyperv: resource not found") ErrInvalidParentPath = errors.New("hyperv: invalid parent path") ErrChecksumMismatch = errors.New("hyperv: image file checksum mismatch") ErrDecompressionFailed = errors.New("hyperv: image file decompression failed") ErrContentDrift = errors.New("hyperv: destination file no longer matches the resource's last-known content") ErrPSExecution = errors.New("hyperv: powershell execution failed") )
Sentinel errors; resources match against these with `errors.Is(err, X)` to decide how to surface to the user (RemoveResource for ErrNotFound, AddAttributeError for ErrInvalidParentPath, etc.). ErrNotFound vs ErrUnavailable is load-bearing: ErrNotFound means the object genuinely does not exist (PS ObjectNotFound) and a resource Read should RemoveResource so Terraform plans a recreate; ErrUnavailable means the object is known but temporarily inaccessible (PS ResourceUnavailable — vmms stopped, cluster node fenced, transport blip) and the resource MUST surface a transient error rather than dropping the resource from state.
Functions ¶
func ComputeFileSHA256 ¶ added in v0.2.0
ComputeFileSHA256 returns the lowercase-hex SHA-256 of the file at path, streamed via io.Copy so files of any size hash without buffering the whole payload in memory. Exported because the resource layer's local_path-mode plan-time hashing reuses this -- both the typed-client method and the resource's ModifyPlan need the same function so the SHA the runner commits to at plan time is byte-identical to the one it sends on the wire at apply time.
Types ¶
type AttachDvdDriveInput ¶
type AttachDvdDriveInput struct {
Name string `json:"name"`
ControllerType string `json:"controller_type"`
ControllerNumber int `json:"controller_number"`
ControllerLocation int `json:"controller_location"`
IsoPath *string `json:"iso_path,omitempty"`
}
AttachDvdDriveInput is the stdin JSON format for vm/add-dvd-drive.ps1. IsoPath is *string so the wire JSON drops it cleanly when the user wants an empty drive (script's "if not empty" guard then omits -Path from the cmdlet call).
type AttachHardDiskInput ¶
type AttachHardDiskInput struct {
Name string `json:"name"`
ControllerType string `json:"controller_type"`
ControllerNumber int `json:"controller_number"`
ControllerLocation int `json:"controller_location"`
Path string `json:"path"`
}
AttachHardDiskInput is the stdin JSON format for vm/add-hard-disk-drive.ps1. All fields are required; the script's ValidateSet on ControllerType is the second line of defense against typos that the resource-layer schema validator should catch first.
type AttachNetworkAdapterInput ¶
type AttachNetworkAdapterInput struct {
Name string `json:"name"`
VMName string `json:"vm_name"`
SwitchName string `json:"switch_name"`
// MacAddress is optional. Empty string means "let Hyper-V auto-
// assign from its dynamic pool" -- the script omits the
// -StaticMacAddress flag in that case. Any non-empty value is
// passed through verbatim; the schema validator at the resource
// layer pre-screens the format.
MacAddress string `json:"mac_address,omitempty"`
// VlanID is optional. 0 means untagged (the script issues
// `Set-VMNetworkAdapterVlan -Untagged` after the Add). 1-4094 sets
// access-mode VLAN. The schema validator pre-screens the range.
VlanID int `json:"vlan_id,omitempty"`
}
AttachNetworkAdapterInput is the stdin JSON format for vm/add-network-adapter.ps1. Name / VMName / SwitchName are required; MacAddress and VlanID are optional. Uniqueness of Name within a VM is enforced by the resource-layer schema validator (Hyper-V itself doesn't enforce it).
type BootOrderEntry ¶
type BootOrderEntry struct {
Type string `json:"Type"`
ControllerType string `json:"ControllerType"`
ControllerNumber int `json:"ControllerNumber"`
ControllerLocation int `json:"ControllerLocation"`
Name string `json:"Name"`
}
BootOrderEntry is the per-entry format vm/get.ps1 emits inside VM.BootOrder. Type discriminates between hard_disk_drive / dvd_drive (which carry the ControllerType + ControllerNumber + ControllerLocation slot tuple) and network_adapter (which carries Name); unused fields for a given Type are zero values, and consumers branch on Type. Gen 1 VMs always emit []BootOrderEntry{}, since the script doesn't fetch firmware for them; gen 1 BIOS StartupOrder is a separate, deferred schema slice.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the typed wrapper resources use to invoke Hyper-V cmdlets. One instance per provider configuration, passed via the framework's resp.ResourceData / resp.DataSourceData.
func NewClient ¶
func NewClient(r connection.Runner, opts ...ClientOption) *Client
NewClient wraps a connection.Runner. The Runner abstraction is what lets unit tests substitute a fake without standing up a real PowerShell host.
func (*Client) AttachDvdDrive ¶
func (c *Client) AttachDvdDrive(ctx context.Context, in AttachDvdDriveInput) error
AttachDvdDrive adds a DVD drive to a VM at a specific controller slot via Add-VMDvdDrive, optionally loading an ISO. IsoPath=nil produces an empty drive (the medium tray exists but no ISO is loaded); IsoPath=&"path" loads the ISO at attach time.
func (*Client) AttachHardDisk ¶
func (c *Client) AttachHardDisk(ctx context.Context, in AttachHardDiskInput) error
AttachHardDisk wires an existing VHD to a VM at a specific controller slot via Add-VMHardDiskDrive. (ControllerType, ControllerNumber, ControllerLocation) identifies the slot uniquely; a second attachment at the same slot errors. Path is the existing VHD's location; this method doesn't create the VHD itself, pair it with hyperv_vhd or hyperv_image_file for that. ControllerType=IDE on a gen 2 VM errors at the cmdlet layer as defense in depth, since the resource-layer schema validator should already catch it at plan time. Returns ErrNotFound if the VM is missing; other errors map to ErrPSExecution.
func (*Client) AttachNetworkAdapter ¶
func (c *Client) AttachNetworkAdapter(ctx context.Context, in AttachNetworkAdapterInput) error
AttachNetworkAdapter adds a new NIC to a VM and binds it to the named virtual switch via Add-VMNetworkAdapter. The display name is the slot key used by the resource-layer Update reconciliation. Returns ErrNotFound if the VM is missing. Switch-not-found surfaces as ErrPSExecution (Hyper-V's InvalidArgument category isn't routed to a typed sentinel for this cmdlet).
func (*Client) CopyHostFile ¶ added in v0.4.0
CopyHostFile copies a file the host already holds at in.SourcePath into in.DestinationPath, staging through a sibling .part and atomic-renaming; nothing crosses Connection.StreamFile, so multi-GiB clones run at host disk speed. Shared by hyperv_image_file's source_path mode and hyperv_vhd's. Returns ErrChecksumMismatch when the copy doesn't hash to in.ExpectedSha256, or ErrNotFound when the source is absent at apply time.
func (*Client) DetachDvdDrive ¶
func (c *Client) DetachDvdDrive(ctx context.Context, in DetachDvdDriveInput) error
DetachDvdDrive removes a DVD drive from a VM at a specific controller slot via Remove-VMDvdDrive. Same slot-keyed semantics as DetachHardDisk -- whatever ISO (if any) was loaded gets implicitly ejected.
func (*Client) DetachHardDisk ¶
func (c *Client) DetachHardDisk(ctx context.Context, in DetachHardDiskInput) error
DetachHardDisk removes a VHD attachment from a VM at a specific controller slot via Remove-VMHardDiskDrive. The slot tuple alone identifies the attachment (Path is not part of the wire payload). "Slot already empty" surfaces as ObjectNotFound from the cmdlet -> ErrNotFound on the Go side; the resource-layer reconciliation in Update treats ErrNotFound as a no-op (desired state is "empty", already met). Other errors map to ErrPSExecution.
func (*Client) DetachNetworkAdapter ¶
func (c *Client) DetachNetworkAdapter(ctx context.Context, in DetachNetworkAdapterInput) error
DetachNetworkAdapter removes a NIC from a VM by display name via Remove-VMNetworkAdapter. Missing VM and "no NIC by that name" both surface as ObjectNotFound -> ErrNotFound; the resource-layer Update reconciliation treats ErrNotFound as a no-op (desired state is "no NIC by that name", already met).
func (*Client) GetImageFile ¶
GetImageFile reads metadata + SHA-256 for a file on the host. Returns ErrNotFound when the file is absent (resource Read should call RemoveResource), or ErrUnauthorized for permission errors. SHA-256 is recomputed on every call as intentional drift detection.
func (*Client) GetNatStaticMapping ¶ added in v0.3.0
func (c *Client) GetNatStaticMapping(ctx context.Context, in GetNatStaticMappingInput) (*NatStaticMapping, error)
GetNatStaticMapping fetches a NAT static netnat-static-mapping mapping by its (nat_name, protocol, external_ip, external_port) lookup tuple and joins the optional companion firewall rule into the read result. Returns ErrNotFound when no mapping matches the tuple (resource Read should call RemoveResource), or ErrUnavailable when the underlying service is transiently unreachable.
func (*Client) GetVHD ¶
GetVHD reads a VHD's metadata + parent/format/attached flags. Returns ErrNotFound when the file is absent (resource Read should call RemoveResource), or ErrUnauthorized for permission errors.
func (*Client) GetVM ¶
GetVM fetches a VM by name. Returns ErrNotFound when the VM doesn't exist (resource Read should call RemoveResource), or ErrUnauthorized for permission errors. SecureBootEnabled in the returned VM is *bool because gen 1 VMs report null (no Secure Boot concept).
func (*Client) GetVMHost ¶
GetVMHost returns the Hyper-V host info. The cmdlet stays inline; when M1c lands the vswitch scripts they'll move to internal/scripts/<resource>/<verb>.ps1 with Pester coverage.
func (*Client) GetVMSwitch ¶
GetVMSwitch fetches a virtual switch by name. Returns ErrNotFound when the switch doesn't exist (resource Read should call RemoveResource), or ErrUnavailable when vmms is stopped or a cluster node is fenced (transient). natName is optional: when set, the script joins Get-NetNat and Get-NetIPAddress with the VMSwitch read and synthesizes SwitchType="NAT", so callers managing NAT-typed resources pass nat_name from state for Read to round-trip correctly. An empty natName returns the bare six-field result, with SwitchType reflecting Hyper-V's own enum instead.
func (*Client) ListVHDsByPrefix ¶ added in v0.3.0
ListVHDsByPrefix returns paths of every VHD/VHDX/avhd/avhdx file under parentDir whose filename starts with prefix. Unlike ListVMsByPrefix, which enumerates host-globally via Get-VM, VHDs are path-addressable, so the caller supplies the directory to scan (the acctest sweeper threads HYPERV_TEST_VHD_DIR). A missing parentDir returns []VHDPath{} rather than an error, since a fresh bench legitimately has no fixture directory yet; other errors propagate. Backed by vhd/list.ps1, read-only.
func (*Client) ListVMSwitchesByPrefix ¶ added in v0.3.0
ListVMSwitchesByPrefix returns the names of all virtual switches whose Name begins with prefix (typically "tfacc-" for the acceptance-test sweeper). An empty result is a normal return, not an error. Backed by vswitch/list.ps1, read-only; doesn't take netNatMu since bare enumeration never touches the NetNat backing file (the NAT join only happens in GetVMSwitch's natName path).
func (*Client) ListVMsByPrefix ¶ added in v0.3.0
ListVMsByPrefix returns the names of all VMs whose Name begins with the given prefix (typically "tfacc-" for the acceptance-test sweeper). Empty result is a normal return ([]VMName{}, nil) -- the caller can distinguish "no matches" from "fault" without checking err. Backed by vm/list.ps1 -- see that script's header for the wire contract. Read-only operation; no power transitions or other side effects.
func (*Client) NewImageFileFromBytes ¶ added in v0.3.0
func (c *Client) NewImageFileFromBytes(ctx context.Context, in NewImageFileFromBytesInput) (*ImageFile, error)
NewImageFileFromBytes lands a literal byte payload at DestinationPath via the same route as local_path mode: it stages Bytes to a runner tmpfile, hashes it, then streams and verifies like a local file. Returns ErrChecksumMismatch on a hash mismatch. The payload sits twice in memory briefly, fine for sub-MiB seed ISOs; prefer NewImageFileFromLocalPath or NewImageFileFromURL for multi-GiB files.
func (*Client) NewImageFileFromHostPath ¶
func (c *Client) NewImageFileFromHostPath(ctx context.Context, destinationPath string) (*ImageFile, error)
NewImageFileFromHostPath verifies a file the user attests already exists at destinationPath and returns its metadata: no copy, no fetch. Returns ErrNotFound if the file is absent. For host_path-mode resources, Delete is a no-op on the Go side, since the user didn't ask the provider to put the file there.
func (*Client) NewImageFileFromLocalPath ¶ added in v0.2.0
func (c *Client) NewImageFileFromLocalPath(ctx context.Context, in NewImageFileFromLocalPathInput) (*ImageFile, error)
NewImageFileFromLocalPath streams the runner-local file at LocalPath to the host, then asks new.ps1 to verify the staged bytes against a runner-computed SHA-256 and atomic-rename to DestinationPath. Returns ErrChecksumMismatch when the landed bytes don't match.
func (*Client) NewImageFileFromURL ¶
func (c *Client) NewImageFileFromURL(ctx context.Context, in NewImageFileFromURLInput) (*ImageFile, error)
NewImageFileFromURL fetches a file by URL, streaming to a sibling .part file and verifying its SHA-256 before an atomic rename into place. A supported Compression ("gz" or "gzip") routes through newImageFileFromCompressedURL instead, since PS 5.1 has no built-in decompressor. Returns ErrChecksumMismatch on a hash mismatch, or ErrDecompressionFailed when the compressed path hits a corrupt stream.
func (*Client) NewNatStaticMapping ¶ added in v0.3.0
func (c *Client) NewNatStaticMapping(ctx context.Context, in NewNatStaticMappingInput) (*NatStaticMapping, error)
NewNatStaticMapping creates a static NAT mapping plus the optional inbound firewall allow rule. The script-side rollback handles the partial-failure case (mapping landed, firewall rule failed); see nat_static_mapping/new.ps1 for the catch path. Cross-resource: nat_name must resolve to an existing NetNat instance on the host, and the script's Get-NetNat precondition surfaces a clear "missing NetNat" error if it doesn't, mapped here through the typed-error path.
func (*Client) NewVHDDifferencing ¶
NewVHDDifferencing creates a child that reads from in.ParentPath and writes new blocks locally. Returns ErrInvalidParentPath when the parent path is missing or invalid. Recovers from connection.ErrSessionDropped like NewVHDFixed, but the recovery's expectedVHD passes SizeBytes=0 (skip the size check), since a differencing disk inherits its size from the parent and Path + VhdType alone are the load-bearing match for this variant.
func (*Client) NewVHDDynamic ¶
NewVHDDynamic creates a sparse VHD/VHDX. Initial on-disk size is minimal; the file grows as the guest writes blocks, up to SizeBytes. Recovers from connection.ErrSessionDropped via verify-on-drop -- see NewVHDFixed.
func (*Client) NewVHDFixed ¶
NewVHDFixed creates a pre-allocated (full-sized on disk) VHD/VHDX: slow create, no runtime expansion. Returns the post-create read result. Recovers from connection.ErrSessionDropped the same way NewVMSwitch does: a concurrent resource's External-switch NIC rebind can blink this call's SSH session after New-VHD succeeds. Verify-on-drop polls GetVHD; a match adopts the VHD into state, a mismatch surfaces the drop with the mismatch detail so the operator can retry.
func (*Client) NewVM ¶
NewVM creates a VM and returns the canonical read result. The script-side sequence is New-VM (with -NoVHD -BootDevice None -- no auto-attach of storage or boot device) followed by Set-VMMemory (static, with DynamicMemoryEnabled=$false in the same call), Set-VMProcessor, and the optional Set-VMFirmware (gen 2 + SecureBoot) and Set-VM (Notes) tail.
func (*Client) NewVMSwitch ¶
NewVMSwitch creates a virtual switch and returns the canonical read result. The script-side guard rejects Private + AllowManagementOS before invoking the cmdlet. Recovers from connection.ErrSessionDropped: New-VMSwitch on the NIC the SSH session traverses rebinds it, which can blink the session before the cmdlet's exit status reaches the runner. Recovery polls GetVMSwitch and returns the first hit, safe since Hyper-V refuses to create over an existing same-name switch; if verify can't confirm the switch exists, the original ErrSessionDropped surfaces for the operator to retry.
func (*Client) RemoveImageFile ¶
func (c *Client) RemoveImageFile(ctx context.Context, in RemoveImageFileInput) error
RemoveImageFile deletes a file from the host, locked per destination_path so a concurrent destroy or hash-check on the same file can't race. Resource Delete should treat ErrNotFound as success, and must not call this for host_path-mode resources. Force opts into remove.ps1's detach-then-retry on a Hyper-V-DVD sharing violation, instead of surfacing the locked-file diagnostic. Returns ErrContentDrift when ExpectedSha256 no longer matches the on-host file.
func (*Client) RemoveNatStaticMapping ¶ added in v0.3.0
func (c *Client) RemoveNatStaticMapping(ctx context.Context, in RemoveNatStaticMappingInput) error
RemoveNatStaticMapping deletes the static mapping and the companion firewall rule. Resource Delete should treat ErrNotFound as success (the mapping is already gone). Best-effort destroy: a missing firewall rule doesn't fail Delete.
func (*Client) RemoveVHD ¶
RemoveVHD deletes the VHD file. Resource Delete should treat ErrNotFound as success (already gone). The cmdlet errors loudly when the file is attached to a running VM (open file handle); that surfaces as ErrPSExecution rather than being swallowed. Locked per path against CopyHostFile: source_path-mode hyperv_vhd creates through the same shared CopyHostFile as hyperv_image_file, so a vhd and an image_file sharing a path need the same create/destroy interlock CopyHostFile and RemoveImageFile already have.
func (*Client) RemoveVM ¶
RemoveVM deletes a VM. Resource Delete should treat ErrNotFound as success (the VM is already gone). The script stops the VM first if it's running (Remove-VM errors on a running VM); this is the one place the PS layer drives a power transition, justified because destroy is destructive by definition.
func (*Client) RemoveVMSwitch ¶
RemoveVMSwitch deletes a virtual switch by name; ErrNotFound is success (already gone). An External switch with AllowManagementOS=true gets a two-step destroy via prepareVMSwitchExternalForRemove before the actual Remove; every other switch type or state removes directly. natName forwards to remove.ps1's NAT teardown (Remove-NetNat, Remove-NetIPAddress, then Remove-VMSwitch), each step tolerating ObjectNotFound; empty natName skips it. Recovers from connection.ErrSessionDropped on the actual Remove via recoverVMSwitchRemoveOnDrop.
func (*Client) ResizeVHD ¶
ResizeVHD changes the declared size of an existing VHD. The cmdlet errors on shrink-without-compaction (run Optimize-VHD first) and on fixed-format resize while the disk is attached to a running VM; both surface as ErrPSExecution to the resource layer.
func (*Client) RunScript ¶ added in v0.3.3
func (c *Client) RunScript(ctx context.Context, script string, stdinJSON []byte) (connection.Result, error)
RunScript executes a PowerShell script on the remote host via the underlying runner. This method exists solely to support acceptance-test helpers (e.g. acctest.BenchCanReach) that need to run connectivity pre-checks without opening a separate connection. It is not part of the production resource API and should not be called from resource implementations.
func (*Client) SetBootOrder ¶
func (c *Client) SetBootOrder(ctx context.Context, in SetBootOrderInput) error
SetBootOrder replaces the boot device sequence on a gen 2 VM via Set-VMFirmware -BootOrder. Wholesale replacement: each call sets the full order; the script resolves each entry's slot/name to the underlying device handle the cmdlet expects. Gen 1 isn't supported in this slice -- the resource-layer schema validator should reject boot_order on gen 1 at plan time.
func (*Client) SetNatStaticMapping ¶ added in v0.3.0
func (c *Client) SetNatStaticMapping(ctx context.Context, in SetNatStaticMappingInput) (*NatStaticMapping, error)
SetNatStaticMapping applies a partial update. internal_ip/internal_port changes are Remove + Add under the hood (NatStaticMapping has no in-place edit); firewall.* changes go through Set-NetFirewallRule. Returns the post-mutation read result: the StaticMappingID may change because Hyper-V re-numbers mappings on Add.
func (*Client) SetVM ¶
SetVM applies a partial update and returns the post-mutation read result: set.ps1 follows its Set-* calls with a Get-VM read-back so the result matches GetVM exactly. Callers should populate in.Generation from prior state so set.ps1's gen-2-only SecureBoot guard fires as defense in depth (the ConfigValidator already catches this at plan time). vcpu, memory_bytes, and secure_boot generally require the VM to be Off; the script surfaces those errors verbatim, since the operator drives power transitions via hyperv_vm_state.
func (*Client) SetVMState ¶
SetVMState transitions the VM's power state via Start-VM (Desired= 'Running') or Stop-VM -TurnOff -Force (Desired='Off'). Returns the post-transition VM read so callers can refresh state without a separate GetVM round-trip. Idempotent at the cmdlet level: setting Desired='Running' on an already-Running VM is a no-op.
func (*Client) SetVMSwitch ¶
SetVMSwitch applies a partial update and returns the post-mutation read result (set.ps1 follows Set-VMSwitch with a Get-VMSwitch read-back so the result matches GetVMSwitch exactly). Callers should populate in.SwitchType from prior state so set.ps1's Private + AllowManagementOS guard can fire at the script layer; without it, the cmdlet's opaque "parameter is not applicable" error surfaces instead.
func (*Client) StatImageFile ¶ added in v0.4.0
StatImageFile reads the same fields as GetImageFile but bounds the call by the caller's context instead of the 60s defaultReadTimeout, for the source_path plan-time hash where Get-FileHash over a multi-GiB vhdx routinely outruns that cap. Callers must supply their own deadline.
func (*Client) SweepImageFiles ¶ added in v0.3.0
SweepImageFiles removes orphan files under parentDir whose name starts with prefix and whose extension isn't .vhd/.vhdx/.avhd/.avhdx (the hyperv_vhd sweeper's territory). An empty result is a normal return. Backed by image_file/sweep.ps1.
func (*Client) SweepNetNats ¶ added in v0.3.0
SweepNetNats removes every NetNat on the host whose Name starts with prefix (typically "tfacc-" for the acceptance-test sweeper) and returns the removed names; an empty, non-error result means no orphans. Takes the package netNatMu write lock for the same reason RemoveVMSwitch's NAT branch does: Remove-NetNat mutates NetNat's backing file under an exclusive handle and would race any concurrent writer otherwise. Backed by netnat/sweep.ps1.
type ClientOption ¶ added in v0.3.0
type ClientOption func(*Client)
ClientOption customizes a Client at construction time. The functional- options pattern, rather than a constructor variant, means a future knob (per-call timeouts, retry policy) won't ripple out into every NewClient call site.
func WithHTTPClient ¶ added in v0.3.0
func WithHTTPClient(hc *http.Client) ClientOption
WithHTTPClient overrides the default *http.Client the runner-pipelined image_file fetch uses. Tests pass a transport pointed at httptest.Server; integrators with non-default proxy / TLS requirements pass their tuned client. nil restores the default (no panic surface for callers passing a maybe-nil value).
type CopyHostFileInput ¶ added in v0.4.0
type CopyHostFileInput struct {
DestinationPath string `json:"destination_path"`
SourcePath string `json:"source_path"`
ExpectedSha256 string `json:"expected_sha256"`
ReplaceWhileMounted bool `json:"replace_while_mounted"`
}
CopyHostFileInput is the public input for a host-side copy. Both paths are host-local, so unlike the other write modes there's no StreamFile leg and no staging_path for the caller to compute; new.ps1 picks its own. ExpectedSha256 is the hash the caller read from SourcePath at plan time; a mismatch at apply means the source changed underneath, which fails loudly rather than writing bytes the plan never promised. ReplaceWhileMounted matches the local_path input.
type DetachDvdDriveInput ¶
type DetachDvdDriveInput struct {
Name string `json:"name"`
ControllerType string `json:"controller_type"`
ControllerNumber int `json:"controller_number"`
ControllerLocation int `json:"controller_location"`
}
DetachDvdDriveInput mirrors DetachHardDiskInput -- slot tuple identifies the DVD to remove, no Path needed.
type DetachHardDiskInput ¶
type DetachHardDiskInput struct {
Name string `json:"name"`
ControllerType string `json:"controller_type"`
ControllerNumber int `json:"controller_number"`
ControllerLocation int `json:"controller_location"`
}
DetachHardDiskInput is the stdin JSON format for vm/remove-hard-disk-drive.ps1. Path is intentionally omitted -- the slot tuple identifies the attachment, not the underlying VHD.
type DetachNetworkAdapterInput ¶
DetachNetworkAdapterInput is the stdin JSON format for vm/remove-network-adapter.ps1. Name + VMName identify the NIC to detach; the cmdlet would happily remove ALL NICs sharing the same Name, but the schema-level uniqueness validator means there's only ever one match in our state.
type DvdDrive ¶
type DvdDrive struct {
Path string `json:"Path"`
ControllerType string `json:"ControllerType"`
ControllerNumber int `json:"ControllerNumber"`
ControllerLocation int `json:"ControllerLocation"`
}
DvdDrive is the per-attachment format vm/get.ps1 emits inside VM.DvdDrives. Same slot-tuple identity as HardDiskDrive (ControllerType + ControllerNumber + ControllerLocation), but Path may be empty -- a DVD drive without an ISO loaded is a legitimate state (the drive exists, the medium tray is empty).
type GetNatStaticMappingInput ¶ added in v0.3.0
type GetNatStaticMappingInput struct {
NatName string `json:"nat_name"`
Protocol string `json:"protocol"`
ExternalIPAddress string `json:"external_ip"`
ExternalPort int `json:"external_port"`
FirewallName string `json:"firewall_name"`
}
GetNatStaticMappingInput is the stdin JSON format for nat_static_mapping/get.ps1 and nat_static_mapping/remove.ps1. The lookup tuple uniquely identifies a mapping; firewall_name is needed alongside because the firewall rule is keyed by DisplayName, not derived from the mapping itself.
type HardDiskDrive ¶
type HardDiskDrive struct {
Path string `json:"Path"`
ControllerType string `json:"ControllerType"`
ControllerNumber int `json:"ControllerNumber"`
ControllerLocation int `json:"ControllerLocation"`
}
HardDiskDrive is the per-attachment format vm/get.ps1 emits inside VM.HardDiskDrives. The (ControllerType, ControllerNumber, ControllerLocation) tuple identifies the slot uniquely on a given VM; Path identifies the underlying VHD/VHDX. The same VHD attached at two different slots produces two HardDiskDrive entries.
type ImageFile ¶
type ImageFile struct {
Path string `json:"Path"`
SizeBytes int64 `json:"SizeBytes"`
Sha256 string `json:"Sha256"`
}
ImageFile is the canonical read format image_file/{get,new}.ps1 emits. Sha256 is lowercase hex (the wire contract); SizeBytes is int64 because VHDX/ISO files routinely exceed 2^31 bytes.
type NatStaticMapping ¶ added in v0.3.0
type NatStaticMapping struct {
ID string `json:"Id"`
StaticMappingID int `json:"StaticMappingId"`
NatName string `json:"NatName"`
Protocol string `json:"Protocol"`
ExternalIPAddress string `json:"ExternalIPAddress"`
ExternalPort int `json:"ExternalPort"`
InternalIPAddress string `json:"InternalIPAddress"`
InternalPort int `json:"InternalPort"`
FirewallRulePresent bool `json:"FirewallRulePresent"`
FirewallRuleName string `json:"FirewallRuleName"`
FirewallRuleProfile string `json:"FirewallRuleProfile"`
}
NatStaticMapping is the canonical eleven-field read format nat_static_mapping/{get,new,set}.ps1 emits. Composite Id encodes the lookup tuple (NatName:Protocol:ExternalIPAddress:ExternalPort) lowercase for stable cross-tool interop; Protocol on the rest of the struct is uppercase (TCP / UDP) because that's what Get-NetNatStaticMapping reports natively. StaticMappingID is the Hyper-V-assigned opaque identifier; it changes whenever the mapping is recreated (Set on internal_ip/internal_port is Remove + Add under the hood).
type NatStaticMappingFirewallInput ¶ added in v0.3.0
type NatStaticMappingFirewallInput struct {
Enabled bool `json:"enabled"`
Name string `json:"name"`
Profile string `json:"profile"`
}
NatStaticMappingFirewallInput is the nested firewall block's wire format for new.ps1 / set.ps1. Defaulting (enabled=true, derived name, profile=Any) lives on the resource layer; this struct carries the already-resolved values to the script.
type NetworkAdapter ¶
type NetworkAdapter struct {
Name string `json:"Name"`
SwitchName string `json:"SwitchName"`
IPAddresses []string `json:"IPAddresses"`
// MacAddress is the active MAC. Only populated by the script when
// DynamicMacAddressEnabled is false (i.e. user-set static MAC); for
// dynamic MACs the script emits an empty string so the resource
// layer's flatten can store state value as null without conflating
// "user picked no MAC" with "user picked Hyper-V's auto-assigned
// pool value of the moment".
MacAddress string `json:"MacAddress"`
// VlanID is the access-mode VLAN ID. 0 means untagged. The resource
// layer flattens 0 to a null state value so unset config matches
// unset state on round-trip.
VlanID int `json:"VlanID"`
}
NetworkAdapter is the per-NIC format vm/get.ps1 emits inside VM.NetworkAdapters. Name is the slot key the resource-layer reconciliation uses to diff plan vs state. SwitchName identifies which hyperv_virtual_switch the NIC is bound to, empty when unbound (rare, but Hyper-V allows it). IPAddresses comes from Hyper-V's integration services running in the guest, empty when the VM is Off, integration services haven't loaded, or the guest doesn't ship them; the resource layer flattens it across all NICs into a top-level ip_addresses Computed attribute.
type NewImageFileFromBytesInput ¶ added in v0.3.0
type NewImageFileFromBytesInput struct {
DestinationPath string `json:"destination_path"`
Bytes []byte `json:"-"`
ReplaceWhileMounted bool `json:"-"`
}
NewImageFileFromBytesInput is the public input for the literal_bytes source mode. The runner writes Bytes to a tmpfile, hashes it, streams to a sibling .part of DestinationPath, and asks new.ps1 to verify-and-rename via the same wire path local_path mode uses; new.ps1 can't tell whether the staged bytes came from a runner-local file or an in-memory payload. ReplaceWhileMounted has the same semantics as the local_path input: true for callers that synthesize iso_volume bytes for a DVD-mountable destination, false (default) for a fresh path.
type NewImageFileFromLocalPathInput ¶ added in v0.2.0
type NewImageFileFromLocalPathInput struct {
DestinationPath string `json:"destination_path"`
LocalPath string `json:"-"`
// ReplaceWhileMounted opts the host-side Move-Item into a swap-via-
// pivot dance that handles the case where DestinationPath is currently
// mounted as a DVD on a running VM. Off by default; set true for
// callers that may stream over a destination some VM holds open
// (cidata seeds, autounattend ISOs).
ReplaceWhileMounted bool `json:"-"`
}
NewImageFileFromLocalPathInput is the public input for the local_path source mode of image_file/new.ps1. The runner-local source (LocalPath) is JSON-skipped because it never crosses the wire -- the typed-client method opens it on the runner side, computes the SHA-256, streams the bytes to a sibling .part of DestinationPath via Connection.StreamFile, and asks new.ps1 to verify-and-rename. The discriminator (source_mode) and the computed staging_path / expected_sha256 fields are added internally by the method, so callers can't pass the wrong values for the mode they invoke.
type NewImageFileFromURLInput ¶
type NewImageFileFromURLInput struct {
DestinationPath string `json:"destination_path"`
URL string `json:"url"`
ExpectedSha256 string `json:"expected_sha256"`
Compression string `json:"-"`
RunnerDownload bool `json:"-"`
}
NewImageFileFromURLInput is the public input for the URL source mode of image_file/new.ps1. The discriminator field (source_mode) isn't on the public struct; the typed-client method sets it internally so callers can't pass the wrong value. Compression identifies a decompressor ("gz" currently, "" for none); when set, the client downloads and decompresses on the runner instead, streaming the result to a sibling .part of DestinationPath and dispatching new.ps1 in local_path mode. ExpectedSha256 is always the publisher-signed hash of the *compressed* bytes; the runner-computed *decompressed* SHA is what the host receives for staging verification.
type NewNatStaticMappingInput ¶ added in v0.3.0
type NewNatStaticMappingInput struct {
NatName string `json:"nat_name"`
Protocol string `json:"protocol"`
ExternalIPAddress string `json:"external_ip"`
ExternalPort int `json:"external_port"`
InternalIPAddress string `json:"internal_ip"`
InternalPort int `json:"internal_port"`
Firewall NatStaticMappingFirewallInput `json:"firewall"`
}
NewNatStaticMappingInput is the stdin JSON format for nat_static_mapping/new.ps1. All mapping fields are required; firewall is required as a nested object (resource defaults populate it before reaching the wire).
type NewVHDDifferencingInput ¶
type NewVHDDifferencingInput struct {
Path string `json:"path"`
ParentPath string `json:"parent_path"`
}
NewVHDDifferencingInput is the public input for the Differencing creation mode. SizeBytes and BlockSizeBytes are inherited from the parent and rejected by Hyper-V if supplied; the typed-client method omits them from the wire payload.
type NewVHDDynamicInput ¶
type NewVHDDynamicInput struct {
Path string `json:"path"`
SizeBytes int64 `json:"size_bytes"`
BlockSizeBytes *int64 `json:"block_size_bytes,omitempty"`
}
NewVHDDynamicInput is the public input for the Dynamic creation mode: the same fields as fixed, the discriminator is what differs.
type NewVHDFixedInput ¶
type NewVHDFixedInput struct {
Path string `json:"path"`
SizeBytes int64 `json:"size_bytes"`
BlockSizeBytes *int64 `json:"block_size_bytes,omitempty"`
}
NewVHDFixedInput is the public input for the Fixed creation mode. BlockSizeBytes is *int64 + omitempty so absent leaves the cmdlet default. The discriminator (vhd_type) is set internally by the typed client method, not on the public struct.
type NewVMInput ¶
type NewVMInput struct {
Name string `json:"name"`
Generation int `json:"generation"`
Vcpu int `json:"vcpu"`
MemoryBytes int64 `json:"memory_bytes"`
DynamicMemory *bool `json:"dynamic_memory,omitempty"`
MinMemoryBytes *int64 `json:"min_memory_bytes,omitempty"`
MaxMemoryBytes *int64 `json:"max_memory_bytes,omitempty"`
SecureBoot *bool `json:"secure_boot,omitempty"`
SecureBootTemplate *string `json:"secure_boot_template,omitempty"`
Notes *string `json:"notes,omitempty"`
}
NewVMInput is the stdin JSON format for vm/new.ps1. Required: Name, Generation, Vcpu, MemoryBytes (startup). Optionals use pointer types so missing-vs-explicit-false round-trips correctly: new.ps1 treats an absent key and an explicit null as equivalent (both skip the corresponding Set-*), so omitempty plus a nil pointer yields the cmdlet's default. DynamicMemory opts into Hyper-V's dynamic memory mode; MinMemoryBytes/MaxMemoryBytes only matter when it's true. A nil DynamicMemory defaults to static memory, preserving the behavior for callers that don't manage dynamic memory.
type NewVMSwitchInput ¶
type NewVMSwitchInput struct {
Name string `json:"name"`
SwitchType string `json:"switch_type"`
NetAdapterNames []string `json:"net_adapter_names,omitempty"`
AllowManagementOS *bool `json:"allow_management_os,omitempty"`
Notes *string `json:"notes,omitempty"`
NatName string `json:"nat_name,omitempty"`
NatInternalAddressPrefix string `json:"nat_internal_address_prefix,omitempty"`
NatHostAddress string `json:"nat_host_address,omitempty"`
}
NewVMSwitchInput is the stdin JSON format for vswitch/new.ps1. Required: Name, SwitchType. Optional fields use pointer types so missing-vs-explicit-false round-trips correctly: new.ps1 treats an absent key and an explicit null as equivalent (both skip the splat), so omitempty plus a nil pointer yields the cmdlet's default. NAT fields are required when SwitchType == "NAT" and rejected otherwise; the resource-layer validator enforces this and the script trusts it already happened.
type RemoveImageFileInput ¶ added in v0.5.0
type RemoveImageFileInput struct {
DestinationPath string `json:"path"`
Force bool `json:"force"`
ExpectedSha256 string `json:"expected_sha256"`
}
RemoveImageFileInput is the public input for RemoveImageFile. ExpectedSha256 is the resource's last-known state.sha256; empty skips the drift check (e.g. a caller with no prior state). A non-empty value that no longer matches the on-host file means something else changed the destination since this resource last read it; remove.ps1 refuses the delete rather than removing content this resource no longer recognizes.
type RemoveNatStaticMappingInput ¶ added in v0.3.0
type RemoveNatStaticMappingInput struct {
NatName string `json:"nat_name"`
Protocol string `json:"protocol"`
ExternalIPAddress string `json:"external_ip"`
ExternalPort int `json:"external_port"`
FirewallName string `json:"firewall_name"`
}
RemoveNatStaticMappingInput mirrors GetNatStaticMappingInput -- destroy needs the same lookup tuple plus the firewall display name.
type SetBootOrderEntryInput ¶
type SetBootOrderEntryInput struct {
Type string `json:"type"`
ControllerType string `json:"controller_type"`
ControllerNumber int `json:"controller_number"`
ControllerLocation int `json:"controller_location"`
Name string `json:"name"`
}
SetBootOrderEntryInput is the per-entry format inside SetBootOrderInput.BootOrder, same discriminator pattern as BootOrderEntry: Type drives which subset of fields the script reads. All fields are emitted unconditionally (no omitempty): PowerShell's Set-StrictMode 3.0 throws on access of an absent property on a PSCustomObject, and the script reads $entry.controller_* or $entry.name regardless of Type, so unused fields must still be present on the wire. omitempty on `int` specifically would drop controller_number=0, the most common slot index, and break the resolver.
type SetBootOrderInput ¶
type SetBootOrderInput struct {
Name string `json:"name"`
BootOrder []SetBootOrderEntryInput `json:"boot_order"`
}
SetBootOrderInput is the stdin JSON format for vm/set-boot-order.ps1. BootOrder is the new desired sequence; the script replaces the VM's current order wholesale (Set-VMFirmware -BootOrder is not additive). Each entry mirrors BootOrderEntry above with snake_case keys.
type SetNatStaticMappingInput ¶ added in v0.3.0
type SetNatStaticMappingInput struct {
NatName string `json:"nat_name"`
Protocol string `json:"protocol"`
ExternalIPAddress string `json:"external_ip"`
ExternalPort int `json:"external_port"`
InternalIPAddress string `json:"internal_ip"`
InternalPort int `json:"internal_port"`
Firewall NatStaticMappingFirewallInput `json:"firewall"`
}
SetNatStaticMappingInput is the stdin JSON format for nat_static_mapping/set.ps1, the same fields as NewNatStaticMappingInput: set.ps1 looks up the existing mapping by tuple (nat_name + protocol + external_ip + external_port), then mutates internal_ip/internal_port via Remove + Add and the firewall via Set-NetFirewallRule. The lookup tuple is RequiresReplace at the schema layer; Update only fires when internal_* or firewall.* changes.
type SetVMInput ¶
type SetVMInput struct {
Name string `json:"name"`
Generation int `json:"generation"`
Vcpu *int `json:"vcpu,omitempty"`
MemoryBytes *int64 `json:"memory_bytes,omitempty"`
DynamicMemory *bool `json:"dynamic_memory,omitempty"`
MinMemoryBytes *int64 `json:"min_memory_bytes,omitempty"`
MaxMemoryBytes *int64 `json:"max_memory_bytes,omitempty"`
SecureBoot *bool `json:"secure_boot,omitempty"`
Notes *string `json:"notes,omitempty"`
}
SetVMInput is the stdin JSON format for vm/set.ps1, the same fields as NewVMInput with two differences: Vcpu and MemoryBytes are *int/*int64, since Set is a partial update where only changed fields forward and nil drops them from the JSON (omitempty) so the script skips the corresponding Set-* cmdlet; and Generation is optional on the schema but always forwarded by the Update path, a validation hint for set.ps1's gen-2-only SecureBoot guard, not a mutation.
type SetVMStateInput ¶
type SetVMStateInput struct {
Name string `json:"name"`
Desired string `json:"desired"`
ShutdownMode string `json:"shutdown_mode,omitempty"`
}
SetVMStateInput is the stdin JSON format for vm/set-state.ps1. Desired is the primary mutation: 'Off' invokes Stop-VM, 'Running' invokes Start-VM; other Hyper-V states (Saved, Paused) are out of scope, rejected by the script's ValidateSet. ShutdownMode is optional and only governs the Stop dispatch: "" or "turn_off" (default) runs Stop-VM -TurnOff -Force, a hard power-off with no integration-services dependency; "graceful" runs Stop-VM -Force without -TurnOff, an ACPI shutdown that hangs on guests without integration services. omitempty keeps the format stable for callers that don't care about the mode.
type SetVMSwitchInput ¶
type SetVMSwitchInput struct {
Name string `json:"name"`
SwitchType string `json:"switch_type,omitempty"`
NetAdapterNames []string `json:"net_adapter_names,omitempty"`
AllowManagementOS *bool `json:"allow_management_os,omitempty"`
Notes *string `json:"notes,omitempty"`
NatName string `json:"nat_name,omitempty"`
}
SetVMSwitchInput is the stdin JSON format for vswitch/set.ps1. SwitchType is optional here, a validation hint rather than a mutation: the Update path should populate it from prior state so set.ps1's Private + AllowManagementOS guard fires with a clear error. Only keys present in the input forward to Set-VMSwitch; nil/null means leave it alone, a value means set it. NatName is forwarded for NAT switches so set.ps1 can route the read-back through Get-NetNat + Get-NetIPAddress; every NAT-specific input is RequiresReplace, so Notes is the only in-place mutation Update reaches for a NAT switch.
type VHD ¶
type VHD struct {
Path string `json:"Path"`
VhdType string `json:"VhdType"`
SizeBytes int64 `json:"SizeBytes"`
FileSizeBytes int64 `json:"FileSizeBytes"`
BlockSizeBytes int64 `json:"BlockSizeBytes"`
ParentPath string `json:"ParentPath"`
Format string `json:"Format"`
Attached bool `json:"Attached"`
}
VHD is the canonical read format vhd/{get,new,set}.ps1 emits. SizeBytes is the declared logical size; FileSizeBytes is the actual on-disk size (smaller than SizeBytes for dynamic and differencing). ParentPath is empty unless VhdType is "Differencing".
type VHDPath ¶ added in v0.3.0
type VHDPath struct {
Path string `json:"Path"`
}
VHDPath is the minimal format vhd/list.ps1 emits per result. Path-only because the sweeper's RemoveVHD call only needs it; more fields would mean slower enumeration on a directory with many files and a wider blast radius for script-Go contract drift.
type VM ¶
type VM struct {
Name string `json:"Name"`
ID string `json:"Id"`
Generation int `json:"Generation"`
ProcessorCount int `json:"ProcessorCount"`
MemoryStartupBytes int64 `json:"MemoryStartupBytes"`
MemoryAssignedBytes int64 `json:"MemoryAssignedBytes"`
MemoryDynamicEnabled bool `json:"MemoryDynamicEnabled"`
MemoryMinimumBytes *int64 `json:"MemoryMinimumBytes"`
MemoryMaximumBytes *int64 `json:"MemoryMaximumBytes"`
State string `json:"State"`
Notes string `json:"Notes"`
Path string `json:"Path"`
SecureBootEnabled *bool `json:"SecureBootEnabled"`
SecureBootTemplate string `json:"SecureBootTemplate"`
HardDiskDrives []HardDiskDrive `json:"HardDiskDrives"`
NetworkAdapters []NetworkAdapter `json:"NetworkAdapters"`
DvdDrives []DvdDrive `json:"DvdDrives"`
BootOrder []BootOrderEntry `json:"BootOrder"`
}
VM is the canonical read format vm/{get,new,set}.ps1 emits. SecureBootEnabled is *bool because gen 1 VMs return null (BIOS-based, no Secure Boot concept); gen 2 always returns a real bool. HardDiskDrives, NetworkAdapters, and DvdDrives are always (possibly empty) slices: the script-side @() wrapper guarantees a JSON array even when nothing is attached, so a freshly-created VM with no attachments round-trips as "[]" rather than null.
type VMHost ¶
type VMHost struct {
ComputerName string `json:"ComputerName"`
LogicalProcessorCount int64 `json:"LogicalProcessorCount"`
MemoryCapacity int64 `json:"MemoryCapacity"`
VirtualMachinePath string `json:"VirtualMachinePath"`
VirtualHardDiskPath string `json:"VirtualHardDiskPath"`
}
VMHost mirrors the subset of Get-VMHost output the provider exposes. Field tags match the PowerShell property names emitted by Get-VMHost.
type VMName ¶ added in v0.3.0
type VMName struct {
Name string `json:"Name"`
}
VMName is the minimal format vm/list.ps1 emits per result. Only Name is carried because the sweeper (the sole caller today) only needs it to call RemoveVM; a future caller needing more should add a separate verb rather than fattening this one.
type VMSwitch ¶
type VMSwitch struct {
Name string `json:"Name"`
SwitchType string `json:"SwitchType"`
AllowManagementOS bool `json:"AllowManagementOS"`
NetAdapterInterfaceDescription string `json:"NetAdapterInterfaceDescription"`
Notes string `json:"Notes"`
ID string `json:"Id"`
NatName string `json:"NatName"`
NatInternalAddressPrefix string `json:"NatInternalAddressPrefix"`
NatHostAddress string `json:"NatHostAddress"`
}
VMSwitch is the canonical read format vswitch/{get,new,set}.ps1 emits. Field tags use PascalCase to match Get-VMSwitch's native output (the stdin convention is snake_case per the wire contract; stdout is the raw cmdlet output the typed client consumes as-is). SwitchType reads as "External", "Internal", "Private", or the synthesized "NAT" -- Hyper-V's underlying enum has no NAT type, so the script reports SwitchType=NAT only when the caller passes nat_name and the matching NetNat + NetIPAddress are both present on the host; NAT fields are empty strings for non-NAT switches.
type VMSwitchName ¶ added in v0.3.0
type VMSwitchName struct {
Name string `json:"Name"`
}
VMSwitchName is the minimal format vswitch/list.ps1 emits per result. Only Name is carried because the sweeper (the sole caller today) passes name + empty natName to RemoveVMSwitch; the existing acctest bar uses Private + Internal switches only, so empty natName is correct for everything the sweeper currently encounters. NAT-switch sweep support (which would need NatName carried alongside) is a follow-up when NAT acctests land. Symmetric with VMName.