Archive

Archive for the ‘Uncategorized’ Category

Mono Applications in Docker Containers

February 20, 2016 Leave a comment

Mono applications can be run in docker containers in several ways, including using base images from Xamarin or Microsoft that contain mono. If you have some specific runtime requirements, you may need to build your own images with mono preinstalled or provided on a data volume when launching the container.

Using mono from host

Because mono applications are often very self-contained, you can create a very slim image and make the mono runtime from the host available to the container when launching. This is convenient for keeping all applications using the same version of the mono runtime, allowing you to upgrade the runtime without modifying the existing images.

Dockerfile

from centos
ENV PATH /mnt/mono/bin:$PATH
ENV LD_LIBRARY_PATH=/mnt/mono/lib:$LD_LIBRARY_PATH

This short Dockerfile expects the mono runtime will be provided as a data volumefrom the host under the /mnt/mono mount point.

Build with docker build -t external_mono . to get a new docker image based on CentOS named “external_mono”. This image doesn’t contain mono, and instead you should pass mono in as a data volume from the host.

docker run -v /opt/mono:/mnt/mono --rm external_mono mono --version

The command above runs mono --version using the mono that is provided by the host. The host makes /opt/monoavailable as a data volume at /mnt/mono. The --rm option cleans up the container on exit.

As you’ll usually need an application there as well, you can similarly pass the application to the container as another data volume.

docker run -v /opt/mono:/mnt/mono -v /var/lib/myapp:/mnt/myapp --rm external_mono mono /mnt/myapp/MyExecutable.exe

With this approach, you never really build new images, which is very useful for simply sandboxing applications. The drawback is that all containers are running the same version of mono, shared from the host. If you run an orchestration system, such as Apache Mesos, the runtime must be installed on all hosts (Mesos slaves in this case).

Including mono in image

When all the dependencies are included within the image, the docker containers are much easier to move around because there are no additional host dependencies. This also means that containers can run different versions of the mono runtime if needed. The added flexibility comes at a small cost – images contain the runtime, so they are larger.

Dockerfile

from centos
RUN rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
RUN yum-config-manager --add-repo http://download.mono-project.com/repo/centos/
RUN yum -y install mono-complete

The image is larger, but nothing is required on the host, and now you can run mono directly in the container without a data volume:

docker run --rm included_mono mono --version

This image can be easily reused with any mono application that need to run on CentOS by attaching a data volume containing the application and then running it:

docker run -v /var/lib/myapp:/mnt/myapp --rm included_mono mono /mnt/myapp/MyExecutable.exe

The next step is to build an application-specific image on top of this image.

Dockerfile

from included_mono
COPY MyExecutable.exe /var/lib/MyApplication/

Building with docker build -t mono_with_app . will build an image that contains the application, and you can run it with no data volumes needed:

docker run --rm mono-with-app mono /var/lib/MyApplication/MyExecutable.exe

This option is definitely the simplest to run, and provides you with a base image for building additional images. Each image takes up space, however. Images with base CentOS and no mono are ~200 MB, whereas images with mono included are over 500 MB.

Cross posted on Github.

Categories: Uncategorized Tags: ,

Listing assembly versions on mono

January 13, 2015 3 comments

Need to quickly get a list of all the assembly names and version numbers you are using in your .NET application? Here is a brief command to retrieve this using the mono disassembler:

find . -name '*.dll' -exec monodis --assembly {} \; | grep "Name\|Version" 
Categories: Uncategorized Tags: ,

Launching a ServiceProcess using mono csharp script

December 30, 2014 Leave a comment

When developing service applications that need to run cross platform, you often need some “glue” to make the application behave appropriately on different platforms.  Service applications written in .NET languages derive from ServiceBase so they can be started by the the Windows Service Control Manager.  On Windows, they can be added to the service registry with ‘sc create’ or using installutil.exe.  You can usually get these to run on Unix and Linux using the mono-service executable, however this doesn’t always behave the way you might want when used from the various init systems.  Instead of using mono-service on *nix, you can using the csharp script mechanism in mono to launch the service process and handle signals to interact with your application. Here is an example of a service application:

using System;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;

namespace ServiceApplication {
	public class App : ServiceBase {

		CancellationTokenSource cts = new CancellationTokenSource();

		protected override void OnStart(string[] args) {
			var token = cts.Token;
			Task.Factory.StartNew(() => {
				while(true) {
					if(token.IsCancellationRequested)
						break;
					Console.WriteLine("{0} - service is running", DateTime.Now);
					Thread.Sleep(TimeSpan.FromSeconds(5));
				}
			}, token);
		}

		protected override void OnStop() {
			cts.Cancel();
		}

	}
}

All the code above is compatible across platforms and may be installed and run as a Windows Service without modification. Now for a simple script that can run on mono platforms using the ‘csharp’ command to wrap the service an execute and wait for typical Unix signals before shutting down cleanly:

#!/usr/bin/csharp

/*
 * Script for launching a Windows ServiceProcess applicaiton
 * on mono as an upstart job.
 */

LoadAssembly("System.ServiceProcess.dll");
LoadAssembly("Mono.Posix.dll");
LoadAssembly("ServiceApplication.dll");
using System.Reflection;
using System.ServiceProcess;
using ServiceApplication;
using Mono.Unix;
using Mono.Unix.Native;

var service = new App();
var mi = typeof(App).GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);
var result = mi.Invoke(service, new object[] { new string[] {} });

Console.WriteLine("Service started.");

var signals = new UnixSignal[]{
    new UnixSignal (Signum.SIGINT),
    new UnixSignal (Signum.SIGTERM),
    new UnixSignal (Signum.SIGQUIT),
};

var signal = UnixSignal.WaitAny(signals, -1);
Console.WriteLine("Received {0} signal, exiting.", signals[signal].Signum);

service.Stop();

All the platform specific code is in this script so your application code remains completely cross platform, and it makes for a very simple upstart script, as an example:


# Copy to /etc/init/monoServiceApp.conf
start on runlevel [2345]
stop on runlevel [06]

respawn

chdir /path/to/service/

script
   csharp ServiceRunner.cs
end script

The job above will execute the ServiceRunner.cs script using the csharp shell command automatically on startup, shutdown, reboot, and when executed manually using upstart commands (i.e. sudo start monoServiceApp). Since it’s a simple script, upstart will track the PID automatically and send SIGTERM when it’s time to exit, which will be caught by the script for a clean call to the Stop() method.

Note that you can do something similar with mono-service, which is more robust and has options that will let it fit with various init systems. However, mileage tends to vary, so a csharp wrapper script can be a nice alternative.

Categories: Uncategorized Tags: , , ,

Creating a Mono 3 RPM on CentOS

July 27, 2013 2 comments

Creating a Mono 3 RPM on CentOS

A quick guide to creating an rpm of mono 3 from source, starting with a CentOS 6.4 minimal using fpm to create the package.

  1. Install prerequisites for building mono 3

    yum -y update
    yum -y install glib2-devel libpng-devel libjpeg-devel giflib-devel libtiff-devel libexif-devel libX11-devel fontconfig-devel gettext make gcc-c++
    
  2. Download and extract libgdiplus and mono sources

    curl -O http://download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.9.tar.bz2
    curl -O http://download.mono-project.com/sources/mono/mono-3.1.2.tar.bz2
    tar -jxf libgdiplus-2.10.9.tar.bz2
    tar -jxf mono-3.1.2.tar.bz2
    
  3. Configure, make, and make install

    cd libgdiplus-2.10.9
    ./configure --prefix=/opt/libgdiplus
    # overwrite incompatible libtool script in pixman
    cp libtool pixman/libtool 
    make
    su -c "make install"
    
    cd mono-3.1.2
    ./configure --prefix=/opt/mono-3.1.2
    make
    su -c "make install"
    
  4. Install ruby prerequisites for fpm, then fpm itself

    yum -y install ruby ruby-devel rubygems
    gem install fpm
    
  5. Make sure /etc/hosts contains your host name since it will be used in some fpm defaults.

    vi /etc/hosts
    
  6. Install rpm tools and generate the RPM

    yum -y install rpm-build
    fpm -s dir -t rpm -n "mono" -v 3.1.2 /opt/mono-3.1.2 /opt/libdgiplus
    

You probably will want to explore some other fpm options to customize your rpm further, like setting the maintainer, dependencies, or running pre/post install scripts.

Categories: Uncategorized Tags: , , ,

Quick Sample of Password Hashing in C#

August 27, 2012 11 comments

Since it seems like passwords are getting leaked way too often these days, I thought I’d throw a super quick sample out there for anyone with a need to store user passwords in their system.  Some important rules:

1. Don’t use reversible encryption, like 3DES or AES.
2. Always use a SALT for each set of credentials, otherwise you’re open to dictionary attacks should your hashes be compromised.  You’ll want to store this alongside your hash in whatever password store you’re using.
3. Don’t invent your own algorithms – use a proven one written by experts that write them professionally, like PBKDF2.

Some recommended reading on why you should follow these rules: http://crackstation.net/hashing-security.htm

And on to the code sample.  Six lines of C# that work on Windows and Linux / Mono will get you a solid method for generating secure hashes.  Enjoy.  I hope this helps people out and gets more developers to use effective password security measures.


var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
byte[] salt = new byte[8];
rng.GetBytes (salt); // Create an 8 byte salt
var iterations = 1000; // Choose a value that will perform well given your hardware.
var pbkdf2 = new System.Security.Cryptography.Rfc2898DeriveBytes(pwd, salt, iterations);
var hash = pbkdf2.GetBytes (16); // Get 16 bytes for the hash

Categories: Uncategorized

Revisiting recursion with Dynamic Methods

January 8, 2010 Leave a comment

Dynamic methods were added to .NET back in the 2.0 release as part of Lightweight Code Generation, and lots of technologies (i.e. IronPython) use them to do their dynamic dirty work of emitting code at runtime. Dynamic methods are methods that you create at runtime through System.Reflection.Emit much like you would generate an assembly with reflection, only you don’t need to put the method in an assembly, so there isn’t an assembly hanging around in memory…GC can clean up the JIT’d code after the method goes out of scope.

The code is also a lot more concise: no AssemblyBuilder, ModuleBuilder, TypeBuilder, MethodBuilder needed before you can write a dynamic method. For an example, I’m revisiting my old recursive Fibonacci function to illustrate writing a dynamic method and also show the performance cost for the runtime to resolve dynamic methods. Recursive functions demonstrate this the best because each recursion requires dynamic method resolution to occur.

DynamicMethod dm = new DynamicMethod("Fib", typeof(int), new Type[] { typeof(int) }, true);
ILGenerator il = dm.GetILGenerator();
Label isEqZero = il.DefineLabel();
Label isNotEqZero = il.DefineLabel();
Label isNotEqOne = il.DefineLabel();
Label retLabel = il.DefineLabel();
LocalBuilder local = il.DeclareLocal(typeof(int));
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ceq);
 
il.Emit(OpCodes.Brfalse, isNotEqZero);
// If it got here, then the input was zero, so go to return label.
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Br, retLabel);
 
il.MarkLabel(isNotEqZero);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ceq);
il.Emit(OpCodes.Brfalse, isNotEqOne);
// If it got here, then the input was one, so go to return label.
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Br, retLabel);
 
il.MarkLabel(isNotEqOne);
// Should do recursion here.
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Sub);
il.Emit(OpCodes.Call, dm);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_2);
il.Emit(OpCodes.Sub);
il.Emit(OpCodes.Call, dm);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Stloc_0);
 
// Loads the first local variable onto the stack and returns it.
il.MarkLabel(retLabel);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
 
Func<int, int> invokeDynamicMethod = (Func<int, int>)dm.CreateDelegate(typeof(Func<int, int>));
for (int i = 0; i <= 40; i++)
{
    int result = invokeDynamicMethod.Invoke(i);
    Console.WriteLine("{0} {1}", i, result);
}

If you run this, you’ll notice that it gets slower with larger numbers because bigger numbers require more invocations of the dynamic method. Of course, you could solve this problem without using recursion, but I wanted to illustrate the performance penalty. That said, Lightweight Code Generation and dynamic methods give you some great flexibility without the additional baggage of generating a full fledged .NET assembly.

Terrible UX people are creating in Silverlight just because they can

December 9, 2009 1 comment

After reading some really ridiculous posts of people doing stuff with Silverlight that you really shouldn’t do, I thought I’d make a post of my own, showing how you can display progress bars inside drop down lists that are nodes on a treeview that auto-expand on mouseover just like I tweeted about. I think doing this is a terrible idea, but since every other day I see a blog posting on how to do something in Silverlight that makes for a very bad user experience, I thought I would contribute an example of my own. I hope you enjoy.

I wish I could upload my Silverlight control to WordPress so you could see it running live. Maybe I’ll find someplace else to host it. In the meantime, you can probably imagine how atrocious this looks, but maybe you’re also amazed by how easy it is and how clean the markup can be when making something that looks and behaves so terribly.

Too add to the fun, the source code in this blog post is spilling over the margins.

<usercontrol xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" x:class="TerribleUX.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:ignorable="d" d:designheight="300" d:designwidth="400">
    <usercontrol.resources>
        <style targettype="ProgressBar" x:key="pbStyle">
            <Setter Property="Minimum" Value="0" ></Setter>
            <Setter Property="Maximum" Value="100" ></Setter>
            <Setter Property="Height" Value="30" ></Setter>
            <Setter Property="Width" Value="125" ></Setter>
            <Setter Property="Minimum" Value="0" ></Setter>
        </style>
        <style targettype="ComboBox" x:key="cbStyle">
            <Setter Property="Height" Value="30" ></Setter>
            <Setter Property="Width" Value="130" ></Setter>
        </style>
        <datatemplate x:key="tvDataTemplate">
            <combobox mouseenter="ComboBox_MouseEnter" style="{StaticResource cbStyle}">
                <comboboxitem>
                    <progressbar value="25" style="{StaticResource pbStyle}"></progressbar>
                </comboboxitem>
                <comboboxitem>
                    <progressbar value="65" style="{StaticResource pbStyle}"></progressbar>
                </comboboxitem>
                <comboboxitem>
                    <progressbar value="35" style="{StaticResource pbStyle}"></progressbar>
                </comboboxitem>
            </combobox>
        </datatemplate>
    </usercontrol.resources>
    <grid x:name="LayoutRoot" background="White">
        <toolkit:treeview>
            <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                    <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                    <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                </toolkit:treeviewitem>
            </toolkit:treeviewitem>
            <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
            </toolkit:treeviewitem>
            <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
                <toolkit:treeviewitem mouseenter="TreeViewItem_MouseEnter" headertemplate="{StaticResource tvDataTemplate}">
            </toolkit:treeviewitem>
        </toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeviewitem></toolkit:treeview>
    </grid>
</usercontrol>

And here are the event handlers:

private void ComboBox_MouseEnter(object sender, MouseEventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if(cb != null)
        cb.IsDropDownOpen = true;
}

private void TreeViewItem_MouseEnter(object sender, MouseEventArgs e)
{
    TreeViewItem tvi = sender as TreeViewItem;
    if (tvi != null)
        tvi.IsExpanded = true;
}
Categories: Uncategorized