| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| using log4net; |
| using System; |
| using System.Collections.Generic; |
| 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)); |
| public const string serviceName = "CloudStack Hyper-V Agent"; |
| private static string option = null; |
| private static string user = null; |
| private static string password = null; |
| private const string install = "--install"; |
| private const string uninstall = "--uninstall"; |
| private const string console = "--console"; |
| |
| /// <summary> |
| /// Application entry point allows service to run in console application or as a Windows service. |
| /// Add '--console' to the commandline for the former, the latter is the default. |
| /// </summary> |
| static void Main(params string[] args) |
| { |
| if (args.Length == 0) |
| { |
| logger.InfoFormat(serviceName + " running as Windows Service"); |
| ServiceBase[] ServicesToRun = new ServiceBase[] { new AgentService() }; |
| ServiceBase.Run(ServicesToRun); |
| } |
| else if (ParseArguments(args)) |
| { |
| switch (option) |
| { |
| case install: |
| logger.InfoFormat("Installing and running " + serviceName); |
| InstallService(); |
| StartService(); |
| break; |
| case uninstall: |
| logger.InfoFormat("Stopping and uninstalling " + serviceName); |
| StopService(); |
| UninstallService(); |
| break; |
| case console: |
| logger.InfoFormat(serviceName + " is running as console application"); |
| new AgentService().RunConsole(args); |
| break; |
| default: |
| throw new NotImplementedException(); |
| } |
| } |
| else |
| { |
| string argumentExample = "--(install/uninstall/console) [-u <hyper-v admin user>] [-p <hyper-v admin password>].\n" + |
| " For example:\n " + |
| " --install -u domain1\\user1 -p mypwd\n"+ |
| " --uninstall"; |
| logger.Error("Invalid arguments passed for installing\\uninstalling the service. \n" + argumentExample); |
| } |
| } |
| |
| static private Boolean ParseArguments(string[] args) |
| { |
| logger.DebugFormat(serviceName + " arg is ", args[0]); |
| int argIndex = 0; |
| while (argIndex < args.Length) |
| { |
| switch (args[argIndex]) |
| { |
| case install: |
| case uninstall: |
| case console: |
| option = args[argIndex]; |
| argIndex++; |
| break; |
| case "-u": |
| user = args[argIndex+1]; |
| argIndex+=2; |
| break; |
| case "-p": |
| password = args[argIndex+1]; |
| argIndex+=2; |
| break; |
| default: |
| argIndex++; |
| // Unrecognised argument. Do nothing; |
| break; |
| } |
| } |
| |
| // Validate arguments |
| return ValidateArguments(); |
| } |
| |
| private static Boolean ValidateArguments() |
| { |
| Boolean argsValid = false; |
| switch (option) |
| { |
| case uninstall: |
| case install: |
| case console: |
| argsValid = true; |
| break; |
| default: |
| break; |
| } |
| |
| return argsValid; |
| } |
| |
| public static string GetPassword() |
| { |
| return password; |
| } |
| |
| public static string GetUser() |
| { |
| return user; |
| } |
| |
| 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 occurred 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 occurred 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 occurred 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 occurred in stopping service " + ex.Message); |
| throw; |
| } |
| } |
| } |
| } |
| } |