Raspbian and TightVNC for Dummies

I’ve had some trouble setting up TightVNC on Raspbian, but after 2-3 fresh installs of the OS and a couple of hours of frustration, I finally managed to make TightVNC boot on startup.

Original Tutorial

This is the tutorial I followed: http://elinux.org/RPi_VNC_Server
Following is the modified version, which worked for me.

My Steps

Install TightVNC

$ sudo apt-get install tightvncserver

Set the login password:

$ sudo vncserver

Setup the autostart script:

$ sudo pcmanfm

When the file manager starts, go to /etc/init.d/ and create a new file called vncboot and paste the following content in the file and save:

#!/bin/sh
### BEGIN INIT INFO
# Provides: vncboot
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start VNC Server at boot time
# Description: Start VNC Server at boot time.
### END INIT INFO
 
USER=root
HOME=/root

export USER HOME

case "$1" in
 start)
   echo "Starting VNC Server"
   #Insert your favoured settings for a VNC session
   sudo /usr/bin/vncserver :1
   ;;

 stop)
   echo "Stopping VNC Server"
   sudo /usr/bin/vncserver -kill :1
   ;;

 *)
   echo "Usage: /etc/init.d/vncboot {start|stop}"
   exit 1
   ;;
esac

exit 0

Set execute permissions for the startup script:

$ sudo chmod 755 /etc/init.d/vncboot

Make the script run on startup:

$ sudo update-rc.d /etc/init.d/vncboot

If the previous command displays:

update-rc.d: error: unable to read/etc/init.d//etc/init.d/vncboot

then run:

$ sudo update-rc.d vncboot

You should see the following text when the command succeeds:

update-rc.d: using dependency based boot sequencing

Reboot and try to connect.

Advertisements

Raspberry Pi: Running NodeJS and MongoDB on Pi

Recently I got a Raspberry Pi B+ and I couldn’t wait to start playing with it. My first project was a server application, which runs on NodeJS and uses MongoDB for storing data. This post will guide you how to setup a Pi with Node and Mongo as in my case, this was not that straightforward.

Before you Begin

Note that just doing “apt-get install nodejs” will not work on the Raspberry as the package is not compiled for ARM. Even if the package installs, if you try and run “node -v”, you’ll get an error saying something about segmentation – in this case, you should delete all node-related files read on 🙂

Obtaining the Proper Binaries

NodeJS

Luckily I managed to find a proper NodeJS binary, which was compiled for ARM. You can find binaries for the different NodeJS versions on node-arm. I just grabbed the latest:

wget http://node-arm.herokuapp.com/node_latest_armhf.deb 
sudo dpkg -i node_latest_armhf.deb

After this, you can do

node -v

to make sure everything is OK. Easy 🙂

MongoDB

Getting MongoDB was a bit harder as there aren’t any (or at least I didn’t manage to find any) binaries for ARM uploaded. In this case, I had to build the binaries myself.

Use git to get Mongo’s source code from this GitHub repository, which is especially for ARM.

git clone https://github.com/skrabban/mongo-nonx86

To build the code, you will need the following dependencies:

sudo apt-get install scons build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-all-dev

Next, compile the code!

IMRPORTANT: The compilation process on the Raspberry Pi takes a couple of hours. I started the compilation before going to bed. Also if you have a Pi with less than 512MB of RAM, it might not be enough for the compilation.

cd mongo-nonx86
scons
sudo scons --prefix=/opt/mongo install

When these commands complete, you should have an installed MongoDB in the /opt/mongo directory.

NOTE: If you have trouble compiling the source, be sure to checkout the Building guidelines for the code. Also, I just got the latest version from the master branch, but if you need a nice and stable version with production quality, you might want to check the version branches (currently the latest version is v1.8).

Additional Info

These steps were taken from these two great blog posts:

  1. Raspberry Pi + NodeJS
  2. Install Mongodb in Raspberry Pi (here you can find additional information how to make MongoDB run at startup)

tinyXMLsort

tinyXMLsort is a small portable Windows application, which will sort your XML files. I developed it in my spare time as a helper tool for managing large quiantites of XML and .config files.

tinyXMLsort

Download

tinyXMLsort .zip Download

Features

Feel free to add feature requests in the comments section.

Version 1.0

  • Tabbed user interface
  • Alphabetical sorting of XML (ascending)
    • Can exclude XML elements
    • Can exclude XML element attributes
  • Key binding
    • Ctrl+N – New tab
    • Ctrl+O – Open document
    • Ctrl+S – Save document

Source Code

You can get the latest source code on GitHub.

GoPro Power Tools

From some time I’ve been wanting to try out Xamarin and Gtk# to create a cross-platform application. I recently found a very nice library on GitHub for communication with GoPro using the wireless connection.

GoPro offer a mobile application, which acts as a remote control for the camera, but there isn’t any desktop app, so I decided to build one myself. This was also a good chance for me to try out GitHub.

GoPro.Hero

You can find the original GoPro.Hero library here.

GoPro Power Tools

You can find my forked project here. It can be build using Xamarin or Visual Studio 2013 (you will need to have Xamarin installed).

The application is a Gtk# desktop application, which can be built for Windows, Linux and Mac. Currently I have only tested it on Windows.

GoPro Power Tools

Using the Power Tools

Currently you can get the source code and build the project yourself using Xamarin or Visual Studio 2013. I will soon upload an executable.

  1. Turn on your GoPro camera’s WiFi and connect your PC to it.
  2. Turn on the app and from the Connect menu select Connect.
  3. Start editing your camera’s settings.
  4. From the Connect menu select Disconnect to power off your camera.

Project Roadmap

Currently this is an initial/alpha/pre-release version of project, but I have a bunch of nice feature that I want to implement.

  • Importing and Exporting Profiles
    Assign settings and save them to a file for later importing to the camera. For example you can have settings profiles for action shoots, photos, etc.
  • Bulk Profile Import
    If you do a lot of filming and own a bunch of cameras, the bulk import will allow you to set the cameras to the same profile automatically. This feature will scan all WiFi networks in range, try to detect the ones that are from a GoPro and apply the settings to it.
  • Mobile Version
    Create a mobile version of the app with all the the great features mentioned above.

 

Continuous Deployment Setup for Umbraco

I am working on a project, which features a big website with a lot of people (developers, quality engineers, deployment engineers and content editors) working on it. The site has multiple environments, and each of the environments is distributed among several servers.

The pros of continuous integration for such a project is that with each check-in, the code gets pushed to all development servers. From there with a single click, the code goes to staging and afterwards production. If something is wrong with the code, you can rollback to a previous build again with a single click. The only con I can think of is that you will regularly have to cleanup old deployments, which start to take a lot of space after some time.

This post is intended to guide you how to setup your Umbraco for continuous integration and deployment.

Project Prerequisites

Your website is suitable for continuous integration if it has the following features:

  • A single large website project with lots of custom code, source control, nightly builds and tests.
  • Multiple environments – Development, Staging, Production, etc.
  • Relatively large team of developers, quality engineers, deployment engineers and content editors.

The Setup

The following setup is a bit expensive to achieve and requires a team working on it, but once done, it is extremely easy to push code around and do “magic” with one click. If you are going to work on the project for more than a couple of months or a year, it is worth the effort to setup proper deployment.

Source Setup

In your Visual Studio project, add only the Umbraco Core package and not the whole CMS. The project will also contain your custom code, views, scripts and styles. This way you can have you functionality published on top of a fresh Umbraco install with each deploy.

Deployment Tool

We are using Octopus Deploy and it does the job fairly well. Probably setting up the tool and the deployment scripts is the hardest task. The tool deploys the website to a new folder named after the build number and sets it as site root in IIS. For example:

- mysite
   - wwwroot
      - build1
      - build2

With this site structure, you are able to switch build versions very quickly without any downtime. On every deploy, the tool does the following steps to the new folder:

  1. Extract a fresh copy of Umbraco (a zip downloaded from Umbraco).
  2. Extract predefined Umbraco packages (a regular Umbraco plugin package, which is extracted by a custom tool we developed).
  3. Extract the custom code, views and assets, which are dropped by the build.
  4. Run the Umbraco permissions. For security reasons it is best that you use the default app pool account to runt the site, not NETWORK SERVICE. That is why you should be running the script on each deploy.
  5. Set the new folder as site root in IIS.

Distributed Servers

Umbraco has an article on distributed environments. For the continuous deployment scenario, the tool takes care of pushing the new site to each server so you don’t have to worry about setting up DFS on the whole site.

Following are the files that need to be moved out of the site root folder and handles by DFS:

  • Examine Indexes – rebuilding the indexes after each deploy is a costly operation and takes a lot of time.
  • Media, CSS and Scripts.

You can move out this folders by creating virtual directories in IIS. Example of a folder structure with “resources”:

- mysite
   - resources
      - Indexes
      - Media/CSS/Scripts 
   - wwwroot
      - build1
      - build2

Improving Umbraco’s Public Access

Umbraco’s Public Access is a great feature, but it is not very suitable in some cases.

For example if you are working on a site with multiple environments like Development, Staging and Production, you might find some obstacles:

  • The Public Access settings are stored in ~/App_Data/access.config and not in the database – this is a problem if your environments are distributed using DFS. In this case you need to make sure that DFS will copy the updated settings between the servers.
  • The protected pages are stored using their IDs – you might get ID mismatch between the Dev, Staging and Production installations.
  • Courier does not transfer the access.config out of the box (I haven’t tested this myself, but I checked in the community) and event if you manage to transfer it, it is very likely that you will have ID problems.

Public Access Alternative

Following is a sample access.config file:

<access>
  <page id="8930" loginPage="8472" noRightsPage="9054" simple="False">
    <group id="Administrator" />
  </page>
</access>

I’ve come up with a more flexible design of the XML contents:

<access>
  <page path="Site Root/Page1/Page2"
        loginPath="Site Root/Login"
        errorPath="Site Root/Unauthorized"
        groups="Administrator" />
</access>

Note that the path attributes represent the names of the nodes in the content tree. This way you won’t have to worry about IDs between the different environments and you can store this file in source control.

Parsing the access.xml

Following is the code to parse the XML on application startup. When the application has started, the code will check if App_Data contains the access.xml file. If it exists, it will parse the content and use the APIs that Public Access uses to protect the pages. In my case I only needed roles based protection, so I didn’t implement single user protection.

public class PublicAccessSetup: ApplicationEventHandler
{
    protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        var accessXmlFile = HttpContext.Current.Server.MapPath("~/App_Data/access.xml");
        if (System.IO.File.Exists(accessXmlFile))
        {
            // Clear the old access.config.
            System.IO.File.Delete(HttpContext.Current.Server.MapPath("~/App_Data/access.config"));

            var protectedPages = XDocument.Load(accessXmlFile).XPathSelectElements("/access/page");
            foreach (var protectedPage in protectedPages)
            {
                try
                {
                    var page = GetPageByUrl(protectedPage.Attribute("path").Value);
                    var loginPage = GetPageByUrl(protectedPage.Attribute("loginPath").Value);
                    var errorPage = GetPageByUrl(protectedPage.Attribute("errorPath").Value);
                    var groups = protectedPage.Attribute("groups").Value.Split(';');

                    Access.ProtectPage(false, page.Id, loginPage.Id, errorPage.Id);
                    foreach (var group in groups)
                    {
                        Access.AddMembershipRoleToDocument(page.Id, group);
                    }
                }
                catch
                {
                    // Log
                }
            }
        }
    }

    private static IContent GetPageByUrl(string url)
    {
        var pages = url.ToLower().Split('/');
        if (pages.Any())
        {
            var parent = ApplicationContext.Current.Services.ContentService
                .GetRootContent()
                .First(x => x.Name.ToLower() == pages.First());
            foreach (var page in pages.Skip(1))
            {
                parent = parent.Children().First(x => x.Name.ToLower() == page);
            }

            return parent;
        }

        return null;
    }
}

Custom Error Pages in Umbraco

When you develop an Umbraco website with custom controller you might need a way to specify custom error pages. For example a 404 or 500 page that can be easily displayed as an action result. In my case I have multiple site roots and each site has its own error pages:
Umbraco
– Site1
— Error Page
— Not Found Page
– Site2
— Error Page
— Not Found Page
— Unauthorized Page

The ErrorPage Document Type

Create a simple document type called ErrorPage with one number property called Error Code. The property will store the status code of the page whether it is 404, 500, etc.

The ErrorPage Template

We will define a Template Controller, which will be activated whenever an error page is loaded in the browser. The controller will set the status code to the response.

using System.Web.Mvc;
using Umbraco.Web;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;

namespace Web.Umbraco.Extensions.Controllers.DocumentTypeControllers
{
    public class ErrorPageController : RenderMvcController
    {
        public override ActionResult Index(RenderModel model)
        {
            Response.StatusCode = model.Content.GetPropertyValue<int>("errorCode");

            return base.Index(model);
        }
    }
}

Calling an ErrorPage from Code

In the following code snippet I have created a custom NotFoundPage action result, which can be returned from an action and will automatically discover the 404 page for the site. You can further extend this by making the NotFoundResult a generic result, which accepts an error code and retrieves the error page for this code.

using System.Linq;
using System.Web.Mvc;
using umbraco.cms.businesslogic.web;
using Umbraco.Web;

namespace Web.Umbraco.Extensions.Mvc.ActionResults
{
    public class NotFoundResult : HttpNotFoundResult
    {
        public override void ExecuteResult(ControllerContext context)
        {
            var domain = Domain.GetRootFromDomain(context.HttpContext.Request.Url.Host);
            var siteRoot = UmbracoContext.Current.Application.Services.ContentService.GetById(domain);

            // Discover the 404 page for the current site.
            var notFoundContent = UmbracoContext.Current.Application.Services.ContentService
                .GetDescendants(siteRoot)
                .FirstOrDefault(x =>
                    x.ContentType.Alias == "ErrorPage" &&
                    x.GetValue<int>("errorCode") == 404);

            var notFoundUrl = "/not-found"; // Have a default value for the url.
            if (notFoundContent != null)
            {
                var notFoundPublishedContent = UmbracoContext.Current.ContentCache.GetById(notFoundContent.Id);
                notFoundUrl = notFoundPublishedContent.Url;
            }

            context.HttpContext.Server.TransferRequest(notFoundUrl, true);
        }
    }
}