Merge pull request #1463 from geosharath/CP-17250

CP-17250: [XC] Allow host to join an existing pool with management on a VLAN
This commit is contained in:
Mihaela Stoica 2017-03-31 09:26:53 +01:00 committed by GitHub
commit 499c30dd5d
9 changed files with 267 additions and 36 deletions

View File

@ -95,6 +95,8 @@ namespace XenAdmin.Actions
ApiMethodsToRoleCheck.Add("pif.plug");
ApiMethodsToRoleCheck.AddRange(XenAPI.Role.CommonSessionApiList);
ApiMethodsToRoleCheck.AddRange(XenAPI.Role.CommonTaskApiList);
if(!Helpers.FeatureForbidden(Connection, Host.RestrictManagementOnVLAN))
ApiMethodsToRoleCheck.Add("pool.management_reconfigure");
#endregion
}
@ -135,6 +137,12 @@ namespace XenAdmin.Actions
if (Pool != null)
{
progress += inc;
if (!Helpers.FeatureForbidden(Connection, Host.RestrictManagementOnVLAN))
{
PoolReconfigureManagement(progress);
return;
}
ReconfigureManagement(false, progress);
}
@ -195,6 +203,16 @@ namespace XenAdmin.Actions
clearDownManagementIP);
}
private void PoolReconfigureManagement(int hi)
{
System.Diagnostics.Trace.Assert(downManagement != null);
if (newManagement == null)
return;
NetworkingActionHelpers.PoolReconfigureManagement(this, Pool, newManagement, downManagement, hi);
}
private void BringUp(PIF new_pif, PIF existing_pif, int hi)
{
string ip = existing_pif.IP;

View File

@ -32,7 +32,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using XenAPI;
using XenAdmin.Model;
@ -269,6 +269,93 @@ namespace XenAdmin.Actions
action.Description = string.Format(Messages.ACTION_CHANGE_NETWORKING_MANAGEMENT_RECONFIGURED, pif.Name);
}
internal static void WaitForslavesToRecover(Pool pool)
{
int RetryLimit = 60, RetryAttempt = 0;
List<string> deadHost = new List<string>();
/* host count -1 is for excluding master */
while (deadHost.Count < (pool.Connection.Cache.HostCount -1) && (RetryAttempt <= RetryLimit))
{
foreach (Host host in pool.Connection.Cache.Hosts)
{
if (host.IsMaster())
continue;
if (!host.IsLive && !deadHost.Contains(host.uuid))
{
deadHost.Add(host.uuid);
}
}
RetryAttempt++;
Thread.Sleep(1000);
}
RetryAttempt = 0;
while (deadHost.Count != 0 && (RetryAttempt <= RetryLimit))
{
foreach (Host host in pool.Connection.Cache.Hosts)
{
if (host.IsMaster())
continue;
if (host.IsLive && deadHost.Contains(host.uuid))
{
deadHost.Remove(host.uuid);
}
}
RetryAttempt++;
Thread.Sleep(1000);
}
}
internal static void PoolReconfigureManagement(AsyncAction action, Pool pool, PIF up_pif, PIF down_pif, int hi)
{
System.Diagnostics.Trace.Assert(down_pif.host.opaque_ref == up_pif.host.opaque_ref);
int lo = action.PercentComplete;
int inc = (hi - lo) / 3;
lo += inc;
PoolManagementReconfigure_( action, up_pif, lo);
/* pool_management_reconfigure triggers a pool_recover_slaves, which in turn spawns two tasks
* dbsync (update_env) and server_init on each slaves.
* Only after their completion master will be able to execute reconfigure_IPs.
* Hence, we check Host.IsLive metric of all slaves for a transition from true -> false -> true
*/
action.Description = string.Format(Messages.ACTION_WAIT_FOR_SLAVES_TO_RECOVER);
WaitForslavesToRecover(pool);
/* Reconfigure IP for slaves and then master */
lo += inc;
ForSomeHosts(action, down_pif, false, true, lo, ClearIP);
lo += inc;
ForSomeHosts(action, down_pif, true, true, hi, ClearIP);
}
/// <summary>
/// Switch the Pool's management interface from its current setting over to the given PIF.
/// </summary>
private static void PoolManagementReconfigure_(AsyncAction action, PIF pif, int hi)
{
log.DebugFormat("Switching to PIF {0} {1} for management...", pif.Name, pif.uuid);
action.Description = string.Format(Messages.ACTION_CHANGE_NETWORKING_MANAGEMENT_RECONFIGURING, pif.Name);
action.RelatedTask = Pool.async_management_reconfigure(action.Session, pif.network.opaque_ref);
action.PollToCompletion(action.PercentComplete, hi);
action.Description = string.Format(Messages.ACTION_CHANGE_NETWORKING_MANAGEMENT_RECONFIGURED, pif.Name);
log.DebugFormat("Switched to PIF {0} {1} for management...", pif.Name, pif.uuid);
}
/// <summary>
/// Remove the IP address from the given PIF.
/// </summary>

View File

@ -3390,6 +3390,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Waiting for slaves to recover....
/// </summary>
public static string ACTION_WAIT_FOR_SLAVES_TO_RECOVER {
get {
return ResourceManager.GetString("ACTION_WAIT_FOR_SLAVES_TO_RECOVER", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disconnecting Workload Balancing failed on pool {0}: {1} Workload Balancing has been paused..
/// </summary>
@ -11333,10 +11342,10 @@ namespace XenAdmin {
public static string DISABLED_VMSS {
get {
return ResourceManager.GetString("DISABLED_VMSS", resourceCulture);
}
}
/// <summary>
}
}
/// <summary>
/// Looks up a localized string similar to Disabling.
/// </summary>
public static string DISABLING {
@ -13641,10 +13650,10 @@ namespace XenAdmin {
public static string ENABLED_VMSS {
get {
return ResourceManager.GetString("ENABLED_VMSS", resourceCulture);
}
}
/// <summary>
}
}
/// <summary>
/// Looks up a localized string similar to Enabling.
/// </summary>
public static string ENABLING {
@ -15973,10 +15982,10 @@ namespace XenAdmin {
public static string GENERAL_PAGE_VMSS_SETTINGS {
get {
return ResourceManager.GetString("GENERAL_PAGE_VMSS_SETTINGS", resourceCulture);
}
}
/// <summary>
}
}
/// <summary>
/// Looks up a localized string similar to {0} on {1}.
/// </summary>
public static string GENERAL_PANEL_UPDATE_KEY {
@ -23404,10 +23413,10 @@ namespace XenAdmin {
public static string NEW_SCHEDULE {
get {
return ResourceManager.GetString("NEW_SCHEDULE", resourceCulture);
}
}
/// <summary>
}
}
/// <summary>
/// Looks up a localized string similar to New Search.
/// </summary>
public static string NEW_SEARCH {
@ -27910,6 +27919,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to This server must not have any bonds, non management VLANs or cross-server private networks.
/// </summary>
public static string POOL_JOIN_NON_COMPATIBLE_MANAGEMENT_INTERFACE {
get {
return ResourceManager.GetString("POOL_JOIN_NON_COMPATIBLE_MANAGEMENT_INTERFACE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This server must not have any bonds, VLANs or cross-server private networks.
/// </summary>
@ -36557,15 +36575,6 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to Details:.
/// </summary>
public static string VMSS_ALERT_DETAILS {
get {
return ResourceManager.GetString("VMSS_ALERT_DETAILS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} VMs.
/// </summary>
public static string VMS_MANY {
@ -36574,6 +36583,24 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to 1 VM.
/// </summary>
public static string VMS_ONE {
get {
return ResourceManager.GetString("VMS_ONE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Details:.
/// </summary>
public static string VMSS_ALERT_DETAILS {
get {
return ResourceManager.GetString("VMSS_ALERT_DETAILS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0}. {1}: {2}.
/// </summary>
@ -36751,15 +36778,6 @@ namespace XenAdmin {
public static string VMSS_WIZARD_TITLE {
get {
return ResourceManager.GetString("VMSS_WIZARD_TITLE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 1 VM.
/// </summary>
public static string VMS_ONE {
get {
return ResourceManager.GetString("VMS_ONE", resourceCulture);
}
}

View File

@ -1227,6 +1227,9 @@
<data name="ACTION_VM_TEMPLATIZING_TITLE" xml:space="preserve">
<value>Converting VM '{0}' to template</value>
</data>
<data name="ACTION_WAIT_FOR_SLAVES_TO_RECOVER" xml:space="preserve">
<value>Waiting for slaves to recover...</value>
</data>
<data name="ACTION_WLB_DECONFIGURE_FAILED" xml:space="preserve">
<value>Disconnecting Workload Balancing failed on pool {0}: {1} Workload Balancing has been paused.</value>
</data>
@ -9736,6 +9739,9 @@ The VM protection policy for this VM does not have automatic archiving configure
<data name="POOL_JOIN_IMPOSSIBLE" xml:space="preserve">
<value>Pool join not possible</value>
</data>
<data name="POOL_JOIN_NON_COMPATIBLE_MANAGEMENT_INTERFACE" xml:space="preserve">
<value>This server must not have any bonds, non management VLANs or cross-server private networks</value>
</data>
<data name="POOL_JOIN_NOT_PHYSICAL_PIF" xml:space="preserve">
<value>This server must not have any bonds, VLANs or cross-server private networks</value>
</data>

View File

@ -66,6 +66,7 @@ namespace XenAdmin.Core
DifferentNetworkBackends,
MasterHasHA,
NotPhysicalPif,
NonCompatibleManagementInterface,
WrongRoleOnMaster,
WrongRoleOnSlave,
NotConnected,
@ -152,9 +153,12 @@ namespace XenAdmin.Core
if (HaEnabled(masterConnection))
return Reason.MasterHasHA;
if (HasSlaveAnyNonPhysicalPif(slaveConnection))
if (Helpers.FeatureForbidden(slaveConnection, Host.RestrictManagementOnVLAN) && HasSlaveAnyNonPhysicalPif(slaveConnection))
return Reason.NotPhysicalPif;
if (!Helpers.FeatureForbidden(slaveConnection, Host.RestrictManagementOnVLAN) && !HasCompatibleManagementInterface(slaveConnection))
return Reason.NonCompatibleManagementInterface;
return Reason.Allowed;
}
@ -206,6 +210,8 @@ namespace XenAdmin.Core
return Messages.POOL_JOIN_FORBIDDEN_BY_HA;
case Reason.NotPhysicalPif :
return Messages.POOL_JOIN_NOT_PHYSICAL_PIF;
case Reason.NonCompatibleManagementInterface :
return Messages.POOL_JOIN_NON_COMPATIBLE_MANAGEMENT_INTERFACE;
case Reason.WrongRoleOnMaster:
return Messages.NEWPOOL_MASTER_ROLE;
case Reason.WrongRoleOnSlave:
@ -617,5 +623,23 @@ namespace XenAdmin.Core
return
slaveConnection.Cache.PIFs.Any(p => !p.physical);
}
public static bool HasCompatibleManagementInterface(IXenConnection slaveConnection)
{
/* if there are non physical pifs present then the slave should have
* only one VLAN and it has to be the managment interface.
* Bonds and cross server private networks are not allowed */
int numberOfNonPhysicalPifs = slaveConnection.Cache.PIFs.Count(p => !p.physical);
/* allow the case where there are only physical pifs */
if (numberOfNonPhysicalPifs == 0)
return true;
if(numberOfNonPhysicalPifs != 1)
return false;
else
return slaveConnection.Cache.PIFs.Any(p => !p.physical && p.management && p.VLAN != -1);
}
}
}

View File

@ -2274,6 +2274,42 @@ namespace XenAPI {
}
}
/// <summary>
/// Looks up a localized string similar to The host joining the pool must not have any bonds..
/// </summary>
public static string POOL_JOINING_HOST_HAS_BONDS {
get {
return ResourceManager.GetString("POOL_JOINING_HOST_HAS_BONDS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The host joining the pool must not have any non-management vlans..
/// </summary>
public static string POOL_JOINING_HOST_HAS_NON_MANAGEMENT_VLANS {
get {
return ResourceManager.GetString("POOL_JOINING_HOST_HAS_NON_MANAGEMENT_VLANS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The host joining the pool must not have any tunnels..
/// </summary>
public static string POOL_JOINING_HOST_HAS_TUNNELS {
get {
return ResourceManager.GetString("POOL_JOINING_HOST_HAS_TUNNELS", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The host joining the pool must have the same management vlan..
/// </summary>
public static string POOL_JOINING_HOST_MANAGEMENT_VLAN_DOES_NOT_MATCH {
get {
return ResourceManager.GetString("POOL_JOINING_HOST_MANAGEMENT_VLAN_DOES_NOT_MATCH", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The server joining the pool must have a physical management NIC (i.e. the management NIC must not be on a VLAN or bonded PIF)..
/// </summary>

View File

@ -855,6 +855,18 @@
<data name="POOL_JOINING_EXTERNAL_AUTH_MISMATCH" xml:space="preserve">
<value>The external authentication configuration of the server joining the pool must match the pool's own external authentication configuration.</value>
</data>
<data name="POOL_JOINING_HOST_HAS_BONDS" xml:space="preserve">
<value>The host joining the pool must not have any bonds.</value>
</data>
<data name="POOL_JOINING_HOST_HAS_NON_MANAGEMENT_VLANS" xml:space="preserve">
<value>The host joining the pool must not have any non-management vlans.</value>
</data>
<data name="POOL_JOINING_HOST_HAS_TUNNELS" xml:space="preserve">
<value>The host joining the pool must not have any tunnels.</value>
</data>
<data name="POOL_JOINING_HOST_MANAGEMENT_VLAN_DOES_NOT_MATCH" xml:space="preserve">
<value>The host joining the pool must have the same management vlan.</value>
</data>
<data name="POOL_JOINING_HOST_MUST_HAVE_PHYSICAL_MANAGEMENT_NIC" xml:space="preserve">
<value>The server joining the pool must have a physical management NIC (i.e. the management NIC must not be on a VLAN or bonded PIF).</value>
</data>

View File

@ -1196,6 +1196,28 @@ namespace XenAPI
return XenRef<Task>.Create(session.proxy.async_pool_recover_slaves(session.uuid).parse());
}
/// <summary>
/// Reconfigure the management network interface for all Hosts in the Pool
/// First published in .
/// </summary>
/// <param name="session">The session</param>
/// <param name="_network">The network</param>
public static void management_reconfigure(Session session, string _network)
{
session.proxy.pool_management_reconfigure(session.uuid, (_network != null) ? _network : "").parse();
}
/// <summary>
/// Reconfigure the management network interface for all Hosts in the Pool
/// First published in .
/// </summary>
/// <param name="session">The session</param>
/// <param name="_network">The network</param>
public static XenRef<Task> async_management_reconfigure(Session session, string _network)
{
return XenRef<Task>.Create(session.proxy.async_pool_management_reconfigure(session.uuid, (_network != null) ? _network : "").parse());
}
/// <summary>
/// Create PIFs, mapping a network to the same physical interface/VLAN on each host. This call is deprecated: use Pool.create_VLAN_from_PIF instead.
/// First published in XenServer 4.0.

View File

@ -3528,6 +3528,14 @@ namespace XenAPI
Response<string>
async_host_management_reconfigure(string session, string _pif);
[XmlRpcMethod("pool.management_reconfigure")]
Response<string>
pool_management_reconfigure(string session, string _network);
[XmlRpcMethod("Async.pool.management_reconfigure")]
Response<string>
async_pool_management_reconfigure(string session, string _network);
[XmlRpcMethod("host.local_management_reconfigure")]
Response<string>
host_local_management_reconfigure(string session, string _interface);