Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

Saturday, March 29, 2014

Oh Ubuntu, won't you ever win?

After several months of idling in my basement. I decided to fire up the ol' Ubuntu desktop in order to use one of the few apps I have on that OS that I don't currently have an equivalent on Windows. After successfully using the intended software, Ubuntu's Update Manager helpfully notified me that I needed hundreds of critical and recommended updates to software packages. I am fine with that, and figured it wouldn't hurt to update since it had been some months and I expected to need to use Ubuntu again more regularly.

After downloading and installing all the updates, I needed a reboot. After doing so, my desktop wouldn't come up due to errors like this: Xorg says the kernel module is of version 304.88 (The old version before I updated) but the driver components are of version 319.32 (The new version).

This isn't the first time I've gone down that road, and it usually doesn't end well. I don't know why security fixes can bring down the GUI of my desktop. But oh well.

Thankfully, to Google and AskUbuntu, the answer is so simple it brought tears to my weary eyes.

Thanks to a Mr. "Joren" for the solution:
 
First remove all the old drivers:
sudo apt-get purge nvidia*
Then reinstall the current drivers:
sudo apt-get install nvidia-current
Reboot, and your're good to go!
sudo reboot 

Worked like a charm.
 

Source: http://askubuntu.com/questions/349129/12-04-lts-wont-boot-after-nvidia-driver-upgrade

 

Wednesday, December 19, 2012

Uninstalling Xubuntu from Ubuntu 12.04

I have been trying to learn to love Ubuntu 12.04 since my previous upgrade experience. It has been no easy task.

Among other things, my PC is not cutting edge, but even running Firefox was beginning to slow down to a crawl. I have not yet determined if this was due to some specific software or driver error, the Gnome 3/Unity interface, or other background tasks fault.

Getting desperate I have been looking around for lighter weight alternatives. I tried installing Xubuntu, which is supposed to be much more bare bones than the flashy Unity desktop.

I installed it
sudo apt-get install xubuntu-desktop

That was all fine and good. I restarted and went into the Xubuntu desktop. First of all, what I didn't realize, and my mistake for being ignorant, it kind of adds a lot of other software into your system, changes the boot screen, and generally is a bit more invasive that I liked. In the end, it was performing better, but due to some persistent graphics issues I have been having with Ubuntu I couldn't see the whole desktop after logging in. From what I could see of the desktop it looks a lot like the Linux experience I had in the mid-2000's on Red Hat or SuSE distros, pretty bare-bones, almost Windows 95-ish. Not saying it's awful, but I almost have to say I like Windows 7 more now. At least it was fast!

So, how to uninstall?

Well it's more difficult than it might seem. I have followed these excellently well-documented steps

Ubuntu 12.04 – How to Completely Uninstall/Remove a Package/Software/Program

The one comment I had, (which I could not post, apparently my email or website flags me as a spammer) is that GEdit 3 which come with Ubuntu 12.04 does not have the Regular Expression find and replace capabilities shown in those steps. You must additionally go and install a Gedit regex replace plugin to do so.

For now, I am using the Unity 2d interface. It looks almost the same for me, feels pretty quick. I'll stick with it. Not saying I would rule out a switch to Xubuntu or another desktop in the future if unity continues to be trouble.



Sunday, November 4, 2012

Things you shouldn't do: or how I upgraded to Ubuntu 12.04: Precise Pangolin

A pangolin
A Pangolin
So I just moved to a new house, and now that I actually have room for my stuff, I dusted off my old Ubuntu desktop for the fun of it and set it up on a desk in my new basement. It has been several months since I used it, so after booting I get prompted by Ubuntu's Update Manager program to install a million updates for things that I probably never used. Fine, maybe there are some security fixes or something. I click "Install Updates" and away, we go. Not too long later, I get some errors about the Bootloader being out of disk space. That sounds troubling. So I Googled for a while and found some advice about cleaning up old packages, and I did all that, removed a bunch of games and other programs I didn't need. That seemed to solve things. I ran update manager again, and finished the install. Everything seemed great.

There was just one more problem. Update Manager had a little tiny message above the normal dialog to select packages. It said something like "Upgrade to Ubuntu 12.04 LTS". So my desktop was on 10.04. I had actually recently tried out the new version of Ubuntu on a VM using their prepackaged all-in-one Windows installer "Wubi". I didn't like it, and found the performance was horrible on my Windows 7 laptop. Opening a folder a document would take 30 seconds and literally lock me out of doing anything else. I wasn't crazy about the new "Unity" style OS face lift they now package. But regardless of that experience, I am now a well trained animal, and when my computer's operating system tells me I should upgrade, and they make it so easy to accept it, newer is always better, always more security issues resolved, defects fixed, I mean why wouldn't I want to upgrade? So I couldn't help myself after a couple of days I went back and started the upgrade process.

It ran all night long. Not necessarily because it took that long, but because every so often in the upgrade process it would sit waiting for a user prompt, usually for some third-party software license exception. Finally at the end of the process I had a new looking default desktop background, everything seemed great with the upgrade. It asked me to reboot and...

Ubuntu 12.04 default desktop background with nothing else.
Approximation of the Ubuntu screen after upgrade
Then I couldn't log in anymore. Somehow they managed to make it so when I type my password for my normal super user account it just goes back to the same login screen. When I logged in as the guest user, it gave me a bunch of pop ups that I didn't have permission, but then loaded a totally blank screen with just the new Ubuntu background and my mouse cursor. I was trapped. "Linuuuuux!!" Since that point, I've been trying to recover this PC. I downloaded a new 12.04 Ubuntu Live CD to boot with. From that you get into the option to either Try Ubuntu out or Install Ubuntu. I wasn't prepared to reinstall and lose my data yet.

So first and foremost I was looking into similar related problems like screen resolutions not being detected. I found a few tips, for example editing /etc/X11/xorg.conf and manually specify the Screen subsection with your resolution modes. However, of course, in the Try out Ubuntu from the Live CD none of your hard disks partitions are mounted. Even worse, in my case, I couldn't directly mount my partition containing my existing OS and data (/dev/sda5) was of type lvm2, which of course, the default Ubuntu doesn't have the packages for it. Somebody has gone through something similar and I was able to do those steps in the Live CD Ubuntu, the only difference is that I would mount the partitions as rw:

sudo mount /dev/VolGroup00/LogVol00 /mnt/fcroot -o rw,user ...
So that was half the battle. But once I had done that, I tried the edit to xorg.conf. I saved the file and rebooted. Still got the same "Not optimum mode" message on my monitor. I tried a few settings, but no luck. I decided to try a more radical solution: A reinstall using thie Live CD without overwriting my existing partitions and data. Unfortunately. Due to having the "lvm2" partition that contained my logical volumes from my existing install the installer doesn't recognize these are a partition! So I had to go into the Try Ubuntu option first, and then follow all the steps described above to install lvm2 and activate my Logical Group in the lvm2 partition, then try the install.

I went through the entire install and ended up with a error that it was unable to install the Bootloader! Great! I went through an exercise to resize partitions thinking that might be the cause see:
lvm-resizing-guide ,linux-lvm-resizing-partitions (note Ubuntu 12.04 ships with GParted v0.11 which doesn't support the lvm2 file system format!, so in my Live CD OS I had to uninstall that and manually install the 0.14 version.). However after all that, I ended up using these steps to successfully manually install the Grub boot loader and use the Boot Repair program. After all this work I ended up with the same result as my upgrade, I was unable to see anything when I logged in as a guest (didn't recognize my actual admin user and password).

At this point after struggling with it for two days, I've decided to just do a reinstall. I don't know who or what installed the LVM partition, or where the boot loader should go. So I just went with a straight up new install of Ubuntu 12.04 LTS Desktop edition over my existing PC and I told it to reformat my HDD


After reinstalling clean. I had still got the Not Optimum Mode from my monitor during boot up. But from the login screen onwards everything looked ok. I did start getting new errors from Ubuntu telling me that jockey-gtk had crashed. Always helpfully I did a good search and located a few similar bug reports on the ubuntu forums. Seems to be an Nvidia driver issue. So I did an
apt-get update and
apt-get upgrade
to make sure I had all the latest packages. Then run sudo jockey-gtk, this prompts me to install Additional Drivers, I selected (version current)[Recommended], it installed the Nvidia driver, but didn't solve the problem in the boot screen and then I get a "The application Compiz has closed unexpectedly." error and a really messed up garbled background instead of the desktop, looking at the error details, it said that I had "obsolete packages" and that I should update "unity, libunity-core-5.05, unity-common and unity-services". So I rebooted this time into "Unity 2D" and did the update manager  which had a ton of updates (funny, why didn't apt-get upgrade install these before?)

Even after all this, I was still getting weird Not optimum messages on my monitor on shut downs and start ups. Seems that I was hitting some flavor of this problem. What worked for me. Use your own judgement was to first edit the /etc/default/grub config file

sudo gedit /etc/default/grub

Change GRUB_CMDLINE_LINUX_DEFAULT="splash" (removed quiet).
Some answers for related questions tell you to set nomodeset. I tried this but had negative results...

Uncomment and change GRUB_GFXMODE=1280x1024
Default was something like 640x480, the 1280 resolution was the "optimum" resolution displayed by monitor in the error messages I was getting in start up.

Next update grub
sudo update-grub

I think followed steps in the above linked question's answer for the purple start up screen to force the graphics drivers to be loaded in start up by configuring
/etc/initramfs-tools/conf.d/splash.

Lastly, the other quirk which apparently is benign? Was that in the System Settings > Details it was reporting an "Unknown" graphics driver. This is apparently due to a missing library(?) mesa-utils that is needed for displaying the graphics driver information:
http://askubuntu.com/questions/151608/details-window-showing-unknown-driver-for-graphics
So following the steps:
sudo apt-get install mesa-utils

Solved that issue. A few reboots later and the splash screen came up and the login works fine on my brand new re-installed Ubuntu 12.04. Gotta love "Linux for Human Beings".

Edit: Courtesy of this Google+ post when #Linux briefly trended
Linux...

Sunday, August 14, 2011

libSDL Project

For the last few weekends I have given PunchClock and my java work a break, to get back to the fun stuff in C. I am trying to learn the open source Simple DirectMedia Layer (libSDL) api for 2d graphics.

My first simple project was to draw a background and move an object around the foreground. Enter "Bouncy Rectangle".

This is a very simple program where you control the movements of the red square by using the keyboard arrows. Pressing in a direction will either speed you up or slow you down, when you hit one of the edges your speed will be translated into the opposite direction so you "bounce" like a pool ball.

I'd like to work further on separating the movement speeds from the "game loop" which will use 100% of whatever CPU you have if you let it, which would vary the speed from system to system.

The source code is all in one file, after installing libSDL (not so simple on Ubuntu) the program was developed in Eclipse CDT.

Full Source for reference:

/*
============================================================================
Name : BouncyRectangle.c
Author : ammianus
Version : 0.0.1
Copyright : Copyright Brian Laskey 2011
Description : Bouncy rectangle SDL example
Developed in Eclipse CDT, using SDL 1.3.0
============================================================================
*/

#include <stdio.h>
#include <sdl sdl.h="">

/* game loop states */
#define GAME_LOOP_RUNNING 1
#define GAME_LOOP_STOP 0

/* movement constant */
#define MAX_VELOCITY 20
#define VELOCITY_INCREMENT 10

/* pointer to the main window surface */
SDL_Surface *screen;

/*
* Draw the graphic to the coordinates specified on to the screen.
*
* (0,0) is the top left corner of the visible screen.
*
* \param graphic the pointer to a surface containing graphic
* to draw on screen
* \param x the x-coordinate on the screen surface
* of the top-left corner of the graphic to draw
* \param y the y-coordinate on the screen surface of the top-left corner
* of the graphic to draw
*/
void drawGraphic(SDL_Surface *graphic, const int x, const int y) {
/*initialize SDL_Rect struct to hold destination blitting data*/
SDL_Rect dst;

/*fill dst with relevant information*/
dst.x = x;
dst.y = y;
dst.w = graphic->w;
dst.h = graphic->h;

/*blit the graphic to the screen*/
SDL_BlitSurface(graphic, NULL, screen, &dst);
}

/*
* Check if the velocity plus the increment is under max velocity
*/
Uint8 checkVelocity(int velocity) {
Uint8 underMax;

if (velocity + VELOCITY_INCREMENT <= MAX_VELOCITY) { underMax = 1; } else { underMax = 0; } return underMax; } /* * Check if the velocity minus the increment is under absolute max velocity */ Uint8 checkNegativeVelocity(int velocity) { Uint8 underMax; if (abs(velocity - VELOCITY_INCREMENT) <= MAX_VELOCITY) { underMax = 1; } else { underMax = 0; } return underMax; } /* * Process the SDL Event queue * * \param running pointer to running flag for game loop (passed by reference) * \param velocity_y pointer to velocity_y incremented * or decremented by up or down (passed by reference) * \param velocity_x pointer to velocity_x incremented * or decremented by left or right (passed by reference) */ void processEvents(int *running, int *velocity_y, int *velocity_x) { /*e stores the event union which is fetched from the event queue*/ SDL_Event e; /*check the event queue*/ while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_KEYDOWN: if (e.key.keysym.sym == SDLK_ESCAPE) { *running = GAME_LOOP_STOP; } else if (e.key.keysym.sym == SDLK_DOWN) { /* increase or decrease current velocity */ if (checkVelocity(*velocity_y)) *velocity_y = *velocity_y + 10; } else if (e.key.keysym.sym == SDLK_UP) { if (checkNegativeVelocity(*velocity_y)) *velocity_y = *velocity_y - 10; } else if (e.key.keysym.sym == SDLK_LEFT) { if (checkNegativeVelocity(*velocity_x)) *velocity_x = *velocity_x - 10; } else if (e.key.keysym.sym == SDLK_RIGHT) { if (checkVelocity(*velocity_x)) *velocity_x = *velocity_x + 10; } break; case SDL_QUIT: *running = GAME_LOOP_STOP; break; } } fprintf(stdout, "velocity_x: %d, velocity_y: %d\n", *velocity_x, *velocity_y); } /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void quit(int rc) { SDL_Quit(); exit(rc); } /* * main: no arguments * * \return: * 0 success * 1 could not init SDL * 2 could not create the screen surface * 3 graphics error */ int main(void) { Uint8 video_bpp; Uint32 videoflags; int x_offset; int y_offset; int video_w, video_h; int velocity_x, velocity_y; /*declare pointer to reference the graphic * (done here for plain C compatibility)*/ SDL_Surface *background_graphic; SDL_Surface *bouncy_rectangle; int running; int fillRectRet; /* Initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return (EXIT_FAILURE); } video_bpp = 0; videoflags = SDL_HWSURFACE | SDL_DOUBLEBUF; video_w = 640; video_h = 480; puts("!!!SDL_INIT!!!"); screen = NULL; /*set a 640x480x32 double-buffered window*/ if ((screen = SDL_SetVideoMode(video_w, video_h, video_bpp, videoflags)) == NULL) { fprintf(stderr, "Couldn't set %dx%d %d video mode: %s\n", video_w, video_h, video_bpp, SDL_GetError()); quit(2); } /*Example: set up a fullscreen double-buffered hardware display * surface at 640x480x32*/ /*SDL_Surface *screen = * SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF);*/ /*load the background graphic from a file*/ background_graphic = NULL; background_graphic = SDL_LoadBMP("background1.bmp"); if (background_graphic != NULL) { puts("!!!SDL_LoadBMP!!!"); } else { fprintf(stderr, "my_graphic is NULL: %s\n", SDL_GetError()); quit(3); } /* create moving red rectangle on the surface */ bouncy_rectangle = NULL; bouncy_rectangle = SDL_CreateRGBSurface(0, 50, 50, 32, 0, 0, 0, 0); if (bouncy_rectangle != NULL) { fillRectRet = SDL_FillRect(bouncy_rectangle, NULL, SDL_MapRGB( screen->format, 255, 0, 0));
if (fillRectRet == 0) {
puts("Filled bouncy_rectangle");
} else {
fprintf(stderr, "SDL_FillRect error: %s\n", SDL_GetError());
}
} else {
fprintf(stderr, "bouncy_rectangle is NULL: %s\n", SDL_GetError());
quit(3);
}

/* initial values */
running = GAME_LOOP_RUNNING;
x_offset = 0;
y_offset = 0;
velocity_x = 0;
velocity_y = 0;
while (running) {
/*clear the screen*/
fillRectRet = SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,
0, 0));
if (fillRectRet == 0) {
puts("!!!Screen Cleared!!!");
} else {
fprintf(stderr, "SDL_FillRect error: %s\n", SDL_GetError());
}

/* calculate the boundary of bouncy_rectangle against edges of screen */
/* x-axis */
if ((x_offset + 50 + velocity_x > video_w) || (x_offset + velocity_x
< 0)) { velocity_x = velocity_x * -1; } x_offset = (x_offset + velocity_x); /* y-axis */ if ((y_offset + 50 + velocity_y > video_h) || (y_offset + velocity_y
< 0)) { velocity_y = velocity_y * -1; } y_offset = (y_offset + velocity_y); /*draw the background*/ drawGraphic(background_graphic, 0, 0); fprintf(stdout, "x %d, y %d\n", x_offset, y_offset); /* move the rectangle across the screen */ drawGraphic(bouncy_rectangle, x_offset, y_offset); puts("!!!Draw!!!"); /*update the screen*/ SDL_Flip(screen); puts("!!!Flip!!!"); /*check the event queue*/ processEvents(&running, &velocity_y, &velocity_x); /* pause the program so CPU doesn't go to 100% */ SDL_Delay(40); } /*deinitialize SDL*/ SDL_Quit(); puts("!!!SDL_Quit!!!"); return EXIT_SUCCESS; }


The build command I used was:

gcc -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -MMD -MP -MF"src/BouncyRectangle.d" -MT"src/BouncyRectangle.d" -o"src/BouncyRectangle.o" "../src/BouncyRectangle.c"


And the linking command was:

gcc -L/usr/local/lib -o"SB-Proto1" ./src/BouncyRectangle.o -lSDLmain -lSDL


References
Helpful sites that allowed me to get this far

Friday, July 22, 2011

On Configuring Automated Builds on an Amazon EC2 micro-instance using Jenkins, SVN and Apache

I am a big fan of the continuous integration approach with using tools and build scripts to automate the build process for programs. Combine this with comprehensive unit testing and static analysis provides some easy ways to improve the quality of code.

So I wanted to implement a continuous integration set up, partly as a way to improve my infrastructure around the PunchClock project, as well as a chance to explore some new technologies, especially Amazon Web Services.

What I settled on was to create a "build machine" using Jenkins CI, formerly Hudson, an open source program specifically for automating building software in a continuous integration environment. On the same server I would also host my Subversion repository (SVN), and being that it is an Amazon EC2 instance I have less worry of a possibility of a catastrophic loss of data from my current Ubuntu box at home. Both SVN and the Jenkins web application would sit behind an Apache2 Web Server. All of this would be on a Debian Linux distro running as an EC2 instance. (I chose to go with Debian purely to gain exposure to other distros besides Ubuntu). I learned a lot from this set up, the AWS/EC2 was actually more challenging than you would normally find from a hosted server, but their AWS Management Console allows you to do most operations pretty easily.


Prereqs
  1. Install Apache2 if not present
    On the default Debian install Apache is present, but on the Debian EC2 AMI I used it wasn't installed.
    apt-get install apache2
  2. Install Java 1.6 (update 25)
    You'll need to edit your /etc/apt/sources.list see http://jayraj87.blogspot.com/2010/02/installing-sun-java6-jdk-in-debian.html
  3. Install Ant 1.8.0
    • installs version 1.8.0 to /usr/bin/ant (/usr/share/ant)
      apt-get install ant
    • copy junit.jar to ANT_HOME\lib (junit 3.8.2 or later download here)
  4. Install SVN and Repository
  5. Before you begin I assume you have your own working ANT script that would compile, run JUnit tests, run any static analysis utilities (e.g. FindBugs or CheckStyle) and package your project into artifacts for distribution. The PunchClock application had an existing ANT build.xml that I started from.

Installation

All of these steps I honed on a default Debian install. I tested this on VMWare Player running the 6.0.1a "Squeeze" Debian install, from an iso file found on BitTorrent. Once I had got the steps down, basically the same applied to installing on the Debian instance on Amazon EC2 except for a few issues. All of these steps were performed as root unless otherwise noted.
  1. Install Jenkins LTS

    • wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
      • Add site to debian packages /etc/apt/sources.list: deb http://pkg.jenkins-ci.org/debian binary/
      apt-get update
      apt-get install jenkins

    • Installs at http://localhost:8080/ by default
    • Followed steps to configure Jenkins to run behind Apache  https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache
      • configuration is in /etc/default/jenkins
      • I changed default port from 8080 for added security
      • add HTTP_HOST=127.0.0.1 #only takes requests from apache2
      • append to JENKINS_ARGS="... --prefix=/jenkins httpListenAddress=$HTTP_HOST"
    • To restart after config changes:
      /etc/init.d/jenkins force-reload
    • Log file will be placed in /var/log/jenkins/jenkins.log. Check this file if you are troubleshooting Jenkins.

  2. Setting up apache for Jenkins
    Apache will be a reverse proxy to the Jenkins web application. We've already set up Jenkins to only accept requests from Apache (localhost), we will also add basic authentication. See also (https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu)
    • Create or copy this file called "jenkins" to /etc/apache2/sites-available
      <VirtualHost *:80>
      ServerAdmin your.email@yourorganization.com
      ServerName your.ip.here.goes.here
      ServerAlias debian-build
      ProxyRequests Off
      <Proxy *>
      Order deny,allow
      Allow from all
      </Proxy>
      ProxyPreserveHost on
      ProxyPass /jenkins http://localhost:8089/jenkins
      ProxyPassReverse /jenkins http://localhost:8089/jenkins
      <Location /jenkins/>
      AuthType basic
      AuthName "Jenkins"
      AuthUserFile "/etc/apache2/sites-available/jenkins.htpasswd"
      Require valid-user
      </Location>
    • Run the following commands to set up Apache for virtual hosts and create the site "/jenkins"
      a2enmod proxy
      a2enmod proxy_http
      a2enmod vhost_alias
      a2ensite jenkins
      apache2ctl restart

    • Note: apache logs under /var/log/apache/error.log
    • I am no apache security configuration expert, but following this article was useful for configuring basic authentication for now. https://wiki.jenkins-ci.org/display/JENKINS/Apache+frontend+for+security
      • E.g in my case it was something like this: htpasswd -cm /etc/apache2/sites-available/jenkins.htpasswd your-username
      • In my opinion security is often overlooked in small scale projects, other general, but useful Apache security tips: http://httpd.apache.org/docs/2.0/misc/security_tips.html
    • After all of this you should be able to access Jenkins with the specified username/password at a URL like
      • http://your.ip.here.goes.here/jenkins

  3. Install checkstyle
    For CheckStyle analysis of Java code (assuming you've already configured your project and build.xml to run CheckStyle during the build)
    • Download checkstyle-5.3-bin.tar.gz (at the time of this post 5.4 is available)
    • Copy to somewhere on the server e.g. /usr/share
    • Extract the tar
      $/usr/share# tar zxf check checkstyle-5.3-bin.tar.gz
    • Log in to Jenkins and navigate to Manage Jenkins > Configure System
      • Check "Environment Variables" under Global Properties
      • Add name = "CHECKSTYLE_HOME" value = "/usr/share/checkstyle-5.3"
  4. Install findbugs
    Similarly for FindBugs analysis of Java code. (* I couldn't actually get this to successfully run on the EC2 Micro instance, it appeared to make the server run out of memory and the Jenkins build process would crash.)
    • Download findbugs-1.3.9.tar.gz
    • Copy to somewhere on the server e.g. /usr/share
    • Extract the tar
      $/usr/share# tar zxf check findbugs-1.3.9.tar.gz
    • Log in to Jenkins and navigate to Manage Jenkins > Configure System
      • For "Environment Variables" under Global Properties
      • Add name = "FINDBUGS_HOME" value = "/usr/share/findbugs-1.3.9"
    • Copy the findbugs_ant.jar to ANT_HOME/lib
      • $/usr/share/findbugs-1.3.9/lib# cp findbugs-ant.jar /usr/share/ant/lib
  5. Manage Jenkins plugins for Static Analysis
    • Log in to and navigate to Jenkins > Manage > Available >
    • Check the following plugins
      • Static Analysis Utilities
      • Checkstyle Plug-in
      • FindBugs Plug-in
      • etc...
    • Jenkins may need to be restarted manually using /etc/init.d/jenkins force-reload

  6. Configure Jenkins project: PunchClock
    • Log in to Jenkins and click New Jobs from the left menu. Fill out the following form. The details will vary per your project and needs.
    • Job Name: PunchClock
    • Set repostitory to Subversion
      • URL: http://ip.of.my.svn.repo/svn/trunk/TimeTrack
      • Will fail, need to enter credentials
    • Add Build Step > Invoke Ant
    • Check publishing options
      • Publish Checkstyle analysis results
      • Publish FindBugs analysis results
      • Publish combined analysis results
      • Publish JUnit test result report
        • My Test Result XMLs use the pattern "TEST*.xml"
      • Archive the artifacts
        • This depends on what artifacts your build.xml creates, my PunchClock complete packages are zipped in the distributions folder of my work space so: Files to archive: "distributions/*.*"
    • Optional you can set an automated checkout strategy. Under Build Triggers I chose "Poll SCM"
      • For schedule I used "@hourly"

Amazon EC2 Configuration

This is a whole other technology, which deserves its own post. I'll touch on what I did find in the end. I was motivated to look into this, Amazon AWS recently began offering the ability to have a single "micro" sized instance hosted for free. This gets you among other things, a virtual machine with 620 MB of memory, a single "virtual cpu", about up to 10GB EBS storage space, the OS of your choice* and a certain monthly bandwidth. I haven't been on the service a month yet, so we'll see how I get billed.

*The idea with these instances is that they are virtual machines that you can start from a pre-packaged snapshot referred to as an AMI. Amazon provides some (of their own linux flavor) but most appear to be community created public images for different OS's. I found a lot of information around this whole topic, as well as really well done, standardized AMI's from http://alestic.com/, which focuses mostly on Ubuntu images. The EC2StartersGuide for Ubuntu is also a great starting resource, especially for managing and configuring your EC2 instances from a Ubuntu desktop. In my case with Debian, the ec2debian google group was also a good place to start.

Long story short, when you sign up for AWS and log in to the Management Console, go to "Instances" and click on Launch Instance, you can search for an select a starting AMI. I went wit this one from the ec2debian group

us-east-1
i386 EBS: ami-0ce41865
x86_64 EBS: ami-80e915e9
i386 8gb instance: ami-c041bda9
x86_64 8gb instance: ami-1cbc4375


The distinction between instance and EBS is that instance root volume apparently doesn't survive a stoppage of the VM, not sure the benefit of that other than to keep things clean? I went with the x86_64 EBS: ami-80e915e9 after a false start with the 32 bit version.

Note these all start out with a 1GB Root volume. Needs to be reized.

After booting up, and figuring out how to connect to the instance (only can use ssh, scp...be prepared to use vi!).

Some issues I hit:
Java 6 won't install on 32-bit "micro" instance
Originally I tried a 32 bit debian instance AMI. Hit this bug everytime I installed sun-java6-jdk: https://bugs.launchpad.net/ubuntu/+source/linux-ec2/+bug/634487 which basically caused the whole instance to hang due to 100% CPU usage from a runaway install process. The only fix was to use a 64-bit AMI.

Enlarging EBS Root Volume
After finally installing everything and pressing the final key-stroke to start Jenkins, I was severly disappointed to only get a 503: Service Unavailable error from Apache. The Jenkins log wasn't created even and the Apache logs just stated that it couldn't connect to the Jenkins site. After banging my head against the wall, I found a not enough disk space error in the /var/logs/daemon log. It turned out I maxed the 1GB initial volume size. Unfortunately EBS volumes can't just be "dialed up" like you can do with a VMWare Player VM. Some guidance can be found here on how to resize a root EBS volume:  http://alestic.com/2010/02/ec2-resize-running-ebs-root

Basically what I ended up doing using the AWS Management Console
  1. Create EBS snapshot
  2. Stop Instance
  3. Detach old volume
  4. create new volume from snapshot
  5. Attach new volume (as /dev/sda1...same as old volume!)
  6. Start Instance
  7. resize2fs /dev/xvda1 (Debian is tricky that it doesn't list the volume as /dev/sda1). It did an online resize in about 5 minutes and I was good to go.

Monday, November 8, 2010

GNU/Linux Application Programming book review

I completed the sections of GNU/Linux Application Programming (Programming Series) by M. Tim Jones which I have been learning from for the past three months or so.


I focused on Part I - Introduction, Part II - GNU Tools and Part III - Application Development Topics. I just skimmed through Part IV - GNU/Linux Shells and Scripting and Part V - Debugging, which I have a feeling I'll come back to.

I posted my review to Amazon which I'll reprint here:

I am an experienced software engineer but have not had much experience programming for Unix/Linux environment. I was also interested in a basic book to go into low-level C system APIs. This book provided a good introduction for me at a reasonable pace over a wide range of subjects. I focused on the C programming chapters, but there are additional chapters for things like source control, shell commands, awk, sed, Ruby, Python and debugging.

Book expects some familiarity or background with C programming language. While basic functions of the Standard C library are described, the language constructs and syntax of C are not referred to at all but are assumed familiar to the reader.

Other reviewers have mentioned that source code was available for free online so CD was not valuable. I have not found this to be the case, so in that respect the CD is useful.

Some negatives, in general code samples were often incomplete, with errors. Several of the chapters of the book contain content with mistakes or do not list all necessary prerequisites. For example, I tried to perform almost every code/script sample provided and ran into numerous issues or additional packages and tools to install that were never mentioned. Some code would execute on a 32-bit Linux system but not on a 64-bit system. Also I found the code samples provided on the CD to be lacking in completeness, for example a sample code for a Makefile example from chapter 6 did not include the source files the Make script was supposed to build. In the end it did encourage me to create my own "Hello World" type source files just to go through the same steps being described in the book. Other chapters included source but not Makefiles to compile the code, source files with no relation to the examples in the book and source files that did not compile. Generally such errors could be resolved with a few minutes of Internet research on the errors/warnings.


For my next act I'll start on Real-Time Systems and Programming Languages by Alan Burns and Andy Wellings.

Sunday, October 31, 2010

C Socket Server example, with semaphores, signal handling

This is a quick program that combines various examples from the GNU/Linux Application Programming book I have been studying.

The program is a BSD Socket based server (ch. 13), that accepts connections on a specific port and sends over TCP a "temperature" value, which at the moment I am simply randomly generating for example. I have added the use of counting semaphores (ch 17) to demonstrate a critical section of code as well as used POSIX signal handling (ch. 14) as a mechanism to cleanly exit. I developed this in Eclipse CDT IDE. I am not a C expert, this is my first C program since approx 2002 but it runs and compiles without warning!

Therm- ServerProject set up and dependencies
I created two static libraries for generating the random number/temperature reading. This are linked in my Eclipse project. For the purposes of this example you only need to know about these function prototypes (from thermapi.h)
/*
* Initialization for Therm API. Call before using any other function
*/
extern void initTherm( void );

/*
* Returns the current temperature reading from sensor
*/
extern float getTemp( void );

Other than this, I depend on various standard libraries in Linux for sockets, signal handling, etc..

thermserv.c - Includes and Defines.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

/* sockets and addresses */
#include <sys.h>
#include <arpa.h>
#include <netinet.h>
#include <netinet.h>
#include <netinet.h>
#include <netinet.h>
#include <netdb.h>

/* semaphores */
#include <sys.h>

/* signal handling */
#include <sys.h>
#include <sys.h>
#include <signal.h>

/* my own includes for custom functions */
#include <thermapi.h>
#include "thermserv.h"

/* magic number constants */
#define MAX_BUFFER 128
#define THERM_SERVER_PORT 6777
#define THERM_SEM_ID 6778

static int loopCounter = 1;

/* Exit handler function called by sigaction */
void exitHandler(int sig, siginfo_t *siginfo, void *ignore) {
printf("*** Got %d signal from %d\n", siginfo->si_signo, siginfo->si_pid);
loopCounter = 0;

return;
}


Print Server Info utility method just to clean up the main function a little. It still is too long.
/*
* Prints out basic server information for startup
*/
void printTServerInfo(struct sockaddr_in servaddr, int cliLen,
time_t startupTime) {

printf("*** Thermo Server initialized.\n");
printf("*** cliLen size: %d\n", cliLen);
printf("*** Server Listening as %s:%d\n", inet_ntoa(servaddr.sin_addr),
ntohs(servaddr.sin_port));
printf("*** Server PID: %d\n", getpid());
printf("*** Start up time: %s", ctime(&startupTime));

}

Note: I was getting warnings from gcc for this function.

../thermserv.c: In function ‘main’:
../thermserv.c:122: warning: implicit declaration of function ‘printTServerInfo’
../thermserv.c: At top level:
../thermserv.c:180: warning: conflicting types for ‘printTServerInfo’
../thermserv.c:122: note: previous implicit declaration of ‘printTServerInfo’ was here

To resolve these, I added thermserv.h:

#ifndef THERMSERV_H_
#define THERMSERV_H_

/*
* Prints out basic server information for startup
*/
void printTServerInfo(struct sockaddr_in servaddr,
int cliLen,
time_t startupTime);

#endif /* THERMSERV_H_ */

Warnings resolved!

back to the rest of thermserv.c:
main() - set up code

/* start main */
int main(void) {

/*
* TODO implement server as daemon, per best
* practices, Advanced Programming in Unix Environment (ch 13, p417)
*/

int serverFd, connectionFd;
struct sockaddr_in servaddr;
char tempBuffer[MAX_BUFFER + 1];
time_t currentTime;
time_t startupTime;
float fread;
socklen_t cliLen;
struct sockaddr_in cliaAddr;
int therm_sem_id;
struct sembuf semAcquireBuffer;
struct sembuf semReleaseBuffer;
struct sigaction act;

/*init socket*/
serverFd = socket(AF_INET, SOCK_STREAM, 0);

/* set up semaphore */
therm_sem_id = semget(THERM_SEM_ID, 1, 0666 | IPC_CREAT);
if (therm_sem_id >= 0) {
printf("*** Semaphore %d\n", therm_sem_id);
/* init semaphore count to 1 */
semctl(therm_sem_id, 0, SETVAL, 1);
} else {
printf("Could not create/get semaphore with errno: %d %s", errno,
strerror(errno));
exit(-1);
}

semAcquireBuffer.sem_flg = 0;
semAcquireBuffer.sem_op = -1;
semAcquireBuffer.sem_num = 0;

semReleaseBuffer.sem_flg = 0;
semReleaseBuffer.sem_op = 1;
semReleaseBuffer.sem_num = 0;

/* Set exit handler function for SIGUSR1 , SIGINT (ctrl+c) */
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = exitHandler;
sigaction(SIGUSR1, &act, 0);
sigaction(SIGINT, &act, 0);

/* Set socket server */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(THERM_SERVER_PORT);

bind(serverFd, (struct sockaddr *) &servaddr, sizeof(servaddr));

listen(serverFd, 5);

/* initialize thermometer api (required by rand api) */
initTherm();

/* get set up to capture client socket address */
cliLen = sizeof(struct sockaddr_in);
startupTime = time(NULL);
printTServerInfo(servaddr, cliLen, startupTime);



Now the block with all the hot action, an infinite while loop for the socket server to accept connections, get the current temperature value and then write to the socket. If a SIGUSR1 or SIGINT (ctrl+c) is received by the handlers the loop value loopCounter will be set to false and the while loop will end allowing for some clean up at the end to close the sockets, semaphores, etc...

/* infinite loop until SIGUSR1 or SIGINT is handled */
while (loopCounter) {

printf("Waiting for Client connection\n");
connectionFd = accept(serverFd, (struct sockaddr*) &cliaAddr, &cliLen);
/* valid connection to client accepted */
if (connectionFd >= 0) {

currentTime = time(NULL);
/*print client address info and time of connection*/
/* http://www.cs.odu.edu/~cs476/fall03/lectures/sockets.htm
*
* Note ctime() seems to build in trailing \n
* */
printf("Client Connected %s:%d at %s",
inet_ntoa(cliaAddr.sin_addr), ntohs(cliaAddr.sin_port),
ctime(&currentTime));

/*Begin Critical Section acquire Semaphore*/
if (semop(therm_sem_id, &semAcquireBuffer, 1) == -1) {
printf("Critical Section Begin failed semid: %d\n",
therm_sem_id);
} else {
printf("Critical Section Begin\n");
/*write current temp in F to connected socket*/
fread = getTemp();
snprintf(tempBuffer, MAX_BUFFER, "%f\n", fread);

/*End Critical Section Release Semaphore*/
if (semop(therm_sem_id, &semReleaseBuffer, 1) == -1) {
printf("Critical Section End failed semid: %d\n",
therm_sem_id);
}
printf("Critical Section End\n");
}
/*write string tempBuffer to connected socket, close connection*/
write(connectionFd, tempBuffer, strlen(tempBuffer));
close(connectionFd);

}

}


The clean up code is reached by the signal handler function changing the loopCounter to allow the while loop to end. Other signals could cause the process to exit, I am not sure what that really means for the still open socket, and more importantly the semaphore. Might there be a better facility in C to handle this case?

/* clean up socket, semaphore before process exits*/
/* TODO better way to do this? ie Java finally{}?*/
printf("Shutting down server\n");
close(serverFd);
semctl(therm_sem_id, 0, IPC_RMID);

return 0;

}


Building therm-server

Invoking: GCC C Compiler - note libtherm and libexp are my custom static libraries
gcc -I"/home/ammianus/workspace/libtherm" -I"/home/ammianus/workspace/libexp" -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -MMD -MP -MF"thermserv.d" -MT"thermserv.d" -o"thermserv.o" "../thermserv.c

Invoking: GCC C Linker
gcc -static -L"/home/ammianus/workspace/libtherm/Debug" -L"/home/ammianus/workspace/libexp/Debug" -o"therm-server" ./thermserv.o -ltherm -lexp

Running therm-server
For the fun part. Open a terminal and navigate to /home/ammianus/workspace/libtherm/Debug
./therm-serv
This launches the server, it acquires the semaphore and inits the socket listening on port 6777

*** Semaphore 131075
*** Thermo Server initialized.
*** cliLen size: 16
*** Server Listening as 0.0.0.0:6777
*** Server PID: 4790
*** Start up time: Sun Oct 31 12:27:11 2010
Waiting for Client connection



To connect to the socket with a client, use telnet or a web browser and connect to 0.0.0.0:6777

ammianus@Hadrian:~$ telnet 0.0.0.0 6777
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.
72.720497
Connection closed by foreign host.

Getting 72.720497 is the "temperature" that was our goal from the start!

On the server side it logged this connection attempt:
Waiting for Client connection
Client Connected 127.0.0.1:57090 at Sun Oct 31 12:30:17 2010
Critical Section Begin
Critical Section End
Waiting for Client connection

Etc..

The server will continue to run and accept connections, (try connecting with a browser and holding down 'F5').

To shutdown the server, you can send a signal to its PID
ammianus@Hadrian:~$ kill -s SIGUSR1 4790
And server handles this signal gracefully
*** Got 10 signal from 4794
Shutting down server


References
http://www.suite101.com/content/c-header-files-a2936
http://stackoverflow.com/questions/2406986/c-warning-implicit-declaration-of-function-exit
http://stackoverflow.com/questions/4009090/what-is-correct-way-to-have-single-signal-handler-function-for-multiple-signals
http://www.cs.odu.edu/~cs476/fall03/lectures/sockets.htm
Jones, M. Tim. GNULinux application programming. 2nd ed. Cengage Learning, 2005. Print.
Richard, W., and Stephen A. Advanced Programming in the UNIX Environment. Addison-Wesley Professional, 2008. Print.

Sunday, October 10, 2010

Subclipse SVN plug-in for Eclipse

10/10/10 - had to post something.

I've experiences utter frustration with the SVN command-line client to maintain the various projects I've been working on and the lack of a Linux equivalent to TortoiseSVN. Typical example, I added a directory to the repository by mistake before running a clean operation. It took 20 minutes trying to delete files, cleanup commands to get back to a starting place with the files I really wanted to add.

The only apparent GUI for SVN on Linux appears to be through an Eclipse plug-in. Since I am moving my projects to Eclipse anyway this is a no-brainer.

Subclipse

Subclipse is the Eclipse client that integrates directly with the Eclipse IDE, even my Eclipse CDT IDE works. The download instructions are out of date with the Helios package of Eclipse (or Linux version). But you can more or less follow the instructions they give.

The installation is performed from within Eclipse

1. Start Eclipse
2. Help > Install New Software
3. In the Install wizard, Work with: field, enter the URL for the Subclipse version from the download and install page of the Subclipse site. In my case: http://subclipse.tigris.org/update_1.6.x.
4. I selected all the packages there, Core SVNKit Library, Optional JNA Library, Subclipse.
5. Finish your way through the wizard to install everything.
6. After the install you have to restart Eclipse.
7. I got a JavaHL error on start up of Eclipse, having to do with the JNA library. This is another topic discussed on the Subclipse wiki.
8. I ignored the error and Subclipse worked so I don't know how serious it is. I since went and installed then performed the JavaHL test cases successfully.
9. Note: I already had the SVN subversion command-line client installed, that may be a prerequisite, I am not sure to be honest.


The usage of Subclipse is not that clear-cut and documentation is lacking.

1. You need to set up a repository. Under Window > Open Perspective > Other choose SVN Repository Exploring. You can add a new repository if you have the URL (I had already created a local repository with the command line client, "file:///home/ammianus/svn-repo").
2. From the SVN Repository Explorer perspective, you can right-click a folder in your repository then click Import..., select a project in your workspace and you are good to go.
3. Once a project is associated with a location in your repository, if you right-click on a project or file > Context Menu > Team > * there will be all the normal SVN commands you would need. You will also notice that next to the project name will be the SVN repository location in brackets [].
4. You can see the behavior of Subclipse in a Console view in which you can switch to the SVN console output.

Sunday, September 26, 2010

Building Static Libraries and Test Program with Eclipse CDT

Based on sample code from a book, GNU/Linux Application Programming by M. Tim Jones, I have been reading to refresh myself on Linux programming, specifically in the C language, I have been trying to explore using the Eclipse CDT IDE.

I have managed to get projects set up in Eclipse for a simple application that prints numbers to a file. For the sake of practice, I have split the code into 1) a static library, libexp, based on the random number API library example from Chapter 7 2) a static library, libtherm, that wraps the random function with a function that returns the "temperature" 3) a simple executable that calls the temperature library function multiple times and prints the results.

Eclipse CDT
I downloaded and installed the Eclipse CDT Helios version for Linux (x86_64)
This requires a Java Runtime be installed on the machine. I had to install OpenJDK (1.6.0_18, 64-bit)

Project Structure

I started from an existing project I had created using the Automake/Autoconfig to set up a build environment. In this set up, I there was a single "project" directory with an app and lib subfolders containing respective source and build files.

As far as I can tell, the Eclipse CDT approach is that there is a single build target per Project. Perhaps if you develop the Makefile rather than have Eclipse create one you could do a different set up. Going with a completely Eclipse controlled build process I created separate projects for each static library and the executable file. All the source files went directly into each project directory under the workspace.


Build Artifacts

See Right-click Project > Properties > C/C++ Build > Settings > Build Artifact
For each of my projects libexp and libtherm, I set the Build Artifact properties as Artifact Type: Static Library, Artifact Name: ${ProjName}, Artifact Extension: a.

This results when you compile in Eclipse building and archiving the object files into libexp.a and

For temp-app the difference was the Build Artifact was set to Type Executable and there was no extension.

Referencing Libraries

In my case, the libtherm library references libexp library. The temp-app needed to reference both libtherm and libexp.
For libtherm Properties > C/C++ General > Paths and Symbols > References. I checked off libexp / Active.

This adds under the Includes > GNU C tab the Include directory /libexp.

I also updated the Properties > Project References to check off libexp project.

These steps also add GCC Compiler flags. Under Properties > C/C++ Build > Settings > GCC C Compiler > Includes it adds under -l included paths: "${workspace_loc:/libexp}"

If you click on the main GCC C Compiler heading All the options are listed:
-I"/home/me/workspace/libexp" -O0 -g3 -pedantic -Wall -c -fmessage-length=0


For the temp-app the procedure was more or less the same. Under the Project References, Path and Symbol References I added the two library projects libexp, libtherm.

Difference seems to be in the Executable type Project, the C/C++ Build > Settings has new options for GCC C Linker. Under Libraries -l I added "therm" and "exp" (GCC C Linker will prepend "lib" and append ".a"). Under the Library Search Path (-L) I added paths to the Debug directories in my other projects where the library artifacts were being built. For GCC C Linker All Options this results in:
-static -L"/home/me/workspace/libtherm/Debug" -L"/home/me/workspace/libexp/Debug" -o"appexp" ./test.o -ltherm -lexp

(note: one crucial step when linking libraries that may refer to each other: you must order them in a top down way. i.e. the libraries that have their own references to lower level libraries should be ordered first, so in my case it was -ltherm then -lexp. See this discussion on StackOverflow for more details: GCC C++ Linker errors: Undefined reference to ...')

Running the Project

Once the projects have been set up and you have a working build. You can try to run it.

See Run > Run Configurations
Add a new C/C++ Application to run e.g. "AppExp". Clicking run will execute the program with output going to your Eclipse Console panel

Saturday, August 7, 2010

Ubuntu Remote Desktop

Last week after installing Ubuntu Linux on a new desktop I had moderate success trying to remote into the box using vncserver.

After speaking to a co-worker I found out that Ubuntu has a remote desktop capability built in to Gnome. That was great to know, so this weekend I spent some time to set that up finally. Enabling Remote Desktop connections is as easy as going to a Preferences Control Panel, a few check boxes are you it took to set it up. See this guide for more info: Remote Access to the Ubuntu Linux Desktop.

On the Windows side, my laptop already had TightVNC client (http://www.tightvnc.com). Using the above guide it was easy to connect to the Remote Desktop on the server using the default port of 5900 and desktop of :0.

This did log me in to the Gnome desktop, and thought I could move the mouse and control the desktop through TightVNC, it would not refresh the screen in the client window. After trying out a few solutions from the Ubuntu forums that didn't work, I remembered something the same co-worker mentioned. Basically there are some issues with VNC if you have any of the desktop effects enabled.

To disable them go to:
System > Preferences > Appearence >Visual Effects

Set to "None"
Immediately this disables the "effects". The only noticeable difference is that there were some transparency effects in some of the windows, and these were turned off. This probably helps with performance in any case.

This did the trick and my VNC client came back to life and started to function. Although it is a little choppy if you try to drag a window around the desktop it worked pretty well with the "High-speed Network" connection profile in TightVNC.

Update

Adobe Flash Plugin installed today randomly. All I did was go to http://www.pandora.com/ and install the plugin, worked fine, and the box has been serving its first function as a dedicated internet radio player in my living room.

Sunday, August 1, 2010

Ubuntu Experiment

I've been interested in learning about embedded system programming especially as it relates to real-time software and operating systems. This has all been spurred by my interest in the software in used by various areas of our space program ( see post Exploring the Milky Way, May 15, 2010). I did a brief search around job postings for aerospace and NASA type software eng. openings, found very little Ada, the language used to program Cassini, did find a few related VxWorks, real-time C++, POSIX C, so thought it would be worth my while to go back to programming in C/C++ on Linux environments, especially as Embedded Linux is growing in popularity[Yaghmour, Building Embedded Linux Systems, 2003].

To move towards that goal, I needed a Linux development system. I didn't want to dual boot one of my existing Windows machines and possibly deal with driver hell.

Got a machine the other day. Nothing cutting edge. AMD Athlon II X2 215 (Dual cores, ~2.70 GHz). 4GB Memory, 500GB hard disk, NVIDIA® GeForce® 6150 SE. Good thing is that the case has a slim profile, 10.4" H x 3.9" W x 14.6" D. I wanted something small and quiet so I could leave running as a server and work on remotely. It came with Windows 7 and the obligatory set of crappy trial software and spyware. Also bought a book for some programming practice: GNU/Linux Application Programming

I went with the Ubuntu Linux distribution. Created an installer CD with the 10.04 LTS 64 bit Server Edition.

Installing was a simple(!) process, the installation documentation on the Ubuntu site is pretty good, if verbose. No snags were hit, though because I chose the Server edition it didn't come with the Graphical Installer option, though its not like there were any shell commands you had to run during the install. Since I didn't care about the pre-installed Win 7 OS, I didn't have to bother with creating any partitions, I just overwrote the whole drive as one big Linux partition.

Once it booted up after install it came to the default shell prompt. There is no desktop in the Server edition. A quick google search gave me the command to install the Gnome desktop. This was plugged in

$ sudo apt-get install ubuntu-desktop

That probably took longer than the install itself. In any case it loaded up fine with a snappy new purple themed Ubuntu desktop. From start to end it was probably around 4 hours of time.


Ubuntu Gnome desktop

One odd thing is that during the server install you are prompted for what kind of "server package" you want to set up. I chose Java/Tomcat, though I may not even use it. I can find no evidence that Java was installed so I am not sure what that was supposed to do.

Startup now takes under 10 seconds I would say, it is incredibly smooth.

I tried to connect remotely from my windows PC using PuTTy, but no luck, there was no SSH listener running on the server. You have to enable it by installing the SSH packages.

$ sudo apt-get install ssh

That worked and I could connect via PuTTy SSH over port 22. Trouble is you needed to connect by the IP address of the box, you apparently can't resolve the Linux server's machine name from Windows. Fine, so I had to add an entry into my Hosts file, C:\Windows\System32\Drivers\etc\hosts. Its funny that Windows to Windows doesn't require this to resolve the machine name, but Windows to Linux doesn't work. I noticed that the Linksys router administration site did recognize the Linux server's name in the DHCP Clients Table.

In any case minor issue.

The other thing I've found is that Adobe Flash plugins doesn't seem to install, I tried the .apt and the .deb versions offered by Adobe, neither worked, getting "Architecture Not Supported 'I386'" errors. Great job Linux! I would guess it may have to do with 64-bit vs 32 as I believe Flash doesn't have any native 64 bit versions, at least not on Windows.

Next step is to try to set up VNC in order to make a remote desktop connection from my laptop to the new server. We do this at work with our Linux Oracle database host, so I know it works well.