2222import java .net .InetAddress ;
2323import java .nio .charset .StandardCharsets ;
2424import java .security .MessageDigest ;
25+ import java .security .NoSuchAlgorithmException ;
26+ import org .apache .logging .log4j .LogManager ;
27+ import org .apache .logging .log4j .Logger ;
2528
2629import com .cloud .utils .component .AdapterBase ;
2730import com .cloud .utils .component .ComponentLifecycle ;
4447 */
4548public class ManagementServerNode extends AdapterBase implements SystemIntegrityChecker {
4649
47- private static final String FQDN_ENV_VAR = "CLOUDSTACK_MSID_FROM_FQDN" ;
48- private static final String FQDN_SYS_PROP = "cloudstack.msid.from.fqdn" ;
50+ private static final String FQDN_ENV_VAR = "CLOUDSTACK_MSID_FROM_ID" ;
51+ private static final String FQDN_SYS_PROP = "cloudstack.msid.from.id" ;
52+
53+
54+ // op_lock.mac is varchar(17) and holds the msid, so the id must stay within the 48-bit MAC address range.
55+ private static final int MSID_BYTES = 6 ;
56+
57+ private static final Logger s_logger = LogManager .getLogger (ManagementServerNode .class );
4958
5059 private static String s_nodeIdSource ;
51- private static Exception s_initError ;
5260 private static final long s_nodeId = initNodeId ();
5361
5462 private static long initNodeId () {
55- if (isFqdnModeEnabled ()) {
56- return generateIdFromFqdn ();
57- }
58- s_nodeIdSource = "mac-address" ;
59- return MacAddress .getMacAddress ().toLong ();
60- }
6163
62- private static boolean isFqdnModeEnabled () {
63- return isTruthy (System .getenv (FQDN_ENV_VAR )) || isTruthy (System .getProperty (FQDN_SYS_PROP ));
64- }
64+ s_logger .info ("Initializing management server node ID" );
65+ // Check if FQDN_ENV_VAR or FQDN_SYS_PROP has a value
66+ String fqdnEnv = System .getenv (FQDN_ENV_VAR );
67+ String fqdnSysProp = System .getProperty (FQDN_SYS_PROP );
6568
66- private static boolean isTruthy (String value ) {
67- if (value == null ) {
68- return false ;
69+ String identity = null ;
70+ if (fqdnEnv != null ) {
71+ identity = trimToNull (fqdnEnv );
72+ s_logger .info ("FQDN environment variable: {}" , fqdnEnv );
6973 }
70- String trimmed = value .trim ();
71- return "true" .equalsIgnoreCase (trimmed ) || "1" .equals (trimmed ) || "yes" .equalsIgnoreCase (trimmed );
74+ if (fqdnSysProp != null ) {
75+ identity = trimToNull (fqdnSysProp );
76+ s_logger .info ("FQDN system property: {}" , fqdnSysProp );
77+ }
78+
79+ if (identity != null ) {
80+ s_nodeIdSource = "fqdn" ;
81+ s_logger .info ("Using {} for management server node ID: {}" , s_nodeIdSource , identity );
82+ return hashNodeIdentity (identity );
83+ }
84+
85+ // Use mac address
86+ s_nodeIdSource = "mac-address" ;
87+ long macAddress = MacAddress .getMacAddress ().toLong ();
88+ s_logger .info ("Using {} for management server node ID: {}" , s_nodeIdSource , macAddress );
89+ return macAddress ;
7290 }
7391
74- /**
75- * Derives a stable node id from a SHA-256 hash of the local FQDN.
76- *
77- * <p>On failure it records the cause and returns {@code 0} (an invalid id) rather than
78- * silently reverting to an unstable MAC-based id. The invalid id makes {@link #check()}
79- * fail the system-integrity check, which stops startup cleanly via {@link #start()}
80- * instead of raising an {@code ExceptionInInitializerError} from static initialization.
81- *
82- * @return a positive, non-zero 48-bit id, or {@code 0} if it cannot be derived
83- */
84- private static long generateIdFromFqdn () {
92+ static long hashNodeIdentity (String nodeIdentity ) {
8593 try {
86- String fqdn = InetAddress .getLocalHost ().getCanonicalHostName ();
87- s_nodeIdSource = "fqdn:" + fqdn ;
8894 MessageDigest digest = MessageDigest .getInstance ("SHA-256" );
89- byte [] hash = digest .digest (fqdn .getBytes (StandardCharsets .UTF_8 ));
95+ byte [] hash = digest .digest (nodeIdentity .getBytes (StandardCharsets .UTF_8 ));
9096 long id = 0 ;
91- for (int i = 0 ; i < 6 ; i ++) {
92- id = (id << 8 ) | (hash [i ] & 0xFF );
93- }
94- // Ensure positive and non-zero
95- id = id & 0x7FFFFFFFFFFFFFFFL ;
96- if (id == 0 ) {
97- id = 1 ;
97+ for (int i = 0 ; i < MSID_BYTES ; i ++) {
98+ id = (id << 8 ) | (hash [i ] & 0xFFL );
9899 }
99- return id ;
100- } catch (Exception e ) {
101- s_nodeIdSource = "fqdn-error" ;
102- s_initError = e ;
103- return 0 ;
100+
101+ return id == 0 ? 1 : id ;
102+ } catch (NoSuchAlgorithmException e ) {
103+ throw new CloudRuntimeException ("SHA-256 algorithm not available for management server ID generation" , e );
104+ }
105+ }
106+
107+ private static String trimToNull (String value ) {
108+ if (value == null ) {
109+ return null ;
104110 }
111+
112+ String trimmed = value .trim ();
113+ return trimmed .isEmpty () ? null : trimmed ;
105114 }
106115
107116 public ManagementServerNode () {
@@ -111,8 +120,7 @@ public ManagementServerNode() {
111120 @ Override
112121 public void check () {
113122 if (s_nodeId <= 0 ) {
114- throw new CloudRuntimeException (
115- "Unable to derive the management server node id (source: " + s_nodeIdSource + ")" , s_initError );
123+ throw new CloudRuntimeException ("Unable to get the management server node id" );
116124 }
117125 }
118126
@@ -124,10 +132,11 @@ public static long getManagementServerId() {
124132 public boolean start () {
125133 try {
126134 check ();
127- } catch (CloudRuntimeException e ) {
128- logger .error ("System integrity check failed for the management server node id " , e );
129- throw e ;
135+ } catch (Exception e ) {
136+ logger .error ("System integrity check exception " , e );
137+ System . exit ( 1 ) ;
130138 }
139+
131140 logger .info ("Management server node id: {} (source: {})" , s_nodeId , s_nodeIdSource );
132141 return true ;
133142 }
0 commit comments