mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			130 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
// 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();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |