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 ;
using System.Collections.Generic ;
using System.Windows.Forms ;
using XenAdmin.Controls ;
using XenAdmin.Controls.DataGridViewEx ;
using XenAdmin.Core ;
using XenAdmin.Properties ;
using XenAPI ;
using System.IO ;
using XenAdmin.Dialogs ;
using System.Drawing ;
2015-07-14 11:05:13 +02:00
using XenAdmin.Alerts ;
2016-05-04 11:27:10 +02:00
using System.Linq ;
2018-03-14 13:12:18 +01:00
using System.Xml ;
using DiscUtils.Iso9660 ;
2016-05-31 20:00:35 +02:00
using XenAdmin.Actions ;
2013-06-24 13:41:48 +02:00
namespace XenAdmin.Wizards.PatchingWizard
{
public partial class PatchingWizard_SelectPatchPage : XenTabPage
{
2018-03-14 13:12:18 +01:00
private static readonly log4net . ILog log = log4net . LogManager . GetLogger ( System . Reflection . MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2015-07-14 11:05:13 +02:00
private bool CheckForUpdatesInProgress ;
2015-07-20 15:28:44 +02:00
public XenServerPatchAlert SelectedUpdateAlert ;
2015-07-20 16:27:41 +02:00
public XenServerPatchAlert FileFromDiskAlert ;
2017-04-20 17:16:09 +02:00
private bool firstLoad = true ;
2017-07-21 16:56:27 +02:00
private string unzippedUpdateFilePath ;
2013-06-24 13:41:48 +02:00
public PatchingWizard_SelectPatchPage ( )
{
InitializeComponent ( ) ;
2016-08-08 12:41:42 +02:00
tableLayoutPanelSpinner . Visible = false ;
2016-08-09 13:45:35 +02:00
2016-12-10 15:44:15 +01:00
labelWithAutomatedUpdates . Visible = automatedUpdatesOptionLabel . Visible = AutomatedUpdatesRadioButton . Visible = false ;
2016-08-09 13:45:35 +02:00
downloadUpdateRadioButton . Checked = true ;
2015-07-14 11:05:13 +02:00
}
2015-08-10 12:25:11 +02:00
private void CheckForUpdates_CheckForUpdatesStarted ( )
{
2016-08-08 12:41:42 +02:00
Program . Invoke ( Program . MainWindow , StartCheckForUpdates ) ;
2015-08-10 12:25:11 +02:00
}
2016-08-08 15:37:47 +02:00
private void Updates_RestoreDismissedUpdatesStarted ( )
{
Program . Invoke ( Program . MainWindow , StartCheckForUpdates ) ;
}
2016-08-08 12:41:42 +02:00
private void StartCheckForUpdates ( )
{
if ( CheckForUpdatesInProgress )
return ;
CheckForUpdatesInProgress = true ;
dataGridViewPatches . Rows . Clear ( ) ;
tableLayoutPanelSpinner . Visible = true ;
RestoreDismUpdatesButton . Enabled = false ;
RefreshListButton . Enabled = false ;
OnPageUpdated ( ) ;
}
2015-08-10 12:25:11 +02:00
2015-07-14 11:05:13 +02:00
private void CheckForUpdates_CheckForUpdatesCompleted ( bool succeeded , string errorMessage )
{
Program . Invoke ( Program . MainWindow , delegate
{
2016-08-08 12:41:42 +02:00
tableLayoutPanelSpinner . Visible = false ;
2016-11-16 13:26:26 +01:00
PopulatePatchesBox ( ) ;
2016-03-16 13:59:20 +01:00
RefreshListButton . Enabled = true ;
2016-08-08 12:41:42 +02:00
RestoreDismUpdatesButton . Enabled = true ;
2015-07-14 11:05:13 +02:00
CheckForUpdatesInProgress = false ;
OnPageUpdated ( ) ;
} ) ;
2013-06-24 13:41:48 +02:00
}
2015-07-20 15:28:44 +02:00
public void SelectDownloadAlert ( XenServerPatchAlert alert )
{
downloadUpdateRadioButton . Checked = true ;
foreach ( PatchGridViewRow row in dataGridViewPatches . Rows )
{
if ( row . UpdateAlert . Equals ( alert ) )
{
row . Selected = true ;
}
}
}
2013-06-24 13:41:48 +02:00
public override string Text
{
get
{
return Messages . PATCHINGWIZARD_SELECTPATCHPAGE_TEXT ;
}
}
public override string PageTitle
{
get
{
return Messages . PATCHINGWIZARD_SELECTPATCHPAGE_TITLE ;
}
}
public override string HelpID
{
get { return "SelectUpdate" ; }
}
2018-03-09 01:31:46 +01:00
protected override void PageLoadedCore ( PageLoadedDirection direction )
{
2015-08-10 12:25:11 +02:00
Updates . CheckForUpdatesStarted + = CheckForUpdates_CheckForUpdatesStarted ;
2015-07-14 11:05:13 +02:00
Updates . CheckForUpdatesCompleted + = CheckForUpdates_CheckForUpdatesCompleted ;
2016-08-08 15:37:47 +02:00
Updates . RestoreDismissedUpdatesStarted + = Updates_RestoreDismissedUpdatesStarted ;
2015-07-14 11:05:13 +02:00
if ( direction = = PageLoadedDirection . Forward )
2013-06-24 13:41:48 +02:00
{
2016-12-10 16:01:25 +01:00
//if any connected host is licensed for automated updates
2016-12-10 15:44:15 +01:00
bool automatedUpdatesPossible = ConnectionsManager . XenConnectionsCopy . Any ( c = > c ! = null & & c . Cache . Hosts . Any ( h = > ! Host . RestrictBatchHotfixApply ( h ) ) ) ;
2016-08-08 12:41:42 +02:00
2016-12-10 15:44:15 +01:00
labelWithAutomatedUpdates . Visible = automatedUpdatesOptionLabel . Visible = AutomatedUpdatesRadioButton . Visible = automatedUpdatesPossible ;
labelWithoutAutomatedUpdates . Visible = ! automatedUpdatesPossible ;
2016-08-08 12:41:42 +02:00
2017-04-20 17:16:09 +02:00
if ( firstLoad )
{
AutomatedUpdatesRadioButton . Checked = automatedUpdatesPossible ;
downloadUpdateRadioButton . Checked = ! automatedUpdatesPossible ;
}
else if ( ! automatedUpdatesPossible & & AutomatedUpdatesRadioButton . Checked )
{
downloadUpdateRadioButton . Checked = true ;
}
2017-01-20 12:35:25 +01:00
Updates . CheckServerPatches ( ) ;
2015-07-14 11:05:13 +02:00
PopulatePatchesBox ( ) ;
2016-08-08 12:41:42 +02:00
OnPageUpdated ( ) ;
2013-06-24 13:41:48 +02:00
}
2017-04-20 17:16:09 +02:00
firstLoad = false ;
2013-06-24 13:41:48 +02:00
}
2017-03-24 17:43:19 +01:00
private bool IsInAutomatedUpdatesMode { get { return AutomatedUpdatesRadioButton . Visible & & AutomatedUpdatesRadioButton . Checked ; } }
public WizardMode WizardMode
{
get
{
if ( AutomatedUpdatesRadioButton . Visible & & AutomatedUpdatesRadioButton . Checked )
return WizardMode . AutomatedUpdates ;
2018-03-14 13:12:18 +01:00
var updateAlert = downloadUpdateRadioButton . Checked
? SelectedUpdateAlert
2017-03-24 17:43:19 +01:00
: selectFromDiskRadioButton . Checked
2018-03-14 13:12:18 +01:00
? FileFromDiskAlert
2017-03-24 17:43:19 +01:00
: null ;
if ( updateAlert ! = null & & updateAlert . NewServerVersion ! = null )
return WizardMode . NewVersion ;
return WizardMode . SingleUpdate ;
}
}
2016-03-14 17:10:16 +01:00
2018-02-05 13:36:49 +01:00
public KeyValuePair < XenServerPatch , string > PatchFromDisk
{
get {
return selectFromDiskRadioButton . Checked & & FileFromDiskAlert ! = null
? new KeyValuePair < XenServerPatch , string > ( FileFromDiskAlert . Patch , SelectedNewPatch )
: new KeyValuePair < XenServerPatch , string > ( null , null ) ;
}
}
2018-03-09 00:55:50 +01:00
protected override void PageLeaveCore ( PageLoadedDirection direction , ref bool cancel )
2013-06-24 13:41:48 +02:00
{
if ( direction = = PageLoadedDirection . Forward )
{
2016-12-10 15:44:15 +01:00
if ( ! IsInAutomatedUpdatesMode )
2016-03-14 17:10:16 +01:00
{
2018-03-14 13:12:18 +01:00
if ( selectFromDiskRadioButton . Checked & & ! string . IsNullOrEmpty ( fileNameTextBox . Text ) & & Path . GetExtension ( fileNameTextBox . Text ) . ToLowerInvariant ( ) . Equals ( ".zip" ) )
2017-07-21 16:56:27 +02:00
{
//check if we are installing update user sees in textbox
if ( Path . GetFileNameWithoutExtension ( unzippedUpdateFilePath ) ! = Path . GetFileNameWithoutExtension ( fileNameTextBox . Text ) )
{
unzippedUpdateFilePath = ExtractUpdate ( fileNameTextBox . Text ) ;
if ( unzippedUpdateFilePath = = null )
cancel = true ;
unzippedFiles . Add ( unzippedUpdateFilePath ) ;
}
}
else
unzippedUpdateFilePath = null ;
var fileName = isValidFile ( unzippedUpdateFilePath ) ? unzippedUpdateFilePath . ToLowerInvariant ( ) : fileNameTextBox . Text . ToLowerInvariant ( ) ;
2016-10-05 00:26:35 +02:00
2018-03-14 13:12:18 +01:00
SelectedUpdateAlert = downloadUpdateRadioButton . Checked & & dataGridViewPatches . SelectedRows . Count > 0
? ( ( PatchGridViewRow ) dataGridViewPatches . SelectedRows [ 0 ] ) . UpdateAlert
2016-10-05 00:26:35 +02:00
: null ;
FileFromDiskAlert = selectFromDiskRadioButton . Checked
2018-03-14 13:12:18 +01:00
? GetAlertFromFile ( fileName )
2016-10-05 00:26:35 +02:00
: null ;
2016-03-14 17:10:16 +01:00
if ( downloadUpdateRadioButton . Checked )
2015-07-09 17:32:08 +02:00
{
2018-03-14 13:12:18 +01:00
if ( SelectedUpdateAlert ! = null & & SelectedUpdateAlert . DistinctHosts ! = null & & SelectedUpdateAlert . DistinctHosts . Any ( Helpers . ElyOrGreater ) ) // this is to check whether the Alert represents an ISO update (Ely or greater)
2016-10-05 00:26:35 +02:00
{
2016-10-04 15:58:54 +02:00
SelectedUpdateType = UpdateType . ISO ;
2016-10-05 00:26:35 +02:00
}
else //legacy format
{
SelectedUpdateType = UpdateType . NewRetail ;
}
2015-07-09 17:32:08 +02:00
}
2016-03-14 17:10:16 +01:00
else
{
2016-10-05 00:26:35 +02:00
if ( isValidFile ( fileName ) )
2016-03-14 17:10:16 +01:00
{
2016-10-19 15:02:29 +02:00
if ( fileName . EndsWith ( "." + Branding . Update ) )
2016-03-14 17:10:16 +01:00
SelectedUpdateType = UpdateType . NewRetail ;
2016-10-19 14:42:16 +02:00
else if ( fileName . EndsWith ( "." + Branding . UpdateIso ) )
2016-08-31 11:42:09 +02:00
SelectedUpdateType = UpdateType . ISO ;
2016-03-14 17:10:16 +01:00
else
SelectedUpdateType = UpdateType . Existing ;
}
}
2013-06-24 13:41:48 +02:00
2016-03-14 17:10:16 +01:00
if ( SelectedExistingPatch ! = null & & ! SelectedExistingPatch . Connection . IsConnected )
{
cancel = true ;
PageLeaveCancelled ( string . Format ( Messages . UPDATES_WIZARD_CANNOT_DOWNLOAD_PATCH ,
SelectedExistingPatch . Connection . Name ) ) ;
}
else if ( ! string . IsNullOrEmpty ( SelectedNewPatch ) & & ! File . Exists ( SelectedNewPatch ) )
{
cancel = true ;
PageLeaveCancelled ( string . Format ( Messages . UPDATES_WIZARD_FILE_NOT_FOUND , SelectedNewPatch ) ) ;
}
2013-06-24 13:41:48 +02:00
}
2016-05-31 20:00:35 +02:00
else //In Automatic Mode
{
2016-11-16 13:26:26 +01:00
var succeed = Updates . CheckForUpdatesSync ( this . Parent ) ;
2016-05-31 20:00:35 +02:00
2016-11-16 13:26:26 +01:00
cancel = ! succeed ;
2016-05-31 20:00:35 +02:00
}
2013-06-24 13:41:48 +02:00
}
2016-03-16 13:59:20 +01:00
2016-05-31 20:00:35 +02:00
if ( ! cancel ) //unsubscribe only if we are really leaving this page
{
2016-08-08 15:37:47 +02:00
Updates . RestoreDismissedUpdatesStarted - = Updates_RestoreDismissedUpdatesStarted ;
2016-08-08 12:41:42 +02:00
Updates . CheckForUpdatesStarted - = CheckForUpdates_CheckForUpdatesStarted ;
2016-05-31 20:00:35 +02:00
Updates . CheckForUpdatesCompleted - = CheckForUpdates_CheckForUpdatesCompleted ;
}
2013-06-24 13:41:48 +02:00
}
2018-03-14 13:12:18 +01:00
private XenServerPatchAlert GetAlertFromFile ( string fileName )
2015-07-20 16:27:41 +02:00
{
2018-03-14 13:12:18 +01:00
var alertFromIso = GetAlertFromIsoFile ( fileName ) ;
if ( alertFromIso ! = null )
return alertFromIso ;
// couldn't find an alert from the information in the iso file, try matching by name
return Updates . FindPatchAlertByName ( Path . GetFileNameWithoutExtension ( fileName ) ) ;
}
private XenServerPatchAlert GetAlertFromIsoFile ( string fileName )
{
if ( ! fileName . EndsWith ( Branding . UpdateIso ) )
return null ;
var xmlDoc = new XmlDocument ( ) ;
try
{
using ( var isoStream = File . Open ( fileName , FileMode . Open ) )
{
var cd = new CDReader ( isoStream , true ) ;
if ( cd . Exists ( "Update.xml" ) )
{
using ( var fileStream = cd . OpenFile ( "Update.xml" , FileMode . Open ) )
{
xmlDoc . Load ( fileStream ) ;
}
}
}
}
catch ( Exception exception )
2015-07-20 16:27:41 +02:00
{
2018-03-14 13:12:18 +01:00
log . ErrorFormat ( "Exception while reading the update data from the iso file: {0}" , exception . Message ) ;
}
var elements = xmlDoc . GetElementsByTagName ( "update" ) ;
var update = elements . Count > 0 ? elements [ 0 ] : null ;
if ( update = = null | | update . Attributes = = null )
return null ;
2018-03-16 15:00:07 +01:00
var uuid = update . Attributes [ "uuid" ] ;
return uuid ! = null ? Updates . FindPatchAlertByUuid ( uuid . Value ) : null ;
2015-07-20 16:27:41 +02:00
}
2013-06-24 13:41:48 +02:00
private void PageLeaveCancelled ( string message )
{
2016-06-20 11:49:12 +02:00
using ( var dlg = new ThreeButtonDialog (
new ThreeButtonDialog . Details ( SystemIcons . Warning , message , Messages . UPDATES_WIZARD ) ) )
{
dlg . ShowDialog ( this ) ;
}
2013-06-24 13:41:48 +02:00
( ( PatchGridViewRow ) dataGridViewPatches . SelectedRows [ 0 ] ) . UpdateDetails ( ) ;
}
private void PopulatePatchesBox ( )
{
dataGridViewPatches . Rows . Clear ( ) ;
2017-03-23 14:58:24 +01:00
2017-03-24 12:37:43 +01:00
var updates = Updates . UpdateAlerts . ToList ( ) ;
2017-03-23 14:58:24 +01:00
2015-07-14 11:05:13 +02:00
if ( dataGridViewPatches . SortedColumn ! = null )
2013-06-24 13:41:48 +02:00
{
2015-07-14 11:05:13 +02:00
if ( dataGridViewPatches . SortedColumn . Index = = ColumnUpdate . Index )
updates . Sort ( Alert . CompareOnTitle ) ;
else if ( dataGridViewPatches . SortedColumn . Index = = ColumnDate . Index )
updates . Sort ( Alert . CompareOnDate ) ;
else if ( dataGridViewPatches . SortedColumn . Index = = ColumnDescription . Index )
2015-09-02 19:21:10 +02:00
updates . Sort ( Alert . CompareOnDescription ) ;
2015-07-14 11:05:13 +02:00
if ( dataGridViewPatches . SortOrder = = SortOrder . Descending )
updates . Reverse ( ) ;
}
2017-03-24 12:37:43 +01:00
else
{
updates . Sort ( new NewVersionPriorityAlertComparer ( ) ) ;
}
2017-03-23 14:58:24 +01:00
foreach ( Alert alert in updates )
{
var patchAlert = alert as XenServerPatchAlert ;
if ( patchAlert ! = null )
{
PatchGridViewRow row = new PatchGridViewRow ( patchAlert ) ;
if ( ! dataGridViewPatches . Rows . Contains ( row ) )
{
dataGridViewPatches . Rows . Add ( row ) ;
if ( patchAlert . RequiredXenCenterVersion ! = null )
{
row . Enabled = false ;
row . SetToolTip ( string . Format ( Messages . UPDATES_WIZARD_NEWER_XENCENTER_REQUIRED , patchAlert . RequiredXenCenterVersion . Version ) ) ;
}
}
}
2013-06-24 13:41:48 +02:00
}
2015-07-14 11:05:13 +02:00
}
public override void PageCancelled ( )
{
2016-08-08 15:37:47 +02:00
Updates . RestoreDismissedUpdatesStarted - = Updates_RestoreDismissedUpdatesStarted ;
2016-08-08 12:41:42 +02:00
Updates . CheckForUpdatesStarted - = CheckForUpdates_CheckForUpdatesStarted ;
2015-07-14 11:05:13 +02:00
Updates . CheckForUpdatesCompleted - = CheckForUpdates_CheckForUpdatesCompleted ;
2013-06-24 13:41:48 +02:00
}
public override bool EnableNext ( )
{
2015-07-14 11:05:13 +02:00
if ( CheckForUpdatesInProgress )
{
return false ;
}
2016-03-14 17:10:16 +01:00
2016-12-10 15:44:15 +01:00
if ( IsInAutomatedUpdatesMode )
2016-03-14 17:10:16 +01:00
{
return true ;
}
2015-07-09 17:32:08 +02:00
if ( downloadUpdateRadioButton . Checked )
2015-07-20 15:28:44 +02:00
{
2015-07-09 17:32:08 +02:00
if ( dataGridViewPatches . SelectedRows . Count = = 1 )
{
DataGridViewExRow row = ( DataGridViewExRow ) dataGridViewPatches . SelectedRows [ 0 ] ;
if ( row . Enabled )
2015-07-20 15:28:44 +02:00
{
2015-07-09 17:32:08 +02:00
return true ;
2015-07-20 15:28:44 +02:00
}
2015-07-09 17:32:08 +02:00
}
}
else if ( selectFromDiskRadioButton . Checked )
2013-06-24 13:41:48 +02:00
{
2016-10-05 00:26:35 +02:00
if ( isValidFile ( fileNameTextBox . Text ) )
2013-06-24 13:41:48 +02:00
return true ;
}
2017-07-21 16:56:27 +02:00
2013-06-24 13:41:48 +02:00
return false ;
}
2016-08-08 12:41:42 +02:00
public override bool EnablePrevious ( )
{
return ! CheckForUpdatesInProgress ;
}
2016-02-04 11:55:18 +01:00
private string UpdateExtension
{
2017-02-17 18:11:03 +01:00
get { return "." + Branding . Update ; }
2016-02-04 11:55:18 +01:00
}
2016-10-05 00:26:35 +02:00
private bool isValidFile ( string fileName )
2015-07-09 17:32:08 +02:00
{
2017-07-21 16:56:27 +02:00
return ! string . IsNullOrEmpty ( fileName ) & & File . Exists ( fileName ) & & ( fileName . ToLowerInvariant ( ) . EndsWith ( UpdateExtension . ToLowerInvariant ( ) )
| | fileName . ToLowerInvariant ( ) . EndsWith ( ".zip" )
| | fileName . ToLowerInvariant ( ) . EndsWith ( ".iso" ) ) ; //this iso is supplemental pack iso for XS, not branded
}
//list to store unzipped files to be removed later by PatchingWizard
private List < string > unzippedFiles = new List < string > ( ) ;
public List < string > UnzippedUpdateFiles
{
get { return unzippedFiles ; }
2015-07-09 17:32:08 +02:00
}
2013-06-24 13:41:48 +02:00
private void BrowseButton_Click ( object sender , EventArgs e )
{
// Showing this dialog has the (undocumented) side effect of changing the working directory
// to that of the file selected. This means a handle to the directory persists, making
// it undeletable until the program exits, or the working dir moves on. So, save and
// restore the working dir...
2015-07-09 17:32:08 +02:00
selectFromDiskRadioButton . Checked = true ;
2013-06-24 13:41:48 +02:00
String oldDir = "" ;
try
{
oldDir = Directory . GetCurrentDirectory ( ) ;
2016-08-08 12:41:42 +02:00
using ( OpenFileDialog dlg = new OpenFileDialog
{
Multiselect = false ,
ShowReadOnly = false ,
Filter = string . Format ( Messages . PATCHINGWIZARD_SELECTPATCHPAGE_UPDATESEXT , Branding . Update ) ,
FilterIndex = 0 ,
CheckFileExists = true ,
ShowHelp = false ,
Title = Messages . PATCHINGWIZARD_SELECTPATCHPAGE_CHOOSE
} )
2013-06-24 13:41:48 +02:00
{
2016-08-08 12:41:42 +02:00
if ( dlg . ShowDialog ( this ) = = DialogResult . OK & & dlg . CheckFileExists )
2017-07-21 16:56:27 +02:00
AddFile ( dlg . FileName ) ;
2013-06-24 13:41:48 +02:00
}
2017-07-21 16:56:27 +02:00
OnPageUpdated ( ) ;
2013-06-24 13:41:48 +02:00
}
finally
{
Directory . SetCurrentDirectory ( oldDir ) ;
}
}
public void AddFile ( string fileName )
{
2017-07-21 16:56:27 +02:00
if ( isValidFile ( fileName ) )
2013-06-24 13:41:48 +02:00
{
2015-07-14 11:05:13 +02:00
fileNameTextBox . Text = fileName ;
selectFromDiskRadioButton . Checked = true ;
2013-06-24 13:41:48 +02:00
}
else
{
2016-06-20 11:49:12 +02:00
using ( var dlg = new ThreeButtonDialog ( new ThreeButtonDialog . Details (
SystemIcons . Error , string . Format ( Messages . UPDATES_WIZARD_NOTVALID_EXTENSION , Branding . Update ) , Messages . UPDATES ) ) )
{
dlg . ShowDialog ( this ) ;
}
2013-06-24 13:41:48 +02:00
}
}
public UpdateType SelectedUpdateType { get ; set ; }
public Pool_patch SelectedExistingPatch { get ; set ; }
public string SelectedNewPatch
{
get
{
2015-07-09 17:32:08 +02:00
if ( downloadUpdateRadioButton . Checked )
{
2016-08-31 11:42:09 +02:00
return SelectedUpdateType = = UpdateType . NewRetail | | SelectedUpdateType = = UpdateType . ISO
2015-07-09 17:32:08 +02:00
? ( ( PatchGridViewRow ) dataGridViewPatches . SelectedRows [ 0 ] ) . PathPatch
: null ;
}
else if ( selectFromDiskRadioButton . Checked )
{
2016-08-31 11:42:09 +02:00
return SelectedUpdateType = = UpdateType . NewRetail | | SelectedUpdateType = = UpdateType . ISO
2017-07-21 16:56:27 +02:00
? isValidFile ( unzippedUpdateFilePath ) & & Path . GetExtension ( fileNameTextBox . Text ) . ToLowerInvariant ( ) . Equals ( ".zip" )
? unzippedUpdateFilePath : fileNameTextBox . Text : null ;
2015-07-09 17:32:08 +02:00
}
2017-07-21 16:56:27 +02:00
else
return null ;
2013-06-24 13:41:48 +02:00
}
}
2017-07-21 16:56:27 +02:00
private string ExtractUpdate ( string zippedUpdatePath )
{
var unzipAction = new DownloadAndUnzipXenServerPatchAction ( Path . GetFileNameWithoutExtension ( zippedUpdatePath ) , null , zippedUpdatePath , true , Branding . Update , Branding . UpdateIso ) ;
using ( var dlg = new ActionProgressDialog ( unzipAction , ProgressBarStyle . Marquee ) )
{
dlg . ShowDialog ( Parent ) ;
}
if ( string . IsNullOrEmpty ( unzipAction . PatchPath ) )
{
using ( var dlg = new ThreeButtonDialog ( new ThreeButtonDialog . Details (
SystemIcons . Error ,
string . Format ( Messages . UPDATES_WIZARD_NOTVALID_ZIPFILE , Path . GetFileName ( zippedUpdatePath ) ) ,
Messages . UPDATES ) ) )
{
dlg . ShowDialog ( this ) ;
2015-07-09 17:32:08 +02:00
}
2017-07-21 16:56:27 +02:00
return null ;
}
else
{
return unzipAction . PatchPath ;
2013-06-24 13:41:48 +02:00
}
}
2017-07-21 16:56:27 +02:00
2016-08-08 12:41:42 +02:00
#region DataGridView
2015-07-14 11:05:13 +02:00
2016-08-08 12:41:42 +02:00
private void dataGridViewPatches_SelectionChanged ( object sender , EventArgs e )
2015-07-14 11:05:13 +02:00
{
2016-08-08 12:41:42 +02:00
OnPageUpdated ( ) ;
2015-07-14 11:05:13 +02:00
}
2013-06-24 13:41:48 +02:00
private void dataGridViewPatches_CellMouseClick ( object sender , DataGridViewCellMouseEventArgs e )
{
if ( e . Button ! = MouseButtons . Left )
return ;
if ( e . RowIndex < 0 )
// The click is on a column header
return ;
PatchGridViewRow row = ( PatchGridViewRow ) dataGridViewPatches . Rows [ e . RowIndex ] ;
row . toggleExpandedState ( ) ;
2016-08-08 12:41:42 +02:00
OnPageUpdated ( ) ;
2013-06-24 13:41:48 +02:00
}
2015-07-14 11:05:13 +02:00
private void dataGridViewPatches_SortCompare ( object sender , DataGridViewSortCompareEventArgs e )
{
Alert alert1 = ( ( PatchGridViewRow ) dataGridViewPatches . Rows [ e . RowIndex1 ] ) . UpdateAlert ;
Alert alert2 = ( ( PatchGridViewRow ) dataGridViewPatches . Rows [ e . RowIndex2 ] ) . UpdateAlert ;
if ( e . Column . Index = = ColumnDate . Index )
{
int sortResult = DateTime . Compare ( alert1 . Timestamp , alert2 . Timestamp ) ;
e . SortResult = ( dataGridViewPatches . SortOrder = = SortOrder . Descending ) ? sortResult * = - 1 : sortResult ;
e . Handled = true ;
}
}
private void dataGridViewPatches_ColumnHeaderMouseClick ( object sender , DataGridViewCellMouseEventArgs e )
{
if ( dataGridViewPatches . Columns [ e . ColumnIndex ] . SortMode = = DataGridViewColumnSortMode . Automatic )
PopulatePatchesBox ( ) ;
}
private void dataGridViewPatches_CellContentClick ( object sender , DataGridViewCellEventArgs e )
2016-08-08 12:41:42 +02:00
{
// The click is on a column header
2015-07-14 11:05:13 +02:00
if ( e . RowIndex = = - 1 )
{
return ;
}
PatchGridViewRow row = dataGridViewPatches . Rows [ e . RowIndex ] as PatchGridViewRow ;
if ( row ! = null & & e . ColumnIndex = = 3 )
{
row . UpdateAlert . FixLinkAction ( ) ;
}
}
private void dataGridViewPatches_Enter ( object sender , EventArgs e )
{
downloadUpdateRadioButton . Checked = true ;
2016-08-08 12:41:42 +02:00
OnPageUpdated ( ) ;
2015-07-14 11:05:13 +02:00
}
2013-06-24 13:41:48 +02:00
private class PatchGridViewRow : DataGridViewExRow , IEquatable < PatchGridViewRow >
{
2017-08-30 10:31:05 +02:00
private readonly XenServerPatchAlert _alert ;
2013-06-24 13:41:48 +02:00
private bool expanded = false ;
private bool _isFile = false ;
private string _patchPath ;
private DataGridViewImageCell _imageCell ;
private DataGridViewTextBoxCell _nameCell ;
private DataGridViewTextBoxCell _descriptionCell ;
2015-07-14 11:05:13 +02:00
private DataGridViewTextBoxCell _dateCell ;
2013-06-24 13:41:48 +02:00
private DataGridViewTextBoxCell _statusCell ;
2015-07-09 17:59:14 +02:00
private DataGridViewLinkCell _webPageCell ;
2013-06-24 13:41:48 +02:00
2017-08-30 10:31:05 +02:00
public PatchGridViewRow ( XenServerPatchAlert alert )
2015-07-14 11:05:13 +02:00
{
_alert = alert ;
_nameCell = new DataGridViewTextBoxCell ( ) ;
_descriptionCell = new DataGridViewTextBoxCell ( ) ;
_dateCell = new DataGridViewTextBoxCell ( ) ;
_webPageCell = new DataGridViewLinkCell ( ) ;
2013-06-24 13:41:48 +02:00
2015-07-14 11:05:13 +02:00
Cells . Add ( _nameCell ) ;
Cells . Add ( _descriptionCell ) ;
Cells . Add ( _dateCell ) ;
Cells . Add ( _webPageCell ) ;
_nameCell . Value = String . Format ( alert . Name ) ;
_descriptionCell . Value = String . Format ( alert . Description ) ;
_dateCell . Value = HelpersGUI . DateTimeToString ( alert . Timestamp . ToLocalTime ( ) , Messages . DATEFORMAT_DMY , true ) ;
_webPageCell . Value = Messages . PATCHING_WIZARD_WEBPAGE_CELL ;
2013-06-24 13:41:48 +02:00
}
public PatchGridViewRow ( string patchPath )
{
_isFile = true ;
_patchPath = patchPath ;
SetupCells ( ) ;
}
2017-08-30 10:31:05 +02:00
public XenServerPatchAlert UpdateAlert
2015-07-14 11:05:13 +02:00
{
get { return _alert ; }
2013-06-24 13:41:48 +02:00
}
public string PathPatch
{
get { return _patchPath ; }
}
private void SetupCells ( )
{
_imageCell = new DataGridViewExImageCell ( ) ;
_nameCell = new DataGridViewTextBoxCell ( ) ;
_descriptionCell = new DataGridViewTextBoxCell ( ) ;
_statusCell = new DataGridViewTextBoxCell ( ) ;
2015-07-09 17:59:14 +02:00
_webPageCell = new DataGridViewLinkCell ( ) ;
2013-06-24 13:41:48 +02:00
Cells . Add ( _imageCell ) ;
Cells . Add ( _nameCell ) ;
Cells . Add ( _descriptionCell ) ;
Cells . Add ( _statusCell ) ;
2015-07-09 17:59:14 +02:00
Cells . Add ( _webPageCell ) ;
2013-06-24 13:41:48 +02:00
this . UpdateDetails ( ) ;
}
private void UpdateFileDetails ( string description , string status )
{
_descriptionCell . Value = description ;
_statusCell . Value = status ;
}
public void UpdateDetails ( )
{
_imageCell . Value = expanded ? Resources . expanded_triangle : Resources . contracted_triangle ;
2015-07-09 17:59:14 +02:00
_webPageCell . Value = Messages . PATCHING_WIZARD_WEBPAGE_CELL ;
2013-06-24 13:41:48 +02:00
if ( _isFile )
{
_nameCell . Value = System . IO . Path . GetFileName ( _patchPath ) ;
FileInfo fileInfo = new FileInfo ( _patchPath ) ;
string description = expanded
? fileInfo . Exists
? String . Format ( Messages . PATCH_EXPANDED_DESCRIPTION
, _patchPath , fileInfo . CreationTime ,
2015-01-20 15:22:29 +01:00
fileInfo . LastWriteTime , Util . DiskSizeString ( fileInfo . Length ) )
2013-06-24 13:41:48 +02:00
: String . Format ( Messages . PATCH_NOT_FOUND_EXPANDED_DESCRIPTION ,
_patchPath )
: _patchPath ;
UpdateFileDetails ( description , fileInfo . Exists ? Messages . NOT_UPLOADED : Messages . PATCH_NOT_FOUND ) ;
2015-07-14 11:05:13 +02:00
}
2013-06-24 13:41:48 +02:00
}
public void toggleExpandedState ( )
{
expanded = ! expanded ;
}
public bool Equals ( PatchGridViewRow other )
{
2015-07-14 11:05:13 +02:00
if ( other . UpdateAlert ! = null & & this . UpdateAlert ! = null & & this . UpdateAlert . uuid = = other . UpdateAlert . uuid )
2013-06-24 13:41:48 +02:00
return true ;
if ( other . PathPatch ! = null & & this . PathPatch ! = null & & this . PathPatch = = other . PathPatch )
return true ;
return false ;
}
public override int GetHashCode ( )
{
return base . GetHashCode ( ) ;
}
public override bool Equals ( object obj )
{
if ( obj is PatchGridViewRow )
return this . Equals ( ( PatchGridViewRow ) obj ) ;
return false ;
}
2017-03-23 14:58:24 +01:00
public void SetToolTip ( string toolTip )
{
foreach ( var c in Cells )
{
if ( c is DataGridViewLinkCell )
continue ;
var cell = c as DataGridViewCell ;
if ( c ! = null )
( ( DataGridViewCell ) c ) . ToolTipText = toolTip ;
}
}
2015-07-23 15:04:43 +02:00
}
2016-08-08 12:41:42 +02:00
#endregion
#region Buttons
2015-07-23 15:04:43 +02:00
private void RestoreDismUpdatesButton_Click ( object sender , EventArgs e )
{
2017-07-21 16:56:27 +02:00
dataGridViewPatches . Focus ( ) ;
2015-07-23 15:04:43 +02:00
Updates . RestoreDismissedUpdates ( ) ;
2016-03-14 17:10:16 +01:00
}
2016-08-08 12:41:42 +02:00
private void RefreshListButton_Click ( object sender , EventArgs e )
{
2016-11-16 13:26:26 +01:00
dataGridViewPatches . Focus ( ) ;
2016-08-08 12:41:42 +02:00
Updates . CheckForUpdates ( true ) ;
}
#endregion
#region TextBox
private void fileNameTextBox_Enter ( object sender , EventArgs e )
{
selectFromDiskRadioButton . Checked = true ;
OnPageUpdated ( ) ;
}
private void fileNameTextBox_TextChanged ( object sender , EventArgs e )
{
selectFromDiskRadioButton . Checked = true ;
OnPageUpdated ( ) ;
}
#endregion
#region RadioButtons
2016-03-14 17:10:16 +01:00
private void AutomaticRadioButton_CheckedChanged ( object sender , EventArgs e )
{
2016-08-08 12:41:42 +02:00
OnPageUpdated ( ) ;
2016-03-14 17:10:16 +01:00
}
private void downloadUpdateRadioButton_CheckedChanged ( object sender , EventArgs e )
{
2016-08-08 12:41:42 +02:00
dataGridViewPatches . HideSelection = ! downloadUpdateRadioButton . Checked ;
if ( downloadUpdateRadioButton . Checked )
dataGridViewPatches . Focus ( ) ;
OnPageUpdated ( ) ;
}
private void selectFromDiskRadioButton_CheckedChanged ( object sender , EventArgs e )
{
OnPageUpdated ( ) ;
}
private void AutomaticRadioButton_TabStopChanged ( object sender , EventArgs e )
{
2016-12-10 15:44:15 +01:00
if ( ! AutomatedUpdatesRadioButton . TabStop )
AutomatedUpdatesRadioButton . TabStop = true ;
2016-08-08 12:41:42 +02:00
}
private void downloadUpdateRadioButton_TabStopChanged ( object sender , EventArgs e )
{
if ( ! downloadUpdateRadioButton . TabStop )
downloadUpdateRadioButton . TabStop = true ;
}
private void selectFromDiskRadioButton_TabStopChanged ( object sender , EventArgs e )
{
if ( ! selectFromDiskRadioButton . TabStop )
selectFromDiskRadioButton . TabStop = true ;
}
#endregion
2015-07-14 11:05:13 +02:00
}
2013-06-24 13:41:48 +02:00
2016-08-31 11:42:09 +02:00
public enum UpdateType { NewRetail , Existing , ISO }
2016-08-08 12:41:42 +02:00
}