Skip to content

Installing and customizing Ubuntu

mwylde edited this page Sep 12, 2011 · 56 revisions

#Installing Ubuntu

Note: this guide is largely for historical interest only. Up-to-date information about setting up a roomtrol box is contained with the chef cookbooks.

If you encounter issues with this section, please check Debugging

Download Ubuntu Server 11.04 (x86_64): http://releases.ubuntu.com/natty/ubuntu-11.04-server-amd64.iso

Write it to your preferred media (CD/DVD/flash drive)

Install as normal, creating one user (name: "roomtrol", password: labuser password). Select no automatic updates when prompted. On the package selection screen, choose only OpenSSH and continue with install. When prompted, install grub2 to the unit's storage media. Remove the installation media and let the computer reboot.

#System Information File Every Roomtrol install that is on a flash drive MUST HAVE a sysinfo.txt file in the home directory of the roomtrol user. touch ~/sysinfo.txt This file will contain information about the current setup of the roomtrol install on the flash drive. Using this method, if a flash drive is every disconnected and we are unable to remember what the current state of the roomtrol install is, we know we can always look in the ~/sysinfo.txt file.

After creating this file please add some information to it. Here is an example: File: sysinfo.txt Brief: A system information file describe what you are doing on this roomtrol isntall.

    Date: 29 April 2011
    20110429

    Name User Working on System: Evan Carmi

    Fresh Install of Ubuntu 11.04

#Customizing install

When the computer boots up, log into the account created earlier. Run

$ sudo apt-get update
$ sudo apt-get dist-upgrade

Install needed packages:

$ sudo apt-get install couchdb xorg xorg-dev libusb-dev build-essential \
      pkg-config xdg-utils libxslt1.1 rabbitmq-server git-core curl daemontools awesome libreadline6-dev avahi-daemon avahi-utils libavahi-compat-libdnssd-dev htop nginx

For graphics drivers, do nvidia-current or xorg-driver-fglrx for nvidia and ATI respectively.

###Install RVM (ruby version manager) Note: this blog article explains these steps somehwat: http://ryanbigg.com/2010/12/ubuntu-ruby-rvm-rails-and-you/

Ubuntu's ruby 1.9 packages seem pretty broken, so we're going to use the excellent ruby version manager instead. RVM is an awesome bundle of scripts that makes managing multiple ruby installs painless. Installing it is very easy; run the following as root:

bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Return to the roomtrol user. On the installer's advice, we also have to change our .bashrc file (~/.bashrc). Change

[ -z "$PS1" ] && return

near the top to

if [ -n "$PS1" ] ; then

and add an extra fi on its own line at the end.

It also seems we need to add the following at the bottom of the .bashrc file after the above added fi statement:

[[ -s "/usr/local/rvm/scripts/rvm" ]] && source "/usr/local/rvm/scripts/rvm"  # This loads RVM into a shell session.

To check that RVM is installed correctly type type rvm | head -n1 which should output rvm is a function. If you don't see this output you probably have a problem. Troubleshoot it!

First we need to install libopenssl-ruby:

$ sudo rvm package install openssl

This will take a while on our poor atoms, so find a good book. If you get any problems doing this (possibly on your development workstation that you want to deploy from) you may need to install the following packages: zlib1g-dev libssl-dev. When that's done, we need to actually install a ruby. We'll be using ruby 1.9.2, since that fixes a bunch of issues, particularly those related to performance, in earlier releases of the 1.9 branch. To do so, simply run

$ sudo rvm install 1.9.2 -C --with-openssl-dir=/usr/local/rvm/usr

and wait while rvm downloads and compiles it. This will also take a while. I hope that book is engrossing. In any case I had to do this like four times to get the OpenSSL thing right, so you're not in much of a position to complain.

Set a default rvm version so our bootup script can use the default

$ sudo rvm --default use 1.9.2

###Fix grub

Edit /etc/grub.d/00_header, locate the following lines:

make_timeout ()
{
     cat << EOF
if [ "\${recordfail}" = 1 ]; then
set timeout=-1
else
    set timeout=${2}
fi
EOF
}

Change it so it looks like the following:

make_timeout ()
{
     cat << EOF
#if [ "\${recordfail}" = 1 ]; then
#set timeout=-1
#else
    set timeout=${GRUB_TIMEOUT}
#fi
EOF
}

Then run sudo update-grub

###Add init files

Save the following as /etc/init/x.conf:

description     "X11"

start on (filesystem
          and started dbus
          and (graphics-device-added fb0 PRIMARY_DEVICE_FOR_DISPLAY=1
               or drm-device-added card0 PRIMARY_DEVICE_FOR_DISPLAY=1
               or stopped udevtrigger))
stop on runlevel [06]
respawn

script
    su - root -c "xinit /usr/lib/X11/xinit/xinitrc"
end script	

###Make DisplayLink devices work

To make DisplayLink devices (like the MIMO-720S/F we're currently using) work, we only need one additional package: the xorg displaylink driver.

We used to need udlfb, but starting Ubuntu 10.10 and continuing with 11.04, it is now included in the linux kernel and works out of the box.

Installing the displaylink driver easy, as it is in Natty's repositories.

sudo apt-get install xserver-xorg-video-displaylink

###Configurating Xorg

Copy the following to /etc/X11/xorg.conf, be mindful that the lines containing /dev/fb1 and /dev/input/event5 could change on a system-to-system basis. If they do change, look at /dev/input/by-id to see what is symlinked where:

Section "Files"
        ModulePath   "/usr/lib/xorg/modules"
        ModulePath   "/usr/local/lib/xorg/modules"
        FontPath     "/usr/share/fonts/X11/misc"
        FontPath     "/usr/share/fonts/X11/cyrillic"
        FontPath     "/usr/share/fonts/X11/100dpi/:unscaled"
        FontPath     "/usr/share/fonts/X11/75dpi/:unscaled"
        FontPath     "/usr/share/fonts/X11/Type1"
        FontPath     "/usr/share/fonts/X11/100dpi"
        FontPath     "/usr/share/fonts/X11/75dpi"
        FontPath     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
EndSection

Section "Module"
        Load  "glx"
EndSection

Section "InputDevice"
        Identifier  "Keyboard0"
        Driver      "kbd"
EndSection

Section "InputDevice"
        Identifier "dummy"
        Driver "void"
        Option "Device" "/dev/input/mice"
EndSection

Section "InputDevice"
        Identifier "touchscreen"
        Driver "evdev"
        Option "Device" "/dev/input/event5"
        Option "DeviceName" "touchscreen"
        Option "ReportingMode" "Raw"
        Option "SendCoreEvents" "On"
        Option "Calibrate" "1"
        Option "InvertX" "true"
        Option "InvertY" "true"
EndSection

Section "Device"
        Identifier      "DisplayLinkDevice"
        Driver          "displaylink"
        Option          "fbdev" "/dev/fb1"
EndSection

Section "Screen"
        Identifier      "screen0"
        Device          "DisplayLinkDevice"
        Monitor         "monitor0"
        SubSection "Display"
                Depth 24
                Modes "800x480"
        EndSubSection
EndSection

Section "Monitor"
        Identifier "monitor0"
EndSection

Section "ServerLayout"
        Identifier "Default Layout"
        Screen "screen0"
        InputDevice "touchscreen" "CorePointer"
        InputDevice "dummy"
EndSection

###(ANTIQUATED: Only necessary for iMo 7" Pivot touchscreens from our pilot systems) Fix touchscreen orientation

Edit /usr/share/hal/fdi/policy/20thirdparty/50-eGalax.fdi and add this line

<merge key="input.x11_options.swapx" type="string">1</merge>

Also change "longtouched_action" to "down" and "longtouchtimer" to 30.

###Install Chrome and it's dependancies

$ sudo apt-get install gconf2-common libasound2 libgconf2-4 libidl0 libnspr4-0d libnss3 libnss3-1d

liborbit2 libpython2.7 $ sudo wget http://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb $ sudo dpkg -i google-chrome-stable_current_amd64.deb

###Install awesome

awesome is a highly configurable tiling window manager written in Lua. It should have been installed through apt-get with the needed packages. If it isn't do:

$ sudo apt-get install awesome

The configuration file of awesome is stored in roots home directory: /root/.config/awesome/rc.lua file.

$ sudo mkdir -p /root/.config/awesome/

Create configuration file for awesome named rc.lua in this directory and add the following:

require("awful")
tags = {}
tags[1] = awful.tag({ 1 }, 1,  awful.layout.suit.max.fullscreen)
awful.util.spawn("xsetroot -cursor /usr/share/X11/empty_cursor.xbm /usr/share/X11/empty_cursor.xbm")

###Add the empty cursor bitmap

Download the file "empty_cursor.xbm" from github, and save it as /usr/share/X11/empty_cursor.xbm

###Configure X start up behavior

Save the following as /usr/lib/X11/xinit/xinitrc:

sed -i 's/"exited_cleanly": false/"exited_cleanly": true/' /root/.config/google-chrome/Default/Preferences
google-chrome --kiosk http://localhost/tp5 &
xsetroot -cursor /usr/share/X11/empty_cursor.xbm /usr/share/X11/empty_cursor.xbm
awesome -c /root/.config/awesome/rc.lua

You can now start X with sudo start x and you should see chrome running full-screen

###Install the fonts

Download the fonts.zip file from github and copy it to the computer. Extract to /usr/share/fonts. (Note: you probably need to apt-get install unzip to extract the files).

#Installing Roomtrol#

Installing and Updating Roomtrol with Heavenly

We assume you've followed the setting up heavenly guide.

To push a version of roomtrol to your staging server do: # Pushes develop branch to staging environment so for example you or your client can test it heavenly push branch develop to staging

# Pushes the master branch to production, which releases a new version of your application
heavenly push branch master to production

# Pushes version "1.5.2" (git tag 1.5.2) of your application to production
heavenly push tag 1.5.2 to production

The heavenly post hooks will run 'bundle install'. You need to manually

Add this as /usr/local/bin/bootup_roomtrol (note: brackets are missing; copy from source)

#!/usr/bin/env bash

export BUNDLE_GEMFILE=/var/roomtrol-daemon/roomtrol.staging/Gemfile

if [[ -s "/usr/local/rvm/environments/default" ]] ; then
  source "/usr/local/rvm/environments/default"
  exec /var/roomtrol-daemon/roomtrol.staging/bin/roomtrol "$@"
else
  echo "ERROR: Missing RVM environment file: '/usr/local/rvm/environments/default" >&2
  exit 1
fi

And make it executable with sudo chmod +x /usr/local/bin/bootup_roomtrol

And some point we might go ahead and automate this.

###Installing the daemon

Deployment of the daemon is now very much deployment of the web interface (described below). The basic idea is you run "rake deploy" from a copy of the roomtrol-daemon repository and it copies the newest code to all of the controllers defined in servers.json.

$ git clone [email protected]:mwylde/roomtrol-daemon.git
$ cd roomtrol-daemon
$ git submodule init
$ git submodule update
$ rake deploy

If you get an error, you probably mis-typed the password. Try again.

###Create a bootup script

Add this as /usr/local/bin/bootup_roomtrol (note: brackets are missing; copy from source)

#!/usr/bin/env bash

export BUNDLE_GEMFILE=/var/roomtrol-daemon/Gemfile

if [[ -s "/usr/local/rvm/environments/ruby-1.9.2-p0" ]] ; then
  source "/usr/local/rvm/environments/ruby-1.9.2-p0"
  exec /var/roomtrol-daemon/bin/roomtrol "$@"
else
  echo "ERROR: Missing RVM environment file: '/usr/local/rvm/environments/ruby-1.9.2-p0'" >&2
  exit 1
fi

And make it executable with sudo chmod +x /usr/local/bin/bootup_roomtrol

###Set the daemon to run automatically

Create /etc/init/roomtrol-daemon.conf with the following:

description "Roomtrol daemon script"

respawn

start on (started rc-sysinit)
stop on runlevel [06]

exec bootup_roomtrol

###Set up CouchDB

CouchDB will be installed through apt-get, but you need to start it. This can be done through it's init.d script

$ sudo /etc/init.d/couchdb start

This should start CouchDB, but let's check anyways:

roomtrol@roomtrol-fisk412:~$ curl localhost:5984
{"couchdb":"Welcome","version":"0.10.0"}

If we see the Welcome JSON string then it's running. We need to create a database and and a document. This can be easily done through a GUI. It may possibly be done even more easily through the command line.

Setup Database

First, to easily access the database from another computer we make it completely unsecured. To do this you need to establish a ssh tunnel from you dev workstation to the device (for allb004 we do):

ssh -ND 8000 [email protected]

Now, set your browser to proxy through localhost:8000. By default, browsers don't ignore proxy settings for localhost, delete these ignored settings and then go to http://129.133.127.4:5984/_utils/config.html and under the httpd section change bind_address from 127.0.0.1 to 0.0.0.0. Now you can access the database without the proxy from any computer simply via http://roomtrol-allb004.class.wesleyan.edu:5984/_utils/

###Set up IR transceiver

Add the IguanaWorks source to apt by editing creating a new file called "iguanaworks.list" in /etc/apt/sources.list.d/
Add the following:

# IguanWorks repo:
    deb http://iguanaworks.net/downloads/debian binary-amd64/

And run

$ sudo apt-get update
$ sudo apt-get install iguanair

Select none, none when asked. Plug in the IR transceiver and do

$ sudo /etc/init.d/iguanaIR restart

Now we need to compile our own version of lirc, with support for iguanaIR.

$ mkdir ~/lirc
$ cd ~/lirc
$ sudo apt-get build-dep lirc
$ sudo apt-get -b source lirc
$ sudo dpkg -i lirc_0.8.7~pre3-0ubuntu1_amd64.deb

Now, we want to 'pin' this package at it's current version, otherwise Ubuntu will try to upgrade it to the official package in the repo:

$ sudo -s        
$ echo lirc hold | dpkg --set-selections

Now, create or download an lircd.conf file, and put it in /etc/lirc/lircd.conf. Remove the init scripts that come with lirc by doing sudo update-rc.d -f lirc remove, and replace them with an upstart script /etc/init/lirc.conf:

description "lircd"

start on (started iguanaIR)
stop on runlevel [06]
expect fork
respawn

pre-start script
	mkdir -p /var/run/lirc
end script

exec lircd -H iguanaIR -d /dev/iguanaIR/0

Do the same for iguanaIR: sudo update-rc.d -f iguanaIR remove and in /etc/init/iguanaIR.conf

description "iguanaIR"

start on (filesystem and started dbus)
stop on runlevel [06]
expect fork
respawn

exec igdaemon

##Install touchscreen interface

The touchscreen interface is an HTML5 application which is served by nginx and runs in a full-screen chrome window.

###Set up nginx

Install

$ sudo apt-get install nginx

Create web directory and permission it appropriately

$ sudo mkdir /var/www
$ sudo chown -R roomtrol /var/www
$ sudo chgrp -R roomtrol /var/www

####Configure nginx

Replace /etc/nginx/sites-enabled/default with the following:

server {
	listen   80;
	server_name  localhost;

	access_log  /var/log/nginx/localhost.access.log;

	location / {
		root   /var/www;
		index  index.html index.htm;
	}

	location ^~ /rooms/ {
		proxy_pass   http://localhost:5984;
	}

	location ^~ /devices/ {
		proxy_pass   http://localhost:1412;
	}
}

Replace /etc/nginx/nginx.conf with the following:

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on;
}

http {
    include       /etc/nginx/mime.types;

    access_log  /var/log/nginx/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

###Deploy touchscreen code

Note: the following instructions should be followed on your local machine not the roomtrol controller. The instructions assume that you have a working ruby install on your machine. If not, I highly recommend RVM rather than using distro packages, because as noted above, distro packaged ruby is screwy.

The code for the touchscreen interface is in the wescontrol-server repository, because it is part of the same sproutcore "application" as the web interface (and they also share a lot of code). To deploy it, we're going to need to check out that repository:

$ git clone [email protected]:mwylde/roomtrol-server.git
$ cd roomtrol-server
$ git submodule init
$ git submodule update

Next we need to add the controller's address to the list of controllers in the servers.json file located in the roomtrol-server directory. servers.json should look like this:

{
	"servers": [
		"ozymandias.class.wesleyan.edu"
	],
	"controllers": [
		"wescontrol-509a.class.wesleyan.edu",
		"YOUR_CONTROLLERS_ADDRESS_HERE"
	]
}

This file needs to be valid json. If it's not, you'll likely get an error when you run the next commands. Now, navigate into your local roomtrol-server directory and run

$ gem install bundler     # install bundler
$ bundle install          # installs all the gems we need to build and deploy the sproutcore app
$ rake deploy_controllers # deploys the sproutcore app onto *ALL OF THE CONTROLLERS* 

Note that running the second command will redeploy the web interface onto every controller in the list in servers.json, as well as restart all of the X servers to display the new code. This might be jarring for users who are using it. I'll probably add a way to deploy to just a single controller before this becomes a problem, though.

#Don't Panic! Errors and Debugging

###Grub Errors - Grub fails to install

We experienced a grub install error while installing Ubuntu Server which seemed to be caused by a problem in the MBR. The fix was to completely erase all data in the MBR (first 512 bytes on disk) and restart the install process. The following dd command cleared the mbr. Other options include using sfdisk or fdisk to clear the mbr.

$ dd if=/dev/zero of=/dev/hda bs=512 count=1