...
If you need an another Windows Version, you must build the image yourself, with good help from the automated cloudbase-scripts. It is recommended to create the image on a Windows 10 host or VMThe example script given in this article will only work on Hyper-V enabled physical host (Windows 10 or a Server varian). The following examples is a list of what we did to create a cloud ready Windows 10 Server 2019 image.
- Install the the latest Windows 10 ADK (download) and choose only Deployment Tools
- Download the Windows 10 Enterprise Evaluation ISO, and mount save it in your host/VM (you need to login with your Microsoft account to download ISOs)
- Download the stable amd64 virto-win iso, following this link
- Download the Windows OpenStack Imaging Tools
- Remember to download the WindowsUpdates tools referenced in the repo as well. This must be done separately.
- Change the following:
UnattendTemplate.xml: Change
InputLocale
andUserLocale
fromen-US
tonb-NO
- Added ntnu_wallpaper.png to the
UnattendResources
-folder - UnattendResources\Specialize.ps1:
- Change the line with
Wallpaper.png
tontnu_wallpaper.png
(do not change the destination filename in the copy-command, as the wallpaper is set through an imported local GPO)
- Change the line with
- We've added two custom scripts to the image build. These scripts must be named exactly what they are named in the following examples, as the names dictate when in the building process they will run. Set the path to the scripts in the "custom_scripts_path" section in the wrapper script in step 7.
We provide Windows Server images with the KMS activiation key injected. To make that work, we need to set the DNS Search Suffix. This will only run on servers, as we are not allowed to use KMS for Client SKUs
Code Block language powershell title RunBeforeCloudbaseInitInstall.ps1 collapse true # Set DNS Search Suffix to NTNUs windows domain # This is a requirement in order to do KMS activation in the images # This should only run on Server SKUs and on non-eval versions! if ((Get-ComputerInfo).OsProductType -eq 'Server') { if( -Not ((Get-WindowsEdition -Online).Edition).Contains('Eval') ) { Set-DnsClientGlobalSetting -SuffixSearchList @('win.ntnu.no') } }
Openstack Neutron expects all instances to use EUI-64 for IPv6 auto configuration. EUI-64 is not the default in Windows, so we need to enable it (and disable the other magic stuff)
UnattendResources\Logon.ps1:Add the following to commands:Code Block language powershell title RunBeforeSysprep.ps1 collapse true # Enable EUI-64 and disable all other trickery Write-Host "Enabling EUI-64" Set-NetIPv6Protocol -RandomizeIdentifiers Disabled -UseTemporaryAddresses Disabled
netsh advfirewall firewall add rule name="All ICMP V4" protocol=icmpv4:any,any dir=in action=allow
andnetsh advfirewall firewall add rule name="All ICMP V6" protocol=icmpv6:any,any dir=in action=allow
- Create the following powershell-script, modify the three path-variables, and run it:
Code Block language powershell title CreateOpenStackImage.ps1 linenumbers true collapse true Import-Module .c:\dev\windows-openstack-imaging-tools-master\WinImageBuilder.psm1 $virtualDiskPath = "C:\path\to\diskfile.raw" $wimFilePath = "<windowsiso-mountpoint>\sources\install.wim>Import-Module C:\dev\windows-openstack-imaging-tools-master\Config.psm1 Import-Module C:\dev\windows-openstack-imaging-tools-master\UnattendResources\ini.psm1 function Set-Config { param($file, $section, $key, $value) Set-IniFileValue -Path (Resolve-Path $file) -Section $section ` -Key $key ` -Value $value } $date = Get-Date -UFormat "%Y%m%d" $virtualDiskPath = "C:\dev\images\WS2019_Standard_Eval_$date.qcow2" $virtIOISOPath = "C:\pathiso\to\virtio-win-x.x.xxx.iso" 0.1.160.iso" $winISOPath = "C:\iso\17763.1.180914-1434.rs5_release_SERVER_EVAL_x64FRE_en-us.iso" $mountResult = Mount-DiskImage -ImagePath $winISOPath -StorageType ISO -PassThru $imageDrive = ($mountResult | Get-Volume).DriveLetter $wimFilePath = "${imageDrive}:\sources\install.wim" $diskSize = 40GB $ramSize = 4GB # Check which SKU from the WimFile you want, and specify the corresponding index to $image $images = Get-WimFileImagesInfo -WimFilePath $wimFilePath $image = $images[01] $configfile = '.\config.ini' New-WindowsCloudImage -WimFilePath $wimFilePath -ImageName $image.ImageName -VirtualDiskFormat RAW -VirtualDiskPath $virtualDiskPath -SizeBytes 18GB -VirtIOISOPath $virtIOISOPath -InstallUpdates
You now have a .raw diskfile, which contains a Windows 10-installation that will automatically run sysprep once booted. Now you have to choices:
- Import the .raw file to glance (see Upload new images), and spawn an instance from the new image
- Create a new local KVM-vm (on a Linux host), be sure to choose a virtio NIC, attach the .raw-file, boot the VM
- Wait for the instance to shutdown (it will install updates, run the powershellscripts
Logon.ps1
,FirstLogon.ps1
andSpecialize.ps1
and finally run sysprep - If you chose 8a, create a public snapshot of the instance. This snapshot is your new cloud ready Windows 10 image.
-WindowsImageConfig -ConfigFilePath $configfile if ( ! (Test-Path C:\dev\images) ) { New-Item C:\dev\images -Type Directory } Set-Config -file $configfile -section "DEFAULT" -key "wim_file_path" -value $wimFilePath Set-Config -file $configfile -section "DEFAULT" -key "image_name" -value $image.ImageName Set-Config -file $configfile -section "DEFAULT" -key "image_path" -value $virtualDiskPath Set-Config -file $configfile -section "DEFAULT" -key "virtual_disk_format" -value "QCOW2" Set-Config -file $configfile -section "DEFAULT" -key "image_type" -value "KVM" Set-Config -file $configfile -section "DEFAULT" -key "disk_layout" -value "BIOS" Set-Config -file $configfile -section "DEFAULT" -key "custom_scripts_path" -value "C:\dev\custom" Set-Config -file $configfile -section "DEFAULT" -key "wallpaper_solid_color" -value "0 0 0" Set-Config -file $configfile -section "DEFAULT" -key "enable_ping_requests" -value "True" Set-Config -file $configfile -section "DEFAULT" -key "enable_ipv6_eui64" -value "True" Set-Config -file $configfile -section "DEFAULT" -key "enable_active_mode" -value "True" # This is the KMS key config. 'default_kms_key' will grab the correct key automatically #Set-Config -file $configfile -section "DEFAULT" -key "product_key" -value "default_kms_key" Set-Config -file $configfile -section "vm" -key "external_switch" -value "ext-net" Set-Config -file $configfile -section "vm" -key "cpu_count" -value $cpuCount Set-Config -file $configfile -section "vm" -key "ram_size" -value $ramSize Set-Config -file $configfile -section "vm" -key "disk_size" -value $diskSize Set-Config -file $configfile -section "drivers" -key "virtio_iso_path" -value $virtIOISOPath Set-Config -file $configfile -section "updates" -key "install_updates" -value "False" Set-Config -file $configfile -section "updates" -key "purge_updates" -value "False" Set-Config -file $configfile -section "cloudbase_init" -key "beta_release" -value "False" Set-Config -file $configfile -section "custom" -key "time_zone" -value "W. Europe Standard Time" # Check if we are on a Hyper-V enabled host if ( $(Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V).State -eq "Enabled" ) { New-WindowsOnlineImage -ConfigFilePath $configfile } else { Write-Host "This script only works on Hyper-V enabled hosts" } Dismount-DiskImage -InputObject $mountResult
You now have a .qcow2 diskfile, which contains an updated and sysprepped Windows-installation with cloud-init installed
Convert the qcow2 disk to raw
Code Block qemu-img convert -f qcow2 -O raw disk.qcow2 disk.raw
The raw image can now be imported to glance.
- Set property os_type=windows on all images
- Set property os_distro=windows on KMS-Licensed images
When you spawn a Windows instance, be sure to attach a keypair. Cloudbase-init will generate a random password for the user Admin
, which can be retrieved with:
Code Block | ||
---|---|---|
| ||
nova get-password <instance-id> <private-key-file> |
The password can also be retrieved in Horizon through the "Retrieve password" action on the instance.
NOTE: There is a known issue with Windows 10 - the hostname will not be set to wahtever you chose for instance name. This might be fixed in the future... (Link)
KMS keys
We are allowed to provide Windows Server images which will use KMS for automatic activation. The KMS keys are global, and here is a list of the SKUs we care about:
SKU | KMS key |
---|---|
Windows Server 2012 R2 Standard | D2N9P-3P6X9-2R39C-7RTCD-MDVJX |
Windows Server 2016 Standard | WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY |
Windows Server 2019 Standard | N69G4-B89J2-4G8F4-WWYCC-J464C |
Windows Server 2022 Standard | VDYBN-27WPP-V4HQT-9VMD4-VMK7H |