2017-01-16 20:59:50 +01:00
/ * Copyright ( c ) Citrix Systems , Inc .
2016-08-19 11:55:18 +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 .
2016-03-24 19:24:12 +01:00
* /
using System ;
using System.Collections.Generic ;
using XenAdmin.Actions ;
using XenAdmin.Core ;
using XenAPI ;
using System.Linq ;
using System.IO ;
2016-04-28 16:56:45 +02:00
using XenAdmin.Network ;
2016-08-19 11:55:18 +02:00
using XenAdmin.Diagnostics.Problems.HostProblem ;
namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
class UploadPatchToMasterPlanAction : PlanActionWithSession
{
2016-03-24 19:24:12 +01:00
private readonly XenServerPatch patch ;
private readonly List < PoolPatchMapping > mappings ;
private Dictionary < XenServerPatch , string > AllDownloadedPatches = new Dictionary < XenServerPatch , string > ( ) ;
2018-02-05 13:36:49 +01:00
private KeyValuePair < XenServerPatch , string > patchFromDisk ;
2016-06-17 15:15:59 +02:00
private AsyncAction inProgressAction = null ;
2016-03-24 19:24:12 +01:00
2018-02-05 13:36:49 +01:00
public UploadPatchToMasterPlanAction ( IXenConnection connection , XenServerPatch patch , List < PoolPatchMapping > mappings , Dictionary < XenServerPatch , string > allDownloadedPatches , KeyValuePair < XenServerPatch , string > patchFromDisk )
2017-02-03 18:41:23 +01:00
: base ( connection , string . Format ( Messages . UPDATES_WIZARD_UPLOADING_UPDATE , patch . Name , connection . Name ) )
2016-03-24 19:24:12 +01:00
{
2016-08-19 11:55:18 +02:00
this . patch = patch ;
2016-03-24 19:24:12 +01:00
this . mappings = mappings ;
2016-08-19 11:55:18 +02:00
this . AllDownloadedPatches = allDownloadedPatches ;
2018-02-05 13:36:49 +01:00
this . patchFromDisk = patchFromDisk ;
2016-08-19 11:55:18 +02:00
}
protected override void RunWithSession ( ref Session session )
2016-03-24 19:24:12 +01:00
{
2018-02-05 13:36:49 +01:00
var path = AllDownloadedPatches . ContainsKey ( patch )
? AllDownloadedPatches [ patch ]
: patchFromDisk . Key = = patch ? patchFromDisk . Value : null ;
2016-03-24 19:24:12 +01:00
var poolPatches = new List < Pool_patch > ( session . Connection . Cache . Pool_patches ) ;
2016-10-04 15:58:54 +02:00
var poolUpdates = new List < Pool_update > ( session . Connection . Cache . Pool_updates ) ;
2016-03-24 19:24:12 +01:00
var conn = session . Connection ;
2016-08-18 12:25:39 +02:00
var master = Helpers . GetMaster ( conn ) ;
2016-03-24 19:24:12 +01:00
2016-08-19 11:55:18 +02:00
var existingMapping = mappings . Find ( m = > m . MasterHost ! = null & & master ! = null & &
2016-10-04 15:58:54 +02:00
m . MasterHost . uuid = = master . uuid & & ( m . Pool_patch ! = null | | m . Pool_update ! = null ) & & m . XenServerPatch . Equals ( patch ) ) ;
2016-08-18 12:25:39 +02:00
2016-03-24 19:24:12 +01:00
if ( existingMapping = = null
2016-10-04 15:58:54 +02:00
| | ! ( existingMapping . Pool_patch ! = null & & poolPatches . Any ( p = > string . Equals ( p . uuid , existingMapping . Pool_patch . uuid , StringComparison . OrdinalIgnoreCase ) ) )
& & ! ( existingMapping . Pool_update ! = null & & poolUpdates . Any ( p = > string . Equals ( p . uuid , existingMapping . Pool_update . uuid , StringComparison . OrdinalIgnoreCase ) ) )
)
2016-03-24 19:24:12 +01:00
{
2016-04-28 16:56:45 +02:00
try
{
2016-10-04 15:58:54 +02:00
if ( Helpers . ElyOrGreater ( master ) )
{
var uploadIsoAction = new UploadSupplementalPackAction ( session . Connection , new List < Host > ( ) { master } , path , true ) ;
inProgressAction = uploadIsoAction ;
uploadIsoAction . RunExternal ( session ) ;
2016-10-05 00:26:35 +02:00
var poolupdate = uploadIsoAction . PoolUpdate ;
2016-03-24 19:24:12 +01:00
2016-10-04 15:58:54 +02:00
if ( poolupdate = = null )
{
log . ErrorFormat ( "Upload finished successfully, but Pool_update object has not been found for update (uuid={0}) on host (uuid={1})." , patch . Uuid , session . Connection ) ;
2016-03-24 19:24:12 +01:00
2016-10-04 15:58:54 +02:00
throw new Exception ( Messages . ACTION_UPLOADPATCHTOMASTERPLANACTION_FAILED ) ;
}
2016-06-27 20:39:49 +02:00
2016-10-04 15:58:54 +02:00
var newMapping = new PoolPatchMapping ( patch , poolupdate , Helpers . GetMaster ( session . Connection ) ) ;
2016-06-27 20:39:49 +02:00
2016-10-04 15:58:54 +02:00
if ( ! mappings . Contains ( newMapping ) )
mappings . Add ( newMapping ) ;
2016-04-28 16:56:45 +02:00
}
2016-10-04 15:58:54 +02:00
else
{
var checkSpaceForUpload = new CheckDiskSpaceForPatchUploadAction ( Helpers . GetMaster ( conn ) , path , true ) ;
inProgressAction = checkSpaceForUpload ;
checkSpaceForUpload . RunExternal ( session ) ;
var uploadPatchAction = new UploadPatchAction ( session . Connection , path , true , false ) ;
inProgressAction = uploadPatchAction ;
uploadPatchAction . RunExternal ( session ) ;
// this has to be run again to refresh poolPatches (to get the recently uploaded one as well)
poolPatches = new List < Pool_patch > ( session . Connection . Cache . Pool_patches ) ;
2016-04-28 16:56:45 +02:00
2016-10-04 15:58:54 +02:00
var poolPatch = poolPatches . Find ( p = > string . Equals ( p . uuid , patch . Uuid , StringComparison . OrdinalIgnoreCase ) ) ;
if ( poolPatch = = null )
{
log . ErrorFormat ( "Upload finished successfully, but Pool_patch object has not been found for patch (uuid={0}) on host (uuid={1})." , patch . Uuid , session . Connection ) ;
2016-03-24 19:24:12 +01:00
2016-10-04 15:58:54 +02:00
throw new Exception ( Messages . ACTION_UPLOADPATCHTOMASTERPLANACTION_FAILED ) ;
}
var newMapping = new PoolPatchMapping ( patch , poolPatch , Helpers . GetMaster ( session . Connection ) ) ;
if ( ! mappings . Contains ( newMapping ) )
mappings . Add ( newMapping ) ;
}
2016-04-28 16:56:45 +02:00
}
catch ( Exception ex )
{
Error = ex ;
throw ;
}
2016-08-19 11:55:18 +02:00
}
2016-03-24 19:24:12 +01:00
}
2016-06-17 15:15:59 +02:00
public override void Cancel ( )
{
if ( inProgressAction ! = null )
inProgressAction . Cancel ( ) ;
base . Cancel ( ) ;
2016-08-19 11:55:18 +02:00
}
}
}