2016-08-19 11:55:18 +02:00
/ * Copyright ( c ) Citrix Systems Inc .
* 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 > ( ) ;
private string tempFileName = null ;
2016-06-17 15:15:59 +02:00
private AsyncAction inProgressAction = null ;
2016-03-24 19:24:12 +01:00
2016-08-19 11:55:18 +02:00
public UploadPatchToMasterPlanAction ( IXenConnection connection , XenServerPatch patch , List < PoolPatchMapping > mappings , Dictionary < XenServerPatch , string > allDownloadedPatches )
: base ( connection , string . Format ( "Uploading update {0} to {1}..." , 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 ;
}
protected override void RunWithSession ( ref Session session )
2016-03-24 19:24:12 +01:00
{
var path = AllDownloadedPatches [ patch ] ;
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-03-24 19:24:12 +01:00
2016-10-04 15:58:54 +02:00
poolUpdates = new List < Pool_update > ( session . Connection . Cache . Pool_updates ) ;
var poolupdate = poolUpdates . Find ( p = > string . Equals ( p . uuid , patch . Uuid , StringComparison . OrdinalIgnoreCase ) ) ;
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
}
private void DownloadFile ( ref Session session )
{
string patchUri = patch . PatchUrl ;
if ( string . IsNullOrEmpty ( patchUri ) )
return ;
Uri address = new Uri ( patchUri ) ;
tempFileName = Path . GetTempFileName ( ) ;
var downloadAction = new DownloadAndUnzipXenServerPatchAction ( patch . Name , address , tempFileName , Branding . Update ) ;
if ( downloadAction ! = null )
{
downloadAction . Changed + = downloadAndUnzipXenServerPatchAction_Changed ;
downloadAction . Completed + = downloadAndUnzipXenServerPatchAction_Completed ;
}
downloadAction . RunExternal ( session ) ;
}
private void downloadAndUnzipXenServerPatchAction_Changed ( object sender )
{
var action = sender as AsyncAction ;
if ( action = = null )
return ;
2016-06-17 15:15:59 +02:00
if ( Cancelling )
action . Cancel ( ) ;
2016-03-24 19:24:12 +01:00
}
private void downloadAndUnzipXenServerPatchAction_Completed ( ActionBase sender )
{
var action = sender as AsyncAction ;
if ( action = = null )
return ;
action . Changed - = downloadAndUnzipXenServerPatchAction_Changed ;
action . Completed - = downloadAndUnzipXenServerPatchAction_Completed ;
if ( action . Succeeded )
{
if ( action is DownloadAndUnzipXenServerPatchAction )
{
Host master = Helpers . GetMaster ( action . Connection ) ;
2016-03-31 16:40:23 +02:00
AllDownloadedPatches [ patch ] = ( action as DownloadAndUnzipXenServerPatchAction ) . PatchPath ;
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
}
}
}