| // 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 System; |
| using System.Collections.Generic; |
| using System.ComponentModel; |
| using System.Data; |
| using System.Diagnostics; |
| using System.Linq; |
| using System.ServiceProcess; |
| using System.Text; |
| using System.Threading.Tasks; |
| using System.Web.Http.SelfHost; |
| using System.Web.Http; |
| using log4net; |
| using HypervResource; |
| |
| namespace CloudStack.Plugin.AgentShell |
| { |
| public partial class AgentService : ServiceBase |
| { |
| [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] |
| static extern bool AllocConsole(); |
| |
| [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)] |
| static extern bool FreeConsole(); |
| |
| HttpSelfHostServer server; |
| |
| private static ILog logger = LogManager.GetLogger(typeof(AgentService)); |
| |
| public AgentService() |
| { |
| logger.Info("Starting CloudStack agent"); |
| InitializeComponent(); |
| |
| UriBuilder baseUri = new UriBuilder("https", AgentSettings.Default.private_ip_address, AgentSettings.Default.port); |
| |
| var config = new HttpSelfHostConfiguration(baseUri.Uri); |
| |
| // Allow ActionName to be applied to methods in ApiController, which allows it to serve multiple POST URLs |
| config.Routes.MapHttpRoute( |
| "API Default", "api/{controller}/{action}", |
| new { action = RouteParameter.Optional } |
| ); |
| |
| // Load controller assemblies that we want to config to route to. |
| ConfigServerResource(); |
| AssertControllerAssemblyAvailable(config, typeof(HypervResourceController), "Cannot load Controller of type" + typeof(HypervResourceController)); |
| |
| server = new HttpSelfHostServer(config); |
| } |
| |
| public static void ConfigServerResource() |
| { |
| // For simplicity, ServerResource config and settings file are tightly coupled. |
| // An alternative is to pass a dictionary to the server resource and let it find |
| // required settings. In contrast, the approach below is strongly typed and makes |
| // use of VisualStudio settings designer. The designer allows us to avoid |
| // accessing config using their key strings. |
| HypervResourceControllerConfig rsrcCnf = new HypervResourceControllerConfig(); |
| rsrcCnf.RootDeviceReservedSpaceBytes = AgentSettings.Default.RootDeviceReservedSpaceBytes; |
| rsrcCnf.RootDeviceName = AgentSettings.Default.RootDeviceName; |
| rsrcCnf.ParentPartitionMinMemoryMb = AgentSettings.Default.dom0MinMemory; |
| rsrcCnf.LocalSecondaryStoragePath = AgentSettings.Default.local_secondary_storage_path; |
| |
| // Side effect: loads the assembly containing HypervResourceController, which |
| // allows HttpSelfHostServer to route requests to the controller. |
| HypervResourceController.Configure(rsrcCnf); |
| |
| } |
| |
| // TODO: update to examine not the assembly resolver, but the list of available controllers themselves! |
| private static bool AssertControllerAssemblyAvailable(HttpSelfHostConfiguration config, Type controllerType, string errorMessage) |
| { |
| var assemblies = config.Services.GetAssembliesResolver().GetAssemblies(); |
| foreach (var assembly in assemblies) |
| { |
| string name = assembly.GetName().Name; |
| if (controllerType.Assembly.GetName().Name.Equals(name)) |
| { |
| logger.DebugFormat("Controller {0} is available", controllerType.Name); |
| return true; |
| } |
| } |
| |
| logger.Error(errorMessage); |
| throw new AgentShellException(errorMessage); |
| } |
| |
| protected override void OnStart(string[] args) |
| { |
| server.OpenAsync().Wait(); |
| } |
| |
| protected override void OnStop() |
| { |
| server.CloseAsync().Wait(); |
| } |
| |
| internal void RunConsole(string[] args) |
| { |
| OnStart(args); |
| |
| AllocConsole(); |
| |
| Console.WriteLine("Service running ... press <ENTER> to stop"); |
| |
| Console.ReadLine(); |
| |
| FreeConsole(); |
| |
| OnStop(); |
| } |
| } |
| } |