From 7d515c24f7a29727aaa3006a2da26865e4df3950 Mon Sep 17 00:00:00 2001 From: Stan Lagun <slagun@mirantis.com> Date: Tue, 12 Mar 2013 22:34:02 +0400 Subject: [PATCH] ExecutionPlanGenerator DSL processor --- .../ExecutionPlanGenerator/App.config | 6 + .../ExecutionPlanGenerator.csproj | 62 ++++++++ .../ExecutionPlanGenerator/Program.cs | 141 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++ .../ExecutionPlanGenerator/packages.config | 4 + 5 files changed, 249 insertions(+) create mode 100644 WindowsAgent/ExecutionPlanGenerator/App.config create mode 100644 WindowsAgent/ExecutionPlanGenerator/ExecutionPlanGenerator.csproj create mode 100644 WindowsAgent/ExecutionPlanGenerator/Program.cs create mode 100644 WindowsAgent/ExecutionPlanGenerator/Properties/AssemblyInfo.cs create mode 100644 WindowsAgent/ExecutionPlanGenerator/packages.config diff --git a/WindowsAgent/ExecutionPlanGenerator/App.config b/WindowsAgent/ExecutionPlanGenerator/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/WindowsAgent/ExecutionPlanGenerator/App.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <startup> + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> + </startup> +</configuration> \ No newline at end of file diff --git a/WindowsAgent/ExecutionPlanGenerator/ExecutionPlanGenerator.csproj b/WindowsAgent/ExecutionPlanGenerator/ExecutionPlanGenerator.csproj new file mode 100644 index 0000000..fa80540 --- /dev/null +++ b/WindowsAgent/ExecutionPlanGenerator/ExecutionPlanGenerator.csproj @@ -0,0 +1,62 @@ +<?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>ConsoleApplication1</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> \ No newline at end of file diff --git a/WindowsAgent/ExecutionPlanGenerator/Program.cs b/WindowsAgent/ExecutionPlanGenerator/Program.cs new file mode 100644 index 0000000..c5c7f12 --- /dev/null +++ b/WindowsAgent/ExecutionPlanGenerator/Program.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace ConsoleApplication1 +{ + 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))); + } + } +} diff --git a/WindowsAgent/ExecutionPlanGenerator/Properties/AssemblyInfo.cs b/WindowsAgent/ExecutionPlanGenerator/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..54a148f --- /dev/null +++ b/WindowsAgent/ExecutionPlanGenerator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +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")] diff --git a/WindowsAgent/ExecutionPlanGenerator/packages.config b/WindowsAgent/ExecutionPlanGenerator/packages.config new file mode 100644 index 0000000..b82a8b0 --- /dev/null +++ b/WindowsAgent/ExecutionPlanGenerator/packages.config @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> +</packages> \ No newline at end of file