Donal Lafferty f9f196a46a A plugin for Hyper-V control is available for CloudStack. The plugin implements basic VM control; however, its
architecture allows additional functionality to be easily added.  Incorporating the plugin in CloudStack will allow
the community to participate in improving the features available with Hyper-V. The plugin uses a Director Connect
Agent architecture described here: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Progress
Add ability to pass kvp data via the key cloudstack-vm-userdata
Rearrange code to make it clearer what .NET objects are being used.
Test failures are easier to deal with if test key is not deleted.
Acquire management/pod ip for control ip when VR deploys in HyperV
Fixed deletion on VM's on hyperv host when mgmt server gets restarted due to HA
Implementation for attach iso command. Attaches an iso to a given vm.
2013-11-04 18:48:53 +05:30

132 lines
5.1 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("http", 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.PrivateIpAddress = AgentSettings.Default.private_ip_address;
rsrcCnf.GatewayIpAddress = AgentSettings.Default.gateway_ip_address;
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();
}
}
}