From 3c2403550586423cc92673e25d8aecfc27175be9 Mon Sep 17 00:00:00 2001 From: Vincent Liu Date: Wed, 8 Jan 2025 21:32:15 +0000 Subject: [PATCH] CA-404512: Add feature flag to the new clustering interface The new clustering interface uses a constructor `Extended` address when a cluster hots is trying to join a cluster. This causes problems during upgrades as a newly upgraded host might send out the new address format to old hosts, which do not understand this format, causing the new hosts not able to join. The fix would be to use a new cluster_address feature flag/pool restrictions to control the use of the new clustering interface. This makes sure that the new interface would only be used if all of the hosts understand this new interface, i.e. have this feature enabled. The cluster_address feature is controlled by v6d and is pool-wide, therefore the new interface would only be enabled if all v6ds are updated to the correct level, which also implies that the accompanying xapi are updated to the correct level. Signed-off-by: Vincent Liu --- ocaml/xapi-types/features.ml | 2 ++ ocaml/xapi-types/features.mli | 1 + ocaml/xapi/xapi_cluster.ml | 9 ++------- ocaml/xapi/xapi_cluster_helpers.ml | 8 ++++++++ ocaml/xapi/xapi_cluster_host.ml | 19 ++++--------------- ocaml/xapi/xapi_cluster_host_helpers.ml | 14 ++++++++++++++ 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ocaml/xapi-types/features.ml b/ocaml/xapi-types/features.ml index c80d3c833a5..52469387acc 100644 --- a/ocaml/xapi-types/features.ml +++ b/ocaml/xapi-types/features.ml @@ -58,6 +58,7 @@ type feature = | USB_passthrough | Network_sriov | Corosync + | Cluster_address | Zstd_export | Pool_secret_rotation | Certificate_verification @@ -123,6 +124,7 @@ let keys_of_features = ; (USB_passthrough, ("restrict_usb_passthrough", Negative, "USB_passthrough")) ; (Network_sriov, ("restrict_network_sriov", Negative, "Network_sriov")) ; (Corosync, ("restrict_corosync", Negative, "Corosync")) + ; (Cluster_address, ("restrict_cluster_address", Negative, "Cluster_address")) ; (Zstd_export, ("restrict_zstd_export", Negative, "Zstd_export")) ; ( Pool_secret_rotation , ("restrict_pool_secret_rotation", Negative, "Pool_secret_rotation") diff --git a/ocaml/xapi-types/features.mli b/ocaml/xapi-types/features.mli index f6efce3f0a5..018749cb685 100644 --- a/ocaml/xapi-types/features.mli +++ b/ocaml/xapi-types/features.mli @@ -65,6 +65,7 @@ type feature = | USB_passthrough (** Enable the use of USB passthrough. *) | Network_sriov (** Enable the use of Network SRIOV. *) | Corosync (** Enable the use of corosync. *) + | Cluster_address (** Enable the use of extended cluster address interface *) | Zstd_export (** Enable the use of VM export with zstd compression. *) | Pool_secret_rotation (** Enable Pool Secret Rotation *) | Certificate_verification (** Used by XenCenter *) diff --git a/ocaml/xapi/xapi_cluster.ml b/ocaml/xapi/xapi_cluster.ml index 498a0ea4111..1968e5f0774 100644 --- a/ocaml/xapi/xapi_cluster.ml +++ b/ocaml/xapi/xapi_cluster.ml @@ -13,7 +13,6 @@ *) open Xapi_clustering -open Ipaddr_rpc_type module D = Debug.Make (struct let name = "xapi_cluster" end) @@ -65,12 +64,8 @@ let create ~__context ~pIF ~cluster_stack ~pool_auto_join ~token_timeout let hostuuid = Inventory.lookup Inventory._installation_uuid in let hostname = Db.Host.get_hostname ~__context ~self:host in let member = - Extended - { - ip= Ipaddr.of_string_exn (ipstr_of_address ip_addr) - ; hostuuid - ; hostname - } + Xapi_cluster_host_helpers.get_cluster_host_address ~__context ~ip_addr + ~hostuuid ~hostname in let token_timeout_ms = Int64.of_float (token_timeout *. 1000.0) in let token_timeout_coefficient_ms = diff --git a/ocaml/xapi/xapi_cluster_helpers.ml b/ocaml/xapi/xapi_cluster_helpers.ml index 954b946b0fa..a4d30bcedaa 100644 --- a/ocaml/xapi/xapi_cluster_helpers.ml +++ b/ocaml/xapi/xapi_cluster_helpers.ml @@ -12,6 +12,8 @@ * GNU Lesser General Public License for more details. *) +module D = Debug.Make (struct let name = __MODULE__ end) + let finally = Xapi_stdext_pervasives.Pervasiveext.finally let all_cluster_operations = [`add; `remove; `enable; `disable; `destroy] @@ -104,6 +106,12 @@ let with_cluster_operation ~__context ~(self : [`Cluster] API.Ref.t) ~doc ~op with _ -> () ) +let cluster_address_enabled ~__context = + let r = Pool_features.is_enabled ~__context Features.Cluster_address in + D.debug "%s extended cluster address is %s" __FUNCTION__ + (if r then "enabled" else "disabled") ; + r + let corosync3_enabled ~__context = let pool = Helpers.get_pool ~__context in let restrictions = Db.Pool.get_restrictions ~__context ~self:pool in diff --git a/ocaml/xapi/xapi_cluster_host.ml b/ocaml/xapi/xapi_cluster_host.ml index e022f75c706..713261931a4 100644 --- a/ocaml/xapi/xapi_cluster_host.ml +++ b/ocaml/xapi/xapi_cluster_host.ml @@ -13,7 +13,6 @@ *) open Xapi_clustering -open Ipaddr_rpc_type module D = Debug.Make (struct let name = "xapi_cluster_host" end) @@ -126,12 +125,8 @@ let join_internal ~__context ~self = let host = Db.Cluster_host.get_host ~__context ~self in let hostname = Db.Host.get_hostname ~__context ~self:host in let member = - Extended - { - ip= Ipaddr.of_string_exn (ipstr_of_address ip_addr) - ; hostuuid - ; hostname - } + Xapi_cluster_host_helpers.get_cluster_host_address ~__context ~ip_addr + ~hostuuid ~hostname in let ip_list = List.filter_map @@ -338,14 +333,8 @@ let enable ~__context ~self = let hostuuid = Inventory.lookup Inventory._installation_uuid in let hostname = Db.Host.get_hostname ~__context ~self:host in let member = - Cluster_interface.( - Extended - { - ip= Ipaddr.of_string_exn (ipstr_of_address ip_addr) - ; hostuuid - ; hostname - } - ) + Xapi_cluster_host_helpers.get_cluster_host_address ~__context ~ip_addr + ~hostuuid ~hostname in let cluster_ref = Db.Cluster_host.get_cluster ~__context ~self in let cluster_stack = diff --git a/ocaml/xapi/xapi_cluster_host_helpers.ml b/ocaml/xapi/xapi_cluster_host_helpers.ml index 37e16d43178..59e5141da73 100644 --- a/ocaml/xapi/xapi_cluster_host_helpers.ml +++ b/ocaml/xapi/xapi_cluster_host_helpers.ml @@ -106,3 +106,17 @@ let with_cluster_host_operation ~__context ~(self : [`Cluster_host] API.Ref.t) (Datamodel_common._cluster_host, Ref.string_of self) with _ -> () ) + +let get_cluster_host_address ~__context ~ip_addr ~hostuuid ~hostname = + let open Ipaddr_rpc_type in + if Xapi_cluster_helpers.cluster_address_enabled ~__context then + Cluster_interface.( + Extended + { + ip= Ipaddr.of_string_exn (ipstr_of_address ip_addr) + ; hostuuid + ; hostname + } + ) + else + Cluster_interface.(IPv4 (ipstr_of_address ip_addr))