# HG changeset patch # User Rob Hoes Update firstboot network data before pool eject When a host is ejected from a pool, its XAPI database objects are removed and recreated by the firstboot scripts after the host reboots. The data used by the firstboot scripts is stored when the host is installed, and never updated anymore after that. Part of the firstboot data is the assignment and IP configuration of the management interface. This patch updates the firstboot data to reflect the current configuration of the management interface on pool eject, such that after the reboot, management is configured in the same way as before. As pool eject removes any bonds, in case management is on a bond, one of the slaves is chosen to become the new management interface. Signed-off-by: Rob Hoes diff -r 98791645ddbb ocaml/xapi/xapi_globs.ml --- a/ocaml/xapi/xapi_globs.ml +++ b/ocaml/xapi/xapi_globs.ml @@ -613,3 +613,5 @@ (** Default feature mask: EST (base_ecx.7) is ignored. *) let cpuid_default_feature_mask = "ffffff7f-ffffffff-ffffffff-ffffffff" +let first_boot_dir = "/etc/firstboot.d/" + diff -r 98791645ddbb ocaml/xapi/xapi_host.ml --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -762,7 +762,11 @@ syslog_config_write destination destination_only listen_remote - +let get_management_interface ~__context ~host = + let pifs = Db.PIF.get_all_records ~__context in + let management_pif, _ = List.find (fun (_, pif) -> pif.API.pIF_management && pif.API.pIF_host = host) pifs in + management_pif + let change_management_interface ~__context interface = debug "Changing management interface"; let addrs = Netdev.Addr.get interface in diff -r 98791645ddbb ocaml/xapi/xapi_host.mli --- a/ocaml/xapi/xapi_host.mli +++ b/ocaml/xapi/xapi_host.mli @@ -116,12 +116,19 @@ val request_config_file_sync : __context:'a -> host:'b -> hash:string -> unit val syslog_config_write : string -> bool -> bool -> unit val syslog_reconfigure : __context:Context.t -> host:'a -> unit + +(** {2 Management Interface} *) + +val get_management_interface : __context:Context.t -> host:API.ref_host -> API.ref_PIF val change_management_interface : __context:Context.t -> string -> unit val local_management_reconfigure : __context:Context.t -> interface:string -> unit val management_reconfigure : __context:Context.t -> pif:[ `PIF ] Ref.t -> unit val management_disable : __context:Context.t -> unit + +(** {2 (Fill in title!)} *) + val get_system_status_capabilities : __context:'a -> host:API.ref_host -> string val get_diagnostic_timing_stats : diff -r 98791645ddbb ocaml/xapi/xapi_pool.ml --- a/ocaml/xapi/xapi_pool.ml +++ b/ocaml/xapi/xapi_pool.ml @@ -651,6 +651,51 @@ (* FIXME: in the future, we should send the windows AD admin/pass here *) (* in order to remove the slave from the AD database during pool-eject *) + debug "Pool.eject: rewrite networking first-boot files"; + let management_pif = Xapi_host.get_management_interface ~__context ~host in + let pif = Db.PIF.get_record ~__context ~self:management_pif in + let management_mac = + (* assumes that the management interface is either physical or a bond *) + if pif.API.pIF_bond_master_of <> [] then + let bond = List.hd pif.API.pIF_bond_master_of in + let slaves = Db.Bond.get_slaves ~__context ~self:bond in + let first_slave = List.hd slaves in + Db.PIF.get_MAC ~__context ~self:first_slave + else + pif.API.pIF_MAC + in + let mode = match pif.API.pIF_ip_configuration_mode with + | `None -> "none" + | `DHCP -> "dhcp" + | `Static -> "static" + in + let t = Xapi_pif.make_tables ~__context ~host in + let interfaces = List.fold_left + (fun ifs (mac, device) -> + let s = + if mac <> management_mac then + "LABEL='" ^ device ^ "'\nMODE=none\n" + else begin + let bridge = Xapi_pif.bridge_naming_convention device in + Xapi_inventory.update Xapi_inventory._management_interface bridge; + "LABEL='" ^ device ^ "'\nMODE=" ^ mode ^ + if mode = "static" then + "\nIP=" ^ pif.API.pIF_IP ^ + "\nNETMASK=" ^ pif.API.pIF_netmask ^ + "\nGATEWAY=" ^ pif.API.pIF_gateway ^ + "\nDNS=" ^ pif.API.pIF_DNS ^ "\n" + else + "\n" + end + in + Unixext.write_string_to_file (Xapi_globs.first_boot_dir ^ "data/interface-" ^ mac ^ ".conf") s; + mac :: ifs + ) [] t.Xapi_pif.mac_to_biosname_table + in + let s = "ADMIN_INTERFACE='" ^ management_mac ^ "'\nINTERFACES='" ^ (String.concat " " interfaces) ^ "'\n" in + Unixext.write_string_to_file (Xapi_globs.first_boot_dir ^ "data/network.conf") s; + Xapi_inventory.update Xapi_inventory._current_interfaces ""; + debug "Pool.eject: deleting Host record (the point of no return)"; (* delete me from the database - this will in turn cause PBDs and PIFs to be GCed *) Db.Host.destroy ~__context ~self:host;