diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj index 39fef1606a2..a4c6b1fc073 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentShell.csproj @@ -70,6 +70,7 @@ ..\packages\NSubstitute.1.6.1.0\lib\NET40\NSubstitute.dll + @@ -101,6 +102,12 @@ + + Component + + + ProjectInstaller.cs + True @@ -137,4 +144,4 @@ --> - + \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs index 10663708508..e84350020c4 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/Program.cs @@ -21,12 +21,15 @@ using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks; +using System.Configuration.Install; +using System.Collections; namespace CloudStack.Plugin.AgentShell { static class Program { private static ILog logger = LogManager.GetLogger(typeof(Program)); + private static string serviceName = "CloudStack ServerResource"; /// /// Application entry point allows service to run in console application or as a Windows service. @@ -34,25 +37,174 @@ namespace CloudStack.Plugin.AgentShell /// static void Main(params string[] args) { - string arg1 = string.Empty; - - if (args.Length > 0) - { - arg1 = args[0]; - logger.DebugFormat("CloudStack ServerResource arg is ", arg1); - } - - if (string.Compare(arg1, "--console", true) == 0) - { - logger.InfoFormat("CloudStack ServerResource running as console app"); - new AgentService().RunConsole(args); - } - else + if (args.Length == 0) { logger.InfoFormat("CloudStack ServerResource running as Windows Service"); ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() }; ServiceBase.Run(ServicesToRun); } + else if (args.Length == 1) + { + logger.DebugFormat("CloudStack ServerResource arg is ", args[0]); + switch (args[0]) + { + case "--install": + logger.InfoFormat("Installing and running CloudStack ServerResource "); + InstallService(); + StartService(); + break; + case "--uninstall": + logger.InfoFormat("stopping and uninstalling CloudStack ServerResource "); + StopService(); + UninstallService(); + break; + case "--console": + logger.InfoFormat("CloudStack ServerResource running as console app"); + new AgentService().RunConsole(args); + break; + default: + throw new NotImplementedException(); + } + } + } + + private static bool IsInstalled() + { + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + ServiceControllerStatus status = controller.Status; + } + catch + { + return false; + } + return true; + } + } + + private static bool IsRunning() + { + using (ServiceController controller = + new ServiceController(serviceName)) + { + if (!IsInstalled()) return false; + return (controller.Status == ServiceControllerStatus.Running); + } + } + + private static AssemblyInstaller GetInstaller() + { + AssemblyInstaller installer = new AssemblyInstaller( + typeof(Program).Assembly, null); + installer.UseNewContext = true; + return installer; + } + + private static void InstallService() + { + if (IsInstalled()) return; + + try + { + using (AssemblyInstaller installer = GetInstaller()) + { + IDictionary state = new Hashtable(); + try + { + installer.Install(state); + installer.Commit(state); + } + catch + { + try + { + installer.Rollback(state); + } + catch { } + throw; + } + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in installing service " + ex.Message); + throw; + } + } + + private static void UninstallService() + { + if (!IsInstalled()) return; + try + { + using (AssemblyInstaller installer = GetInstaller()) + { + IDictionary state = new Hashtable(); + try + { + installer.Uninstall(state); + } + catch + { + throw; + } + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in uninstalling service " + ex.Message); + throw; + } + } + + private static void StartService() + { + if (!IsInstalled()) return; + + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + if (controller.Status != ServiceControllerStatus.Running) + { + controller.Start(); + controller.WaitForStatus(ServiceControllerStatus.Running, + TimeSpan.FromSeconds(10)); + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in starting service " + ex.Message); + throw; + } + } + } + + private static void StopService() + { + if (!IsInstalled()) return; + using (ServiceController controller = + new ServiceController(serviceName)) + { + try + { + if (controller.Status != ServiceControllerStatus.Stopped) + { + controller.Stop(); + controller.WaitForStatus(ServiceControllerStatus.Stopped, + TimeSpan.FromSeconds(10)); + } + } + catch (Exception ex) + { + logger.ErrorFormat(" Error occured in stopping service " + ex.Message); + throw; + } + } } } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs new file mode 100644 index 00000000000..9b9dbb6edb9 --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.Designer.cs @@ -0,0 +1,60 @@ +namespace CloudStack.Plugin.AgentShell +{ + partial class ProjectInstaller + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); + this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller(); + // + // serviceProcessInstaller1 + // + this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; + this.serviceProcessInstaller1.Password = null; + this.serviceProcessInstaller1.Username = null; + // + // serviceInstaller1 + // + this.serviceInstaller1.Description = "CloudStack Agent"; + this.serviceInstaller1.DisplayName = "CloudStack ServerResource"; + this.serviceInstaller1.ServiceName = "CloudStack ServerResource"; + this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic; + // + // ProjectInstaller + // + this.Installers.AddRange(new System.Configuration.Install.Installer[] { + this.serviceProcessInstaller1, + this.serviceInstaller1}); + + } + + #endregion + + private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; + private System.ServiceProcess.ServiceInstaller serviceInstaller1; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs new file mode 100644 index 00000000000..c3a225f540a --- /dev/null +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/ProjectInstaller.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; +using System.Linq; +using System.Threading.Tasks; + +namespace CloudStack.Plugin.AgentShell +{ + [RunInstaller(true)] + public partial class ProjectInstaller : System.Configuration.Install.Installer + { + public ProjectInstaller() + { + InitializeComponent(); + } + } +}