-
Notifications
You must be signed in to change notification settings - Fork 487
Add proxmox windows #1976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add proxmox windows #1976
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -173,6 +173,7 @@ deps-huaweicloud: deps-common | |
| .PHONY: deps-proxmox | ||
| deps-proxmox: ## Installs/checks dependencies for Proxmox builds | ||
| deps-proxmox: deps-common | ||
| hack/ensure-ansible-windows.sh | ||
| $(PACKER) init packer/config.pkr.hcl | ||
| $(PACKER) init packer/proxmox/config.pkr.hcl | ||
|
|
||
|
|
@@ -403,7 +404,7 @@ NUTANIX_BUILD_NAMES ?= nutanix-ubuntu-2204 nutanix-ubuntu-2404 nutanix-rhel-9 nu | |
|
|
||
| HCLOUD_BUILD_NAMES ?= hcloud-ubuntu-2204 hcloud-ubuntu-2404 hcloud-rockylinux-9 hcloud-flatcar hcloud-flatcar-arm64 | ||
|
|
||
| PROXMOX_BUILD_NAMES ?= proxmox-ubuntu-2204 proxmox-ubuntu-2404 proxmox-ubuntu-2404-efi proxmox-rockylinux-9 proxmox-flatcar | ||
| PROXMOX_BUILD_NAMES ?= proxmox-ubuntu-2204 proxmox-ubuntu-2404 proxmox-ubuntu-2404-efi proxmox-rockylinux-9 proxmox-flatcar proxmox-windows-2022 | ||
|
|
||
| VULTR_BUILD_NAMES ?= vultr-ubuntu-2204 vultr-ubuntu-2404 | ||
|
|
||
|
|
@@ -644,7 +645,11 @@ $(HCLOUD_VALIDATE_TARGETS): deps-hcloud | |
|
|
||
| .PHONY: $(PROXMOX_BUILD_TARGETS) | ||
| $(PROXMOX_BUILD_TARGETS): deps-proxmox set-ssh-password | ||
| $(PACKER) build $(PACKER_NODE_FLAGS) -var-file="$(abspath packer/proxmox/$(subst build-proxmox-,,$@).json)" $(ABSOLUTE_PACKER_VAR_FILES) packer/proxmox/packer.json | ||
| # This uses a packer file builder to input unattend variables into a JSON file to be consumed by the python script before running the vsphere provisioner | ||
| $(if $(findstring windows,$@),$(PACKER) build $(PACKER_WINDOWS_NODE_FLAGS) -var-file="$(abspath packer/proxmox/$(subst build-proxmox-,,$@).json)" -var-file="$(abspath packer/proxmox/$(subst build-proxmox-,,$@).json)" -only=file $(ABSOLUTE_PACKER_VAR_FILES) packer/proxmox/packer-windows.json,) | ||
| $(if $(findstring windows,$@),hack/windows-unattend.py --unattend-file='./packer/proxmox/windows/$(subst build-proxmox-,,$@)/autounattend.xml',) | ||
| $(PACKER) build $(if $(findstring windows,$@),$(PACKER_WINDOWS_NODE_FLAGS),$(PACKER_NODE_FLAGS)) -var-file="$(abspath packer/proxmox/$(subst build-proxmox-,,$@).json)" $(ABSOLUTE_PACKER_VAR_FILES) packer/proxmox/packer$(if $(findstring windows,$@),-windows,).json | ||
|
|
||
|
|
||
| .PHONY: $(PROXMOX_VALIDATE_TARGETS) | ||
| $(PROXMOX_VALIDATE_TARGETS): deps-proxmox set-ssh-password | ||
|
|
@@ -859,6 +864,11 @@ build-proxmox-ubuntu-2404: ## Builds Ubuntu 24.04 Proxmox image | |
| build-proxmox-ubuntu-2404-efi: ## Builds Ubuntu 24.04 Proxmox image that EFI boots | ||
| build-proxmox-rockylinux-9: ## Builds Rocky Linux 9 Proxmox image | ||
| build-proxmox-flatcar: ## Builds Flatcar Proxmox image | ||
| build-proxmox-ubuntu-2204: ## Builds the Proxmox ubuntu-2204 image | ||
| build-proxmox-ubuntu-2404: ## Builds the Proxmox ubuntu-2404 image | ||
| build-proxmox-ubuntu-2404-efi: ## Builds the Proxmox ubuntu-2404-efi image that EFI boots | ||
| build-proxmox-rockylinux-9: ## Builds the Proxmox rockylinux-9 image | ||
|
Comment on lines
+867
to
+870
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Look like duplicate lines of 862 - 865 |
||
| build-proxmox-windows-2022: ## Builds the Proxmox Windows 2022 image | ||
| build-proxmox-all: $(PROXMOX_BUILD_TARGETS) ## Builds all Proxmox images | ||
|
|
||
| build-vultr-ubuntu-2204: ## Builds Ubuntu 22.04 Vultr Snapshot | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| # Copyright 2026 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. | ||
|
|
||
| """Apply Proxmox NoCloud network data from a config-drive file.""" | ||
|
|
||
| import logging | ||
| import os | ||
| import string | ||
| import sys | ||
|
|
||
| try: | ||
| from oslo_log import log as oslo_logging | ||
|
|
||
| LOG = oslo_logging.getLogger(__name__) | ||
| except Exception: # pragma: no cover - fallback when oslo logging is unavailable | ||
| logging.basicConfig(level=logging.INFO) | ||
| LOG = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| DEFAULT_NETWORK_DATA_FILENAMES = ("NETWORK_CONFIG", "network-config") | ||
|
|
||
|
|
||
| def _iter_search_roots(): | ||
| search_roots = os.environ.get("PROXMOX_NETWORK_DATA_SEARCH_ROOTS") | ||
| if search_roots: | ||
| for root in search_roots.split(os.pathsep): | ||
| root = root.strip() | ||
| if root: | ||
| yield root | ||
| return | ||
|
|
||
| for drive_letter in string.ascii_uppercase: | ||
| yield "%s:\\" % drive_letter | ||
|
|
||
|
|
||
| def _iter_candidate_paths(): | ||
| override_path = os.environ.get("PROXMOX_NETWORK_DATA_PATH", "").strip() | ||
| if override_path: | ||
| yield override_path | ||
| return | ||
|
|
||
| for root in _iter_search_roots(): | ||
| normalized_root = root.rstrip("\\/") | ||
| for filename in DEFAULT_NETWORK_DATA_FILENAMES: | ||
| yield "%s\\%s" % (normalized_root, filename) | ||
|
|
||
|
|
||
| def find_network_data_path(path_exists=os.path.exists): | ||
| for candidate_path in _iter_candidate_paths(): | ||
| if path_exists(candidate_path): | ||
| return candidate_path | ||
| return None | ||
|
|
||
|
|
||
| def load_network_data(network_data_path, open_file=open, parser=None): | ||
| if parser is None: | ||
| from cloudbaseinit.utils import serialization | ||
|
|
||
| parser = serialization.parse_json_yaml | ||
|
|
||
| with open_file(network_data_path, "r", encoding="utf-8") as network_data_file: | ||
| raw_network_data = network_data_file.read() | ||
|
|
||
| network_data = parser(raw_network_data) | ||
| if not isinstance(network_data, dict): | ||
| raise ValueError( | ||
| "Proxmox network data parsed into %r, expected dict" % | ||
| type(network_data) | ||
| ) | ||
|
|
||
| return network_data | ||
|
|
||
|
|
||
| def apply_network_data(network_data, network_parser=None, plugin_factory=None): | ||
| if network_parser is None: | ||
| from cloudbaseinit.metadata.services.nocloudservice import ( | ||
| NoCloudNetworkConfigParser, | ||
| ) | ||
|
|
||
| network_parser = NoCloudNetworkConfigParser.parse | ||
|
|
||
| if plugin_factory is None: | ||
| from cloudbaseinit.plugins.common import networkconfig | ||
|
|
||
| plugin_factory = networkconfig.NetworkConfigPlugin | ||
|
|
||
| network_details = network_parser(network_data) | ||
| if not network_details: | ||
| LOG.warning("NoCloud network parser returned no interfaces") | ||
| return False | ||
|
|
||
| plugin = plugin_factory() | ||
| process_network_details = getattr(plugin, "_process_network_details_v2", None) | ||
| if process_network_details is None: | ||
| raise AttributeError( | ||
| "Cloudbase-Init network plugin is missing _process_network_details_v2" | ||
| ) | ||
|
|
||
| process_network_details(network_details) | ||
| return True | ||
|
|
||
|
|
||
| def main(): | ||
| network_data_path = find_network_data_path() | ||
| if not network_data_path: | ||
| LOG.info( | ||
| "No Proxmox network data found in candidate paths: %s", | ||
| ", ".join(_iter_candidate_paths()), | ||
| ) | ||
| return 0 | ||
|
|
||
| try: | ||
| network_data = load_network_data(network_data_path) | ||
| except Exception: | ||
| LOG.exception( | ||
| "Failed to load Proxmox network data from %s", network_data_path | ||
| ) | ||
| return 0 | ||
|
|
||
| try: | ||
| LOG.info("Applying Proxmox network data from %s", network_data_path) | ||
| applied = apply_network_data(network_data) | ||
| except Exception: | ||
| LOG.exception( | ||
| "Failed to apply Proxmox network data from %s", network_data_path | ||
| ) | ||
| return 0 | ||
|
|
||
| if not applied: | ||
| LOG.warning( | ||
| "No network interfaces were applied from %s", network_data_path | ||
| ) | ||
|
|
||
| return 0 | ||
|
Comment on lines
+114
to
+145
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it not be better to fail a little louder rather than return 0 if something fails? As I'm reading this, it looks like failures will happen silently meaning an image could successfully build even if something like applying the proxmox network fails. Would we be ok with this?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is kind of my hack to read the cloudinit network data that CAPMOX injects via a ISO-9660 cd drive for kubeadm boostrap. So this wont fail the build of the VM, as its a node first boot helper script for cloudbase-init(windows version of cloud-init). Though I should try to write to a file to troubleshoot networking incase CAPMOX changes its kubeadmbootstrap process, and be more verbose on failures. |
||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Copyright 2026 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. | ||
| --- | ||
| - name: Ensure Proxmox Cloudbase-Init LocalScripts directory exists | ||
| ansible.windows.win_file: | ||
| path: "{{ programfiles.stdout | trim }}\\Cloudbase Solutions\\Cloudbase-Init\\LocalScripts" | ||
| state: directory | ||
|
|
||
| - name: Copy Proxmox Cloudbase-Init compatibility helper | ||
| ansible.windows.win_copy: | ||
| src: proxmox/cloudbase_helper.py | ||
| dest: "{{ programfiles.stdout | trim }}\\Cloudbase Solutions\\Cloudbase-Init\\LocalScripts\\cloudbase_helper.py" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| { | ||
| "ansible_common_vars": "runtime={{user `runtime`}} containerd_url={{user `containerd_url`}} containerd_sha256={{user `containerd_sha256_windows`}} containerd_version={{user `containerd_version`}} pause_image={{user `pause_image`}} additional_debug_files=\"{{user `additional_debug_files`}}\" containerd_additional_settings={{user `containerd_additional_settings`}} custom_role_names=\"{{user `custom_role_names`}}\" http_proxy={{user `http_proxy`}} https_proxy={{user `https_proxy`}} no_proxy={{user `no_proxy`}} kubernetes_base_url={{user `kubernetes_base_url`}} kubernetes_semver={{user `kubernetes_semver`}} kubernetes_install_path={{user `kubernetes_install_path`}} cloudbase_init_url=\"{{user `cloudbase_init_url`}}\" cloudbase_plugins=\"{{user `cloudbase_plugins`}}\" cloudbase_metadata_services=\"{{user `cloudbase_metadata_services`}}\" cloudbase_plugins_unattend=\"{{user `cloudbase_plugins_unattend`}}\" cloudbase_metadata_services_unattend=\"{{user `cloudbase_metadata_services_unattend`}}\" prepull={{user `prepull`}} windows_updates_kbs=\"{{user `windows_updates_kbs`}}\" windows_updates_categories=\"{{user `windows_updates_categories`}}\" windows_service_manager={{user `windows_service_manager`}} nssm_url={{user `nssm_url`}} distribution_version={{user `distribution_version`}} netbios_host_name_compatibility={{user `netbios_host_name_compatibility`}} disable_hypervisor={{ user `disable_hypervisor` }} cloudbase_logging_serial_port={{ user `cloudbase_logging_serial_port` }} cloudbase_real_time_clock_utc={{ user `cloudbase_real_time_clock_utc` }} load_additional_components={{ user `load_additional_components`}} ecr_credential_provider={{ user `ecr_credential_provider` }} additional_registry_images={{ user `additional_registry_images`}} additional_registry_images_list={{ user `additional_registry_images_list`}} additional_url_images={{ user `additional_url_images`}} additional_url_images_list={{ user `additional_url_images_list`}} additional_executables={{ user `additional_executables`}} additional_executables_list={{ user `additional_executables_list`}} additional_executables_destination_path={{ user `additional_executables_destination_path`}} ssh_source_url={{user `ssh_source_url` }} debug_tools={{user `debug_tools`}}" | ||
| "ansible_common_vars": "runtime={{user `runtime`}} containerd_url={{user `containerd_url`}} containerd_sha256={{user `containerd_sha256_windows`}} containerd_version={{user `containerd_version`}} pause_image={{user `pause_image`}} additional_debug_files=\"{{user `additional_debug_files`}}\" containerd_additional_settings={{user `containerd_additional_settings`}} custom_role_names=\"{{user `custom_role_names`}}\" http_proxy={{user `http_proxy`}} https_proxy={{user `https_proxy`}} no_proxy={{user `no_proxy`}} kubernetes_base_url={{user `kubernetes_base_url`}} kubernetes_semver={{user `kubernetes_semver`}} kubernetes_install_path={{user `kubernetes_install_path`}} cloudbase_init_url=\"{{user `cloudbase_init_url`}}\" cloudbase_plugins=\"{{user `cloudbase_plugins`}}\" cloudbase_metadata_services=\"{{user `cloudbase_metadata_services`}}\" cloudbase_plugins_unattend=\"{{user `cloudbase_plugins_unattend`}}\" cloudbase_metadata_services_unattend=\"{{user `cloudbase_metadata_services_unattend`}}\" cloudbase_nocloud_metadata_file=\"{{user `cloudbase_nocloud_metadata_file`}}\" cloudbase_nocloud_networkdata_file=\"{{user `cloudbase_nocloud_networkdata_file`}}\" cloudbase_nocloud_userdata_file=\"{{user `cloudbase_nocloud_userdata_file`}}\" prepull={{user `prepull`}} windows_updates_kbs=\"{{user `windows_updates_kbs`}}\" windows_updates_categories=\"{{user `windows_updates_categories`}}\" windows_service_manager={{user `windows_service_manager`}} nssm_url={{user `nssm_url`}} distribution_version={{user `distribution_version`}} netbios_host_name_compatibility={{user `netbios_host_name_compatibility`}} disable_hypervisor={{ user `disable_hypervisor` }} cloudbase_logging_serial_port={{ user `cloudbase_logging_serial_port` }} cloudbase_real_time_clock_utc={{ user `cloudbase_real_time_clock_utc` }} load_additional_components={{ user `load_additional_components`}} ecr_credential_provider={{ user `ecr_credential_provider` }} additional_registry_images={{ user `additional_registry_images`}} additional_registry_images_list={{ user `additional_registry_images_list`}} additional_url_images={{ user `additional_url_images`}} additional_url_images_list={{ user `additional_url_images_list`}} additional_executables={{ user `additional_executables`}} additional_executables_list={{ user `additional_executables_list`}} additional_executables_destination_path={{ user `additional_executables_destination_path`}} ssh_source_url={{user `ssh_source_url` }} debug_tools={{user `debug_tools`}}" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section looks copy-pasted: the same -var-file is passed twice, and the comment references vSphere in the Proxmox path. Is the duplicate var-file intentional?