diff --git a/docs/book/src/capi/providers/oci.md b/docs/book/src/capi/providers/oci.md index 8306046996..08338c865a 100644 --- a/docs/book/src/capi/providers/oci.md +++ b/docs/book/src/capi/providers/oci.md @@ -31,7 +31,8 @@ the different operating systems. | `ubuntu-1804.json` | The settings for the Ubuntu 18.04 image | | `ubuntu-2004.json` | The settings for the Ubuntu 20.04 image | | `ubuntu-2204.json` | The settings for the Ubuntu 22.04 image | - +| `windows-2019.json` | The settings for the Windows Server 2019 image | +| `windows-2022.json` | The settings for the Windows Server 2022 image | #### Common options @@ -42,6 +43,7 @@ list, and greater explanation can be found in the | Variable | Description | Default | Mandatory | |----------|-------------|---------|---------| +| `base_image_ocid` | The OCID of an existing image to build upon. | | No | | `compartment_ocid` | The OCID of the compartment that the instance will run in. | | Yes | | `subnet_ocid` | The OCID of the subnet within which a new instance is launched and provisioned. | | Yes | | `availability_domain` | The name of the Availability Domain within which a new instance is launched and provisioned. The names of the Availability Domains have a prefix that is specific to your tenancy. | | Yes | @@ -83,4 +85,39 @@ is defined in images/capi/packer/config/containerd.json. "kubernetes_rpm_repo": "https://packages.cloud.google.com/yum/repos/kubernetes-el7-aarch64", "containerd_sha256": "9ac616b5f23c1d10353bd45b26cb736efa75dfef31a2113baff2435dbc7becb8" } +``` + +### Building a Windows image + +> NOTE: In order to use Windows with CAPI a Baremetal instance is required. This means a Baremetal instance is required for building the image as well. The OCIDs for the 2019 +and 2022 Datacenter edition of Windows can be found in their respective documentation: +> +> - [Windows server 2019](https://docs.oracle.com/en-us/iaas/images/windows-server-2019-bm/) +> - [Windows server 2022](https://docs.oracle.com/en-us/iaas/images/windows-server-2022-bm/) + +#### Windows environment variables + +| Variable | Description | Default | Mandatory | +|----------|-------------|---------|---------| +| `OPC_USER_PASSWORD` | The password to set the OPC user to when creating the image. This will be used for accessing instances using this image. | | Yes | + +> NOTE: The `OPC_USER_PASSWORD` will be set in the `winrm_bootstrap.txt` file temporarily, while building the image. + This is required in order for winrm to access the instance building the image. Once the build process is complete + the password will be deleted along with the fil so the password isn't stored long term in a cleartext file. + +#### Build a Windows based image + +The following example json would use the [Windows Server 2019 Datacenter Edition BM E4 image in the us-ashburn-1 region](https://docs.oracle.com/en-us/iaas/images/image/4d56c93a-2165-49b0-9c6e-f9e9a9b05011/). + +```json +{ + "build_name": "windows", + "base_image_ocid": "", + "ocpus": "128", + "shape": "BM.Standard.E4.128", + "region": "us-ashburn-1", + "compartment_ocid": "Fill compartment OCID here", + "subnet_ocid": "Fill Subnet OCID here", + "availability_domain": "Fill Availability Domain here" +} ``` \ No newline at end of file diff --git a/images/capi/Makefile b/images/capi/Makefile index 318ca802f2..2ced6c325d 100644 --- a/images/capi/Makefile +++ b/images/capi/Makefile @@ -322,7 +322,7 @@ AZURE_BUILD_VHD_NAMES ?= $(addprefix azure-vhd-,$(VHD_TARGETS)) AZURE_BUILD_SIG_NAMES ?= $(addprefix azure-sig-,$(SIG_TARGETS)) AZURE_BUILD_SIG_GEN2_NAMES ?= $(addsuffix -gen2,$(addprefix azure-sig-,$(SIG_GEN2_TARGETS))) -OCI_BUILD_NAMES ?= oci-ubuntu-1804 oci-ubuntu-2004 oci-ubuntu-2204 oci-oracle-linux-8 oci-oracle-linux-9 +OCI_BUILD_NAMES ?= oci-ubuntu-1804 oci-ubuntu-2004 oci-ubuntu-2204 oci-oracle-linux-8 oci-oracle-linux-9 oci-windows-2019 oci-windows-2022 DO_BUILD_NAMES ?= do-centos-7 do-ubuntu-1804 do-ubuntu-2004 @@ -485,7 +485,9 @@ $(RAW_VALIDATE_TARGETS): deps-raw .PHONY: $(OCI_BUILD_TARGETS) $(OCI_BUILD_TARGETS): deps-oci - packer build $(PACKER_NODE_FLAGS) -var-file="$(abspath packer/oci/$(subst build-oci-,,$@).json)" $(ABSOLUTE_PACKER_VAR_FILES) packer/oci/packer.json + $(if $(findstring windows,$@),./packer/oci/scripts/set_bootstrap.sh,) + packer build $(if $(findstring windows,$@),$(PACKER_WINDOWS_NODE_FLAGS),$(PACKER_NODE_FLAGS)) -var-file="$(abspath packer/oci/$(subst build-oci-,,$@).json)" $(ABSOLUTE_PACKER_VAR_FILES) packer/oci/packer$(findstring -windows,$@).json + $(if $(findstring windows,$@),./packer/oci/scripts/unset_bootstrap.sh,) .PHONY: $(OCI_VALIDATE_TARGETS) $(OCI_VALIDATE_TARGETS): deps-oci @@ -678,6 +680,8 @@ build-oci-ubuntu-2004: ## Builds the OCI ubuntu-2004 image build-oci-ubuntu-2204: ## Builds the OCI ubuntu-2204 image build-oci-oracle-linux-8: ## Builds the OCI Oracle Linux 8.x image build-oci-oracle-linux-9: ## Builds the OCI Oracle Linux 9.x image +build-oci-windows-2019: ## Builds the OCI Windows Server 2019 image +build-oci-windows-2022: ## Builds the OCI Windows Server 2022 image build-oci-all: $(OCI_BUILD_TARGETS) ## Builds all OCI image build-osc-ubuntu-2004: ## Builds Ubuntu 20.04 Outscale Snapshot @@ -790,6 +794,8 @@ validate-oci-ubuntu-2004: ## Validates the OCI ubuntu-2004 image packer config validate-oci-ubuntu-2204: ## Validates the OCI ubuntu-2204 image packer config validate-oci-oracle-linux-8: ## Validates the OCI Oracle Linux 8.x image packer config validate-oci-oracle-linux-9: ## Validates the OCI Oracle Linux 9.x image packer config +validate-oci-windows-2019: ## Validates the OCI Windows 2019 image packer config +validate-oci-windows-2022: ## Validates the OCI Windows 2022 image packer config validate-oci-all: $(OCI_VALIDATE_TARGETS) ## Validates all OCI image packer config validate-osc-ubuntu-2004: ## Validates Ubuntu 20.04 Outscale Snapshot Packer config diff --git a/images/capi/ansible/windows/roles/cloudbase-init/templates/cloudbase-init.conf b/images/capi/ansible/windows/roles/cloudbase-init/templates/cloudbase-init.conf index 2c6dd6280d..6732db7c21 100644 --- a/images/capi/ansible/windows/roles/cloudbase-init/templates/cloudbase-init.conf +++ b/images/capi/ansible/windows/roles/cloudbase-init/templates/cloudbase-init.conf @@ -32,8 +32,5 @@ ephemeral_disk_volume_label="Temporary Storage" netbios_host_name_compatibility={{ netbios_host_name_compatibility }} metadata_services={{ cloudbase_metadata_services }} -plugins=cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, - cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, - cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, - cloudbaseinit.plugins.common.userdata.UserDataPlugin, +plugins=cloudbaseinit.plugins.common.userdata.UserDataPlugin, {{ cloudbase_plugins }} diff --git a/images/capi/packer/ami/packer-windows.json b/images/capi/packer/ami/packer-windows.json index afb60923f6..f0373dcdd3 100644 --- a/images/capi/packer/ami/packer-windows.json +++ b/images/capi/packer/ami/packer-windows.json @@ -176,7 +176,7 @@ "cloudbase_init_url": "https://github.com/cloudbase/cloudbase-init/releases/download/{{user `cloudbase_init_version`}}/CloudbaseInitSetup_{{user `cloudbase_init_version` | replace_all `.` `_` }}_x64.msi", "cloudbase_metadata_services": "cloudbaseinit.metadata.services.ec2service.EC2Service", "cloudbase_metadata_services_unattend": "cloudbaseinit.metadata.services.base.EmptyMetadataService", - "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin", + "cloudbase_plugins": "cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin", "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", "containerd_sha256": null, "containerd_url": "", diff --git a/images/capi/packer/azure/packer-windows.json b/images/capi/packer/azure/packer-windows.json index a46ff46d5c..ae5d815afe 100644 --- a/images/capi/packer/azure/packer-windows.json +++ b/images/capi/packer/azure/packer-windows.json @@ -206,7 +206,7 @@ "cloudbase_logging_serial_port": "COM2,115200,N,8", "cloudbase_metadata_services": "cloudbaseinit.metadata.services.azureservice.AzureService", "cloudbase_metadata_services_unattend": "cloudbaseinit.metadata.services.base.EmptyMetadataService", - "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.windows.azureguestagent.AzureGuestAgentPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin", + "cloudbase_plugins": "cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.windows.azureguestagent.AzureGuestAgentPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin", "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", "community_gallery_image_id": "", "containerd_url": "", diff --git a/images/capi/packer/nutanix/packer-windows.json b/images/capi/packer/nutanix/packer-windows.json index abee974723..655826095a 100644 --- a/images/capi/packer/nutanix/packer-windows.json +++ b/images/capi/packer/nutanix/packer-windows.json @@ -120,7 +120,7 @@ "cloudbase_init_url": "https://github.com/cloudbase/cloudbase-init/releases/download/{{user `cloudbase_init_version`}}/CloudbaseInitSetup_{{user `cloudbase_init_version` | replace_all `.` `_` }}_x64.msi", "cloudbase_metadata_services": "cloudbaseinit.metadata.services.configdrive.ConfigDriveService", "cloudbase_metadata_services_unattend": "cloudbaseinit.metadata.services.base.EmptyMetadataService", - "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", + "cloudbase_plugins": "cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", "containerd_sha256": null, "containerd_url": "", diff --git a/images/capi/packer/oci/packer-windows.json b/images/capi/packer/oci/packer-windows.json new file mode 100644 index 0000000000..c9ee812ed6 --- /dev/null +++ b/images/capi/packer/oci/packer-windows.json @@ -0,0 +1,148 @@ +{ + "builders": [ + { + "availability_domain": "{{user `availability_domain`}}", + "base_image_filter": { + "operating_system": "{{user `operating_system`}}", + "operating_system_version": "{{user `operating_system_version`}}" + }, + "base_image_ocid": "{{user `base_image_ocid`}}", + "communicator": "winrm", + "compartment_ocid": "{{user `compartment_ocid`}}", + "image_name": "cluster-api-{{user `build_name`}}-{{user `kubernetes_semver`}}-{{user `build_timestamp`}}", + "shape": "{{user `shape`}}", + "shape_config": { + "ocpus": "{{user `ocpus`}}" + }, + "subnet_ocid": "{{user `subnet_ocid`}}", + "tenancy_ocid": "{{user `tenancy_ocid`}}", + "type": "oracle-oci", + "user_data_file": "packer/oci/scripts/winrm_bootstrap.txt", + "user_ocid": "{{user `user_ocid`}}", + "winrm_insecure": true, + "winrm_password": "{{user `opc_user_password`}}", + "winrm_port": 5986, + "winrm_timeout": "10m", + "winrm_use_ntlm": true, + "winrm_use_ssl": true, + "winrm_username": "opc" + } + ], + "post-processors": [ + { + "custom_data": { + "build_date": "{{isotime}}", + "build_name": "{{user `build_name`}}", + "build_timestamp": "{{user `build_timestamp`}}", + "build_type": "node", + "containerd_version": "{{user `containerd_version`}}", + "kubernetes_cni_semver": "{{user `kubernetes_cni_semver`}}", + "kubernetes_semver": "{{user `kubernetes_semver`}}", + "kubernetes_source_type": "{{user `kubernetes_source_type`}}", + "os_name": "{{user `distro_name`}}", + "resource_group_name": "{{user `resource_group_name`}}", + "storage_account_name": "{{user `storage_account_name`}}" + }, + "output": "{{user `manifest_output`}}", + "strip_path": true, + "type": "manifest" + } + ], + "provisioners": [ + { + "elevated_password": "{{.WinRMPassword}}", + "elevated_user": "opc", + "script": "ansible/windows/ansible_winrm.ps1", + "type": "powershell" + }, + { + "extra_arguments": [ + "-e", + "ansible_winrm_server_cert_validation=ignore ansible_winrm_operation_timeout_sec=120 ansible_winrm_read_timeout_sec=150", + "--extra-vars", + "{{user `ansible_common_vars`}}", + "--extra-vars", + "{{user `azure_extra_vars`}}", + "--extra-vars", + "{{user `ansible_extra_vars`}}", + "--extra-vars", + "{{user `ansible_user_vars`}}" + ], + "max_retries": 5, + "pause_before": "15s", + "playbook_file": "ansible/windows/node_windows.yml", + "type": "ansible", + "use_proxy": false, + "user": "opc" + }, + { + "restart_timeout": "10m", + "type": "windows-restart" + }, + { + "destination": "C:\\Users\\opc\\", + "source": "./packer/oci/scripts/sysprep.ps1", + "type": "file" + }, + { + "destination": "C:\\Users\\opc\\", + "source": "./packer/oci/scripts/attach_secondary_vnic.ps1", + "type": "file" + }, + { + "destination": "C:\\Windows\\Setup\\Scripts\\", + "source": "./packer/oci/scripts/enable_second_nic.ps1", + "type": "file" + }, + { + "inline": [ + "rm -Force -Recurse C:\\var\\log\\kubelet\\*" + ], + "type": "powershell" + }, + { + "elevated_password": "{{.WinRMPassword}}", + "elevated_user": "opc", + "inline": [ + "C:\\Users\\opc\\sysprep.ps1" + ], + "type": "powershell" + } + ], + "variables": { + "additional_debug_files": null, + "ansible_common_vars": "", + "ansible_extra_vars": "", + "ansible_user_vars": "", + "azure_extra_vars": "wire_server_users={{user `wire_server_users`}}", + "build_name": null, + "build_timestamp": "{{timestamp}}", + "cloudbase_init_url": "https://github.com/cloudbase/cloudbase-init/releases/download/{{user `cloudbase_init_version`}}/CloudbaseInitSetup_{{user `cloudbase_init_version` | replace_all `.` `_` }}_x64.msi", + "cloudbase_logging_serial_port": "COM1,9600,N,8", + "cloudbase_metadata_services": "cloudbaseinit.metadata.services.httpservice.HttpService", + "cloudbase_metadata_services_unattend": "cloudbaseinit.metadata.services.httpservice.HttpService", + "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin", + "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", + "containerd_url": "", + "containerd_version": null, + "ib_version": "{{env `IB_VERSION`}}", + "image_version": "latest", + "kubernetes_base_url": "https://kubernetesreleases.blob.core.windows.net/kubernetes/{{user `kubernetes_semver`}}/binaries/node/windows/{{user `kubernetes_goarch`}}", + "manifest_output": "manifest.json", + "nssm_url": null, + "ocpus": "2", + "opc_user_password": "{{env `OPC_USER_PASSWORD`}}", + "prepull": null, + "private_virtual_network_with_public_ip": "", + "runtime": "containerd", + "shape": "VM.Standard.E4.Flex", + "virtual_network_name": "", + "virtual_network_resource_group_name": "", + "virtual_network_subnet_name": "", + "vm_size": "", + "windows_service_manager": null, + "windows_updates_kbs": null, + "wins_url": "", + "wire_server_users": "" + } +} diff --git a/images/capi/packer/oci/scripts/attach_secondary_vnic.ps1 b/images/capi/packer/oci/scripts/attach_secondary_vnic.ps1 new file mode 100644 index 0000000000..4bbb53db7c --- /dev/null +++ b/images/capi/packer/oci/scripts/attach_secondary_vnic.ps1 @@ -0,0 +1,39 @@ +function Get-Second-Vnic-Ocid() { + $ocid = "" + $vnics = Invoke-RestMethod -Uri "http://169.254.169.254/opc/v1/vnics/" + if ($vnics.Count -eq 2) { + $ocid = $vnics[1].vnicId + } else { + Write-Host "vnics count not equal 2" + } + return $ocid +} + +$vnicId = Get-Second-Vnic-Ocid +Write-Host "found vnic id: ${vnicId}" + + +$retryDelaySeconds = 30 +# We should continue to retry indefinitely until the vnic is +# detected by IMDS +# https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm +while($vnicId -eq "") { + $vnicId = Get-Second-Vnic-Ocid + Write-Host("Getting second vnic failed. Waiting " + $retryDelaySeconds + " seconds before next attempt.") + Start-Sleep -Seconds $retryDelaySeconds +} + +if ($vnicId -ne "") { + Write-Host "Pulling down the secondary_vnic_windows_configure.ps1" + Invoke-WebRequest -Uri "https://docs.oracle.com/en-us/iaas/Content/Resources/Assets/secondary_vnic_windows_configure.ps1" -OutFile "C:\Users\opc\secondary_vnic_windows_configure.ps1" + + Write-Host "calling script using ${vnicId}" + + , 'Y', 'A' | powershell "C:\Users\opc\secondary_vnic_windows_configure.ps1 ${vnicId}" + Write-Error "secondary_vnic_windows_configure.ps1 - done" + + $ipconfig = ipconfig + Write-Error "${ipconfig}" +}else{ + Write-Error "VNIC OCID is empty. Can't configure." +} \ No newline at end of file diff --git a/images/capi/packer/oci/scripts/enable_second_nic.ps1 b/images/capi/packer/oci/scripts/enable_second_nic.ps1 new file mode 100644 index 0000000000..764cfe7895 --- /dev/null +++ b/images/capi/packer/oci/scripts/enable_second_nic.ps1 @@ -0,0 +1,47 @@ + +$newNetAdapterName = "Ethernet 2" + +# check for two nics +$netAdapters = Get-NetAdapter +if ($netAdapters.Length -le 1) { + Write-Output "Could not find multiple Network Adapters." + Exit 1 +} + +$secondNic = $netAdapters[1] + +# make sure the network adapter is known +if ($secondNic.Name -ne "") { + Write-Output "Changing ${secondNic.Name} to ${newNetAdapterName} ..." + try + { + Rename-NetAdapter -Name $secondNic.Name -NewName "${newNetAdapterName}" + $secondNic.Name = $newNetAdapterName + } + catch + { + Write-Output "Could not rename net adapter" + Write-Output $_ + } +} else { + Write-Output "Can not change network adapter named: ${secondNic.Name}" +} + +# check that second is disabled +if ($secondNic.Status -ne "up") { + + try + { + Enable-NetAdapter -Name $secondNic.Name + Write-Output "${secondNic.Name} enabled ..." + } + catch + { + Write-Output "Could not enable net adapter" + Write-Output $_ + } +} else { + Write-Output "${secondNic.Name} already enabled ..." +} + +Remove-Item -Path .\enable_second_nic.ps1 \ No newline at end of file diff --git a/images/capi/packer/oci/scripts/set_bootstrap.sh b/images/capi/packer/oci/scripts/set_bootstrap.sh new file mode 100755 index 0000000000..3814f46c6b --- /dev/null +++ b/images/capi/packer/oci/scripts/set_bootstrap.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script overrides the 'opc' password set in the winrm_bootstrap.txt file +# This script is assumed to be run from the make file hence the pathing to the winrm_bootstrap.txt + +set -o errexit +set -o nounset +set -o pipefail + +echo "Changing Password in winrm_bootstrap.txt" + +cp packer/oci/scripts/winrm_bootstrap_template.txt packer/oci/scripts/winrm_bootstrap.txt + +sed "s/(\[adsi\].*/([adsi](\"WinNT:\/\/\"+\$opcUser.caption).replace(\"\\\\\",\"\/\")).SetPassword(\"$OPC_USER_PASSWORD\")/g" packer/oci/scripts/winrm_bootstrap.txt | tee packer/oci/scripts/winrm_bootstrap.txt >/dev/null diff --git a/images/capi/packer/oci/scripts/sysprep.ps1 b/images/capi/packer/oci/scripts/sysprep.ps1 new file mode 100644 index 0000000000..5f25fd75b4 --- /dev/null +++ b/images/capi/packer/oci/scripts/sysprep.ps1 @@ -0,0 +1,37 @@ +# Copyright 2020 The Kubernetes Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if( Test-Path $Env:SystemRoot\system32\Sysprep\unattend.xml ) { + Remove-Item $Env:SystemRoot\system32\Sysprep\unattend.xml -Force +} + +$unattendedXml = "$ENV:ProgramFiles\Cloudbase Solutions\Cloudbase-Init\conf\Unattend.xml" +$FileExists = Test-Path $unattendedXml +If ($FileExists -eq $True) { + # Use the Cloudbase-init provided unattend file during install + Write-Output "Using cloudbase-init unattend file for sysprep: $unattendedXml" + & $Env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /mode:vm /quit /quiet /unattend:$unattendedXml +}else { + & $Env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /mode:vm /quit /quiet +} + +# Wait for the image to be reset +while($true) { + $imageState = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State).ImageState + Write-Output $imageState + if ($imageState -eq 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { break } + Start-Sleep -s 5 +} + +Write-Output '>>> Sysprep complete ...' diff --git a/images/capi/packer/oci/scripts/unset_bootstrap.sh b/images/capi/packer/oci/scripts/unset_bootstrap.sh new file mode 100755 index 0000000000..c2162daab0 --- /dev/null +++ b/images/capi/packer/oci/scripts/unset_bootstrap.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script overrides the 'opc' password set in the winrm_bootstrap.txt file +# This script is assumed to be run from the make file hence the pathing to the winrm_bootstrap.txt + +set -o errexit +set -o nounset +set -o pipefail + +echo "resetting Password in winrm_bootstrap.txt" + +rm packer/oci/scripts/winrm_bootstrap.txt diff --git a/images/capi/packer/oci/scripts/winrm_bootstrap_template.txt b/images/capi/packer/oci/scripts/winrm_bootstrap_template.txt new file mode 100644 index 0000000000..31b7fbbe29 --- /dev/null +++ b/images/capi/packer/oci/scripts/winrm_bootstrap_template.txt @@ -0,0 +1,50 @@ + + +# MAKE SURE IN YOUR PACKER CONFIG TO SET: +# +# +# "winrm_username": "Administrator", +# "winrm_insecure": true, +# "winrm_use_ssl": true, +# +# +#ps1_sysnative +cmd /C 'wmic UserAccount where Name="opc" set PasswordExpires=False' +$opcUser = get-wmiobject win32_useraccount | Where-Object { $_.Name -match 'opc' } +([adsi]("WinNT://"+$opcUser.caption).replace("\","/")).SetPassword("myTemp#Pa55_Word") + +write-output "Running User Data Script" +write-host "(host) Running User Data Script" + +Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore + +# Don't set this before Set-ExecutionPolicy as it throws an error +$ErrorActionPreference = "stop" + +# Remove HTTP listener +Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse + +# Create a self-signed certificate to let ssl work +$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer" +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force + +# WinRM +write-output "Setting up WinRM" +write-host "(host) setting up WinRM" + +cmd.exe /c winrm quickconfig -q +cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}' +cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}' +cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}' +cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}" +cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes +cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986" +cmd.exe /c net stop winrm +cmd.exe /c sc config winrm start= auto +cmd.exe /c net start winrm + + \ No newline at end of file diff --git a/images/capi/packer/oci/windows-2019.json b/images/capi/packer/oci/windows-2019.json new file mode 100644 index 0000000000..a3b8bef2da --- /dev/null +++ b/images/capi/packer/oci/windows-2019.json @@ -0,0 +1,7 @@ +{ + "build_name": "windows-2019", + "operating_system": "Windows", + "operating_system_version": "Server 2019 Standard", + "runtime": "containerd", + "ssh_username": "opc" +} diff --git a/images/capi/packer/oci/windows-2022.json b/images/capi/packer/oci/windows-2022.json new file mode 100644 index 0000000000..c27b30f11b --- /dev/null +++ b/images/capi/packer/oci/windows-2022.json @@ -0,0 +1,7 @@ +{ + "build_name": "windows-2022", + "operating_system": "Windows", + "operating_system_version": "Server 2022 Standard", + "runtime": "containerd", + "ssh_username": "opc" +} diff --git a/images/capi/packer/ova/packer-windows.json b/images/capi/packer/ova/packer-windows.json index 065a24dbad..98f9352f10 100644 --- a/images/capi/packer/ova/packer-windows.json +++ b/images/capi/packer/ova/packer-windows.json @@ -240,7 +240,7 @@ "cloudbase_init_url": "https://github.com/cloudbase/cloudbase-init/releases/download/{{user `cloudbase_init_version`}}/CloudbaseInitSetup_{{user `cloudbase_init_version` | replace_all `.` `_` }}_x64.msi", "cloudbase_metadata_services": "cloudbaseinit.metadata.services.vmwareguestinfoservice.VMwareGuestInfoService", "cloudbase_metadata_services_unattend": "cloudbaseinit.metadata.services.vmwareguestinfoservice.VMwareGuestInfoService", - "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", + "cloudbase_plugins": "cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", "containerd_sha256": null, "containerd_url": "", diff --git a/images/capi/packer/vbox/packer-windows.json b/images/capi/packer/vbox/packer-windows.json index cf1c1d012a..782c3e1d6d 100644 --- a/images/capi/packer/vbox/packer-windows.json +++ b/images/capi/packer/vbox/packer-windows.json @@ -102,7 +102,7 @@ "build_timestamp": "{{timestamp}}", "build_version": "{{user `build_name`}}-kube-{{user `kubernetes_semver`}}", "cloudbase_init_url": "https://github.com/cloudbase/cloudbase-init/releases/download/{{user `cloudbase_init_version`}}/CloudbaseInitSetup_{{user `cloudbase_init_version` | replace_all `.` `_` }}_x64.msi", - "cloudbase_plugins": "cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", + "cloudbase_plugins": "cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin, cloudbaseinit.plugins.common.ephemeraldisk.EphemeralDiskPlugin, cloudbaseinit.plugins.common.mtu.MTUPlugin, cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin, cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin, cloudbaseinit.plugins.common.userdata.UserDataPlugin, cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin, cloudbaseinit.plugins.windows.createuser.CreateUserPlugin, cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin", "cloudbase_plugins_unattend": "cloudbaseinit.plugins.common.mtu.MTUPlugin", "containerd_sha256": null, "containerd_url": "",