CP-10204: XenCenter: guest RDP control

Signed-off-by: Cheng Zhang <cheng.zhang@citrix.com>
This commit is contained in:
Cheng Zhang 2014-12-04 16:35:36 +08:00
parent e4729a6402
commit 6b6b515fe7
14 changed files with 123 additions and 32 deletions

View File

@ -40,13 +40,15 @@ using XenAdmin.Core;
using XenAdmin.Network;
using XenAPI;
using XenAdmin.Commands;
using XenAdmin.Dialogs;
using System.Collections.Generic;
namespace XenAdmin.ConsoleView
{
public partial class VNCTabView : UserControl
{
private static readonly string UseRDP = Messages.VNC_RDESKTOP;
private static readonly string enableRDP = Messages.VNC_RDESKTOP_TRUN_ON;
// public only for the automated tests.
public static readonly string UseVNC = Messages.VNC_VIRTUAL_CONSOLE;
public static readonly string UseXVNC = Messages.VNC_X_CONSOLE;
@ -78,6 +80,8 @@ namespace XenAdmin.ConsoleView
private bool hasRDP { get { return source != null ? source.HasRDP : false; } }
private bool RDPEnabled { get { return source != null ? source.RDPEnabled : false; } }
public VNCTabView(VNCView parent, VM source, string elevatedUsername, string elevatedPassword)
{
Program.AssertOnEventThread();
@ -97,6 +101,9 @@ namespace XenAdmin.ConsoleView
this.parentVNCView = parent;
this.scaleCheckBox.Checked = false;
this.source = source;
this.guestMetrics = source.Connection.Resolve(source.guest_metrics);
if (this.guestMetrics != null)
guestMetrics.PropertyChanged += guestMetrics_PropertyChanged;
log.DebugFormat("'{0}' console: Register Server_PropertyChanged event listener on {0}", this.source.Name);
this.source.PropertyChanged += Server_PropertyChanged;
Host_CollectionChangedWithInvoke = Program.ProgramInvokeHandler(Host_CollectionChanged);
@ -502,6 +509,7 @@ namespace XenAdmin.ConsoleView
if (e.PropertyName == "other")
{
EnableRDPIfCapable();
UpdateButtons();
}
}
@ -519,7 +527,10 @@ namespace XenAdmin.ConsoleView
{
log.DebugFormat("'{0}' console: Starting RDP polling. (RDP polling is enabled in settings.)", source);
toggleConsoleButton.Visible = true;
toggleConsoleButton.Enabled = false;
if(Helpers.CreedenceOrGreater(targetHost))
toggleConsoleButton.Enabled = true;
else
toggleConsoleButton.Enabled = false;
ThreadPool.QueueUserWorkItem(TryToConnectRDP);
}
else
@ -768,7 +779,7 @@ namespace XenAdmin.ConsoleView
if (osString != null)
{
if (osString.Contains("Microsoft"))
label = UseRDP;
label = (Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled) ? enableRDP : UseRDP;
else
label = UseXVNC;
}
@ -1064,6 +1075,12 @@ namespace XenAdmin.ConsoleView
toggleConsoleButton.Enabled = false;
}
public void EnableToggleVNCButton()
{
Program.AssertOnEventThread();
toggleConsoleButton.Enabled = true;
}
private void OnDetectRDP()
{
Program.Invoke(this, OnDetectRDP_);
@ -1075,8 +1092,11 @@ namespace XenAdmin.ConsoleView
{
log.DebugFormat("RDP detected for VM '{0}'", source == null ? "unknown/null" : source.name_label);
this.toggleToXVNCorRDP = RDP;
if (vncScreen.UseVNC)
this.toggleConsoleButton.Text = UseRDP;
if (vncScreen.UseVNC)
if(Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled)
this.toggleConsoleButton.Text = enableRDP;
else
this.toggleConsoleButton.Text = UseRDP;
this.toggleConsoleButton.Enabled = true;
tip.SetToolTip(this.toggleConsoleButton, null);
if (!vncScreen.UserWantsToSwitchProtocol&& Properties.Settings.Default.AutoSwitchToRDP)
@ -1133,7 +1153,25 @@ namespace XenAdmin.ConsoleView
vncScreen.UseVNC = !vncScreen.UseVNC;
vncScreen.UserWantsToSwitchProtocol = true;
if (Helpers.CreedenceOrGreater(targetHost))
{
if (!RDPEnabled)
{
ThreeButtonDialog d = new ThreeButtonDialog(
new ThreeButtonDialog.Details(System.Drawing.SystemIcons.Warning, Messages.FORCE_ENABLE_RDP),
"EnableRDPonVM",
new ThreeButtonDialog.TBDButton(Messages.YES, DialogResult.Yes),
new ThreeButtonDialog.TBDButton(Messages.NO, DialogResult.No));
if (d.ShowDialog(Program.MainWindow) == DialogResult.Yes)
{
Session session = source.Connection.DuplicateSession();
Dictionary<string, string> _arguments = new Dictionary<string, string>();
XenAPI.VM.call_plugin(session, source.opaque_ref, "guest-agent-operation", "request-rdp-on", _arguments);
}
}
}
if (vncScreen.rdpIP == null && vncScreen.UseVNC && Properties.Settings.Default.EnableRDPPolling)
{
toggleConsoleButton.Enabled = false;
@ -1143,15 +1181,13 @@ namespace XenAdmin.ConsoleView
if (vncScreen.rdpIP == null) // disable toggleConsoleButton; it will be re-enabled in TryToConnectRDP() when rdp port polling is complete (CA-102755)
toggleConsoleButton.Enabled = false;
ThreadPool.QueueUserWorkItem(TryToConnectRDP);
}
}
else
{
oldScaleValue = scaleCheckBox.Checked;
vncScreen.UseSource = !vncScreen.UseSource;
if (vncScreen.vncIP == null && vncScreen.UseSource && Properties.Settings.Default.EnableRDPPolling)
{
toggleConsoleButton.Enabled = false;
@ -1171,7 +1207,7 @@ namespace XenAdmin.ConsoleView
{
bool rdp = (toggleToXVNCorRDP == RDP);
if (rdp)
toggleConsoleButton.Text = vncScreen.UseVNC ? UseRDP : UseStandardDesktop;
toggleConsoleButton.Text = vncScreen.UseVNC ? ((Helpers.CreedenceOrGreater(targetHost) && !RDPEnabled) ? enableRDP : UseRDP) : UseStandardDesktop;
else
toggleConsoleButton.Text = vncScreen.UseSource ? UseXVNC : UseVNC;
scaleCheckBox.Visible = !rdp || vncScreen.UseVNC;

View File

@ -686,10 +686,15 @@ namespace XenAdmin.ConsoleView
private void startPolling()
{
//Disable the button first, but only if in text/default console (to allow user to return to the text console - ref. CA-70314)
if (InDefaultConsole())
{
if (Helpers.CreedenceOrGreater(Source.Connection))
{
parentVNCTabView.EnableToggleVNCButton();
}
else if (InDefaultConsole())
{
parentVNCTabView.DisableToggleVNCButton();
}
//Start the polling again
if (Source != null && !Source.is_control_domain)

View File

@ -88,7 +88,6 @@ namespace XenAdmin.Dialogs.OptionsPages
resources.ApplyResources(this.checkBoxDisableRDPPolling, "checkBoxDisableRDPPolling");
this.checkBoxDisableRDPPolling.Name = "checkBoxDisableRDPPolling";
this.checkBoxDisableRDPPolling.UseVisualStyleBackColor = true;
this.checkBoxDisableRDPPolling.CheckedChanged += new System.EventHandler(this.checkBoxDisableRDPPolling_CheckedChanged);
//
// WindowsKeyCheckBox
//

View File

@ -75,11 +75,6 @@ namespace XenAdmin.Dialogs.OptionsPages
PreserveUndockedScaleCheckBox.Checked = Properties.Settings.Default.PreserveScaleWhenUndocked;
PreserveVNCConsoleScalingCheckBox.Checked = Properties.Settings.Default.PreserveScaleWhenSwitchBackToVNC;
checkBoxDisableRDPPolling.Checked = Properties.Settings.Default.EnableRDPPolling;
if (!checkBoxDisableRDPPolling.Checked)
{
AutoSwitchCheckBox.Checked = false;
AutoSwitchCheckBox.Enabled = false;
}
}
private void buildKeyCodeListBox()
@ -203,17 +198,5 @@ namespace XenAdmin.Dialogs.OptionsPages
#endregion
private void checkBoxDisableRDPPolling_CheckedChanged(object sender, EventArgs e)
{
if (checkBoxDisableRDPPolling.Checked)
{
AutoSwitchCheckBox.Enabled = true;
}
else
{
AutoSwitchCheckBox.Enabled = false;
AutoSwitchCheckBox.Checked = false;
}
}
}
}

View File

@ -190,7 +190,7 @@
<value>4</value>
</data>
<data name="checkBoxDisableRDPPolling.Text" xml:space="preserve">
<value>E&amp;nable Remote Desktop console scanning</value>
<value>E&amp;nable Remote Desktop console scanning (XenServer 6.5 and earlier)</value>
</data>
<data name="&gt;&gt;checkBoxDisableRDPPolling.Name" xml:space="preserve">
<value>checkBoxDisableRDPPolling</value>

View File

@ -160,5 +160,6 @@
<call name="secret_set_value" />
<call name="secret_get_all" />
<call name="secret_get_all_records" />
<call name="vm_call_plugin" />
</version>
</ApiVersionTool>

View File

@ -262,6 +262,7 @@ vm_appliance_assert_can_be_recovered,boston
async_vm_appliance_assert_can_be_recovered,boston
vm_appliance_recover,boston
async_vm_appliance_recover,boston
vm_call_plugin,creedence
dr_task_create,boston
async_dr_task_create,boston
dr_task_destroy,boston

1 session_login_with_password rio
262 vm_appliance_recover boston
263 async_vm_appliance_recover boston
264 dr_task_create vm_call_plugin boston creedence
265 dr_task_create boston
266 async_dr_task_create boston
267 dr_task_destroy boston
268 async_dr_task_destroy boston

View File

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
// Runtime Version:4.0.30319.18444
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -13789,6 +13789,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop?.
/// </summary>
public static string FORCE_ENABLE_RDP {
get {
return ResourceManager.GetString("FORCE_ENABLE_RDP", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Force Reboot.
/// </summary>
@ -32960,6 +32969,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Turn &amp;on Remote Desktop.
/// </summary>
public static string VNC_RDESKTOP_TRUN_ON {
get {
return ResourceManager.GetString("VNC_RDESKTOP_TRUN_ON", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &amp;Redock.
/// </summary>

View File

@ -4836,6 +4836,9 @@ CD をイジェクトしてから再試行してください。</value>
<data name="FORCE_CLOSE_PLUGIN_PROMPT" xml:space="preserve">
<value>プラグイン {0} がキャンセル要求に応答していません。プロセスを強制終了するか、バックグラウンドでの続行を許可するかを選択してください。</value>
</data>
<data name="FORCE_ENABLE_RDP" xml:space="preserve">
<value>Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop?</value>
</data>
<data name="FORCE_REBOOT" xml:space="preserve">
<value>強制再起動</value>
</data>
@ -11403,6 +11406,9 @@ StorageLink Gateway を使用する VM の XenServer 6.0 へのアップグレ
<data name="VNC_RDESKTOP" xml:space="preserve">
<value>リモート デスクトップに切り替える(&amp;I)</value>
</data>
<data name="VNC_RDESKTOP_TRUN_ON" xml:space="preserve">
<value>Turn &amp;on Remote Desktop</value>
</data>
<data name="VNC_REDOCK" xml:space="preserve">
<value>元に戻す(&amp;R)</value>
</data>

View File

@ -4836,6 +4836,9 @@ Would you like to eject these ISOs before continuing?</value>
<data name="FORCE_CLOSE_PLUGIN_PROMPT" xml:space="preserve">
<value>Plugin {0} has not yet responded to your cancel request. Would you like to force close the process or allow it to continue to run in the background?</value>
</data>
<data name="FORCE_ENABLE_RDP" xml:space="preserve">
<value>Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop?</value>
</data>
<data name="FORCE_REBOOT" xml:space="preserve">
<value>Force Reboot</value>
</data>
@ -11406,6 +11409,9 @@ To learn more about the XenServer Dynamic Workload Balancing feature or to start
<data name="VNC_RDESKTOP" xml:space="preserve">
<value>Sw&amp;itch to Remote Desktop</value>
</data>
<data name="VNC_RDESKTOP_TRUN_ON" xml:space="preserve">
<value>Turn &amp;on Remote Desktop</value>
</data>
<data name="VNC_REDOCK" xml:space="preserve">
<value>&amp;Redock</value>
</data>

View File

@ -4835,6 +4835,9 @@ XenServer 可以重新启动服务器并将服务器的 CPU 级别降至池中
<data name="FORCE_CLOSE_PLUGIN_PROMPT" xml:space="preserve">
<value>插件 {0} 尚未对您的取消请求作出响应。是强制关闭进程还是允许其继续在后台运行?</value>
</data>
<data name="FORCE_ENABLE_RDP" xml:space="preserve">
<value>Would you like to turn on Remote Desktop in this VM, and then connect to it over Remote Desktop?</value>
</data>
<data name="FORCE_REBOOT" xml:space="preserve">
<value>强制重启</value>
</data>
@ -11405,6 +11408,9 @@ XenServer 可以重新启动服务器并将其 CPU 降至主服务器的级别
<data name="VNC_RDESKTOP" xml:space="preserve">
<value>切换到远程桌面(&amp;I)</value>
</data>
<data name="VNC_RDESKTOP_TRUN_ON" xml:space="preserve">
<value>启用远程桌面(&amp;o)</value>
</data>
<data name="VNC_REDOCK" xml:space="preserve">
<value>重新停靠(&amp;R)</value>
</data>

View File

@ -431,6 +431,18 @@ namespace XenAPI
}
}
public bool RDPEnabled
{
get
{
var metrics = Connection.Resolve(this.guest_metrics);
if (metrics == null)
return false;
return 0 != IntKey(metrics.other, "data-ts", 0);
}
}
/// <summary>Returns true if
/// 1) the guest is HVM and
/// 2a) the allow-gpu-passthrough restriction is absent or

View File

@ -2556,6 +2556,10 @@ namespace XenAPI
Response<Object>
vm_appliance_get_all_records(string session);
[XmlRpcMethod("VM.call_plugin")]
Response<string>
vm_call_plugin(string session, string _vm, string _plugin, string _fn, Object _args);
[XmlRpcMethod("DR_task.get_record")]
Response<Proxy_DR_task>
dr_task_get_record(string session, string _dr_task);

View File

@ -3797,6 +3797,20 @@ namespace XenAPI
}
private vm_power_state _power_state;
/// <summary>
/// Call a XenAPI plugin on this vm
/// First published in XenServer 6.6.
/// </summary>
/// <param name="session">The session</param>
/// <param name="_vm">The opaque_ref of the given vm</param>
/// <param name="_plugin">The name of the plugin</param>
/// <param name="_fn">The name of the function within the plugin</param>
/// <param name="_args">Arguments for the function</param>
public static string call_plugin(Session session, string _vm, string _plugin, string _fn, Dictionary<string, string> _args)
{
return (string)session.proxy.vm_call_plugin(session.uuid, (_vm != null) ? _vm : "", (_plugin != null) ? _plugin : "", (_fn != null) ? _fn : "", Maps.convert_to_proxy_string_string(_args)).parse();
}
/// <summary>
/// a human-readable name
/// </summary>