Windows agent was moved to another repo

Now it is at https://github.com/murano-project/murano-windows-agent

Change-Id: Ifedfbbc339b1eb00fd2584aef141cce7c87e1616
This commit is contained in:
Stan Lagun 2014-09-25 23:30:43 +04:00
parent 051e026062
commit 87367a4020
21 changed files with 0 additions and 1325 deletions

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{501BE151-4B8C-4355-88DC-3AEF1921B2D7}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mirantis.Murano</RootNamespace>
<AssemblyName>ExecutionPlanGenerator</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,141 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Mirantis.Murano
{
class Command
{
public string Name { get; set; }
public Dictionary<string, object> Arguments { get; set; }
}
class ExecutionPlan
{
public List<string> Scripts { get; set; }
public List<Command> Commands { get; set; }
public int RebootOnCompletion { get; set; }
}
class Program
{
static void Main(string[] args)
{
if (args.Length < 1 || args.Length > 2)
{
Console.WriteLine("Usage: ExecutionPlanGenerator inputfile [outputfile]");
return;
}
var outFile = args.Length == 2 ? args[1] : null;
var plan = new ExecutionPlan {
Scripts = new List<string>(),
Commands = new List<Command>()
};
var lines = File.ReadAllLines(args[0]);
foreach (var statement in lines
.Select(t => t.Split(new[] { ' ', '\t' }, 2))
.Where(t => t.Length == 2)
.Select(t => new Tuple<string, string>(t[0].Trim().ToLower(), t[1].Trim())))
{
switch (statement.Item1)
{
case "include":
Include(statement.Item2, plan, args[0]);
break;
case "call":
Call(statement.Item2, plan);
break;
case "reboot":
plan.RebootOnCompletion = int.Parse(statement.Item2);
break;
case "out":
if (args.Length < 2)
{
var path = statement.Item2;
if (!Path.IsPathRooted(path))
{
path = Path.Combine(Path.GetDirectoryName(args[0]), path);
}
outFile = path;
}
break;
}
}
var data = JsonConvert.SerializeObject(plan, Formatting.Indented);
if (outFile == null)
{
Console.WriteLine(data);
}
else
{
File.WriteAllText(outFile, data);
}
}
private static void Call(string line, ExecutionPlan plan)
{
var parts = line.Split(new[] { ' ', '\t'}, 2);
var command = new Command() {
Name = parts[0].Trim(),
Arguments = new Dictionary<string, object>()
};
if (parts.Length == 2)
{
foreach (var x in parts[1]
.Split(',')
.Select(t => t.Split('='))
.Where(t => t.Length == 2)
.Select(t => new KeyValuePair<string, string>(t[0].Trim(), t[1].Trim())))
{
object value = null;
long num;
bool boolean;
if (x.Value.StartsWith("\""))
{
value = x.Value.Substring(1, x.Value.Length - 2);
}
else if (long.TryParse(x.Value, out num))
{
value = num;
}
else if (bool.TryParse(x.Value, out boolean))
{
value = boolean;
}
else
{
continue;
}
command.Arguments.Add(x.Key, value);
}
}
plan.Commands.Add(command);
}
private static void Include(string file, ExecutionPlan plan, string dslPath)
{
var path = file;
if (!Path.IsPathRooted(file))
{
path = Path.Combine(Path.GetDirectoryName(dslPath), path);
}
var text = File.ReadAllText(path, Encoding.UTF8);
plan.Scripts.Add(Convert.ToBase64String(Encoding.UTF8.GetBytes(text)));
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ConsoleApplication1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConsoleApplication1")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9aab688a-ce5f-402e-8891-2d7b4ae85ea3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
</packages>

View File

@ -1,26 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsAgent", "WindowsAgent\WindowsAgent.csproj", "{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecutionPlanGenerator", "ExecutionPlanGenerator\ExecutionPlanGenerator.csproj", "{501BE151-4B8C-4355-88DC-3AEF1921B2D7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}.Release|Any CPU.Build.0 = Release|Any CPU
{501BE151-4B8C-4355-88DC-3AEF1921B2D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{501BE151-4B8C-4355-88DC-3AEF1921B2D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{501BE151-4B8C-4355-88DC-3AEF1921B2D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{501BE151-4B8C-4355-88DC-3AEF1921B2D7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File" fileName="${basedir}/log.txt" layout="${date} ${level}: &lt;${logger:shortName=true}&gt; ${message} ${exception:format=tostring}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>
<appSettings>
<add key="rabbitmq.host" value="localhost"/>
<add key="rabbitmq.user" value="murano"/>
<add key="rabbitmq.password" value="murano"/>
<add key="rabbitmq.vhost" value="murano"/>
<add key="rabbitmq.resultExchange" value=""/>
<add key="rabbitmq.resultRoutingKey" value="-execution-results"/>
<add key="rabbitmq.durableMessages" value="true"/>
</appSettings>
</configuration>

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mirantis.Murano.WindowsAgent
{
class ExecutionPlan
{
public class Command
{
public string Name { get; set; }
public Dictionary<string, object> Arguments { get; set; }
}
public string[] Scripts { get; set; }
public LinkedList<Command> Commands { get; set; }
public int RebootOnCompletion { get; set; }
}
}

View File

@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mirantis.Murano.WindowsAgent
{
class MqMessage
{
private readonly Action ackFunc;
public MqMessage(Action ackFunc)
{
this.ackFunc = ackFunc;
}
public MqMessage()
{
}
public string Body { get; set; }
public string Id { get; set; }
public void Ack()
{
ackFunc();
}
}
}

View File

@ -1,233 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
using Newtonsoft.Json.Linq;
using NLog;
using Newtonsoft.Json;
namespace Mirantis.Murano.WindowsAgent
{
class PlanExecutor
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
class ExecutionResult
{
public bool IsException { get; set; }
public object Result { get; set; }
}
private readonly string path;
public PlanExecutor(string path)
{
this.path = path;
}
public bool RebootNeeded { get; set; }
public void Execute()
{
RebootNeeded = false;
var resultPath = this.path + ".result";
Runspace runSpace = null;
try
{
var plan = JsonConvert.DeserializeObject<ExecutionPlan>(File.ReadAllText(this.path));
List<ExecutionResult> currentResults = null;
try
{
currentResults = File.Exists(resultPath) ?
JsonConvert.DeserializeObject<List<ExecutionResult>>(File.ReadAllText(resultPath)) :
new List<ExecutionResult>();
}
catch(Exception exception)
{
Log.WarnException("Cannot deserialize previous execution result", exception);
currentResults = new List<ExecutionResult>();
}
runSpace = RunspaceFactory.CreateRunspace();
runSpace.Open();
var runSpaceInvoker = new RunspaceInvoke(runSpace);
runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
if (plan.Scripts != null)
{
var index = 0;
foreach (var script in plan.Scripts)
{
runSpaceInvoker.Invoke(Encoding.UTF8.GetString(Convert.FromBase64String(script)));
Log.Debug("Loaded script #{0}", ++index);
}
}
while (plan.Commands != null && plan.Commands.Any())
{
var command = plan.Commands.First();
Log.Debug("Preparing to execute command {0}", command.Name);
var pipeline = runSpace.CreatePipeline();
var psCommand = new Command(command.Name);
if (command.Arguments != null)
{
foreach (var kvp in command.Arguments)
{
var value = ConvertArgument(kvp.Value);
psCommand.Parameters.Add(kvp.Key, value);
}
}
Log.Info("Executing {0} {1}", command.Name, string.Join(" ",
(command.Arguments ?? new Dictionary<string, object>()).Select(
t => string.Format("{0}={1}", t.Key, t.Value == null ? "null" : t.Value.ToString()))));
pipeline.Commands.Add(psCommand);
try
{
var result = pipeline.Invoke();
Log.Debug("Command {0} executed", command.Name);
if (result != null)
{
currentResults.Add(new ExecutionResult {
IsException = false,
Result = result.Select(SerializePsObject).Where(obj => obj != null).ToList()
});
}
}
catch (Exception exception)
{
object additionInfo = null;
if (exception is ActionPreferenceStopException)
{
var apse = exception as ActionPreferenceStopException;
if (apse.ErrorRecord != null)
{
additionInfo = new {
ScriptStackTrace = apse.ErrorRecord.ScriptStackTrace,
PositionMessage = apse.ErrorRecord.InvocationInfo.PositionMessage
};
exception = apse.ErrorRecord.Exception;
}
}
Log.WarnException("Exception while executing command " + command.Name, exception);
currentResults.Add(new ExecutionResult
{
IsException = true,
Result = new[] {
exception.GetType().FullName, exception.Message, command.Name, additionInfo
}
});
break;
}
finally
{
plan.Commands.RemoveFirst();
File.WriteAllText(path, JsonConvert.SerializeObject(plan));
File.WriteAllText(resultPath, JsonConvert.SerializeObject(currentResults));
}
}
runSpace.Close();
var executionResult = JsonConvert.SerializeObject(new ExecutionResult {
IsException = false,
Result = currentResults
}, Formatting.Indented);
if (plan.RebootOnCompletion > 0)
{
if (plan.RebootOnCompletion == 1)
{
RebootNeeded = !currentResults.Any(t => t.IsException);
}
else
{
RebootNeeded = true;
}
}
File.WriteAllText(resultPath, executionResult);
}
catch (Exception exception)
{
Log.WarnException("Exception while processing execution plan", exception);
File.WriteAllText(resultPath, JsonConvert.SerializeObject(new ExecutionResult {
IsException = true,
Result = exception.Message
}, Formatting.Indented));
}
finally
{
if (runSpace != null)
{
try
{
runSpace.Close();
}
catch
{}
}
Log.Debug("Finished processing of execution plan");
}
}
private static object ConvertArgument(object arg)
{
if (arg is JArray)
{
var array = arg as JArray;
return array.Select(ConvertArgument).ToArray();
}
else if (arg is JValue)
{
var value = (JValue) arg;
return value.Value;
}
else if (arg is JObject)
{
var dict = (JObject)arg;
var result = new Hashtable();
foreach (var item in dict)
{
result.Add(item.Key, ConvertArgument(item.Value));
}
return result;
}
return arg;
}
private static object SerializePsObject(PSObject obj)
{
if (obj.BaseObject is PSCustomObject)
{
var result = new Dictionary<string, object>();
foreach (var property in obj.Properties.Where(p => p.IsGettable))
{
try
{
result[property.Name] = property.Value.ToString();
}
catch
{
}
}
return result;
}
else if (obj.BaseObject is IEnumerable<PSObject>)
{
return ((IEnumerable<PSObject>) obj.BaseObject).Select(SerializePsObject).ToArray();
}
else
{
return obj.BaseObject;
}
}
}
}

View File

@ -1,168 +0,0 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Net;
using System.Text;
using System.Threading;
using NLog;
namespace Mirantis.Murano.WindowsAgent
{
[DisplayName("Murano Agent")]
sealed public class Program : WindowsService
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private volatile bool stop;
private Thread thread;
private RabbitMqClient rabbitMqClient;
private int delayFactor = 1;
private string plansDir;
static void Main(string[] args)
{
Start(new Program(), args);
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
Log.Info("Version 0.5.3");
this.rabbitMqClient = new RabbitMqClient();
var basePath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
this.plansDir = Path.Combine(basePath, "plans");
if (!Directory.Exists(plansDir))
{
Directory.CreateDirectory(plansDir);
}
this.thread = new Thread(Loop);
this.thread.Start();
}
void Loop()
{
const string unknownName = "unknown";
while (!stop)
{
try
{
foreach (var file in Directory.GetFiles(this.plansDir, "*.json.result")
.Where(file => !File.Exists(Path.Combine(this.plansDir, Path.GetFileNameWithoutExtension(file)))))
{
var id = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)) ?? unknownName;
if (id.Equals(unknownName, StringComparison.InvariantCultureIgnoreCase))
{
id = "";
}
var result = File.ReadAllText(file);
Log.Info("Sending results for {0}", id ?? unknownName);
rabbitMqClient.SendResult(new MqMessage { Body = result, Id = id });
File.Delete(file);
}
var path = Directory.EnumerateFiles(this.plansDir, "*.json").FirstOrDefault();
if (path == null)
{
var message = rabbitMqClient.GetMessage();
var id = message.Id;
if(string.IsNullOrEmpty(id))
{
id = unknownName;
}
path = Path.Combine(this.plansDir, string.Format("{0}.json", id));
File.WriteAllText(path, message.Body);
Log.Info("Received new execution plan {0}", id);
message.Ack();
}
else
{
var id = Path.GetFileNameWithoutExtension(path);
Log.Info("Executing exising plan {0}", id);
}
var executor = new PlanExecutor(path);
executor.Execute();
File.Delete(path);
delayFactor = 1;
if (stop) break;
if (executor.RebootNeeded)
{
Reboot();
}
}
catch (Exception exception)
{
WaitOnException(exception);
}
}
}
private void Reboot()
{
Log.Info("Going for reboot!!");
LogManager.Flush();
/*try
{
System.Diagnostics.Process.Start("shutdown.exe", "-r -t 0");
}
catch (Exception ex)
{
Log.ErrorException("Cannot execute shutdown.exe", ex);
}*/
try
{
PowerShell.Create().AddCommand("Restart-Computer").AddParameter("Force").Invoke();
}
catch (Exception exception)
{
Log.FatalException("Reboot exception", exception);
}
finally
{
Log.Info("Waiting for reboot");
for (var i = 0; i < 10 * 60 * 5 && !stop; i++)
{
Thread.Sleep(100);
}
Log.Info("Done waiting for reboot");
}
}
private void WaitOnException(Exception exception)
{
if (stop) return;
Log.WarnException("Exception in main loop", exception);
var i = 0;
while (!stop && i < 10 * (delayFactor * delayFactor))
{
Thread.Sleep(100);
i++;
}
delayFactor = Math.Min(delayFactor + 1, 6);
}
protected override void OnStop()
{
stop = true;
this.rabbitMqClient.Dispose();
base.OnStop();
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WindowsAgent")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WindowsAgent")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9591bf2c-f38b-47e0-a39d-ea9849356371")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,147 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using NLog;
using RabbitMQ.Client;
namespace Mirantis.Murano.WindowsAgent
{
class RabbitMqClient : IDisposable
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private static readonly ConnectionFactory connectionFactory;
private IConnection currentConnecton;
static RabbitMqClient()
{
var ssl = new SslOption {
Enabled = bool.Parse(ConfigurationManager.AppSettings["rabbitmq.ssl"] ?? "false"),
Version = SslProtocols.Default,
AcceptablePolicyErrors = bool.Parse(ConfigurationManager.AppSettings["rabbitmq.allowInvalidCA"] ?? "true") ?
SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None
};
var sslServerName = ConfigurationManager.AppSettings["rabbitmq.sslServerName"] ?? "";
ssl.ServerName = sslServerName;
if (String.IsNullOrWhiteSpace(sslServerName))
{
ssl.AcceptablePolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
}
connectionFactory = new ConnectionFactory {
HostName = ConfigurationManager.AppSettings["rabbitmq.host"] ?? "localhost",
UserName = ConfigurationManager.AppSettings["rabbitmq.user"] ?? "guest",
Password = ConfigurationManager.AppSettings["rabbitmq.password"] ??"guest",
Protocol = Protocols.DefaultProtocol,
VirtualHost = ConfigurationManager.AppSettings["rabbitmq.vhost"] ?? "/",
Port = int.Parse(ConfigurationManager.AppSettings["rabbitmq.port"] ?? "5672"),
RequestedHeartbeat = 10,
Ssl = ssl
};
}
public RabbitMqClient()
{
}
public MqMessage GetMessage()
{
var queueName = ConfigurationManager.AppSettings["rabbitmq.inputQueue"] ?? Dns.GetHostName().ToLower();
try
{
IConnection connection = null;
lock (this)
{
connection = this.currentConnecton = this.currentConnecton ?? connectionFactory.CreateConnection();
}
var session = connection.CreateModel();
session.BasicQos(0, 1, false);
//session.QueueDeclare(queueName, true, false, false, null);
var consumer = new QueueingBasicConsumer(session);
var consumeTag = session.BasicConsume(queueName, false, consumer);
var e = (RabbitMQ.Client.Events.BasicDeliverEventArgs) consumer.Queue.Dequeue();
Action ackFunc = delegate {
session.BasicAck(e.DeliveryTag, false);
session.BasicCancel(consumeTag);
session.Close();
};
return new MqMessage(ackFunc) {
Body = Encoding.UTF8.GetString(e.Body),
Id = e.BasicProperties.MessageId
};
}
catch (Exception exception)
{
Dispose();
throw;
}
}
public void SendResult(MqMessage message)
{
var exchangeName = ConfigurationManager.AppSettings["rabbitmq.resultExchange"] ?? "";
var resultRoutingKey = ConfigurationManager.AppSettings["rabbitmq.resultRoutingKey"] ?? "-execution-results";
bool durable = bool.Parse(ConfigurationManager.AppSettings["rabbitmq.durableMessages"] ?? "true");
try
{
IConnection connection = null;
lock (this)
{
connection = this.currentConnecton = this.currentConnecton ?? connectionFactory.CreateConnection();
}
var session = connection.CreateModel();
/*if (!string.IsNullOrEmpty(resultQueue))
{
//session.QueueDeclare(resultQueue, true, false, false, null);
if (!string.IsNullOrEmpty(exchangeName))
{
session.ExchangeBind(exchangeName, resultQueue, resultQueue);
}
}*/
var basicProperties = session.CreateBasicProperties();
basicProperties.SetPersistent(durable);
basicProperties.MessageId = message.Id;
basicProperties.ContentType = "application/json";
session.BasicPublish(exchangeName, resultRoutingKey, basicProperties, Encoding.UTF8.GetBytes(message.Body));
session.Close();
}
catch (Exception)
{
Dispose();
throw;
}
}
public void Dispose()
{
lock (this)
{
try
{
if (this.currentConnecton != null)
{
this.currentConnecton.Close();
}
}
catch
{
}
finally
{
this.currentConnecton = null;
}
}
}
}
}

View File

@ -1,37 +0,0 @@
{
"Scripts":
[
"ZnVuY3Rpb24gdDMgeyAxMjsgcmV0dXJuICJ0ZXN0IiB9",
"ZnVuY3Rpb24gTmV3LVBlcnNvbigpDQp7DQogIHBhcmFtICgkRmlyc3ROYW1lLCAkTGFzdE5hbWUsICRQaG9uZSkNCg0KICAkcGVyc29uID0gbmV3LW9iamVjdCBQU09iamVjdA0KDQogICRwZXJzb24gfCBhZGQtbWVtYmVyIC10eXBlIE5vdGVQcm9wZXJ0eSAtTmFtZSBGaXJzdCAtVmFsdWUgJEZpcnN0TmFtZQ0KICAkcGVyc29uIHwgYWRkLW1lbWJlciAtdHlwZSBOb3RlUHJvcGVydHkgLU5hbWUgTGFzdCAtVmFsdWUgJExhc3ROYW1lDQogICRwZXJzb24gfCBhZGQtbWVtYmVyIC10eXBlIE5vdGVQcm9wZXJ0eSAtTmFtZSBQaG9uZSAtVmFsdWUgJFBob25lDQoNCiAgcmV0dXJuICRwZXJzb24NCn0=",
"ZnVuY3Rpb24gVGVzdFRocm93KCkNCnsNCglUaHJvdyBbc3lzdGVtLkluZGV4T3V0T2ZSYW5nZUV4Y2VwdGlvbl0gDQp9"
],
"Commands" :
[
{
"Name": "New-Person",
"Arguments" :
{
"FirstName": "MyFirstName",
"LastName": "MyLastName",
"Phone": "123-456"
}
},
{
"Name": "t3",
"Arguments" :
{
}
},
{
"Name": "Get-Date",
},
{
"Name": "TestThrow",
}
],
"RebootOnCompletion": 0
}

View File

@ -1,111 +0,0 @@
using System;
using System.Configuration.Install;
using System.Reflection;
using System.ServiceProcess;
using NLog;
namespace Mirantis.Murano.WindowsAgent
{
public class ServiceManager
{
private readonly string serviceName;
public ServiceManager(string serviceName)
{
this.serviceName = serviceName;
}
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
public bool Restart(string[] args, TimeSpan timeout)
{
var service = new ServiceController(serviceName);
try
{
var millisec1 = TimeSpan.FromMilliseconds(Environment.TickCount);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
Log.Info("Service is stopped");
// count the rest of the timeout
var millisec2 = TimeSpan.FromMilliseconds(Environment.TickCount);
timeout = timeout - (millisec2 - millisec1);
service.Start(args);
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
Log.Info("Service has started");
return true;
}
catch (Exception ex)
{
Log.ErrorException("Cannot restart service " + serviceName, ex);
return false;
}
}
public bool Stop(TimeSpan timeout)
{
var service = new ServiceController(serviceName);
try
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
return true;
}
catch (Exception ex)
{
Log.ErrorException("Cannot stop service " + serviceName, ex);
return false;
}
}
public bool Start(string[] args, TimeSpan timeout)
{
var service = new ServiceController(serviceName);
try
{
service.Start(args);
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
return true;
}
catch (Exception ex)
{
Log.ErrorException("Cannot start service " + serviceName, ex);
return false;
}
}
public bool Install()
{
try
{
ManagedInstallerClass.InstallHelper(
new string[] { Assembly.GetEntryAssembly().Location });
}
catch(Exception ex)
{
Log.ErrorException("Cannot install service " + serviceName, ex);
return false;
}
return true;
}
public bool Uninstall()
{
try
{
ManagedInstallerClass.InstallHelper(
new string[] { "/u", Assembly.GetEntryAssembly().Location });
}
catch (Exception ex)
{
Log.ErrorException("Cannot uninstall service " + serviceName, ex);
return false;
}
return true;
}
}
}

View File

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F7E2A8D5-6D24-4651-A4BC-1024D59F4903}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mirantis.Murano.WindowsAgent</RootNamespace>
<AssemblyName>WindowsAgent</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog">
<HintPath>..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll</HintPath>
</Reference>
<Reference Include="RabbitMQ.Client">
<HintPath>..\packages\RabbitMQ.Client.3.0.2\lib\net30\RabbitMQ.Client.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ExecutionPlan.cs" />
<Compile Include="MqMessage.cs" />
<Compile Include="PlanExecutor.cs" />
<Compile Include="Program.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RabbitMqClient.cs" />
<Compile Include="ServiceManager.cs" />
<Compile Include="WindowsService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="WindowsServiceInstaller.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="SampleExecutionPlan.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>$(SolutionDir)Tools\nuget install $(ProjectDir)packages.config -o $(SolutionDir)Packages</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,95 +0,0 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using NLog;
namespace Mirantis.Murano.WindowsAgent
{
public abstract class WindowsService : ServiceBase
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
public bool RunningAsService { get; private set; }
protected static void Start(WindowsService service, string[] arguments)
{
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
if (arguments.Contains("/install", StringComparer.OrdinalIgnoreCase))
{
new ServiceManager(service.ServiceName).Install();
}
else if (arguments.Contains("/uninstall", StringComparer.OrdinalIgnoreCase))
{
new ServiceManager(service.ServiceName).Uninstall();
}
else if (arguments.Contains("/start", StringComparer.OrdinalIgnoreCase))
{
new ServiceManager(service.ServiceName).Start(Environment.GetCommandLineArgs(), TimeSpan.FromMinutes(1));
}
else if (arguments.Contains("/stop", StringComparer.OrdinalIgnoreCase))
{
new ServiceManager(service.ServiceName).Stop(TimeSpan.FromMinutes(1));
}
else if (arguments.Contains("/restart", StringComparer.OrdinalIgnoreCase))
{
new ServiceManager(service.ServiceName).Restart(Environment.GetCommandLineArgs(), TimeSpan.FromMinutes(1));
}
else if (!arguments.Contains("/console", StringComparer.OrdinalIgnoreCase))
{
service.RunningAsService = true;
Run(service);
}
else
{
try
{
service.RunningAsService = false;
Console.Title = service.ServiceName;
service.OnStart(Environment.GetCommandLineArgs());
service.WaitForExitSignal();
}
finally
{
service.OnStop();
service.Dispose();
}
}
}
protected WindowsService()
{
var displayNameAttribute =
this.GetType().GetCustomAttributes(typeof (DisplayNameAttribute), false).Cast<DisplayNameAttribute>().
FirstOrDefault();
if(displayNameAttribute != null)
{
ServiceName = displayNameAttribute.DisplayName;
}
}
protected virtual void WaitForExitSignal()
{
Console.WriteLine("Press ESC to exit");
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
}
}
protected override void OnStart(string[] args)
{
Log.Info("Service {0} started", ServiceName);
base.OnStart(args);
}
protected override void OnStop()
{
Log.Info("Service {0} exited", ServiceName);
base.OnStop();
}
}
}

View File

@ -1,39 +0,0 @@
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
namespace Mirantis.Murano.WindowsAgent
{
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
public WindowsServiceInstaller()
{
var processInstaller = new ServiceProcessInstaller { Account = ServiceAccount.LocalSystem };
foreach (var type in Assembly.GetEntryAssembly().GetExportedTypes().Where(t => t.IsSubclassOf(typeof(ServiceBase))))
{
var nameAttribute = type.GetCustomAttributes(typeof (DisplayNameAttribute), false)
.Cast<DisplayNameAttribute>().FirstOrDefault();
if(nameAttribute == null) continue;
var serviceInstaller = new ServiceInstaller {
StartType = ServiceStartMode.Automatic,
ServiceName = nameAttribute.DisplayName,
DisplayName = nameAttribute.DisplayName
};
var descriptionAttribute = type.GetCustomAttributes(typeof(DescriptionAttribute), false)
.Cast<DescriptionAttribute>().FirstOrDefault();
if(descriptionAttribute != null)
{
serviceInstaller.Description = descriptionAttribute.Description;
}
Installers.Add(serviceInstaller);
}
Installers.Add(processInstaller);
}
}
}

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
<package id="NLog" version="2.0.0.2000" targetFramework="net45" />
<package id="RabbitMQ.Client" version="3.0.2" targetFramework="net45" />
</packages>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\WindowsAgent\packages.config" />
</repositories>