2013-06-24 13:41:48 +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 .
* /
using System ;
2013-09-20 12:24:46 +02:00
using System.Collections.Generic ;
2013-06-24 13:41:48 +02:00
using System.Diagnostics ;
using System.Drawing ;
2013-09-18 14:06:47 +02:00
using System.Linq ;
2013-06-24 13:41:48 +02:00
using XenAdmin.Actions ;
2013-09-18 14:06:47 +02:00
using XenAdmin.Controls ;
2013-06-24 13:41:48 +02:00
using XenAdmin.Core ;
using XenAdmin.Properties ;
using XenAPI ;
namespace XenAdmin.SettingsPanels
{
2013-09-20 12:24:46 +02:00
public partial class GpuEditPage : XenTabPage , IEditPage
2013-06-24 13:41:48 +02:00
{
2013-09-20 12:24:46 +02:00
public VM vm ;
2013-09-18 14:06:47 +02:00
private GpuTuple currentGpuTuple ;
private GPU_group [ ] gpu_groups ;
private bool gpusAvailable ;
2013-06-24 13:41:48 +02:00
public GpuEditPage ( )
{
InitializeComponent ( ) ;
2013-11-14 12:29:41 +01:00
imgRDP . Visible = labelRDP . Visible =
imgNeedDriver . Visible = labelNeedDriver . Visible =
imgNeedGpu . Visible = labelNeedGpu . Visible =
imgStopVM . Visible = labelStopVM . Visible =
2013-11-14 12:57:28 +01:00
imgHA . Visible = labelHA . Visible =
2013-11-14 12:29:41 +01:00
false ;
2013-09-20 12:24:46 +02:00
}
public GPU_group GpuGroup
{
get
{
GpuTuple tuple = comboBoxGpus . SelectedItem as GpuTuple ;
return tuple = = null ? null : tuple . GpuGroup ;
}
}
public VGPU_type VgpuType
{
get
{
GpuTuple tuple = comboBoxGpus . SelectedItem as GpuTuple ;
if ( tuple = = null | | tuple . VgpuTypes = = null | | tuple . VgpuTypes . Length = = 0 )
return null ;
return tuple . VgpuTypes [ 0 ] ;
}
2013-06-24 13:41:48 +02:00
}
2013-11-14 13:38:00 +01:00
public VM . HA_Restart_Priority SelectedPriority { private get ; set ; }
2013-06-24 13:41:48 +02:00
#region IEditPage Members
public AsyncAction SaveSettings ( )
{
2013-09-20 12:24:46 +02:00
return new GpuAssignAction ( vm , GpuGroup , VgpuType ) ;
2013-06-24 13:41:48 +02:00
}
public void SetXenObjects ( IXenObject orig , IXenObject clone )
{
Trace . Assert ( clone is VM ) ; // only VMs should show this page
Trace . Assert ( Helpers . BostonOrGreater ( clone . Connection ) ) ; // If not Boston or greater, we shouldn't see this page
Trace . Assert ( ! Helpers . FeatureForbidden ( clone , Host . RestrictGpu ) ) ; // If license insufficient, we show upsell page instead
vm = ( VM ) clone ;
2013-11-14 13:38:00 +01:00
SelectedPriority = vm . HARestartPriority ;
2013-09-18 14:06:47 +02:00
2013-09-20 12:24:46 +02:00
if ( Connection = = null ) // on the PropertiesDialog
Connection = vm . Connection ;
2013-06-24 13:41:48 +02:00
2013-09-20 12:24:46 +02:00
PopulatePage ( ) ;
2013-06-24 13:41:48 +02:00
}
public bool ValidToSave
{
get { return true ; }
}
public void ShowLocalValidationMessages ( )
{
}
public void Cleanup ( )
{
}
public bool HasChanged
{
get
{
2013-09-18 14:06:47 +02:00
var tuple = comboBoxGpus . SelectedItem as GpuTuple ;
if ( tuple = = null )
return false ;
return ! tuple . Equals ( currentGpuTuple ) ;
2013-06-24 13:41:48 +02:00
}
}
#region VerticalTab Members
public string SubText
{
get
{
2013-11-14 12:32:51 +01:00
string txt = Messages . GPU_UNAVAILABLE ;
if ( gpusAvailable )
{
var tuple = comboBoxGpus . SelectedItem as GpuTuple ;
if ( tuple ! = null )
txt = tuple . ToString ( ) ;
}
return txt ;
2013-06-24 13:41:48 +02:00
}
}
public Image Image
{
get { return Resources . _000_GetMemoryInfo_h32bit_16 ; }
}
#endregion
#endregion
2013-09-20 12:24:46 +02:00
#region XenTabPage overrides
public override string Text
2013-06-24 13:41:48 +02:00
{
2013-09-20 12:24:46 +02:00
get { return Messages . GPU ; }
}
public override string PageTitle
{
get { return Messages . NEWVMWIZARD_VGPUPAGE_TITLE ; }
}
public override string HelpID
{
get { return "GPU" ; }
}
public override List < KeyValuePair < string , string > > PageSummary
{
get
{
var summ = new List < KeyValuePair < string , string > > ( ) ;
GpuTuple tuple = comboBoxGpus . SelectedItem as GpuTuple ;
if ( tuple ! = null )
summ . Add ( new KeyValuePair < string , string > ( Messages . GPU , tuple . ToString ( ) ) ) ;
return summ ;
}
}
public override void PopulatePage ( )
{
2013-11-14 12:44:05 +01:00
currentGpuTuple = new GpuTuple ( null , null , null ) ;
2013-09-20 12:24:46 +02:00
if ( vm . VGPUs . Count ! = 0 )
{
VGPU vgpu = Connection . Resolve ( vm . VGPUs [ 0 ] ) ;
if ( vgpu ! = null )
{
var vgpuGroup = Connection . Resolve ( vgpu . GPU_group ) ;
2015-01-22 10:48:04 +01:00
if ( Helpers . FeatureForbidden ( Connection , Host . RestrictVgpu ) | | ! vm . CanHaveVGpu )
2013-11-14 12:44:05 +01:00
currentGpuTuple = new GpuTuple ( vgpuGroup , null , null ) ;
2013-09-20 12:24:46 +02:00
else
{
VGPU_type vgpuType = Connection . Resolve ( vgpu . type ) ;
2013-12-11 11:23:02 +01:00
currentGpuTuple = new GpuTuple ( vgpuGroup , vgpuType , null ) ;
2013-09-20 12:24:46 +02:00
}
}
}
2015-03-25 18:04:45 +01:00
// vGPU was introduced in Clearwater SP1
gpu_groups = ! Helpers . ClearwaterSp1OrGreater ( Connection ) //We used to check host.RestrictVgpu here (instead of checking the API version); this is not correct anymore, because vGPU is a licensed feature.
2013-11-20 12:30:51 +01:00
? Connection . Cache . GPU_groups
: Connection . Cache . GPU_groups . Where ( g = > g . PGPUs . Count > 0 & & g . supported_VGPU_types . Count ! = 0 ) . ToArray ( ) ;
//not showing empty groups
2013-09-20 12:24:46 +02:00
gpusAvailable = gpu_groups . Length > 0 ;
2013-11-14 13:38:00 +01:00
if ( gpusAvailable )
{
PopulateComboBox ( ) ;
ShowHideWarnings ( ) ;
}
else
2013-06-24 13:41:48 +02:00
{
2013-09-20 12:24:46 +02:00
labelRubric . Text = Helpers . GetPool ( Connection ) = = null
2013-09-18 14:06:47 +02:00
? Messages . GPU_RUBRIC_NO_GPUS_SERVER
: Messages . GPU_RUBRIC_NO_GPUS_POOL ;
2013-11-14 13:38:00 +01:00
tableLayoutPanel1 . Visible = false ;
warningsTable . Visible = false ;
2013-06-24 13:41:48 +02:00
}
2013-11-14 13:38:00 +01:00
}
#endregion
2013-09-18 14:06:47 +02:00
2013-11-14 13:38:00 +01:00
private void PopulateComboBox ( )
{
2013-12-11 11:23:02 +01:00
var noneItem = new GpuTuple ( null , null , null ) ; // "None" item
2013-11-14 13:38:00 +01:00
comboBoxGpus . Items . Add ( noneItem ) ;
Array . Sort ( gpu_groups ) ;
foreach ( GPU_group gpu_group in gpu_groups )
{
2015-01-22 10:48:04 +01:00
if ( Helpers . FeatureForbidden ( Connection , Host . RestrictVgpu ) | | ! vm . CanHaveVGpu )
2013-09-18 14:06:47 +02:00
{
2013-12-11 11:23:02 +01:00
comboBoxGpus . Items . Add ( new GpuTuple ( gpu_group , null , null ) ) ; //GPU pass-through item
2013-11-14 13:38:00 +01:00
}
else
{
2013-12-11 11:19:31 +01:00
var enabledTypes = Connection . ResolveAll ( gpu_group . enabled_VGPU_types ) ;
2013-11-14 13:38:00 +01:00
var allTypes = Connection . ResolveAll ( gpu_group . supported_VGPU_types ) ;
2013-11-14 12:44:05 +01:00
2013-11-14 13:38:00 +01:00
var disabledTypes = allTypes . FindAll ( t = > ! enabledTypes . Exists ( e = > e . opaque_ref = = t . opaque_ref ) ) ;
2013-11-14 12:44:05 +01:00
2013-11-14 13:38:00 +01:00
if ( allTypes . Count > 1 )
{
allTypes . Sort ( ( t1 , t2 ) = >
2013-12-11 11:23:02 +01:00
{
int result = t1 . Capacity . CompareTo ( t2 . Capacity ) ;
if ( result ! = 0 )
return result ;
return t1 . Name . CompareTo ( t2 . Name ) ;
} ) ;
2013-12-11 11:26:54 +01:00
comboBoxGpus . Items . Add ( new GpuTuple ( gpu_group , allTypes . ToArray ( ) ) ) ; // Group item
2013-09-18 14:06:47 +02:00
}
2013-12-11 11:23:02 +01:00
foreach ( var vgpuType in allTypes )
comboBoxGpus . Items . Add ( new GpuTuple ( gpu_group , vgpuType , disabledTypes . ToArray ( ) ) ) ; // GPU_type item
2013-09-18 14:06:47 +02:00
}
2013-06-24 13:41:48 +02:00
}
2013-11-14 13:38:00 +01:00
foreach ( var item in comboBoxGpus . Items )
{
var tuple = item as GpuTuple ;
if ( tuple = = null )
continue ;
2013-06-24 13:41:48 +02:00
2013-11-14 13:38:00 +01:00
if ( tuple . Equals ( currentGpuTuple ) )
{
comboBoxGpus . SelectedItem = item ;
break ;
}
}
if ( comboBoxGpus . SelectedItem = = null )
comboBoxGpus . SelectedItem = noneItem ;
}
2013-09-20 12:24:46 +02:00
2013-11-14 13:38:00 +01:00
public void ShowHideWarnings ( )
2013-06-24 13:41:48 +02:00
{
if ( ! gpusAvailable )
return ;
2013-09-20 12:24:46 +02:00
if ( vm . power_state ! = vm_power_state . Halted )
2013-06-24 13:41:48 +02:00
{
2013-09-18 14:06:47 +02:00
imgRDP . Visible = labelRDP . Visible =
imgNeedDriver . Visible = labelNeedDriver . Visible =
imgNeedGpu . Visible = labelNeedGpu . Visible =
2013-11-14 12:57:28 +01:00
imgHA . Visible = labelHA . Visible =
2013-06-24 13:41:48 +02:00
false ;
2013-09-18 14:06:47 +02:00
imgStopVM . Visible = labelStopVM . Visible = true ;
2013-06-24 13:41:48 +02:00
2013-09-18 14:06:47 +02:00
labelGpuType . Enabled = comboBoxGpus . Enabled = false ;
2013-06-24 13:41:48 +02:00
return ;
}
2015-03-26 17:57:25 +01:00
Pool pool = Helpers . GetPool ( Connection ) ;
if ( pool ! = null & & pool . ha_enabled & & VM . HaPriorityIsRestart ( Connection , SelectedPriority ) )
2013-11-14 12:57:28 +01:00
{
imgRDP . Visible = labelRDP . Visible =
imgNeedDriver . Visible = labelNeedDriver . Visible =
imgNeedGpu . Visible = labelNeedGpu . Visible =
imgStopVM . Visible = labelStopVM . Visible =
false ;
imgHA . Visible = labelHA . Visible = true ;
labelGpuType . Enabled = comboBoxGpus . Enabled = false ;
return ;
}
2013-11-14 13:38:00 +01:00
labelGpuType . Enabled = comboBoxGpus . Enabled = true ;
2013-09-18 14:06:47 +02:00
GpuTuple tuple = comboBoxGpus . SelectedItem as GpuTuple ;
2013-06-24 13:41:48 +02:00
2013-11-14 12:57:28 +01:00
imgStopVM . Visible = labelStopVM . Visible =
imgHA . Visible = labelHA . Visible = false ;
2013-09-18 14:06:47 +02:00
imgRDP . Visible = labelRDP . Visible =
HasChanged & & currentGpuTuple . GpuGroup = = null & &
tuple ! = null & & ! tuple . IsFractionalVgpu ;
2013-06-24 13:41:48 +02:00
2013-09-18 14:06:47 +02:00
imgNeedGpu . Visible = labelNeedGpu . Visible =
labelNeedDriver . Visible = imgNeedDriver . Visible =
tuple ! = null & & tuple . GpuGroup ! = null ;
2013-06-24 13:41:48 +02:00
}
private void comboBoxGpus_SelectedIndexChanged ( object sender , EventArgs e )
{
2013-09-18 14:06:47 +02:00
warningsTable . SuspendLayout ( ) ;
2013-06-24 13:41:48 +02:00
ShowHideWarnings ( ) ;
2013-09-18 14:06:47 +02:00
warningsTable . ResumeLayout ( ) ;
2013-06-24 13:41:48 +02:00
}
private void warningsTable_SizeChanged ( object sender , EventArgs e )
{
int [ ] columnsWidth = warningsTable . GetColumnWidths ( ) ;
2013-09-18 14:06:47 +02:00
int textColumnWidth = columnsWidth . Length > 1 ? columnsWidth [ 1 ] : 1 ;
labelRDP . MaximumSize = labelStopVM . MaximumSize = new Size ( textColumnWidth , 999 ) ;
2013-06-24 13:41:48 +02:00
}
}
}