2017-01-16 20:59:50 +01:00
/ * Copyright ( c ) Citrix Systems , Inc .
2013-06-24 13:41:48 +02:00
* All rights reserved .
*
* Redistribution and use in source and binary forms ,
* with or without modification , are permitted provided
* that the following conditions are met :
*
* * Redistributions of source code must retain the above
* copyright notice , this list of conditions and the
* following disclaimer .
* * Redistributions in binary form must reproduce the above
* copyright notice , this list of conditions and the
* following disclaimer in the documentation and / or other
* materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES ,
* INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING ,
* BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ,
* WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
* /
using System.Collections.Generic ;
using System.Linq ;
2018-06-22 11:58:08 +02:00
using XenAdmin.Core ;
2018-06-21 13:28:49 +02:00
using XenAdmin.Wizards.PatchingWizard ;
using XenAdmin.Wizards.PatchingWizard.PlanActions ;
2013-06-24 13:41:48 +02:00
using XenAdmin.Wizards.RollingUpgradeWizard.PlanActions ;
2018-06-21 13:28:49 +02:00
using XenAPI ;
2013-06-24 13:41:48 +02:00
2018-06-29 20:49:28 +02:00
2013-06-24 13:41:48 +02:00
namespace XenAdmin.Wizards.RollingUpgradeWizard
{
2018-06-21 13:28:49 +02:00
public partial class RollingUpgradeUpgradePage : AutomatedUpdatesBasePage
2013-06-24 13:41:48 +02:00
{
public RollingUpgradeUpgradePage ( )
{
InitializeComponent ( ) ;
}
#region XenTabPage overrides
public override string PageTitle { get { return Messages . UPGRADE_PLAN ; } }
public override string Text { get { return Messages . UPGRADE_PLAN ; } }
public override string HelpID { get { return "Upgradepools" ; } }
#endregion
#region Accessors
public bool ManualModeSelected { private get ; set ; }
public Dictionary < string , string > InstallMethodConfig { private get ; set ; }
2018-10-04 15:38:07 +02:00
public bool ApplySuppPackAfterUpgrade { private get ; set ; }
public string SelectedSuppPackPath { private get ; set ; }
#endregion
#region Fields
private Dictionary < UpdateProgressBackgroundWorker , List < XenServerPatch > > AllUploadedPatches = new Dictionary < UpdateProgressBackgroundWorker , List < XenServerPatch > > ( ) ;
private Dictionary < UpdateProgressBackgroundWorker , List < XenServerPatch > > MinimalPatches = new Dictionary < UpdateProgressBackgroundWorker , List < XenServerPatch > > ( ) ; // should be calculated only once per pool (to ensure update homogeneity)
private Dictionary < Host , Pool_update > UploadedSuppPacks = new Dictionary < Host , Pool_update > ( ) ;
2013-06-24 13:41:48 +02:00
#endregion
2018-06-21 13:28:49 +02:00
#region AutomatedUpdatesBesePage overrides
2018-06-22 16:57:31 +02:00
protected override string BlurbText ( )
{
return Messages . ROLLING_UPGRADE_UPGRADE_IN_PROGRESS ;
}
protected override string SuccessMessageOnCompletion ( bool multiplePools )
2013-06-24 13:41:48 +02:00
{
2018-06-22 16:57:31 +02:00
return multiplePools ? Messages . ROLLING_UPGRADE_SUCCESS_MANY : Messages . ROLLING_UPGRADE_SUCCESS_ONE ;
}
protected override string FailureMessageOnCompletion ( bool multiplePools )
{
return multiplePools ? Messages . ROLLING_UPGRADE_ERROR_MANY : Messages . ROLLING_UPGRADE_ERROR_ONE ;
}
2018-08-17 13:05:16 +02:00
protected override string SuccessMessagePerPool ( Pool pool )
2018-06-22 16:57:31 +02:00
{
return Messages . ROLLING_UPGRADE_SUCCESS_ONE ;
}
protected override string FailureMessagePerPool ( bool multipleErrors )
{
return multipleErrors ? Messages . ROLLING_UPGRADE_ERROR_POOL_MANY : Messages . ROLLING_UPGRADE_ERROR_POOL_ONE ;
2013-06-24 13:41:48 +02:00
}
2018-06-26 15:04:51 +02:00
protected override string UserCancellationMessage ( )
{
return Messages . ROLLING_UPGRADE_CANCELLATION ;
}
2018-12-20 14:23:49 +01:00
protected override string ReconsiderCancellationMessage ( )
{
return Messages . ROLLING_UPGRADE_CANCELLATION_RECONSIDER ;
}
2018-06-29 20:49:28 +02:00
protected override List < HostPlan > GenerateHostPlans ( Pool pool , out List < Host > applicableHosts )
2013-06-24 13:41:48 +02:00
{
2018-07-06 13:49:16 +02:00
//Add masters first, then the slaves (add all hosts for now, they will be skipped from upgrade if already upgraded)
applicableHosts = pool . Connection . Cache . Hosts . ToList ( ) ;
applicableHosts . Sort ( ) ;
2018-06-29 20:49:28 +02:00
return applicableHosts . Select ( GetSubTasksFor ) . ToList ( ) ;
2013-06-24 13:41:48 +02:00
}
2018-06-21 13:28:49 +02:00
protected override bool SkipInitialPlanActions ( Host host )
2013-06-24 13:41:48 +02:00
{
2018-06-21 13:28:49 +02:00
//Skip hosts already upgraded
if ( host . IsMaster ( ) )
2013-06-24 13:41:48 +02:00
{
2018-06-21 13:28:49 +02:00
var pool = Helpers . GetPoolOfOne ( host . Connection ) ;
if ( pool ! = null & & pool . IsMasterUpgraded ( ) )
2013-06-24 13:41:48 +02:00
{
2018-06-21 13:28:49 +02:00
log . Debug ( string . Format ( "Skipping master '{0}' because it is upgraded" , host . Name ( ) ) ) ;
return true ;
2013-06-24 13:41:48 +02:00
}
}
2018-06-21 13:28:49 +02:00
else
2013-06-24 13:41:48 +02:00
{
2018-06-21 13:28:49 +02:00
var master = Helpers . GetMaster ( host . Connection ) ;
if ( master ! = null & & host . LongProductVersion ( ) = = master . LongProductVersion ( ) )
2016-03-17 17:12:43 +01:00
{
2018-06-21 13:28:49 +02:00
log . Debug ( string . Format ( "Skipping host '{0}' because it is upgraded" , host . Name ( ) ) ) ;
return true ;
2016-03-17 17:12:43 +01:00
}
2018-06-21 13:28:49 +02:00
}
return false ;
2013-06-24 13:41:48 +02:00
}
2018-06-22 11:58:08 +02:00
protected override void DoAfterInitialPlanActions ( UpdateProgressBackgroundWorker bgw , Host host , List < Host > hosts )
{
2018-10-04 15:38:07 +02:00
if ( ! ApplyUpdatesToNewVersion & & ! ApplySuppPackAfterUpgrade )
2018-07-11 01:43:28 +02:00
return ;
2018-06-25 01:59:21 +02:00
var theHostPlan = bgw . HostPlans . FirstOrDefault ( ha = > ha . Host . Equals ( host ) ) ;
if ( theHostPlan = = null )
2018-06-22 11:58:08 +02:00
return ;
2018-06-25 01:59:21 +02:00
if ( theHostPlan . UpdatesPlanActions . Count > 0 ) // this is a retry; do not recreate actions
2018-07-11 01:43:28 +02:00
return ;
2018-06-22 11:58:08 +02:00
2018-06-25 11:37:28 +02:00
host = host . Connection . TryResolveWithTimeout ( new XenRef < Host > ( host . opaque_ref ) ) ;
2018-10-04 15:38:07 +02:00
if ( ApplyUpdatesToNewVersion )
2018-07-11 01:43:28 +02:00
{
2018-10-04 15:38:07 +02:00
var automatedUpdatesRestricted = host . Connection . Cache . Hosts . Any ( h = > Helpers . DundeeOrGreater ( h ) & & Host . RestrictBatchHotfixApply ( h ) ) ; //if any host is not licensed for automated updates (only considering DundeeOrGreater hosts)
2018-07-11 01:43:28 +02:00
2018-10-04 15:38:07 +02:00
if ( ! automatedUpdatesRestricted )
{
if ( ! MinimalPatches . ContainsKey ( bgw ) )
{
log . InfoFormat ( "Calculating minimal patches for {0}" , host . Name ( ) ) ;
Updates . CheckForUpdatesSync ( null ) ;
var mp = Updates . GetMinimalPatches ( host ) ;
log . InfoFormat ( "Minimal patches for {0}: {1}" , host . Name ( ) ,
mp = = null ? "None" : string . Join ( "," , mp . Select ( p = > p . Name ) ) ) ;
MinimalPatches . Add ( bgw , mp ) ;
}
var minimalPatches = MinimalPatches [ bgw ] ;
if ( minimalPatches ! = null )
{
if ( ! AllUploadedPatches . ContainsKey ( bgw ) )
AllUploadedPatches . Add ( bgw , new List < XenServerPatch > ( ) ) ;
var uploadedPatches = AllUploadedPatches [ bgw ] ;
var hp = GetUpdatePlanActionsForHost ( host , hosts , minimalPatches , uploadedPatches ,
new KeyValuePair < XenServerPatch , string > ( ) , false ) ;
if ( hp . UpdatesPlanActions ! = null & & hp . UpdatesPlanActions . Count > 0 )
{
theHostPlan . UpdatesPlanActions . AddRange ( hp . UpdatesPlanActions ) ;
theHostPlan . DelayedPlanActions . InsertRange ( 0 , hp . DelayedPlanActions ) ;
}
}
}
else
{
log . InfoFormat ( "Skipping updates installation on {0} because the batch hotfix application is restricted in the pool" , host . Name ( ) ) ;
}
2018-07-11 01:43:28 +02:00
}
2018-06-22 11:58:08 +02:00
2018-10-04 15:38:07 +02:00
if ( ApplySuppPackAfterUpgrade & & Helpers . ElyOrGreater ( host ) )
2018-06-22 11:58:08 +02:00
{
2018-10-04 15:38:07 +02:00
var suppPackPlanAction = new RpuUploadAndApplySuppPackPlanAction ( host . Connection ,
host , hosts , SelectedSuppPackPath , UploadedSuppPacks , hostsThatWillRequireReboot ) ;
theHostPlan . UpdatesPlanActions . Add ( suppPackPlanAction ) ;
2018-06-22 11:58:08 +02:00
}
}
2018-06-21 13:28:49 +02:00
#endregion
2013-06-24 13:41:48 +02:00
2018-06-21 13:28:49 +02:00
#region Private methods
2018-10-04 15:38:07 +02:00
2018-06-25 01:59:21 +02:00
private HostPlan GetSubTasksFor ( Host host )
2013-06-24 13:41:48 +02:00
{
2018-06-23 00:44:40 +02:00
var runningVMs = host . GetRunningVMs ( ) ;
2018-03-06 16:12:04 +01:00
2018-06-23 04:06:36 +02:00
UpgradeHostPlanAction upgradeAction ;
if ( ManualModeSelected )
upgradeAction = new UpgradeManualHostPlanAction ( host , this ) ;
else
upgradeAction = new UpgradeAutomatedHostPlanAction ( host , this , InstallMethodConfig ) ;
2018-03-06 16:12:04 +01:00
2018-06-25 01:59:21 +02:00
var initialPlanActions = new List < PlanAction > ( )
2018-03-06 16:12:04 +01:00
{
new EvacuateHostPlanAction ( host ) ,
2018-06-25 17:31:46 +02:00
upgradeAction ,
2018-03-06 16:12:04 +01:00
new BringBabiesBackAction ( runningVMs , host , true )
} ;
2018-06-25 17:31:46 +02:00
return new HostPlan ( host , initialPlanActions , null , new List < PlanAction > ( ) ) ;
2018-06-22 11:58:08 +02:00
}
2013-06-24 13:41:48 +02:00
2018-06-21 13:28:49 +02:00
#endregion
2013-06-24 13:41:48 +02:00
}
}