diff --git a/packer/windowsserver2019.json b/packer/windowsserver2019.json index 25cbf46..45270d2 100644 --- a/packer/windowsserver2019.json +++ b/packer/windowsserver2019.json @@ -218,10 +218,12 @@ "only": ["srv2019-v"], "type": "shell-local", "inline": [ +"cat '/scratch/srv2019-v/{{user `vm_guestos`}}-{{user `vm_name`}}-v.ovf'", "pwsh -command \"& scripts/Update-OvfConfiguration.ps1 \\", " -OVFFile '/scratch/srv2019-v/{{user `vm_guestos`}}-{{user `vm_name`}}-v.ovf' \\", " -Parameter @{'appliance.name'='{{user `vm_guestos`}}';'appliance.version'='{{user `vm_name`}}'}\"", - "pwsh -file scripts/Update-Manifest.ps1 \\", +"cat '/scratch/srv2019-v/{{user `vm_guestos`}}-{{user `vm_name`}}-v.ovf'", + "pwsh -file scripts/Update-Manifest.ps1 \\", " -ManifestFileName '/scratch/srv2019-v/{{user `vm_guestos`}}-{{user `vm_name`}}-v.mf'", "ovftool --acceptAllEulas --allowExtraConfig --overwrite \\", " '/scratch/srv2019-v/{{user `vm_guestos`}}-{{user `vm_name`}}-v.ovf' \\", diff --git a/scripts/Update-OvfConfiguration.ps1 b/scripts/Update-OvfConfiguration.ps1 index c0fc01f..f1eddd0 100644 --- a/scripts/Update-OvfConfiguration.ps1 +++ b/scripts/Update-OvfConfiguration.ps1 @@ -47,7 +47,102 @@ $GetContentSplat = @{ } $XML = [xml](Get-Content @GetContentSplat) $NS = [System.Xml.XmlNamespaceManager]$XML.NameTable -[void]$NS.AddNamespace('Any', $XML.DocumentElement.xmlns) +[void]$NS.AddNamespace('ns', $XML.DocumentElement.xmlns) +[void]$NS.AddNamespace('ovf', $XML.DocumentElement.ovf) + +ForEach ($ReferencedDisk in $OVFConfig.Disks.Referenced) { + $XMLDisk = $XML.SelectSingleNode("//ns:DiskSection/ns:Disk[@ovf:diskId='$($ReferencedDisk.Id)']") + If ($XMLDisk.Count -eq 1) { + Switch ($ReferencedDisk.UnitSize) { + 'KB' { + $CapacityInBytes = $ReferencedDisk.Capacity * 1KB + } + 'MB' { + $CapacityInBytes = $ReferencedDisk.Capacity * 1MB + } + 'GB' { + $CapacityInBytes = $ReferencedDisk.Capacity * 1GB + } + 'TB' { + $CapacityInBytes = $ReferencedDisk.Capacity * 1TB + } + 'PB' { + $CapacityInBytes = $ReferencedDisk.Capacity * 1PB + } + default { + # Invalid UnitSize; skipping modification of existing disk + Continue + } + } + + # Determine if specified size is equal or larger than allocated size + If ($XMLDisk.populatedSize -le $CapacityInBytes) { + [void]$XMLDisk.SetAttribute('ovf:capacity', $CapacityInBytes) + } + } +} +ForEach ($DynamicDisk in $OVFConfig.Disks.Dynamic) { + # Determine next free available diskId + $XMLDisks = $XML.SelectNodes("//ns:DiskSection/ns:Disk[contains(@ovf:diskId,'vmdisk')]") + $DiskId = $XMLDisks.Count + 1 + While ($XMLDisks.DiskId -contains "vmdisk$($DiskId)") { + $DiskId++ + } + + $XMLDisk = $XML.CreateElement('Disk', $XML.DocumentElement.xmlns) + $XMLDiskAttrUnits = $XML.CreateAttribute('capacityAllocationUnits', $XML.DocumentElement.ovf) + Switch ($DynamicDisk.UnitSize) { + 'KB' { + $Powers = 10 + } + 'MB' { + $Powers = 20 + } + 'GB' { + $Powers = 30 + } + 'TB' { + $Powers = 40 + } + 'PB' { + $Powers = 50 + } + default { + # Invalid UnitSize; skipping modification of existing disk + Continue + } + } + $XMLDiskAttrUnits.Value = "byte * 2^$($Powers)" + $XMLDiskAttrFormat.CreateAttribute('format', $XML.DocumentElement.ovf) + $XMLDiskAttrFormat.Value = 'http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized' + $XMLDiskId.CreateAttribute('diskId', $XML.DocumentElement.ovf) + $XMLDiskId.Value = "vmdisk$($DiskId)" + $XMLDiskAttrCapacity.CreateAttribute('capacity', $XML.DocumentElement.ovf) + $XMLDiskAttrCapacity.Value = '${{vmconfig.disksize.{0}}}' -f $DiskId + $XMLDiskAttrPopulated.CreateAttribute('populatedSize', $XML.DocumentElement.ovf) + $XMLDiskAttrPopulated.Value = 0 + + [void]$XMLDisk.Attributes.Append($XMLDiskAttrUnits) + [void]$XMLDisk.Attributes.Append($XMLDiskAttrFormat) + [void]$XMLDisk.Attributes.Append($XMLDiskId) + [void]$XMLDisk.Attributes.Append($XMLDiskAttrCapacity) + [void]$XMLDisk.Attributes.Append($XMLDiskAttrPopulated) + + $OVFConfig.PropertyCategories[0].ProductProperties += @{ + Key = "vmconfig.disksize.$($DiskId)" + Type = If ([boolean]$DynamicDisk.Constraints.Minimum -or [boolean]$DynamicDisk.Constraints.Maximum) { + "Int($($DynamicDisk.Constraints.Minimum)..$($DynamicDisk.Constraints.Maximum))" + } + Else { + 'Int' + } + Label = "Disk $($DiskId) size*" + Description = "$($DynamicDisk.Description) (in $($DynamicDisk.UnitSize))".Trim() + DefaultValue = "$($DynamicDisk.Constraints.Minimum)" + Configurations = '*' + UserConfigurable = 'true' + } +} If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { $XMLSection = $XML.CreateElement('DeploymentOptionSection', $XML.DocumentElement.xmlns) @@ -73,13 +168,13 @@ If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { [void]$XMLSection.AppendChild($XMLConfig) } - [void]$XML.SelectSingleNode('//Any:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//Any:NetworkSection', $NS)) + [void]$XML.SelectSingleNode('//ns:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//ns:NetworkSection', $NS)) Write-Host "Inserted 'DeploymentOptionSection' with $($Configuration.Count) nodes" } $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) $XMLAttrTransport.Value = 'com.vmware.guestInfo' -[void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).Attributes.Append($XMLAttrTransport) +[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).Attributes.Append($XMLAttrTransport) ForEach ($ExtraConfig in $OVFConfig.AdvancedOptions) { $XMLExtraConfig = $XML.CreateElement('vmw:ExtraConfig', $XML.DocumentElement.vmw) @@ -93,17 +188,17 @@ ForEach ($ExtraConfig in $OVFConfig.AdvancedOptions) { [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrRequired) [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrKey) [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrValue) - [void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).AppendChild($XMLExtraConfig) + [void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).AppendChild($XMLExtraConfig) } Write-Host "Added $($OVFConfig.AdvancedOptions.Count) 'vmw:ExtraConfig' nodes" -$XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS) +$XMLProductSection = $XML.SelectSingleNode('//ns:ProductSection', $NS) If ($XMLProductSection -eq $Null) { $XMLProductSection = $XML.CreateElement('ProductSection', $XML.DocumentElement.xmlns) - [void]$XML.SelectSingleNode('//Any:VirtualSystem', $NS).AppendChild($XMLProductSection) + [void]$XML.SelectSingleNode('//ns:VirtualSystem', $NS).AppendChild($XMLProductSection) Write-Host "Inserted 'ProductSection'" } Else { - ForEach ($Child in $XMLProductSection.SelectNodes('//Any:ProductSection/child::*', $NS)) { + ForEach ($Child in $XMLProductSection.SelectNodes('//ns:ProductSection/child::*', $NS)) { [void]$Child.ParentNode.RemoveChild($Child) } Write-Host "Destroyed pre-existing children in 'ProductSection'" diff --git a/scripts/Update-OvfConfiguration.yml b/scripts/Update-OvfConfiguration.yml index 3c3abc7..5e8aa5d 100644 --- a/scripts/Update-OvfConfiguration.yml +++ b/scripts/Update-OvfConfiguration.yml @@ -5,6 +5,22 @@ DeploymentConfigurations: - Id: standalone Label: Stand-alone Description: Stand-alone Windows Server +Disks: + Referenced: + - Id: vmdisk1 + UnitSize: GB + Capacity: 50 + Dynamic: + - Description: Data + UnitSize: GB + Constraints: + Minimum: 10 + Maximum: 500 + - Description: Scratch + UnitSize: GB + Constraints: + Minimum: 5 + Maximum: '' PropertyCategories: - Name: 0) Deployment information ProductProperties: