Cross-Debugging Mono C# Executables Running on Linux

Debugging C# programs that run on a Linux server can be a challenge. On Ubuntu, a server may not have the Unity GUI installed, so you can’t use MonoDevelop. Even if the server had the GUI, MonoDevelop often does not work with a C# project because it doesn’t support many Visual Studio 2015 projects. Visual Studio supposedly can cross-debug a program running on Linux from a Windows box, but I haven’t been able to get one solution to work. (It does work for C++.Xamarin Studio works, but the steps are somewhat convoluted, and won’t work if you naively follow what has been outlined by others for a Windows box (e.g., in (a), you cannot simply build the app on Linux using xbuild, because the paths for files between server and debugger host differ). Here, I note how one can get Xamarin Studio working on Windows.

  1. Download a copy of Xamarin Studio for Windows, and install it. Xamarin Studio for Windows is, in fact, no longer officially available, but you can still find the download here as of July 2016. I don’t know how long this link will last; you can’t download Xamarin Studio for Windows though Xamarin.com.
  2. In your Linux server, make sure to have it set up with a firewall, SSH, and Mono.
  3. Create a variable in your environment to enable Xamarin Studio “Custom Soft Debugging.” Create “MONODEVELOP_SDB_TEST” with the value “1” (no quotes) through the System Properties box.
  4. Start Xamarin Studio, and open or create a C# test program, like “Hello World.” Set the configuration to Debug and build the program.
  5. Mono does not understand PDB files, so you have to create the equivalent MDB files. Start a command-line Bash shell in the directory ‘bin/Debug/”. Type: for i in *.exe *.dll;do echo $i; pdb2mdb $i; done. If pdb2mdb is not found, make sure Mono/bin is on the search path.
  6. Open a command-line Bash shell on your Linux box using “ssh”, e.g., “ssh root@192.168.1.10”.
  7. In the Windows Bash shell, type: tar -cvf – Debug | ssh root@192.168.1.10 ‘cat – > Debug.tar’.
  8. In the Linux Bash shell, type: tar -xvf Debug.tar; cd Debug; mono –debug –debugger-agent=transport=dt_socket,address=0.0.0.0:12345,server=y HelloWorld.exe, replacing HelloWorld.exe with the name of the executable you want to debug.
  9. In Xamarin Studio, open Run -> Run with -> Custom Command Mono Soft Debugger2016-07-14 (1)
  10. In the pop up, enter the IP address of the Linux box, then click on “Connect”. 2016-07-14 (9)
  11. You should now be able to debug your program. Note: you don’t need to compile the program on Linux. Note: if you can’t set breakpoints, it’s because you haven’t copied the .mdb files from Windows to Linux. Path names in the .mdb files are full paths, and Linux path names do not work.

 

Further Information

  1. https://eladnava.com/debug-remote-mono-apps-via-xamarin-studio/
  2. http://www.mono-project.com/docs/advanced/runtime/docs/soft-debugger/
  3. http://www.jeffongames.com/2012/03/debugging-embedded-mono/
  4. http://tirania.org/blog/archive/2008/Sep-04.html
  5. https://blogs.msdn.microsoft.com/vcblog/2015/11/18/announcing-the-vs-gdb-debugger-extension/

Installing Docker

OK, really simple. I want to install Docker on an Ubuntu box. Should be easy. Right?

Wrong!

When I do a Google search for “install docker”, Google returns a link to the Docker installation page for Ubuntu. That’s fine, but following the 18 page/2000 word installation is insane. The first time I did that, it took 15 minutes. What a waste of time, and not easily reproducible if I stop to get a cup of coffee, then come back.

So, I go to docker.com, and somehow find some other documentation for a Linux install through the now totally indecipherable menu system in docker.com. The instructions are shorter, and seem the right thing to do, basically: curl -fsSL https://get.docker.com/ | sh.

Why ask why there are two different instructions?

 

 

The Mysteries of XAML

I’d like to start with a short story. I’m trying to write a simple Hello World program. I want it to run on Android, and it must use Xamarin Forms, and use XAML to describe the UI. Should be easy, 5 minutes to do, right? Not in my case.

I go into Visual Studio and create a blank app (Xamarin.Forms Portable). I then “Add New/Forms Xaml Page”, which creates Page1.xaml, replace the hard-wired C# code for building the UI in App.cs with “MainPage = new Page1();”, compile and try to run the program. Unfortunately, it doesn’t do what I expected: there is no text displayed. Looking at Page1.xaml, I realize that the code “{Binding MainText}”  isn’t working. What the hell did Visual Studio create?

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1Error.Page1">
  <Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

Maybe you know–or maybe not, as I didn’t–the explanation is quite simple: If the BindingContext of the XAML-specified UI data structure is null, which is so in this case, there is no object to get the string property “MainText”. Consequently, the Text property of the Label object is initialized to the empty string. There is no runtime error message produced because referencing a property with a null BindingContext is “OK.”

Excuse me, but this is bad. People don’t have a chance in hell if an IDE generates code that doesn’t work. Don’t just take my word on it, others have the same observation. The IDE should generate an empty XAML file, or it should generate stubs for an app that has some structure (MVVM, MVP, MVC, etc).

So, on I go to investigate XAML, because that’s what this is really all about.

What is XAML?

XAML is a language for specifying tree-oriented data structures. Simply stated, XML elements and attributes are mapped into UI classes and properties, respectively. While you can avoid using XAML in your program, people want the UI to have a clean separation from the logic of the program. XAML helps you accomplish this because it is a declarative language.

XAML has a long history. Initially, there was speculation whether it was a replacement of HTML for web browsers, but it was just a language for UI data structures for Microsoft’s desktop. Writing an XAML spec was supposed “to be developed with a visual tool where developers do not even need to understand the underlying markups,” but in the initial release, the tool was terrible. It still is a problem, because there is no designer for Xamarin Forms XAML.

That would be fine, but there is no formal definition of the language to fall back on. If you read Microsoft’s spec on XAML, it is stated that the interpretation is up to individual XAML processors. In other words, the interpretation of the directive is what it is, whatever that is. But, as we shall see, XAML elements map to UI objects, and we can get a good idea what it does by reading the API for Xamarin Forms.

When a program is compiled, linked, and run, the XAML code is embedded in the assembly, then converted at runtime into a data structure by LoadFromXaml. The code that converts the XML to a data structure is, of course, not open sourced, but you can read how it works using a disassembly (e.g., with DotPeek).

I’ll go over several examples which illustrate some of the ways you can specify a view, and connect it up with a model, since that is what you will want to do 99% of the time.

Disassociated View

After creating an app, change the Label Text property assignment with a simple “Hello World”, i.e., a static string. In this case, there is no associated information with the view. Everything in the view is self-contained. I refer to this as a disassociated view.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
             x:Class="App1.Page1">
  <Label Text="Hello World!" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

Note, Label is an XML element, but it’s converted into an object of type Xamarin.Forms.Label. Text, VerticalOptions, and HorizontalOptions are XML attributes, properties of the Label object. The declaration x:Class=”App1.Page1″ is a directive that clues the XAML translator to generate C# source code for the class. That’s done while you edit the XAML file in the IDE.

Another important note here. A property of an object can be set one of two ways in XAML:

  • a property element, where the property and assigned value is expressed as a nested XML element of the containing object.
  • a property attribute, where the property and assigned value is expressed as an XML attribute.

Above, you see the property attribute Text. Below, you’ll see property element BindingContext.

View with Binding

Most of the time, a UI needs to get information from a Model. To do that, you need a binding, which is an association of the view to another object. In fact, if the binding is between the UI and an object derived from IObserverableObject, then it can do magic. (Note, for a discussion of MVVM, see So What Exactly is a View-Model?.)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App2;assembly=App2"
             x:Class="App2.Page1">
  <ContentPage.BindingContext>
    <local:ViewModel />
  </ContentPage.BindingContext>
  <Label Text="{Binding MessageOfTheDay}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

A binding consists of (1) a context assignment, and (2) a binding assignment. Note: nowhere are these terms defined in the spec or by anyone else. However, in order to talk about binding, you have to have a terminology. If you are so inclined, you can read how binding is implemented in the MS documentation.

The context assignment in this example is specified in the XML element <ContentPage.BindingContext>…</ContentPage.BindingContext>. In terms of C# code, it would be the same as “BindingContext = …”. Note how the assignment is written–using a contained element.

The binding assignment associates an object with the view: Label=”{Binding MessageOfTheDay}”. When the UI is constructed, a tree walk is performed up the predecessors until a context is found with the property. NB: the property specified in the binding expression must be a property, not a field or method, otherwise the binding fails.

Singletons

Sometimes you may want a binding to be shared between multiple ContentPage, e.g., a model. In this situation, you can use a x:Static extension.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App3;assembly=App3"
             x:Class="App3.Page1"
             BindingContext="{x:Static local:Class1.Singleton}">
  <StackLayout>
    <Label Text="{Binding CurrentValue}" />
    <Label Text="{Binding CurrentValue}" />
  </StackLayout>
</ContentPage>

A singleton property is defined and used in one XAML file.

There is no way to create a singleton tree node, but you can share the tree node using x:Key. XAML extensions are discussed below.

Binding Lists

A list of objects can be consumed by the view. In Xamarin, ListView has the property ItemsSource, which contains an enumerable collection to iterate over and create children. The semantics of setting ItemsSource is not documented, but essentially:

IEnumerable<T> collection = ....;
foreach (T t in collection) {Add(new Label(t));}

If the ListView XAML specifies a <ListView.ItemTemplate>, the ListView will contain a collection of items of the type specified in the template. By default, it creates a Label. See the documentation.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App4;assembly=App4"
             x:Class="App4.Page1">
  <ContentPage.BindingContext>
    <local:Class1/>
  </ContentPage.BindingContext>
  <StackLayout>
    <Label Text="Value"/>
    <ListView ItemsSource="{Binding Values}"></ListView>
  </StackLayout>
</ContentPage>
using System.Collections.Generic;

namespace App4
{
    class Class1
    {
        public List<string> Values { get; private set; }= new List<string>()
        {
            "a", "b", "c"
        };
    }
}

 

Observer/Observable Pattern

After getting used to XAML, at some point, you will want information in the view to update whenever the corresponding model changes while it’s happening. The UI requires the binding object have an INotifyPropertyChanged interface. In the properties that change, OnPropertyChanged() is called to produce the side effect in the view.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App5;assembly=App5"
             x:Class="App5.Page1">
  <ContentPage.BindingContext>
    <local:Class1/>
  </ContentPage.BindingContext>
  <StackLayout>
    <Label Text="{Binding FirstName}"/>
    <Label Text="{Binding LastName}"/>
    <Label Text="{Binding CurrentDateTime}"/>
  </StackLayout>
</ContentPage>
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using App5.Annotations;

namespace App5
{
    class Class1 : INotifyPropertyChanged
    {
        public Class1()
        {
            // Set up timer to tick of current time.
            _timer = new Timer((o) =>
            {
                Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
                {
                    CurrentDateTime = DateTime.Now.ToString();
                    LastName = "You should never see this because OnPropertyChanged() is not called!";
                });
            }, null, 0, 1000);
        }

        private Timer _timer;
        public String FirstName { get; set; } = "hi";
        public String LastName { get; set; } = "there";
        private String _current_date_time = DateTime.Now.ToString();
        public String CurrentDateTime
        {
            get
            {
                return _current_date_time;
            }
            set
            {
                _current_date_time = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 

View and Commands

There are two schools for handling events when the user clicks a button or enters text in a data text box. The “old school” is to add an event handler to the code-behind file to make some response, e.g., the OnButtonClicked() override. (In fact, Xamarin shows how you would do that in their last example of this introduction to XAML.) The "new school” is to add a Command property assignment to the XAML, and add the handler into the “ViewModel”. (Note, as someone else points out, placing all the handlers in the ViewModel reduces it to a code behind file.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App6;assembly=App6"
             x:Class="App6.Page1">
  <ContentPage.BindingContext>
    <local:Class1/>
  </ContentPage.BindingContext>
  <StackLayout>
    <Button Text="Click me" Command="{Binding Click}"/>
    <Label Text="{Binding MessageOfTheDay}" />
  </StackLayout>
</ContentPage>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Xamarin.Forms;

namespace App6
{
    public class Class1 : INotifyPropertyChanged
    {
        public Class1()
        {
            _message_of_the_day = _messages[_i];
            Click = new Command((nothing) =>
            {
                DoWhop();
            });
        }

        private String _message_of_the_day;

        public String MessageOfTheDay
        {
            get
            {
                return _message_of_the_day;
            }
            private set
            {
                _message_of_the_day = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private int _i = 0;

        private List<String> _messages = new List<string>()
        {
            "What's happening?",
            "This is cool, huh?",
            "Working for the weekend.",
            "No time like the present.",
            "Time flies like an arrow.",
            "Microsoft and Xamarin XAML is the best thing since sliced bread!"
        };

        public ICommand Click { protected set; get; }

        private void DoWhop()
        {
            _i++;
            if (_i >= _messages.Count)
                _i = 0;
            MessageOfTheDay = _messages[_i];
        }
    }
}

 

Debugging XAML

Binding problems can be resolved sometimes by modifying the binding assignment. At the moment, there doesn’t seem to be a way to check if a context is null in Xamarin Forms. In WPF, it would be accomplished using PresentationTraceSources: add a trace statement, Text=”{Binding MessageOfTheDay, diag:PresentationTraceSources.TraceLevel=High}”; define the namespace “diag”, xmlns:diag=”clr-namespace:System.Diagnostics;assembly=WindowsBase”.

If you have a non-null binding context, you can debug the binding when it’s accessed, either in the property or with a data converter.

XAML Extensions

XAML has a special namespace for extensions to the XAML processor. We’ve already seen some of those, e.g., x:Class.

 

  • x:Class – generate a C# class with the given name.
  • x:Name – generate a C# property.
  • x:Reference – use a C# property. Goes in hand with x:Name.
  • x:Key – create a value, in the context of a resource.

An example containing some of these directives follows.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App6;assembly=App6"
             x:Class="App6.Page1">
  <ContentPage.Resources>
    <ResourceDictionary>
      <x:String x:Key="whatever">3</x:String>
    </ResourceDictionary>
  </ContentPage.Resources>
  <StackLayout>
    <Label Text="{StaticResource whatever}"/>
    <Label Text="fun" x:Name="foobar1"/>
  </StackLayout>
</ContentPage>

 

Conclusions

XAML is an expressive tree-oriented data structure language for UI. Unfortunately, there isn’t a specification of the language, but there are some well-known idioms to help you use it effectively. Enjoy!

Additional Information

Nathan, Adam. XAML unleashed. Sams Publishing, 2014.

As usual, I provide the source for all examples, here in git.

 

 

Posted in Tip

Visual Studio 2015 MRU List Cleanup

Somewhere in the many years that Microsoft has been developing Visual Studio, they’ve managed to completely mess up the Most Recently Used (MRU) list of projects in the Start Page. It used to be that if you opened a project, it would appear at the top of the list the next time you open Visual Studio. Unfortunately, that is no longer the case. Visual Studio 2015 now sorts the list in some bizarre manner, and it adds .csproj files (sub-projects) to the MRU list of a solution that I opened. Rather than try to raise the issue with Microsoft, I decided to write a small program that can reorganize and clean the MRU list to what I want.

The program (source in git here) is a WPF application that, when run as administrator, displays a grid of the project, location, whether it exists, date created, and date accessed. By clicking on the column, the registry data for the MRU list is re-ordered by that column. If you want to remove an entry, select the row(s), then hit the Delete key. Double clicking of an item opens the default program for the file.

Enjoy! –Ken

NOTE: I’ve since filed a bug with MS. VS overwrites the MRU list with stale data on the close of VS. https://connect.microsoft.com/VisualStudio/feedback/details/2648192. This is part of the problem with MRU lists in VS.

Posted in Tip

Mongo, Restheart, and Dokku

Mongo is a popular NoSQL database nowadays. It has several advantages compared to relational databases (schema-less, key-value store, scalable, distributed, propagated consistency) but the main advantage, IMHO, is that JSON is the lingua franca for the data structures it stores and the queries you use. JSON is a nice, simple data structure representation. It can be easily passed between the database and the application; and it can be converted to/from a string and an object in the native language you use. Mongo has many native-language APIs available for interfacing your application with the database, so you should be able to connect your application with Mongo.

Unfortunately, Xamarin Forms applications, written in C#, are Portable Class Library (PCL) applications, and the C# API for Mongo can’t work. Unfortunately, PCL apps and libraries can only link with other PCL libraries that have the same or additional target platforms. So, a PCL app that is targeting Windows, Android, and iOS cannot link with a library that only targets Windows, or only Android, or only iOS.

However, all is not lost. Restheart is an open source REST API server for Mongo databases. You can easily write a layer to encapsulate the calls that you need to access your Mongo database. There aren’t many functions you have to write beyond the usual CRUD, and the signatures for the method are just strings.

Setup

The installations instructions are on the Mongo.org website. Get the latest production version of Mongo. Then, execute the installation file. After it completes, create a directory for the database.

md data/db

To run Mongo, type

mongod --dbpath data/db

To set up Restheart, either copy the latest from Restheart.org, or clone the git repository for Restheart. If you are going to build it from scratch, you will need Maven, Java, and various other tools. Note, I highly recommend you build Restheart from git because the documentation is quite poor, and the only really good way to understand the server is to debug it.

To run Restheart, type java -jar ./restheart/target/restheart.jar, or the appropriate jar file. You can specify a configuration file for Restheart as a parameter when executing the jar.

CRUD

In a SQL database, data are stored in tables. In Mongo, data are stored in a collection. As with SQL, Mongo has CRUD statements for access to the database. The equivalent in Mongo of a row in a SQL table is a document, and is simply a JSON string. A projection of a JSON structure is equivalent to a projection in SQL. If you convert the JSON into a Newtonsoft JObject, you can make a projection of one key/value pair using the [] operator. As in SQL, an index can be created to improve search time.

Examples

SQL Op
Operation
Example
Example in Mongo shell
Example in Restheart
 Create database
 Create a database named db1.
 Create a database named db1.
use db1
NOTE: you need to insert a collection to actually create the database while using the Mongo shell.
 PUT
http://localhost:8080/db1/
NOTE: Do not set data or you will create a record with that data in the database. It can’t be deleted!
Create table
Create collection
 Create a collection named “col”.
db.createCollection(“col”)
PUT
http://localhost:8080/db1/col
Insert a row in a table
Insert a document in a collecton
Insert {“a1″:”b1”} in collection col.
 db.col.insert({“a1″:”b1”})
POST
http://localhost:8080/db1/col
payload is {“a1″:”b1”}
header is Content-Type: application/json
NOTE: The record type/value doesn’t have to be unique. So, you can insert duplicates if you like.
Read a row
Read a document
Find {} — find all records in collection col.
db.col.find({})
or just db.col.find()
GET
http://localhost:8080/db1/col
header is Content-Type: application/json
Read a row
Read a document
Find { “a1” : <value> } — find all records with key a1 in collection col.
db.col.find({“a1”:{$regex : “.*” }})
GET
http://localhost:8080/db1/col?filter={“a1″:{$regex:”.*”}}
NOTE: Make sure to note the correct syntax. The Restheart arg parser is very, very poor. E.g., using parentheses instead of equal sign:
http://localhost:8080/db1/col?filter={“a1″:{$regex:”.*”}}
This will return all records with a1, which is not what you intended!
To limit the find to the “first” record (whatever that means), add ‘&pagelimit=1’ to the args of the GET url.
Read a row
Read a document with projection
Find { “a1” : <value> } — find all records with key a1 in collection col, but only show keys of “cc”. For example, suppose there is one record, {{“aa”:”bb”}, {“cc”:”dd”}}. Return {“cc”:”dd”}.
db.col.find({“aa”:{$regex : “.*” }}).projection({“cc”:1})
http://localhost:8080/db1/col?filter={“aa”:{$regex:”.*”}}&keys={“cc”:1}
 Update a row
 Update a document
Update {“a1″:”*.”} to {“a1″:”asdf”}
db.col.update({“a1″:{$regex:”.*”}},{“a1″:”xx”})
PATCH
http://localhost:8080/tb3/col/*?filter={“a1″:”.*”}
header is Content-Type: application/json
payload is {“a1″:”asdf”}
 Delete a row
 Delete a document
 Delete a record with a particular key/value, { “a1” : <value> }.
 db.col.remove({“a1″:{$regex:”.*”}})
 DELETE
http://localhost:8080/db1/col/*?filter={“aa”:{$regex:”.*”}}
 Delete a table
 Delete a collection
 Nuke an entire collection col.
 db.col.drop()
 DELETE
http://localhost:8080/db1/col
 Delete database
 Delete database
 Nuke the entire database db1.
 db.dropDatabase()
 DELETE
header contains If-Match:<the id of the database>, e.g., 570e3dc71d9563251070fab3
http://localhost:8080/tb1/

 

NOTE: Restheart normally requires an “ETag” header entry, i.e., “If-Match: 570e3dc71d9563251070fab3”, where that number is an ID of the record to delete. You can turn off ETag checking in a configuration file, which you can specify on the java command line.

To get a value, you will have to parse the json for the field of interest. You can use projection to help you with that.

Running Mongo and Restheart on Dokku

To run a Mongo database and a Restheart server on Dokku, you can get a copy of my Github example, then modify it for your needs. The example is here.

References

https://softinstigate.atlassian.net/wiki/display/RH/Installation+and+Setup#InstallationandSetup-7.3.MongoDBauthenticationwithjustenoughpermissionsauth-with-jep

https://softinstigate.atlassian.net/wiki/display/RH/Query+Documents

http://www.tutorialspoint.com/mongodb/mongodb_query_document.htm

https://docs.mongodb.org/manual/reference/method/db.collection.find/

https://www.mongodb.org/downloads#production

http://www.codeproject.com/Articles/1087008/Mongo-DB-Tutorial-and-Mapping-of-SQL-and-Mongo-DB

http://stackoverflow.com/questions/tagged/restheart

https://en.wikipedia.org/wiki/MongoDB

 

Posted in Tip

GoDaddy left at the Docker

I’m in the process of checking out the advantages and disadvantages of GoDaddy’s new Cloud Server product, which has just been announced as generally available. It has few features, less compared to DigitalOcean, which has been available for a few years. AWS, which has been available for even longer, is generally the gold standard–if you like, or need, a cloud platform with every conceivable tweakable option. You have to wonder what took GoDaddy so long. And, even with years to think about what to implement in order to compete with DigitalOcean and Amazon, it has at least one problem which the others don’t.

As I am currently a tepid fan of Dokku, I decided to check out how a GoDaddy VPS would perform compared to a VPS on DigitalOcean. However, I spent a day or two figuring out that GoDaddy has a problem with routing Docker container network traffic. You can see a discussion of the type of problem here, and a solution provided by GoDaddy here. The tweek involves some changes to iptables. Below is a script that wraps it all together: it installs Docker and fixes the iptables for a GoDaddy VPS. Enjoy!

#
sudo apt-get update -y
sudo apt-get install -y apt-transport-https ca-certificates
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo bash -c 'echo deb https://apt.dockerproject.org/repo ubuntu-trusty main > /etc/apt/sources.list.d/docker.list'
sudo apt-get update -y
sudo apt-get purge lxc-docker
sudo apt-cache policy docker-engine
sudo apt-get install linux-image-extra-$(uname -r)
sudo apt-get install -y docker-engine
sudo service docker start
sudo docker run hello-world

# verify ping works
sudo docker run --rm -it ubuntu /bin/bash -c 'ping -c3 8.8.8.8'

# update iptable
export IP=`ip route get 8.8.8.8 | awk '{print $NF; exit}'`
sudo iptables -t nat -I POSTROUTING ! -o docker0 -j SNAT --to $IP
sudo iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -d 208.109.188.8 ! -o docker0 -j SNAT --to $IP
sudo iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -d 208.109.188.9 ! -o docker0 -j SNAT --to $IP

# verify ping works
sudo docker run --rm -it ubuntu /bin/bash -c 'ping -c3 8.8.8.8'

 

Posted in Tip

Setting Up Dokku via Command-Line Script

Dokku is a PAAS implementation, useful for websites, servers, or development. As it notes in its website, the installation in a Debian host running Bash is just three steps:

# only works on debian systems!
wget https://raw.githubusercontent.com/dokku/dokku/v0.5.3/bootstrap.sh
sudo DOKKU_TAG=v0.5.3 bash bootstrap.sh
# go to your server's IP and follow the web installer

The last “step” is written as a Bash comment. It states to complete the installation via a web browser. If you’re like me, this is a surprise, completely opposite of command-line driven provisioning. Using Fiddler, I conjured up a script to fix this problem. Enjoy!

(Note: I asked the question in the Dokku issue page, and the reply pointed to using debconf. You can use that. Or, you can use this script–which I think is easier.)

#
# Set up Dokku via command line

set -e

if [ "$#" -ne 1 ]; then
 echo "Try this: cat ~/.ssh/id_rsa.pub | ${0##*/} -"
 exit 1
fi

export IP=`ip route get 8.8.8.8 | awk '{print $NF; exit}'`
export KEY=$(</dev/stdin)

if [ "${KEY/ssh-rsa}" = "$KEY" ] ; then
 echo "Input is not a ssh key."
 exit 1
fi

curl "http://localhost" > /dev/null 2>&1

export FKEY=`echo -ne "$KEY" | hexdump -v -e '/1 "%02x"' | sed 's/\(..\)/%\1/g'`

cat <<EOF | curl -XPOST --data @- "http://localhost/setup"
keys=$FKEY&hostname=$IP
EOF

 

Posted in Tip

Hints for Securing Ubuntu on a VPS

Digital Ocean and Godaddy Pro are nice VPS providers. However, it’s important to update the security of any box you create ASAP. It took under 24 hours for one of my boxes to be hacked and turned into a DoS! Therefore, when you create your box, make sure to add a firewall immediately.

  1. Add an SSH key to the box so you can log into it without passwords. This can sometimes be a real pain in the ars, but it’s worth it. Remember, the server needs an “authorized_keys” file, and the client needs an agent, either Pageant or ‘eval $(ssh-agent)’.
  2. Turn off passwords for SSH. After adding a key–and making sure that it works–turn off password prompting. Note: if you mess this up and can’t login without password prompting, you are totally screwed!
    1. vi /etc/ssh/sshd_config, uncomment “PasswordAuthentication”, and change “PasswordAuthentication” from “yes” to “no”.
  3. Install UFW (the “Uncomplicated Firewall”). Set up which ports that are exposed. For now, allow SSH (port 22).
sudo apt-get install ufw
sudo ufw default deny incoming
sudo ufw allow ssh
# set up ssh before enabling ufw!
sudo ufw --force enable
sudo ufw status
  1. Install Fail2ban. Fail2ban keeps track of hackers trying to get into the machine, and sets up blocks accordingly.
    1. sudo apt-get update
    2. sudo apt-get install fail2ban
    3. Install any additional rules you want.
      1. sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
      2. vi /etc/fail2ban/jail.local
        1. Add in rules, e.g., ‘^%(__prefix_line)sReceived disconnect from <HOST>: 11: (Bye Bye)? \[preauth\]$’.
      3. To test it with fail2ban-regex or egrep, you can just strip off the ^%(__prefix_line)s from the beginning. Add this line to the failregex variable in your /etc/fail2ban/filter.d/sshd.conf.
  2. Check logs periodically. Look for strange happenings.
    1. grep sshd.\*Failed /var/log/auth.log | less
    2. grep sshd.*Did /var/log/auth.log | less
  3. Do not expose Redis, Mongo DB, or other unsafe programs directly past the firewall:
    1. http://redis.io/topics/security
  4. Install nethogs to see what’s going on with the network.
    1. sudo apt-get install nethogs
    2. sudo nethogs eth0
    3. creating socket failed while establishing local IP – are you rootwget -c https://github.com/raboof/nethogs/archive/v0.8.1.tar.gz
    4. wget -c https://github.com/raboof/nethogs/archive/v0.8.1.tar.gz
    5. tar xf v0.8.1.tar.gz
    6. cd ./nethogs-0.8.1/
    7. sudo apt-get install libncurses5-dev libpcap-devsudo apt-get install make
    8. sudo apt-get install make
    9. sudo apt-get install build-essential g++
    10. make && sudo make install
    11. nethogs
  5. Run netstat occasionally to see what ports are open.
    1. netstat -tnp
    2. netstat -tulpn
  6. Amazon’s AWS has firewalls built in around the machine when you create a VPS. You don’t need to set up these programs, but it’s a good thing to do.

Resources

https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps

https://apps.ubuntu.com/cat/applications/fail2ban/

https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-14-04

https://dodwell.us/security/ufw-fail2ban-portscan/

http://antirez.com/news/96

 

Posted in Tip

Getting a C# Server Working with Dokku and Vagrant

Developing a self-hosted web server in C# to run on Linux is like solo climbing a mountain: not a lot of people will be accompanying you; and the route will be unmarked, unmaintained, and often dangerous. In the digital world, there are two groups of programmers: people who use Node.js, Java, Ruby, etc. hosted on Linux; and people who use C# hosted on Windows. Building a C# server to run on Linux isn’t usually done because there is a perception that Mono is buggy. Most of those arguments are from experiences over 5 years ago, and Mono has come a long way. Of course, there is always room for improvement.

In particular, if you are a developer that wants to create services without focusing on all the crap associated with deployment, then Dokku is the way to go. I definitely prefer a command-line deployment rather than working with IDEs and browsers. Dokku, modeled after Heroku, is a PAAS model whereby the deployment of the server is simply a “git push.”  Unfortunately, the problem with Dokku and C# programming is that the easy “git push” deployment is offset by the difficulty in setting up the environment.

With that in mind, my goal was:

Prerequisites

Dokku requires you to work with SSH (both client and server), so you need to understand SSH very well. It is likely you have to understand how to configure your DHCP router, as I could not get Vagrant to send the DHCP router the name of the virtual machine. Also, if you aren’t familiar with Heroku, you might like to give that a spin with the Java example in order to understand some of the concepts.

Method

  1. Create a vanilla Ubuntu virtual machine, 20 GB disk space, 2048 memory, user “ubuntu”.
    1. Download the latest Ubuntu release from http://www.ubuntu.com.
    2. Start Virtualbox, and create a new virtual machine with a unique virtual_box_name running Ubuntu.
    3. Note: use the 64-bit “desktop” version of the OS. Make sure you have enough disk space for the large ISO file. You will also need at least 10GB of free disk space for the virtual machine itself.
    4. Install Ubuntu. Add user, e.g., “ubuntu”. Note: The Dokku installation scripts create user “dokku”. In order to login, you will want another account other than dokku.
    5. Restart the virtual machine.
    6. Install the VirtualBox Guest Additions.
    7. Restart the virtual machine.
    8. Start a terminal command-line interface in the virtual machine.
    9. sudo apt-get install openssh-server
    10. sudo visudo
      1. Add user ALL=(ALL) NOPASSWD: ALL to the file. This updates user with superuser rights so you don’t have to give a password for every sudo command.
    11. Shutdown the virtual machine.
  2. Create a Vagrant package of the vanilla Ubuntu virtual machine.
    vagrant box remove my-box
    vagrant init my-box
    vagrant package --base <em>virtual_box_name</em>
    vagrant box add my-box package.box
  3. Start the Vagrant virtual machine.
    1. Get a copy of my ‘kukku’ vagrant setup files at https://ken_domino@bitbucket.org/ken_domino/kukku.git
    2. cd kukku
    3. In the Vagrantfile, note the lines for setting up the user id and password for signing into the virtual machine, etc. Make sure they are in agreement with the names you gave in setting up the virtual machine.
      # -*- mode: ruby -*-
      # vi: set ft=ruby :
      # encoding: UTF-8
      
      BOX_NAME = ENV["BOX_NAME"] || "my-box"
      DOKKU_DOMAIN = ENV["DOKKU_DOMAIN"] || "kukku.home"
      # DOKKU_IP = ENV["DOKKU_IP"] || "10.0.0.2"
      PUBLIC_KEY_PATH = "#{Dir.home}/.ssh/id_rsa.pub"
      
      Vagrant.configure(2) do |config|
      
        # Set the name of the vagrant image file.
        config.vm.box = BOX_NAME
      
        # Display the Virtualbox GUI.
        config.vm.provider "virtualbox" do |v|
          v.gui = true
        end
      
        # Declare the name of the VM folder.
        config.vm.provider "virtualbox" do |v|
          v.name = "kukku-fun"
        end
      
        # Set the network to use bridge adapter, with a static IP, and known MAC.
        # My router does not handle the name of the guest correctly, so this bypasses
        # the problem by fixing it all. Note, in the router, I create an entry for
        # "whack" because the name isn't being broadcasted from the guest to the router.
        config.vm.network "public_network", ip: "192.168.1.33", :mac => "080027EA2F24"
        
        # Tell Vagrant to not muck around with the .ssh/authorized_hosts file.
        # It should not exist, or if it does, it should be empty. This is make sure
        # Dokku ssh works.
        config.ssh.insert_key = false
        config.ssh.private_key_path = File.expand_path("../.ssh/vagrant", __FILE__)
      
        # Define user id and password for login.
        config.ssh.username = "ubuntu"
        config.ssh.password = "ubuntu"
        
        # Provision the box with Dokku.
        config.vm.provision "shell", inline: >>-SHELL
      
          wget https://raw.githubusercontent.com/dokku/dokku/v0.4.14/bootstrap.sh
          sudo DOKKU_TAG=v0.4.14 bash bootstrap.sh
      
        SHELL
      end
    4. vagrant up
  4. Set up Dokku, and run the C# server.
    1. In the virtual machine…open a browser, and enter the address “localhost/”. It should be the Dokku set up screen.
    2. In the setup screen, enter the contents of your ~/.ssh/id_rsa.pub file, and set the name of the box to ‘whack’ or what ever machine you set for the machine. Click the button to set up Dokku.
    3. In the host machine…
      1. Verify that you see the help screen for Dokku via ‘ssh dokku@whack’. Otherwise, the ~dokku/.ssh/authorized_keys file on the virtual machine has the wrong entry. Edit that file, or type cat ~/.ssh/id_rsa.pub | ssh dokku@whack "sudo sshcommand acl-add dokku foobar"
      2. ssh dokku@whack apps:create fun
      3. ssh dokku@whack config:set fun BUILDPACK_URL=https://github.com/AdamBurgess/heroku-buildpack-mono
        1. Note: Adam Burgess’ C# buildpack is the only buildpack that seems to work. There are at least 4 others which I tried and don’t work. This buildpack uses xbuild for the build process.
      4. Get a copy of my “Hello World!” https://ken_domino@bitbucket.org/ken_domino/hn.git
        1. Note, you can substitute your program, but it should be an http server, and it must access the environmental variable PORT for the port to open. Dokku monitors that port to verify that the program is operating.
      5. cd hn
      6. git remote add foo dokku@whack:fun
      7. git push foo master
      8. Note: you should see output like the following.
        <code>Ken@Win8-GAZ77X /cygdrive/c/Users/Ken/Documents/hn
        $ git push foo master
        Counting objects: 32, done.
        Delta compression using up to 4 threads.
        Compressing objects: 100% (25/25), done.
        Writing objects: 100% (32/32), 916.64 KiB | 0 bytes/s, done.
        Total 32 (delta 3), reused 0 (delta 0)
        -----> Cleaning up...
        -----> Building fun from herokuish...
        -----> Adding BUILD_ENV to build environment...
        -----> Fetching custom buildpack
        -----> .NET app detected
        -----> Installing mono version 636c0c95cc78-minimal
        -----> Downloading https://github.com/AdamBurgess/heroku-buildpack-mono/releases/download/636c0c95cc78/mono-minimal.tar.xz
        -----> Installing SSL certificates
        -----> Installing NuGet packages
               Installing 'Nancy.Hosting.Self 1.4.1'.
               Installing 'Nancy 1.4.3'.
               Successfully installed 'Nancy.Hosting.Self 1.4.1'.
               Successfully installed 'Nancy 1.4.3'.
        -----> Compiling .NET application
               XBuild Engine Version 14.0
               Mono, Version 4.3.3.0
               Copyright (C) 2005-2013 Various Mono authors
        
               Build started 03/04/2016 19:07:53.
               __________________________________________________
               Project "/tmp/build/hn.sln" (default target(s)):
               Target ValidateSolutionConfiguration:
               Building solution configuration "Release|Any CPU".
               Target Build:
               Project "/tmp/build/hn.csproj" (default target(s)):
               Target PrepareForBuild:
               Configuration: Release Platform: AnyCPU
               Created directory "obj/Release/"
               Target CopyFilesMarkedCopyLocal:
               Copying file from '/tmp/build/packages/Nancy.1.4.3/lib/net40/Nancy.dll' to '/tmp/build/Nancy.dll'
               Copying file from '/tmp/build/packages/Nancy.Hosting.Self.1.4.1/lib/net40/Nancy.Hosting.Self.dll' to '/tmp/build/Nancy.Hosting.Self.dll'
               Target GenerateSatelliteAssemblies:
               No input files were specified for target GenerateSatelliteAssemblies, skipping.
               Target CoreCompile:
               Tool /tmp/build/mono/lib/mono/4.5/mcs.exe execution started with arguments: /noconfig /debug:pdbonly /optimize+ /out:obj/Release/hn.exe Program.cs Properties/AssemblyInfo.cs obj/Release/.NETFramework,Version=v4.5.AssemblyAttribute.cs /target:exe /define:TRACE /nostdlib /platform:AnyCPU /reference:packages/Nancy.1.4.3/lib/net40/Nancy.dll /reference:packages/Nancy.Hosting.Self.1.4.1/lib/net40/Nancy.Hosting.Self.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Xml.Linq.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Data.DataSetExtensions.dll /reference:/tmp/build/mono/lib/mono/4.5-api/Microsoft.CSharp.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Data.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Net.Http.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Xml.dll /reference:/tmp/build/mono/lib/mono/4.5-api/System.Core.dll /reference:/tmp/build/mono/lib/mono/4.5-api/mscorlib.dll /warn:4
               Program.cs(41,17): warning CS0162: Unreachable code detected
               Target _CopyAppConfigFile:
               Copying file from '/tmp/build/App.config' to '/tmp/build/hn.exe.config'
               Target DeployOutputFiles:
               Copying file from '/tmp/build/obj/Release/hn.exe.mdb' to '/tmp/build/hn.exe.mdb'
               Copying file from '/tmp/build/obj/Release/hn.exe' to '/tmp/build/hn.exe
               Done building project "/tmp/build/hn.csproj".
               Done building project "/tmp/build/hn.sln".
        
               Build succeeded.
        
               Warnings:
        
               /tmp/build/hn.sln (default targets) ->
               (Build target) ->
               /tmp/build/hn.csproj (default targets) ->
               /tmp/build/mono/lib/mono/xbuild/14.0/bin/Microsoft.CSharp.targets (CoreCompile target) ->
        
               Program.cs(41,17): warning CS0162: Unreachable code detected
        
               1 Warning(s)
               0 Error(s)
        
               Time Elapsed 00:00:00.4912070
        -----> Discovering process types
               Procfile declares types -> web
        -----> Releasing fun (dokku/fun:latest)...
        -----> Deploying fun (dokku/fun:latest)...
        -----> DOKKU_SCALE file not found in app image. Generating one based on Procfile...
        -----> New DOKKU_SCALE file generated
        =====> web=1
        -----> Running pre-flight checks
               For more efficient zero downtime deployments, create a file CHECKS.
               See http://dokku.viewdocs.io/dokku/checks-examples.md for examples
               CHECKS file not found in container: Running simple container check...
        -----> Waiting for 10 seconds ...
        -----> Default container check successful!
        =====> fun container output:
               http://localhost:5000/
        =====> end fun container output
        -----> Running post-deploy
        =====> renaming container (d6dc5cffa4c9) nauseous_yonath to fun.web.1
        -----> Setting config vars
               DOKKU_NGINX_PORT: 80
        -----> Creating http nginx.conf
        -----> Running nginx-pre-reload
               Reloading nginx
        -----> Setting config vars
               DOKKU_APP_RESTORE: 1
        =====> Application deployed:
               http://dokku:32769 (container)
               http://dokku:80 (nginx)
        
        To dokku@dokku:fun
         * [new branch]      master -> master
        
        Ken@Win8-GAZ77X /cygdrive/c/Users/Ken/Documents/hn
        </code>
    4. In a browser, type ‘whack/’. You should see “Hello world!”.

    Further Information

     

    An Important Side Note

    Part of the motivation for me was to re-examine what is available in website hosting. Currently, I use GoDaddy.com . After years of enduring GoDaddy ads that employ sophomoric humor, themes of misogyny, homophobia, and animal cruelty take on another light when juxtaposed by the actions of the son of Republican GoDaddy founder. It’s particularly important for me because I started a non-profit called “Hikers and Climbers Against Domestic Violence,” which tries to bring attention to the violence some women endure. While GoDaddy does offer good services at a low price, perceptions matter, and I’m shopping around to see what are my best options.

Self-hosting a C# Nancy Server on Linux

Sinatra is a popular and wonderful web application framework that has spawned a number of copycat frameworks. You can write large websites or REST servers with it. While it is a framework only for Ruby, there are alternatives for other languages, Spark Java for Java, Lavarel for PHP, etc. For C#, Nancy is the choice, and you can avoid using ASP.NET if you’d like. This post shows how to set up a “Hello world!” Nancy project that will build and run on Ubuntu and Windows.

Prerequisites:

Method:

  1. In your Windows host machine, start Visual Studio.
  2. In Visual Studio:
    1. Create a new C# console application “hn” within the mapped directory for the virtual machine.
    2. Replace the contents of Program.cs with the following code:
      using System;
      using System.Collections.Generic;
      using Nancy;
      using Nancy.Hosting.Self;
      
      namespace hn
      {
          public class SampleModule : Nancy.NancyModule
          {
              public SampleModule()
              {
                  Get["/"] = _ => "Hello World!";
              }
          }
      
          class Program
          {
              static void Main(string[] args)
              {
                  var uri = new Uri("http://localhost:80");
                  List list_uri = new List();
                  list_uri.Add(uri);
      
                  HostConfiguration hostConfigs = new HostConfiguration()
                  {
                      UrlReservations = new UrlReservations() { CreateAutomatically = true }
                  };
      
                  using (NancyHost host = new NancyHost(new DefaultNancyBootstrapper(), hostConfigs, list_uri.ToArray()))
                  {
                      host.Start();
                      foreach (Uri u in list_uri)
                          Console.WriteLine(u);
                      Console.WriteLine("Press any [Enter] to close the host.");
                      Console.ReadLine();
                  }
              }
          }
      }
    3. In order for this to compile, you will need to add two packages using the Package Manager.
      1. Start the Package Manager in Visual Studio.
      2. At the prompt, type Install-Package Nancy and Install-Package Nancy.Hosting.Self.
    4. Compile and run.
    5. In a browser, type in “http://localhost/”.
      1. Verify that your browser displays “Hello world!”.
  3. In the virtual machine guest:
    1. Open a Terminal.
    2. cd <mapped-directory>/<project-directory>
      1. Make sure the directory is mapped and you see the new project.
    3. xbuild
    4. mono bin/Debug/<project-executable>
    5. In a browser, type in “http://localhost/”.
      1. Verify that your browser displays “Hello world!”.

 

dokku@kukku:/vagrant/hn$ ls
App.config  bin  hn.csproj  hn.sln  obj  packages  packages.config  Program.cs  Properties
dokku@kukku:/vagrant/hn$ xbuild /target:Clean
XBuild Engine Version 12.0
Mono, Version 4.2.2.0
Copyright (C) 2005-2013 Various Mono authors

Build started 2/24/2016 10:20:58 AM.
__________________________________________________
Project "/vagrant/hn/hn.sln" (Clean target(s)):
	Target ValidateSolutionConfiguration:
		Building solution configuration "Debug|Any CPU".
	Target Clean:
		Project "/vagrant/hn/hn.csproj" (Clean target(s)):
/vagrant/hn/hn.csproj:  warning : Project has unknown ToolsVersion '14.0'. Using the default tools version '4.0' instead.
			Target CoreClean:
				Deleting file '/vagrant/hn/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs'
				Deleting file '/vagrant/hn/obj/Debug/hn.exe'
				Deleting file '/vagrant/hn/obj/Debug/hn.exe.mdb'
				Deleting file '/vagrant/hn/obj/Debug/hn.csproj.FilesWrittenAbsolute.txt'
		Done building project "/vagrant/hn/hn.csproj".
Done building project "/vagrant/hn/hn.sln".

Build succeeded.

Warnings:

/vagrant/hn/hn.sln (Clean) ->
(Clean target) ->
/vagrant/hn/hn.csproj (Clean) ->

	/vagrant/hn/hn.csproj:  warning : Project has unknown ToolsVersion '14.0'. Using the default tools version '4.0' instead.

	 1 Warning(s)
	 0 Error(s)

Time Elapsed 00:00:00.5218600
dokku@kukku:/vagrant/hn$ xbuild
XBuild Engine Version 12.0
Mono, Version 4.2.2.0
Copyright (C) 2005-2013 Various Mono authors

Build started 2/24/2016 10:21:05 AM.
__________________________________________________
Project "/vagrant/hn/hn.sln" (default target(s)):
	Target ValidateSolutionConfiguration:
		Building solution configuration "Debug|Any CPU".
	Target Build:
		Project "/vagrant/hn/hn.csproj" (default target(s)):
/vagrant/hn/hn.csproj:  warning : Project has unknown ToolsVersion '14.0'. Using the default tools version '4.0' instead.
			Target PrepareForBuild:
				Configuration: Debug Platform: AnyCPU
			Target GenerateSatelliteAssemblies:
			No input files were specified for target GenerateSatelliteAssemblies, skipping.
			Target CoreCompile:
				Tool /usr/lib/mono/4.5/mcs.exe execution started with arguments: /noconfig /debug:full /debug+ /optimize- /out:obj/Debug/hn.exe Program.cs Properties/AssemblyInfo.cs obj/Debug/.NETFramework,Version=v4.5.AssemblyAttribute.cs /target:exe /define:"DEBUG;TRACE" /nostdlib /platform:AnyCPU /reference:packages/Nancy.1.4.3/lib/net40/Nancy.dll /reference:packages/Nancy.Hosting.Self.1.4.1/lib/net40/Nancy.Hosting.Self.dll /reference:/usr/lib/mono/4.5/System.dll /reference:/usr/lib/mono/4.5/System.Xml.Linq.dll /reference:/usr/lib/mono/4.5/System.Data.DataSetExtensions.dll /reference:/usr/lib/mono/4.5/Microsoft.CSharp.dll /reference:/usr/lib/mono/4.5/System.Data.dll /reference:/usr/lib/mono/4.5/System.Net.Http.dll /reference:/usr/lib/mono/4.5/System.Xml.dll /reference:/usr/lib/mono/4.5/System.Core.dll /reference:/usr/lib/mono/4.5/mscorlib.dll /warn:4
			Target _CopyAppConfigFile:
			Skipping target "_CopyAppConfigFile" because its outputs are up-to-date.
			Target DeployOutputFiles:
				Copying file from '/vagrant/hn/obj/Debug/hn.exe.mdb' to '/vagrant/hn/bin/Debug/hn.exe.mdb'
				Copying file from '/vagrant/hn/obj/Debug/hn.exe' to '/vagrant/hn/bin/Debug/hn.exe'
		Done building project "/vagrant/hn/hn.csproj".
Done building project "/vagrant/hn/hn.sln".

Build succeeded.

Warnings:

/vagrant/hn/hn.sln (default targets) ->
(Build target) ->
/vagrant/hn/hn.csproj (default targets) ->

	/vagrant/hn/hn.csproj:  warning : Project has unknown ToolsVersion '14.0'. Using the default tools version '4.0' instead.

	 1 Warning(s)
	 0 Error(s)

Time Elapsed 00:00:01.0865300
dokku@kukku:/vagrant/hn$ mono bin/Debug/hn.exe

Unhandled Exception:
System.Net.Sockets.SocketException: Access denied
  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end)  in :0 
  at System.Net.EndPointListener..ctor (System.Net.IPAddress addr, Int32 port, Boolean secure)  in :0 
  at System.Net.EndPointManager.GetEPListener (System.String host, Int32 port, System.Net.HttpListener listener, Boolean secure)  in :0 
  at System.Net.EndPointManager.AddPrefixInternal (System.String p, System.Net.HttpListener listener)  in :0 
  at System.Net.EndPointManager.AddListener (System.Net.HttpListener listener)  in :0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException: Access denied
  at System.Net.Sockets.Socket.Bind (System.Net.EndPoint local_end)  in :0 
  at System.Net.EndPointListener..ctor (System.Net.IPAddress addr, Int32 port, Boolean secure)  in :0 
  at System.Net.EndPointManager.GetEPListener (System.String host, Int32 port, System.Net.HttpListener listener, Boolean secure)  in :0 
  at System.Net.EndPointManager.AddPrefixInternal (System.String p, System.Net.HttpListener listener)  in :0 
  at System.Net.EndPointManager.AddListener (System.Net.HttpListener listener)  in :0 
dokku@kukku:/vagrant/hn$ sudo mono bin/Debug/hn.exe
http://localhost/
Press any [Enter] to close the host.

2016-02-24 (1)

 

Code for this example:

For more information: