From 8f3a9e207cbee1099b106578404200aff7dcb2a6 Mon Sep 17 00:00:00 2001 From: James Denton Date: Wed, 17 Jun 2020 19:14:42 +0000 Subject: [PATCH] Add iPXE support to Ironic Conductor This patchset adds support for iPXE, which can speed up baremetal provisioning considerably due to the use of HTTP versus TFTP. Change-Id: I8b49ae37a0380cd7a2191f050a52c85cc373026b --- defaults/main.yml | 8 +++- handlers/main.yml | 13 ++++++ ...xe-conductor-support-d68b68548aa1cf1f.yaml | 6 +++ tasks/ironic_conductor_post_install.yml | 46 ++++++++++++++++++- templates/ironic-ipxe.conf.j2 | 17 +++++++ templates/ironic.conf.j2 | 11 +++++ templates/map-file | 5 ++ vars/debian.yml | 6 +++ vars/main.yml | 4 ++ vars/redhat.yml | 6 +++ vars/suse.yml | 3 ++ 11 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/adds-ipxe-conductor-support-d68b68548aa1cf1f.yaml create mode 100644 templates/ironic-ipxe.conf.j2 diff --git a/defaults/main.yml b/defaults/main.yml index f90d18b5..fe8c4092 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -114,8 +114,8 @@ ironic_service_in_ldap: False # config file. If this is set to False, then Ironic will use # Swift to host the floppy images and generated boot_iso. ironic_enable_web_server_for_images: False -ironic_http_url: null -ironic_http_root: null +ironic_http_url: "{{ ironic_ipxe_proto }}://{{ ansible_host }}:{{ ironic_ipxe_port }}" +ironic_http_root: "/httpboot" # ### Swift Config # @@ -320,6 +320,10 @@ ironic_inspector_db_pool_timeout: 30 ironic_inspector_pip_install_args: "{{ pip_install_options | default('') }}" +# Ironic iPXE support +ironic_ipxe_enabled: False +ironic_ipxe_port: 8051 +ironic_ipxe_proto: "http" # Auth ironic_inspector_service_user_name: "ironic_inspector" diff --git a/handlers/main.yml b/handlers/main.yml index d0b4941e..52116265 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -52,3 +52,16 @@ name: "dnsmasq" state: restarted failed_when: false + +- name: Restart web server + service: + name: "nginx" + enabled: yes + state: restarted + daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}" + register: _restart + until: _restart is success + retries: 5 + delay: 2 + listen: + - "venv changed" diff --git a/releasenotes/notes/adds-ipxe-conductor-support-d68b68548aa1cf1f.yaml b/releasenotes/notes/adds-ipxe-conductor-support-d68b68548aa1cf1f.yaml new file mode 100644 index 00000000..6cacf4d8 --- /dev/null +++ b/releasenotes/notes/adds-ipxe-conductor-support-d68b68548aa1cf1f.yaml @@ -0,0 +1,6 @@ +--- +features: + - New variables have been added to allow a deployer to enable + iPXE support for Ironic Conductor, which uses HTTP rather + than TFTP, and can speed up baremetal provisioning considerably. + To enable, simply set the ``ironic_ipxe_enabled`` override to ``True``. diff --git a/tasks/ironic_conductor_post_install.yml b/tasks/ironic_conductor_post_install.yml index 484d6756..9ac83821 100644 --- a/tasks/ironic_conductor_post_install.yml +++ b/tasks/ironic_conductor_post_install.yml @@ -66,4 +66,48 @@ service: name: "{{ ironic_tftpd_service_name }}" state: started - enabled: true \ No newline at end of file + enabled: true + +- name: Disable default nginx configuration + file: + path: /etc/nginx/sites-enabled/default + state: absent + when: "ironic_ipxe_enabled | bool" + notify: + - Restart web server + +- name: Remove default nginx config + file: + path: /etc/nginx/conf.d/default.conf + state: absent + when: "ironic_ipxe_enabled | bool" + notify: + - Restart web server + +- name: Ensure nginx configuration directories exist + file: + path: "{{ item }}" + state: directory + when: "ironic_ipxe_enabled | bool" + with_items: + - "/etc/nginx/{{ ironic_nginx_conf_path }}" + - "/etc/nginx/conf.d" + +- name: Configure nginx virtual hosts + template: + src: ironic-ipxe.conf.j2 + dest: "/etc/nginx/{{ ironic_nginx_conf_path }}/ironic-ipxe.conf" + when: "ironic_ipxe_enabled | bool" + notify: + - Restart web server + +- name: Link to enable nginx virtual hosts + file: + src: "/etc/nginx/sites-available/ironic-ipxe.conf" + path: "/etc/nginx/sites-enabled/ironic-ipxe.conf" + state: link + when: + - ansible_os_family == "Debian" + - "ironic_ipxe_enabled | bool" + notify: + - Restart web server diff --git a/templates/ironic-ipxe.conf.j2 b/templates/ironic-ipxe.conf.j2 new file mode 100644 index 00000000..27f416b6 --- /dev/null +++ b/templates/ironic-ipxe.conf.j2 @@ -0,0 +1,17 @@ +# {{ ansible_managed }} + +server { + listen 0.0.0.0:{{ ironic_ipxe_port }}; + server_name ironic-ipxe; + + # Logging + access_log /var/log/nginx/ironic-ipxe.access.log combined gzip buffer=32k; + error_log /var/log/nginx/ironix-ipxe.error.log notice; + + # directory to store ipxe + location / { + root /httpboot; + autoindex off; + expires 1h; + } +} diff --git a/templates/ironic.conf.j2 b/templates/ironic.conf.j2 index 1767a45f..16032b61 100644 --- a/templates/ironic.conf.j2 +++ b/templates/ironic.conf.j2 @@ -24,6 +24,10 @@ enabled_inspect_interfaces = {{ filtered_ironic_drivers | json_query('[*].inspec enabled_management_interfaces = {{ filtered_ironic_drivers | json_query('[*].management') | unique | join(',') }} enabled_power_interfaces = {{ filtered_ironic_drivers | json_query('[*].power') | unique | join(',') }} +# Ironic boot interface (defaults to None) +{% if ironic_ipxe_enabled | bool %} +default_boot_interface = ipxe +{% endif %} [agent] @@ -185,6 +189,13 @@ pool_max_size = {{ ironic_wsgi_processes }} [oslo_policy] [pxe] +{% if ironic_ipxe_enabled | bool %} +pxe_bootfile_name = undionly.kpxe +uefi_pxe_bootfile_name = ipxe.efi +pxe_config_template = $pybasedir/drivers/modules/ipxe_config.template +uefi_pxe_config_template = $pybasedir/drivers/modules/ipxe_config.template +{% endif %} + tftp_server = {{ ironic_tftp_server_address }} pxe_append_params = {{ ironic_pxe_append_params }} tftp_root = {{ ironic_tftpd_root }} diff --git a/templates/map-file b/templates/map-file index 91fdd713..f2b95a0a 100644 --- a/templates/map-file +++ b/templates/map-file @@ -1,4 +1,9 @@ +{% if not ironic_ipxe_enabled | bool %} re ^({{ ironic_tftpd_root }}/) {{ ironic_tftpd_root }}/\2 re ^{{ ironic_tftpd_root }}/ {{ ironic_tftpd_root }}/ re ^(^/) {{ ironic_tftpd_root }}/\1 re ^([^/]) {{ ironic_tftpd_root }}/\1 +{% else %} +r ^([^/]) {{ ironic_tftpd_root }}/\1 +r ^({{ ironic_tftpd_root }}/) {{ ironic_tftpd_root }}/\2 +{% endif %} diff --git a/vars/debian.yml b/vars/debian.yml index 39ba2399..7a08bc59 100644 --- a/vars/debian.yml +++ b/vars/debian.yml @@ -37,6 +37,8 @@ ironic_conductor_distro_packages: - ipmitool - tftpd-hpa - gdisk + - ipxe + - nginx ironic_conductor_standalone_distro_packages: - isc-dhcp-server @@ -45,6 +47,8 @@ ironic_library_modules_paths: - "/usr/lib/PXELINUX/pxelinux.0" - "/usr/lib/syslinux/modules/efi64/chain.c32" - "/usr/lib/syslinux/modules/bios/ldlinux.c32" + - "/usr/lib/ipxe/undionly.kpxe" + - "/usr/lib/ipxe/ipxe.efi" ironic_tftpd_service_name: tftpd-hpa ironic_tftpd_root: /tftpboot @@ -84,3 +88,5 @@ ironic_inspector_library_modules_paths: - "/usr/lib/syslinux/modules/efi64/chain.c32" - "/usr/lib/syslinux/modules/bios/ldlinux.c32" - "/usr/lib/syslinux/modules/efi64/ldlinux.e64" + +ironic_nginx_conf_path: "sites-available" diff --git a/vars/main.yml b/vars/main.yml index aa1eb5b5..a04b26c5 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -311,7 +311,11 @@ uwsgi_ironic_services: |- {{ services }} filtered_ironic_drivers: |- + {% if ironic_ipxe_enabled | bool %} + {% set concat_drivers = [{'boot': 'ipxe'}] %} + {% else %} {% set concat_drivers = [] %} + {% endif %} {% for driver in ironic_drivers_enabled %} {% if driver in ironic_driver_types.keys() %} {% set _ = concat_drivers.append(ironic_driver_types[driver]) %} diff --git a/vars/redhat.yml b/vars/redhat.yml index 40ba45c4..c6144e3e 100644 --- a/vars/redhat.yml +++ b/vars/redhat.yml @@ -35,6 +35,8 @@ ironic_conductor_distro_packages: - ipmitool - tftp-server - gdisk + - ipxe-bootimgs + - nginx ironic_conductor_standalone_distro_packages: - isc-dhcp-server @@ -43,6 +45,8 @@ ironic_library_modules_paths: - "/usr/share/syslinux/pxelinux.0" - "/usr/share/syslinux/chain.c32" - "/usr/share/syslinux/linux.c32" + - "/usr/share/ipxe/undionly.kpxe" + - "/usr/share/ipxe/ipxe-x86_64.efi" ironic_tftpd_service_name: tftp ironic_tftpd_root: /var/lib/tftpboot @@ -72,3 +76,5 @@ ironic_inspector_library_modules_paths: - "/usr/lib/syslinux/modules/bios/ldlinux.c32" - "/usr/lib/SYSLINUX.EFI/efi64/syslinux.efi" - "/usr/lib/syslinux/modules/efi64/ldlinux.e64" + +ironic_nginx_conf_path: "conf.d" diff --git a/vars/suse.yml b/vars/suse.yml index 26b48f02..4734e1f2 100644 --- a/vars/suse.yml +++ b/vars/suse.yml @@ -36,6 +36,7 @@ ironic_conductor_distro_packages: - syslinux - tftp - gptfdisk + - nginx ironic_conductor_standalone_distro_packages: - dhcp-server @@ -73,3 +74,5 @@ ironic_inspector_library_modules_paths: - "/usr/lib/syslinux/modules/bios/ldlinux.c32" - "/usr/lib/SYSLINUX.EFI/efi64/syslinux.efi" - "/usr/lib/syslinux/modules/efi64/ldlinux.e64" + +ironic_nginx_conf_path: "conf.d"