From c956414c52a23819b792ce86628ac411f5aacbd9 Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Wed, 5 Dec 2018 15:56:14 +1100 Subject: [PATCH 1/5] IPv6: dhcp/provisioner: make ipv6 aware If the admin network is IPv6 setup the ISC DHCPD server to configure and use the IPv6 daemon. For this use a seperate set of ipv6 files to list hosts and subnets as ipv6 hosts and subnets will fail if v4 dhcp tries to load them. Also make sure tftp is listening on both IPv4 and v6. To make this all happen the Network class in the Barclamp::Inventory library now tracks the ip_version of the network. Which is used to make decisions through the DHCP and provisioner cookbooks. To support backwards compatibilty with ipv4 config naming in the DHCP barclamp a DhcpHelper was added to return config names in an IPv4 or IPv6 way. The same pattern was used throughout the barclamp in the early versions of this patch so it's been refectered to the helper. Finally, when dealing with some IPv6 addresses in URIs the address needs to be wrapped. As such the network barclamp has grown a NetworkHelper module to start gathering network related helper method's, it's first is a wrap_ip function. Which will wrap an address if it happens to an IPv6 address. This makes this available to us anywhere in crowbar, so long as the network barclamp has been applied, and as a core barclamp to crowbar, should be always. --- .../barclamp/libraries/barclamp_library.rb | 8 +++ chef/cookbooks/dhcp/attributes/default.rb | 15 ++++- chef/cookbooks/dhcp/libraries/helpers.rb | 10 +++ chef/cookbooks/dhcp/providers/host.rb | 18 +++-- chef/cookbooks/dhcp/providers/subnet.rb | 18 +++-- chef/cookbooks/dhcp/recipes/default.rb | 40 ++++++----- chef/cookbooks/dhcp/resources/host.rb | 2 + chef/cookbooks/dhcp/resources/subnet.rb | 1 + .../dhcp/templates/default/dhcpd.conf.erb | 6 ++ .../dhcp/templates/default/host.conf.erb | 5 ++ .../dhcp/templates/default/subnet6.conf.erb | 19 ++++++ .../default/suse-sysconfig-dhcpd.erb | 1 + chef/cookbooks/network/libraries/helpers.rb | 12 ++++ chef/cookbooks/provisioner/recipes/base.rb | 2 +- .../provisioner/recipes/dhcp_update.rb | 67 +++++++++++++++---- .../provisioner/recipes/setup_base_images.rb | 10 +-- .../provisioner/recipes/update_nodes.rb | 53 +++++++++++---- .../default/crowbar_join.suse.sh.erb | 22 ++++-- .../provisioner/templates/default/tftp.erb | 2 +- .../templates/suse/crowbar_register.erb | 11 ++- 20 files changed, 252 insertions(+), 70 deletions(-) create mode 100644 chef/cookbooks/dhcp/libraries/helpers.rb create mode 100644 chef/cookbooks/dhcp/templates/default/subnet6.conf.erb create mode 100644 chef/cookbooks/network/libraries/helpers.rb diff --git a/chef/cookbooks/barclamp/libraries/barclamp_library.rb b/chef/cookbooks/barclamp/libraries/barclamp_library.rb index 06927cee8d..6b01dffb71 100644 --- a/chef/cookbooks/barclamp/libraries/barclamp_library.rb +++ b/chef/cookbooks/barclamp/libraries/barclamp_library.rb @@ -92,6 +92,7 @@ class Network attr_reader :vlan, :use_vlan attr_reader :add_bridge, :add_ovs_bridge, :bridge_name attr_reader :conduit + attr_reader :ip_version def initialize(node, net, data) @node = node @@ -112,6 +113,13 @@ def initialize(node, net, data) # let's resolve this only if needed @interface = nil @interface_list = nil + + require "ipaddr" + @ip_version = if IPAddr.new(@subnet).ipv6? + "6" + else + "4" + end end def interface diff --git a/chef/cookbooks/dhcp/attributes/default.rb b/chef/cookbooks/dhcp/attributes/default.rb index d2ce1c50df..6dcd2ae883 100644 --- a/chef/cookbooks/dhcp/attributes/default.rb +++ b/chef/cookbooks/dhcp/attributes/default.rb @@ -1,6 +1,6 @@ default[:dhcp][:interfaces] = ["eth0"] -default[:dhcp][:options] = [ +default[:dhcp][:options][:v4] = [ "ddns-update-style none", "allow booting", "option option-128 code 128 = string", @@ -10,4 +10,17 @@ "option dhcp-client-debug code 226 = unsigned integer 16", "option dhcp-client-debug 0" ] +default[:dhcp][:options][:v6] = [ + "ddns-update-style none", + "allow booting", + "option option-128 code 128 = string", + "option option-129 code 129 = text", + "option dhcp-client-state code 225 = unsigned integer 16", + "option dhcp-client-state 0", + "option dhcp-client-debug code 226 = unsigned integer 16", + "option dhcp-client-debug 0", + "option dhcp6.bootfile-url code 59 = string", + "option dhcp6.client-arch-type code 61 = array of unsigned integer 16", + "option dhcp6.vendor-class code 16 = {integer 32, integer 16, string}" +] diff --git a/chef/cookbooks/dhcp/libraries/helpers.rb b/chef/cookbooks/dhcp/libraries/helpers.rb new file mode 100644 index 0000000000..041d4dfc02 --- /dev/null +++ b/chef/cookbooks/dhcp/libraries/helpers.rb @@ -0,0 +1,10 @@ +module DhcpHelper + def self.config_filename(base, ip_version, extension = ".conf") + if ip_version == "4" + extra = "" + else + extra = ip_version + end + "#{base}#{extra}#{extension}" + end +end diff --git a/chef/cookbooks/dhcp/providers/host.rb b/chef/cookbooks/dhcp/providers/host.rb index 6a590d6206..b1d6247695 100644 --- a/chef/cookbooks/dhcp/providers/host.rb +++ b/chef/cookbooks/dhcp/providers/host.rb @@ -24,7 +24,9 @@ hostname: new_resource.hostname, macaddress: new_resource.macaddress, ipaddress: new_resource.ipaddress, - options: new_resource.options + options: new_resource.options, + prefix: new_resource.prefix, + ip_version: new_resource.ip_version ) owner "root" group "root" @@ -35,7 +37,7 @@ end utils_line "include \"#{filename}\";" do action :add - file "/etc/dhcp3/hosts.d/host_list.conf" + file "/etc/dhcp3/hosts.d/#{DhcpHelper.config_filename("host_list", new_resource.ip_version)}" if node[:provisioner][:enable_pxe] notifies :restart, resources(service: "dhcp3-server"), :delayed end @@ -54,11 +56,13 @@ end new_resource.updated_by_last_action(true) end - utils_line "include \"#{filename}\";" do - action :remove - file "/etc/dhcp3/hosts.d/host_list.conf" - if node[:provisioner][:enable_pxe] - notifies :restart, resources(service: "dhcp3-server"), :delayed + ["host_list.conf", "host_list6.conf"].each do |host_list| + utils_line "include \"#{filename}\";" do + action :remove + file "/etc/dhcp3/hosts.d/#{host_list}" + if node[:provisioner][:enable_pxe] + notifies :restart, resources(service: "dhcp3-server"), :delayed + end end end end diff --git a/chef/cookbooks/dhcp/providers/subnet.rb b/chef/cookbooks/dhcp/providers/subnet.rb index f98823f437..f99df276cc 100644 --- a/chef/cookbooks/dhcp/providers/subnet.rb +++ b/chef/cookbooks/dhcp/providers/subnet.rb @@ -14,10 +14,11 @@ # action :add do + subnet_template = DhcpHelper.config_filename("subnet", new_resource.ip_version, ".conf.erb") filename = "/etc/dhcp3/subnets.d/#{new_resource.subnet}.conf" template filename do cookbook "dhcp" - source "subnet.conf.erb" + source subnet_template variables( network: new_resource.network, options: new_resource.options, @@ -31,9 +32,10 @@ notifies :restart, resources(service: "dhcp3-server"), :delayed end end + subnet_file = DhcpHelper.config_filename("subnet_list", new_resource.ip_version) utils_line "include \"#{filename}\";" do action :add - file "/etc/dhcp3/subnets.d/subnet_list.conf" + file "/etc/dhcp3/subnets.d/#{subnet_file}" if node[:provisioner][:enable_pxe] notifies :restart, resources(service: "dhcp3-server"), :delayed end @@ -52,11 +54,13 @@ end new_resource.updated_by_last_action(true) end - utils_line "include \"#{filename}\";" do - action :remove - file "/etc/dhcp3/subnets.d/subnet_list.conf" - if node[:provisioner][:enable_pxe] - notifies :restart, resources(service: "dhcp3-server"), :delayed + ["subnet_list.conf", "subnet_list6.conf"].each do |subnet_list| + utils_line "include \"#{filename}\";" do + action :remove + file "/etc/dhcp3/subnets.d/#{subnet_list}" + if node[:provisioner][:enable_pxe] + notifies :restart, resources(service: "dhcp3-server"), :delayed + end end end end diff --git a/chef/cookbooks/dhcp/recipes/default.rb b/chef/cookbooks/dhcp/recipes/default.rb index 616fa3f2e5..04d4ca259c 100644 --- a/chef/cookbooks/dhcp/recipes/default.rb +++ b/chef/cookbooks/dhcp/recipes/default.rb @@ -33,17 +33,25 @@ directory "/etc/dhcp3/subnets.d" directory "/etc/dhcp3/hosts.d" -file "/etc/dhcp3/groups.d/group_list.conf" do +# This needs to be evaled. +admin_network = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin") +address = admin_network.address +intfs = [admin_network.interface] + +group_list = DhcpHelper.config_filename("group_list", admin_network.ip_version) +file "/etc/dhcp3/groups.d/#{group_list}" do owner "root" group "root" mode 0644 end -file "/etc/dhcp3/subnets.d/subnet_list.conf" do +subnet_list = DhcpHelper.config_filename("subnet_list", admin_network.ip_version) +file "/etc/dhcp3/subnets.d/#{subnet_list}" do owner "root" group "root" mode 0644 end -file "/etc/dhcp3/hosts.d/host_list.conf" do +host_list = DhcpHelper.config_filename("host_list", admin_network.ip_version) +file "/etc/dhcp3/hosts.d/#{host_list}" do owner "root" group "root" mode 0644 @@ -59,22 +67,20 @@ not_if "test -f /etc/dhcp3/omapi.key" end -# This needs to be evaled. -intfs = [Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin").interface] -address = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin").address -d_opts = node[:dhcp][:options] +d_opts = node[:dhcp][:options]["v#{admin_network.ip_version}"] +dhcpd_conf = DhcpHelper.config_filename("dhcpd", admin_network.ip_version) case node[:platform_family] when "debian" case node[:lsb][:codename] when "natty","oneiric","precise" - template "/etc/dhcp/dhcpd.conf" do + template "/etc/dhcp/#{dhcpd_conf}" do owner "root" group "root" mode 0644 source "dhcpd.conf.erb" - variables(options: d_opts) + variables(options: d_opts, ip_version: admin_network.ip_version) if node[:provisioner][:enable_pxe] notifies :restart, "service[dhcp3-server]" end @@ -90,12 +96,12 @@ end end else - template "/etc/dhcp3/dhcpd.conf" do + template "/etc/dhcp3/#{dhcpd_conf}" do owner "root" group "root" mode 0644 source "dhcpd.conf.erb" - variables(options: d_opts) + variables(options: d_opts, ip_version: admin_network.ip_version) if node[:provisioner][:enable_pxe] notifies :restart, "service[dhcp3-server]" end @@ -115,9 +121,9 @@ dhcp_config_file = case when node[:platform_version].to_f >= 6 - "/etc/dhcp/dhcpd.conf" + "/etc/dhcp/#{dhcpd_conf}" else - "/etc/dhcpd.conf" + "/etc/#{dhcpd_conf}" end template dhcp_config_file do @@ -125,7 +131,7 @@ group "root" mode 0644 source "dhcpd.conf.erb" - variables(options: d_opts) + variables(options: d_opts, ip_version: admin_network.ip_version) if node[:provisioner][:enable_pxe] notifies :restart, "service[dhcp3-server]" end @@ -143,12 +149,12 @@ end when "suse" - template "/etc/dhcpd.conf" do + template "/etc/#{dhcpd_conf}" do owner "root" group "root" mode 0644 source "dhcpd.conf.erb" - variables(options: d_opts) + variables(options: d_opts, ip_version: admin_network.ip_version) if node[:provisioner][:enable_pxe] notifies :restart, "service[dhcp3-server]" end @@ -168,7 +174,7 @@ service "dhcp3-server" do if %w(suse rhel).include?(node[:platform_family]) - service_name "dhcpd" + service_name DhcpHelper.config_filename("dhcpd", admin_network.ip_version, "") elsif node[:platform] == "ubuntu" case node[:lsb][:codename] when "maverick" diff --git a/chef/cookbooks/dhcp/resources/host.rb b/chef/cookbooks/dhcp/resources/host.rb index 0ef4f62f49..aa47107510 100644 --- a/chef/cookbooks/dhcp/resources/host.rb +++ b/chef/cookbooks/dhcp/resources/host.rb @@ -19,6 +19,8 @@ attribute :hostname, kind_of: String attribute :macaddress, kind_of: String attribute :ipaddress, kind_of: String +attribute :prefix, kind_of: String +attribute :ip_version, kind_of: String, default: "4" attribute :group, kind_of: String attribute :options, kind_of: Array, default: [] diff --git a/chef/cookbooks/dhcp/resources/subnet.rb b/chef/cookbooks/dhcp/resources/subnet.rb index 97f18a9bb7..a6b6cda0a8 100644 --- a/chef/cookbooks/dhcp/resources/subnet.rb +++ b/chef/cookbooks/dhcp/resources/subnet.rb @@ -20,4 +20,5 @@ attribute :pools, kind_of: Array, default: ["dhcp"] attribute :pool_options, kind_of: Hash, default: { "dhcp" => ["allow unknown-hosts"] } attribute :options, kind_of: Array, default: [] +attribute :ip_version, kind_of: String, default: "4" diff --git a/chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb b/chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb index 3bb3deb9bf..043c68b59d 100644 --- a/chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb +++ b/chef/cookbooks/dhcp/templates/default/dhcpd.conf.erb @@ -21,6 +21,12 @@ log-facility local7; # Fix for https://bugzilla.opensuse.org/show_bug.cgi?id=961536 always-reply-rfc1048 true; +<% if @ip_version == "6" -%> +include "/etc/dhcp3/groups.d/group_list6.conf"; +include "/etc/dhcp3/subnets.d/subnet_list6.conf"; +include "/etc/dhcp3/hosts.d/host_list6.conf"; +<% else -%> include "/etc/dhcp3/groups.d/group_list.conf"; include "/etc/dhcp3/subnets.d/subnet_list.conf"; include "/etc/dhcp3/hosts.d/host_list.conf"; +<% end -%> diff --git a/chef/cookbooks/dhcp/templates/default/host.conf.erb b/chef/cookbooks/dhcp/templates/default/host.conf.erb index f2f6917860..8a09ec47ec 100644 --- a/chef/cookbooks/dhcp/templates/default/host.conf.erb +++ b/chef/cookbooks/dhcp/templates/default/host.conf.erb @@ -2,7 +2,12 @@ host <%= @name %> { option host-name "<%= @hostname %>"; hardware ethernet <%= @macaddress %>; <% if @ipaddress -%> +<% if @ip_version == "6" -%> + fixed-address6 <%= @ipaddress %>; + fixed-prefix6 <%= @prefix %>; +<% else -%> fixed-address <%= @ipaddress %>; +<% end -%> <% else -%> deny booting; <% end -%> diff --git a/chef/cookbooks/dhcp/templates/default/subnet6.conf.erb b/chef/cookbooks/dhcp/templates/default/subnet6.conf.erb new file mode 100644 index 0000000000..d8af240f5e --- /dev/null +++ b/chef/cookbooks/dhcp/templates/default/subnet6.conf.erb @@ -0,0 +1,19 @@ +# File managed by Crowbar +<% if node[:provisioner][:enable_pxe] -%> + +subnet6 <%= @network["subnet"] %>/<%= @network["netmask"]%> { + option subnet-mask <%= @network["netmask"] %>; +<% @options.each do |option| -%> + <%= option %>; +<% end -%> +<% @pools.each do |pool| -%> + pool6 { + range6 <%=@network["ranges"][pool]["start"]%> <%=@network["ranges"][pool]["end"]%>; + <% @pool_options[pool].each do |opt| -%> + <%=opt%><%=if opt[-1,1] != '}' then ';' else '' end%> + <% end if @pool_options[pool] -%> + } +<% end -%> +} + +<% end -%> diff --git a/chef/cookbooks/dhcp/templates/default/suse-sysconfig-dhcpd.erb b/chef/cookbooks/dhcp/templates/default/suse-sysconfig-dhcpd.erb index 34d3605af4..6d17f1d354 100644 --- a/chef/cookbooks/dhcp/templates/default/suse-sysconfig-dhcpd.erb +++ b/chef/cookbooks/dhcp/templates/default/suse-sysconfig-dhcpd.erb @@ -2,6 +2,7 @@ # Do not edit. <% unless @interfaces.empty? -%> DHCPD_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>" +DHCPD6_INTERFACE="<%= @interfaces.collect! {|i| "#{i}" }.join(" ") %>" <% end -%> DHCPD_IFUP_RESTART="" DHCPD_RUN_CHROOTED="no" diff --git a/chef/cookbooks/network/libraries/helpers.rb b/chef/cookbooks/network/libraries/helpers.rb new file mode 100644 index 0000000000..d94467878e --- /dev/null +++ b/chef/cookbooks/network/libraries/helpers.rb @@ -0,0 +1,12 @@ +module NetworkHelper + def self.wrap_ip(address) + require "ipaddr" + if IPAddr.new(address).ipv6? + "[#{address}]" + else + address.to_s + end + rescue + address.to_s + end +end diff --git a/chef/cookbooks/provisioner/recipes/base.rb b/chef/cookbooks/provisioner/recipes/base.rb index d0a0384a11..cb89fccde1 100644 --- a/chef/cookbooks/provisioner/recipes/base.rb +++ b/chef/cookbooks/provisioner/recipes/base.rb @@ -350,7 +350,7 @@ crowbar_node = node_search_with_cache("roles:crowbar").first address = crowbar_node["crowbar"]["network"]["admin"]["address"] protocol = crowbar_node["crowbar"]["apache"]["ssl"] ? "https" : "http" -server = "#{protocol}://#{address}" +server = "#{protocol}://#{NetworkHelper.wrap_ip(address)}" verify_ssl = !crowbar_node["crowbar"]["apache"]["insecure"] package "ruby2.1-rubygem-crowbar-client" diff --git a/chef/cookbooks/provisioner/recipes/dhcp_update.rb b/chef/cookbooks/provisioner/recipes/dhcp_update.rb index 3a6e01ca19..3af92212de 100644 --- a/chef/cookbooks/provisioner/recipes/dhcp_update.rb +++ b/chef/cookbooks/provisioner/recipes/dhcp_update.rb @@ -1,4 +1,6 @@ -admin_ip = Barclamp::Inventory.get_network_by_type(node, "admin").address +admin_net = Barclamp::Inventory.get_network_by_type(node, "admin") +admin_ip = admin_net.address +admin_ip_version = admin_net.ip_version dns_config = Barclamp::Config.load("core", "dns") dns_servers = dns_config["servers"] || [] @@ -8,16 +10,18 @@ admin_net = Barclamp::Inventory.get_network_definition(node, "admin") lease_time = node[:provisioner][:dhcp]["lease-time"] +web_port = node[:provisioner][:web_port] +admin6_uri = "http://[#{admin_ip}]:#{web_port}/discovery" -pool_opts = { - "dhcp" => ["allow unknown-clients", - "default-lease-time #{lease_time}", - "max-lease-time #{lease_time}", - 'if exists dhcp-parameter-request-list { +ipv4_dhcp_opts = [ + "allow unknown-clients", + "default-lease-time #{lease_time}", + "max-lease-time #{lease_time}", + 'if exists dhcp-parameter-request-list { # Always send the PXELINUX options (specified in hexadecimal) option dhcp-parameter-request-list = concat(option dhcp-parameter-request-list,d0,d1,d2,d3); }', - 'if option arch = 00:06 { + 'if option arch = 00:06 { filename = "discovery/ia32/efi/bootia32.efi"; } else if option arch = 00:07 { filename = "discovery/x86_64/efi/default/boot/bootx64.efi"; @@ -31,18 +35,55 @@ } else { filename = "discovery/x86_64/bios/pxelinux.0"; }', - "next-server #{admin_ip}"], + "next-server #{admin_ip}" +] + +ipv6_dhcp_opts = [ + "allow unknown-clients", + "default-lease-time #{lease_time}", + "max-lease-time #{lease_time}", + "option dhcp6.vendor-class 0 10 \"HTTPClient\"", + "if option dhcp6.client-arch-type = 00:06 { + option dhcp6.bootfile-url \"#{admin6_uri}/ia32/efi/bootia32.efi\"; + } else if option dhcp6.client-arch-type = 00:07 { + option dhcp6.bootfile-url \"#{admin6_uri}x86_64/efi/default/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:09 { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/default/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:10 { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/default/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:0b { + option dhcp6.bootfile-url \"#{admin6_uri}/aarch64/efi/default/boot/bootaa64.efi\"; + } else if option dhcp6.client-arch-type = 00:0e { + option dhcp6.bootfile-url \"#{admin6_uri}/ppc64le/bios/\"; + } else { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/default/boot/bootx64.efi\"; + }" +] + +pool_opts = { "host" => ["deny unknown-clients"] } +if admin_ip_version == "6" + pool_opts["dhcp"] = ipv6_dhcp_opts + subnet_options = [ + "option domain-name \"#{domain_name}\"", + "option dhcp6.name-servers #{dns_servers.join(", ")}" + ] +else + pool_opts["dhcp"] = ipv4_dhcp_opts + subnet_options = [ + "server-identifier #{admin_ip}", + "option domain-name \"#{domain_name}\"", + "option domain-name-servers #{dns_servers.join(", ")}" + ] +end + dhcp_subnet admin_net["subnet"] do action :add network admin_net pools ["dhcp","host"] pool_options pool_opts - options [ - "server-identifier #{admin_ip}", - "option domain-name \"#{domain_name}\"", - "option domain-name-servers #{dns_servers.join(", ")}" - ] + options subnet_options + ip_version admin_ip_version end diff --git a/chef/cookbooks/provisioner/recipes/setup_base_images.rb b/chef/cookbooks/provisioner/recipes/setup_base_images.rb index bf654d8115..71d62298bc 100644 --- a/chef/cookbooks/provisioner/recipes/setup_base_images.rb +++ b/chef/cookbooks/provisioner/recipes/setup_base_images.rb @@ -22,7 +22,7 @@ admin_ip = admin_net.address domain_name = node[:dns].nil? ? node[:domain] : (node[:dns][:domain] || node[:domain]) web_port = node[:provisioner][:web_port] -provisioner_web="http://#{admin_ip}:#{web_port}" +provisioner_web = "http://#{NetworkHelper.wrap_ip(admin_ip)}:#{web_port}" append_line = node[:provisioner][:discovery][:append].dup # We'll modify it inline enable_pxe = node[:provisioner][:enable_pxe] @@ -299,7 +299,7 @@ owner "root" group "root" mode "0644" - variables(tftproot: tftproot, admin_ip: admin_ip) + variables(tftproot: tftproot, admin_ip: NetworkHelper.wrap_ip(admin_ip)) end service "tftp.service" do @@ -505,7 +505,8 @@ web_port: web_port, ntp_servers_ips: ntp_servers, platform: target_platform_distro, - target_platform_version: target_platform_version) + target_platform_version: target_platform_version, + ip_version: admin_net.ip_version) end repos = Provisioner::Repositories.get_repos(target_platform_distro, @@ -534,7 +535,8 @@ repos: repos, packages: packages, platform: target_platform_distro, - target_platform_version: target_platform_version) + target_platform_version: target_platform_version, + ip_version: admin_net.ip_version) end missing_files = !File.exist?("#{os_dir}/install/boot/#{arch}/common") diff --git a/chef/cookbooks/provisioner/recipes/update_nodes.rb b/chef/cookbooks/provisioner/recipes/update_nodes.rb index 690a37f67f..bf04a1a9cc 100644 --- a/chef/cookbooks/provisioner/recipes/update_nodes.rb +++ b/chef/cookbooks/provisioner/recipes/update_nodes.rb @@ -152,6 +152,7 @@ def find_node_boot_mac_addresses(node, admin_data_net) admin_data_net = Chef::Recipe::Barclamp::Inventory.get_network_by_type(mnode, "admin") admin_mac_addresses = find_node_boot_mac_addresses(mnode, admin_data_net) admin_ip_address = admin_data_net.nil? ? mnode[:ipaddress] : admin_data_net.address + admin_prefix = admin_data_net.nil? ? "" : "#{admin_data_net.subnet}/#{admin_data_net.netmask}" #### # First deal with states that don't require PXE booting @@ -181,6 +182,8 @@ def find_node_boot_mac_addresses(node, admin_data_net) hostname mnode.name if admin_mac_addresses.include?(mac_list[i]) ipaddress admin_ip_address + prefix admin_prefix + ip_version admin_data_net.ip_version end macaddress mac_list[i] action :add @@ -219,19 +222,33 @@ def find_node_boot_mac_addresses(node, admin_data_net) #### # Everything below is for states that require PXE booting - append = [] - mac_list.each_index do |i| - dhcp_host "#{mnode.name}-#{i}" do - hostname mnode.name - macaddress mac_list[i] - if admin_mac_addresses.include?(mac_list[i]) - ipaddress admin_ip_address - options [ - "if exists dhcp-parameter-request-list { + if admin_data_net.ip_version == "6" + admin6_uri = "http://[#{admin_ip}]:#{web_port}/discovery" + dchp_options = [ + "option dhcp6.vendor-class 0 10 \"HTTPClient\"", + "if option dhcp6.client-arch-type = 00:06 { + option dhcp6.bootfile-url \"#{admin6_uri}/ia32/efi/bootia32.efi\"; + } else if option dhcp6.client-arch-type = 00:07 { + option dhcp6.bootfile-url \"#{admin6_uri}x86_64/efi/#{boot_ip_hex}/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:09 { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/#{boot_ip_hex}/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:10 { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/#{boot_ip_hex}/boot/bootx64.efi\"; + } else if option dhcp6.client-arch-type = 00:0b { + option dhcp6.bootfile-url \"#{admin6_uri}/aarch64/efi/#{boot_ip_hex}/boot/bootaa64.efi\"; + } else if option dhcp6.client-arch-type = 00:0e { + option dhcp6.bootfile-url \"#{admin6_uri}/ppc64le/bios/\"; + } else { + option dhcp6.bootfile-url \"#{admin6_uri}/x86_64/efi/#{boot_ip_hex}/boot/bootx64.efi\"; + }" + ] + else + dchp_options = [ + "if exists dhcp-parameter-request-list { # Always send the PXELINUX options (specified in hexadecimal) option dhcp-parameter-request-list = concat(option dhcp-parameter-request-list,d0,d1,d2,d3); }", - "if option arch = 00:06 { + "if option arch = 00:06 { filename = \"discovery/ia32/efi/#{boot_ip_hex}/boot/bootx64.efi\"; } else if option arch = 00:07 { filename = \"discovery/x86_64/efi/#{boot_ip_hex}/boot/bootx64.efi\"; @@ -245,8 +262,20 @@ def find_node_boot_mac_addresses(node, admin_data_net) } else { filename = \"discovery/x86_64/bios/pxelinux.0\"; }", - "next-server #{admin_ip}" - ] + "next-server #{admin_ip}" + ] + end + + append = [] + mac_list.each_index do |i| + dhcp_host "#{mnode.name}-#{i}" do + hostname mnode.name + macaddress mac_list[i] + if admin_mac_addresses.include?(mac_list[i]) + ipaddress admin_ip_address + options dchp_options + prefix admin_prefix + ip_version admin_data_net.ip_version end action :add end diff --git a/chef/cookbooks/provisioner/templates/default/crowbar_join.suse.sh.erb b/chef/cookbooks/provisioner/templates/default/crowbar_join.suse.sh.erb index f898eeb1d4..cbffce1038 100644 --- a/chef/cookbooks/provisioner/templates/default/crowbar_join.suse.sh.erb +++ b/chef/cookbooks/provisioner/templates/default/crowbar_join.suse.sh.erb @@ -111,7 +111,11 @@ wait_for_hostname() { wait_for_admin_server() { # wait for admin server to become pingable tries_left=120 - while ! ping -q -c1 $IP > /dev/null; do + local ping="ping" + if (( $IPV6 > 0 )); then + ping="ping6" + fi + while ! $ping -q -c1 $IP > /dev/null; do tries_left=$(($tries_left-1)) if [ $tries_left -eq 0 ]; then return 1 @@ -160,9 +164,9 @@ do_setup() { # Make sure that the client knows how to talk to the server. local cfg=/etc/chef/client.rb if ! [ -f $cfg ] || \ - ! grep -q "^\s*chef_server_url\s*[\"\']http://$IP:4000[\"\']" $cfg; then + ! grep -q "^\s*chef_server_url\s*[\"\']http://$IP_WRAPPED:4000[\"\']" $cfg; then test -f $cfg && mv $cfg $cfg.bak - echo "chef_server_url \"http://$IP:4000\"" >$cfg + echo "chef_server_url \"http://$IP_WRAPPED:4000\"" >$cfg echo "zypper_check_gpg true" >> $cfg fi @@ -395,7 +399,17 @@ EXVAL=0 export HOME=/root IP="<%= @admin_ip %>" -HTTP_SERVER="<%= @admin_ip %>:<%= @web_port %>" +<% if @ip_version == "6" -%> +IPV6=1 +<% else -%> +IPV6=0 +<% end -%> +if (( $IPV6 > 0 )); then + IP_WRAPPED="[$IP]" +else + IP_WRAPPED="$IP" +fi +HTTP_SERVER="$IP_WRAPPED:<%= @web_port %>" NTP_SERVERS="<%= @ntp_servers_ips.join(" ") %>" VALID_NTP_SERVERS="" diff --git a/chef/cookbooks/provisioner/templates/default/tftp.erb b/chef/cookbooks/provisioner/templates/default/tftp.erb index ba53690d62..97c72cf718 100644 --- a/chef/cookbooks/provisioner/templates/default/tftp.erb +++ b/chef/cookbooks/provisioner/templates/default/tftp.erb @@ -8,7 +8,7 @@ service tftp socket_type = dgram protocol = udp wait = yes - flags = IPv4 + flags = IPv6 IPv4 user = root server = /usr/sbin/in.tftpd server_args = -m /etc/tftpd.conf -s <%=@tftproot%> diff --git a/chef/cookbooks/provisioner/templates/suse/crowbar_register.erb b/chef/cookbooks/provisioner/templates/suse/crowbar_register.erb index 5b5fabfefb..70a39d24a6 100644 --- a/chef/cookbooks/provisioner/templates/suse/crowbar_register.erb +++ b/chef/cookbooks/provisioner/templates/suse/crowbar_register.erb @@ -131,7 +131,12 @@ add_user() { ADMIN_IP="<%= @admin_ip %>" ADMIN_BROADCAST="<%= @admin_broadcast %>" WEB_PORT="<%= @web_port %>" -HTTP_SERVER="http://${ADMIN_IP}:${WEB_PORT}" +<% if @ip_version == "6" -%> +ADMIN_IP_WRAPPED="[$ADMIN_IP]" +<% else -%> +ADMIN_IP_WRAPPED="$ADMIN_IP" +<% end -%> +HTTP_SERVER="http://${ADMIN_IP_WRAPPED}:${WEB_PORT}" CROWBAR_OS="<%= @os %>" CROWBAR_ARCH="<%= @arch %>" DOMAIN="<%= @domain %>" @@ -387,7 +392,7 @@ TMP_ATTRIBUTES=$(mktemp --suffix .json) echo "{ \"target_platform\": \"$CROWBAR_OS\", \"crowbar_wall\": { \"registering\": true } }" > "$TMP_ATTRIBUTES" crowbarctl restricted transition $HOSTNAME "discovering" -chef-client -S http://$ADMIN_IP:4000/ -N "$HOSTNAME" --json-attributes "$TMP_ATTRIBUTES" +chef-client -S http://$ADMIN_IP_WRAPPED:4000/ -N "$HOSTNAME" --json-attributes "$TMP_ATTRIBUTES" crowbarctl restricted transition $HOSTNAME "discovered" # TODO need to find way of knowing that chef run is over on server side sleep 30 @@ -399,7 +404,7 @@ echo '{ "crowbar_wall": { "registering": true } }' > "$TMP_ATTRIBUTES" rm -f /etc/chef/client.pem crowbarctl restricted transition $HOSTNAME "hardware-installing" -chef-client -S http://$ADMIN_IP:4000/ -N "$HOSTNAME" --json-attributes "$TMP_ATTRIBUTES" +chef-client -S http://$ADMIN_IP_WRAPPED:4000/ -N "$HOSTNAME" --json-attributes "$TMP_ATTRIBUTES" crowbarctl restricted transition $HOSTNAME "hardware-installed" #TODO #wait_for_pxe_state ".*_install" From b2236090cde22eb67940d7da53ca0b3a30fa4ef7 Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Fri, 29 Mar 2019 17:25:39 +1100 Subject: [PATCH 2/5] ipv6: append the adminip to the cmdline of the discovery image When the sleshammer discovery image boots on nodes in an IPv6 environment there is no sane way of determining the admin ip. In IPv4 we can grab it from the SERVERID produced by wicked's dhcpd4 binary. Except in IPv6 the serverid seems to the be DHCP DUID. This patch adds an 'adminip=..' option to the commandline for the discovery image. The start-up.sh script and sleshammer image has been modified seperately. --- chef/cookbooks/provisioner/recipes/setup_base_images.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chef/cookbooks/provisioner/recipes/setup_base_images.rb b/chef/cookbooks/provisioner/recipes/setup_base_images.rb index 71d62298bc..79118bca42 100644 --- a/chef/cookbooks/provisioner/recipes/setup_base_images.rb +++ b/chef/cookbooks/provisioner/recipes/setup_base_images.rb @@ -80,7 +80,7 @@ owner "root" group "root" source "default.erb" - variables(append_line: "#{append_line} crowbar.state=discovery", + variables(append_line: "#{append_line} crowbar.state=discovery adminip=#{admin_ip}", install_name: "discovery", initrd: "../initrd0.img", kernel: "../vmlinuz0") @@ -151,7 +151,7 @@ owner "root" group "root" source "grub.conf.erb" - variables(append_line: "#{append_line} crowbar.state=discovery", + variables(append_line: "#{append_line} crowbar.state=discovery adminip=#{admin_ip}", install_name: "Crowbar Discovery Image", admin_ip: admin_ip, efi_suffix: arch == "x86_64", From c03c408250d089d6cd096e036f41f0f12df937bd Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Mon, 27 May 2019 16:45:16 +1000 Subject: [PATCH 3/5] IPv6: ntp.conf requires netmask in non CIDR format The ntp.conf used in crowbar wont work with IPv6 as the netmask in the ntp conf file need to be in the full form not CIDR. This patch adds a new method, cidr_to_subnet to the Barclamp library's Network class. Which is then used to send the correct string to the ntp.conf.erb template. Allowing the crowbar nodes being booted via the sleshammer discovery image to sync with the admin node. --- .../barclamp/libraries/barclamp_library.rb | 24 +++++++++++++++++++ chef/cookbooks/ntp/recipes/default.rb | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/chef/cookbooks/barclamp/libraries/barclamp_library.rb b/chef/cookbooks/barclamp/libraries/barclamp_library.rb index 6b01dffb71..f05d104361 100644 --- a/chef/cookbooks/barclamp/libraries/barclamp_library.rb +++ b/chef/cookbooks/barclamp/libraries/barclamp_library.rb @@ -132,6 +132,30 @@ def interface_list @interface_list end + def cidr_to_netmask + if @ip_version == "6" + range = 128 + else + range = 32 + end + + cidr = Integer(@netmask) rescue nil + if cidr && !(1..range).cover?(cidr) + Chef::Log.error("Invalid CIDR netmask '#{cidr}' > '#{range}'") + return @netmask + end + + if cidr + if @ip_version == "6" + IPAddr.new('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').mask(cidr).to_s + else + IPAddr.new('255.255.255.255').mask(cidr).to_s + end + else + @netmask + end + end + protected def resolve_interface_info diff --git a/chef/cookbooks/ntp/recipes/default.rb b/chef/cookbooks/ntp/recipes/default.rb index 907411919e..d64da3241b 100644 --- a/chef/cookbooks/ntp/recipes/default.rb +++ b/chef/cookbooks/ntp/recipes/default.rb @@ -79,7 +79,7 @@ variables(ntp_servers: ntp_servers, admin_interface: local_admin_address, admin_subnet: admin_net.subnet, - admin_netmask: admin_net.netmask, + admin_netmask: admin_net.cidr_to_netmask(), is_server: is_server, listen_interfaces: listen_network_addresses || [], fudgevalue: 10, From 4e70134aa6a6dd97702714c83d03340ea4e061ea Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Thu, 4 Jul 2019 15:18:49 +1000 Subject: [PATCH 4/5] ipv6: add ipv6 support to control scripts, bind9 and more dhcp6 fixes --- chef/cookbooks/bind9/recipes/default.rb | 14 +++++--- .../provisioner/recipes/dhcp_update.rb | 2 +- .../provisioner/recipes/update_nodes.rb | 12 ++++--- updates/control.sh | 35 ++++++++++++------- updates/control_lib.sh | 16 +++++---- 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/chef/cookbooks/bind9/recipes/default.rb b/chef/cookbooks/bind9/recipes/default.rb index c6a9a42510..ab8c4e14ef 100644 --- a/chef/cookbooks/bind9/recipes/default.rb +++ b/chef/cookbooks/bind9/recipes/default.rb @@ -152,6 +152,10 @@ def make_zone(zone) zonefile_entries end +def address_version(address) + 'ip6addr' if IPAddr.new(address).ipv6? + 'ip4addr' if IPAddr.new(address).ipv4? +end # Create our basic zone infrastructure. zones = Mash.new @@ -207,7 +211,7 @@ def make_zone(zone) alias_name = "#{net_name}-#{alias_name_no_net}" if alias_name_no_net end cluster_zone[:hosts][base_name] = Mash.new - cluster_zone[:hosts][base_name][:ip4addr] = network.address + cluster_zone[:hosts][base_name][address_version(network.address)] = network.address cluster_zone[:hosts][base_name][:alias] = alias_name if alias_name end @@ -238,7 +242,7 @@ def make_zone(zone) temporary_dhcp.each_pair do |address, value| _, base_name, alias_name = value cluster_zone[:hosts][base_name] = Mash.new - cluster_zone[:hosts][base_name][:ip4addr] = address + cluster_zone[:hosts][base_name][address_version(address)] = address cluster_zone[:hosts][base_name][:alias] = alias_name if alias_name end @@ -257,7 +261,8 @@ def make_zone(zone) base_name="#{net_name}-#{base_name}" end cluster_zone[:hosts][base_name] = Mash.new - cluster_zone[:hosts][base_name][:ip4addr] = network[:allocated_by_name][host][:address] + address = network[:allocated_by_name][host][:address] + cluster_zone[:hosts][base_name][address_version(address)] = address end end @@ -388,8 +393,7 @@ def make_zone(zone) end end -### FIXME Change to "any" once IPv6 support has been implemented -admin_addr6 = "none" +admin_addr6 = "any" if node[:dns][:enable_designate] && !node[:dns][:master] node[:dns][:forwarders].push master_ip end diff --git a/chef/cookbooks/provisioner/recipes/dhcp_update.rb b/chef/cookbooks/provisioner/recipes/dhcp_update.rb index 3af92212de..fedaec4600 100644 --- a/chef/cookbooks/provisioner/recipes/dhcp_update.rb +++ b/chef/cookbooks/provisioner/recipes/dhcp_update.rb @@ -67,7 +67,7 @@ if admin_ip_version == "6" pool_opts["dhcp"] = ipv6_dhcp_opts subnet_options = [ - "option domain-name \"#{domain_name}\"", + "option dhcp6.domain-search \"#{domain_name}\"", "option dhcp6.name-servers #{dns_servers.join(", ")}" ] else diff --git a/chef/cookbooks/provisioner/recipes/update_nodes.rb b/chef/cookbooks/provisioner/recipes/update_nodes.rb index bf04a1a9cc..544fc8026d 100644 --- a/chef/cookbooks/provisioner/recipes/update_nodes.rb +++ b/chef/cookbooks/provisioner/recipes/update_nodes.rb @@ -54,9 +54,10 @@ def find_node_boot_mac_addresses(node, admin_data_net) states = node["provisioner"]["dhcp"]["state_machine"] tftproot = node["provisioner"]["root"] timezone = node["provisioner"]["timezone"] -admin_ip = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin").address +admin_net = Chef::Recipe::Barclamp::Inventory.get_network_by_type(node, "admin") +admin_ip = admin_net.address web_port = node[:provisioner][:web_port] -provisioner_web = "http://#{admin_ip}:#{web_port}" +provisioner_web = "http://#{NetworkHelper.wrap_ip(admin_ip)}:#{web_port}" dhcp_hosts_dir = node["provisioner"]["dhcp_hosts"] virtual_intfs = ["tap", "qbr", "qvo", "qvb", "brq", "ovs", "vxl"] @@ -153,6 +154,7 @@ def find_node_boot_mac_addresses(node, admin_data_net) admin_mac_addresses = find_node_boot_mac_addresses(mnode, admin_data_net) admin_ip_address = admin_data_net.nil? ? mnode[:ipaddress] : admin_data_net.address admin_prefix = admin_data_net.nil? ? "" : "#{admin_data_net.subnet}/#{admin_data_net.netmask}" + admin_ip_version = admin_data_net.nil? ? "4" : admin_data_net.ip_version #### # First deal with states that don't require PXE booting @@ -222,7 +224,7 @@ def find_node_boot_mac_addresses(node, admin_data_net) #### # Everything below is for states that require PXE booting - if admin_data_net.ip_version == "6" + if admin_ip_version == "6" admin6_uri = "http://[#{admin_ip}]:#{web_port}/discovery" dchp_options = [ "option dhcp6.vendor-class 0 10 \"HTTPClient\"", @@ -275,7 +277,7 @@ def find_node_boot_mac_addresses(node, admin_data_net) ipaddress admin_ip_address options dchp_options prefix admin_prefix - ip_version admin_data_net.ip_version + ip_version admin_ip_version end action :add end @@ -379,7 +381,7 @@ def find_node_boot_mac_addresses(node, admin_data_net) if node[:provisioner][:use_serial_console] append << "textmode=1" end - append << "ifcfg=dhcp4 netwait=60" + append << "ifcfg=dhcp#{admin_net.ip_version} netwait=60" append << "squash=0" # workaround bsc#962397 append << "autoupgrade=1" if mnode[:state] == "os-upgrading" diff --git a/updates/control.sh b/updates/control.sh index 2beec7fa93..98e44122c4 100755 --- a/updates/control.sh +++ b/updates/control.sh @@ -17,7 +17,7 @@ # # We get the following variables from start-up.sh -# MAC BOOTDEV ADMIN_IP DOMAIN HOSTNAME HOSTNAME_MAC MYIP +# MAC BOOTDEV ADMIN_IP ADMIN_IP_WRAPPED DOMAIN HOSTNAME HOSTNAME_MAC MYIP IP_VERSION if [[ ! $IN_SCRIPT ]]; then export IN_SCRIPT=true @@ -58,10 +58,21 @@ function is_suse() { # kernel variable (pre-install). # hostname_re='crowbar\.hostname=([^ ]+)' -[[ $(cat /proc/cmdline) =~ $hostname_re ]] && \ - HOSTNAME="${BASH_REMATCH[1]}" || \ - HOSTNAME="d${MAC//:/-}.${DOMAIN}" +if [[ $(cat /proc/cmdline) =~ $hostname_re ]]; then + HOSTNAME="${BASH_REMATCH[1]}" +else + if [ -n "$DOMAIN" ]; then + HOSTNAME="d${MAC//:/-}.${DOMAIN}" + else + HOSTNAME="d${MAC//:/-}" + fi +fi sed -i -e "s/\(127\.0\.0\.1.*\)/127.0.0.1 $HOSTNAME ${HOSTNAME%%.*} localhost.localdomain localhost/" /etc/hosts +ADMIN_IP_WRAPPED="$ADMIN_IP" +if (( $IP_VERSION == 6 )); then + sed -i -e "s/\(\:\:1.*\)/::1 $HOSTNAME ${HOSTNAME%%.*} localhost.localdomain localhost ipv6-localhost ipv6-loopback/" /etc/hosts + ADMIN_IP_WRAPPED="[$ADMIN_IP]" +fi if is_suse; then echo "$HOSTNAME" > /etc/HOSTNAME else @@ -88,7 +99,7 @@ is_suse && { # enable remote logging to our admin node. if ! grep -q "${ADMIN_IP}" /etc/rsyslog.conf; then echo "# Sledgehammer added to log to the admin node" >> /etc/rsyslog.conf - echo "*.* @@${ADMIN_IP}" >> /etc/rsyslog.conf + echo "*.* @@${ADMIN_IP_WRAPPED}" >> /etc/rsyslog.conf service $RSYSLOGSERVICE restart fi @@ -96,7 +107,7 @@ fi (umask 077 ; mkdir -p /root/.ssh) curl -L -o /root/.ssh/authorized_keys \ --connect-timeout 60 -s \ - "http://$ADMIN_IP:8091/authorized_keys" + "http://$ADMIN_IP_WRAPPED:8091/authorized_keys" MYINDEX=${MYIP##*.} DHCP_STATE=$(grep -o -E 'crowbar\.state=[^ ]+' /proc/cmdline) @@ -110,8 +121,8 @@ BMC_ADDRESS="" BMC_NETMASK="" BMC_ROUTER="" ALLOCATED=false -export DHCP_STATE MYINDEX ADMIN_ADDRESS BMC_ADDRESS BMC_NETMASK BMC_ROUTER ADMIN_IP -export ALLOCATED HOSTNAME CROWBAR_KEY CROWBAR_STATE +export DHCP_STATE MYINDEX ADMIN_ADDRESS BMC_ADDRESS BMC_NETMASK BMC_ROUTER ADMIN_IP ADMIN_IP_WRAPPED +export ALLOCATED HOSTNAME CROWBAR_KEY CROWBAR_STATE IP_VERSION # Make sure date is up-to-date until /usr/sbin/ntpdate $ADMIN_IP || [[ $DHCP_STATE = 'debug' ]]; do @@ -139,7 +150,7 @@ then # Other gem dependency installs. cat > /etc/gemrc < /dev/null echo "New local IP Addresses:" - ip a | awk '/127.0.0./ { next; } /inet / { print }' + ip a | awk '/127.0.0./ { next; } /inet / { print } /inet6 / { print }' fi return 0 } @@ -263,7 +274,7 @@ walk_node_through () { post_state "$name" "$1" && \ renew_dhcp_after_hwinstalling $1 && \ run_hooks "$HOSTNAME" "$1" pre && \ - chef-client -S http://$ADMIN_IP:4000/ -N "$name" && \ + chef-client -S http://$ADMIN_IP_WRAPPED:4000/ -N "$name" && \ run_hooks "$HOSTNAME" "$1" post || \ { post_state "$name" problem; reboot_system; } shift diff --git a/updates/control_lib.sh b/updates/control_lib.sh index 9cd59e326f..b563d6c8b8 100755 --- a/updates/control_lib.sh +++ b/updates/control_lib.sh @@ -40,7 +40,7 @@ parse_node_data() { echo "ADMIN_ADDRESS=${ADMIN_ADDRESS}" echo "ALLOCATED=${ALLOCATED}" echo "Local IP addresses:" - ip a | awk '/127.0.0./ { next; } /inet / { print }' + ip a | awk '/127.0.0./ { next; } /inet / { print } /inet6 / { print }' } try_to() { @@ -64,7 +64,7 @@ __post_state() { # $1 = hostname, $2 = target state USER="$(sed -e 's/:[^:]*$//' <<< $CROWBAR_KEY)" PASS="$(sed -e 's/^.*://' <<< $CROWBAR_KEY)" - crowbarctl restricted transition "$1" "$2" -s "http://$ADMIN_IP" -U $USER -P $PASS --no-verify-ssl + crowbarctl restricted transition "$1" "$2" -s "http://$ADMIN_IP_WRAPPED" -U $USER -P $PASS --no-verify-ssl local RET=$? __get_state "$1" return $RET @@ -74,7 +74,7 @@ __get_state() { # $1 = hostname USER="$(sed -e 's/:[^:]*$//' <<< $CROWBAR_KEY)" PASS="$(sed -e 's/^.*://' <<< $CROWBAR_KEY)" - parse_node_data < <(crowbarctl restricted show $1 -s "http://$ADMIN_IP" -U $USER -P $PASS --no-verify-ssl --plain) + parse_node_data < <(crowbarctl restricted show $1 -s "http://$ADMIN_IP_WRAPPED" -U $USER -P $PASS --no-verify-ssl --plain) } post_state() { try_to "$MAXTRIES" 15 __post_state "$@"; } @@ -141,7 +141,11 @@ wait_for_pxe() { # 22 is the curl exit code for HTTP status codes of 400 and above # convert ADMIN_ADDRESS from decimal to hex - MYHEXIP=`IFS="." ; for i in $ADMIN_ADDRESS; do printf '%02X' $i ; done` + if (( $IP_VERSION == 6 )); then + MYHEXIP=`IFS=":" ; for i in $ADMIN_ADDRESS; do printf '%s' $i ; done` + else + MYHEXIP=`IFS="." ; for i in $ADMIN_ADDRESS; do printf '%02X' $i ; done` + fi count=0 done=0 @@ -156,10 +160,10 @@ wait_for_pxe() { until [ 1 = $done ] ; do if [ -n "$state" ]; then - curl --fail --silent --connect-timeout 5 "http://$ADMIN_IP:8091/discovery/$arch/bios/pxelinux.cfg/$MYHEXIP" | grep -q "^DEFAULT $state$" + curl --fail --silent --connect-timeout 5 "http://$ADMIN_IP_WRAPPED:8091/discovery/$arch/bios/pxelinux.cfg/$MYHEXIP" | grep -q "^DEFAULT $state$" ret=$? else - curl --fail --silent --head --connect-timeout 5 "http://$ADMIN_IP:8091/discovery/$arch/bios/pxelinux.cfg/$MYHEXIP" > /dev/null + curl --fail --silent --head --connect-timeout 5 "http://$ADMIN_IP_WRAPPED:8091/discovery/$arch/bios/pxelinux.cfg/$MYHEXIP" > /dev/null ret=$? fi From ee488f95dc4a3e30dd4d17aa9dbf22b8cd2cdd15 Mon Sep 17 00:00:00 2001 From: Matthew Oliver Date: Thu, 4 Jul 2019 15:22:46 +1000 Subject: [PATCH 5/5] IPv6: Make sure the address written to crowbarrc is wrapped --- chef/cookbooks/crowbar/recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chef/cookbooks/crowbar/recipes/default.rb b/chef/cookbooks/crowbar/recipes/default.rb index 11d9c4cd3d..d537b53880 100644 --- a/chef/cookbooks/crowbar/recipes/default.rb +++ b/chef/cookbooks/crowbar/recipes/default.rb @@ -279,7 +279,7 @@ if node[:crowbar][:network].key?(:admin) && node[:crowbar].key?(:apache) address = node[:crowbar][:network][:admin][:address] protocol = node[:crowbar][:apache][:ssl] ? "https" : "http" - server = "#{protocol}://#{address}" + server = "#{protocol}://#{NetworkHelper.wrap_ip(address)}" verify_ssl = !node[:crowbar][:apache][:insecure] else server = nil