Showing posts with label debian. Show all posts
Showing posts with label debian. Show all posts

07 October, 2010

Hola Android -- Stage 3

So far, we've created the equivalent of a 'Hello World' application, extended the UI to include a menu button, and bound an action with the pressing of the menu button.

Let's expand our example to include a sub-menu system. First, add the additional menu button to the res/layout/main.xml file as follows:


user@River:~/HolaAndroid$ cat -n res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Menu1" />
<Button android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Menu2" />
</LinearLayout>


Rebuilding and running and you'll get twin menu buttons, the first bound to quitting the application, the second unbound to any action.













Next, we need to bind the pressing of button 2 to an action, namely the creation and rendering of another submenu.

Let's contain the behaviors of the second menu button to a newly defined class, as follows:

user@River:~/HolaAndroid$ cat src/com/example/holaandroid/Menu2.java
package com.example.holaandroid;

import com.example.holaandroid.R;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Menu2 extends Activity {
private Button addButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu2);
addButton = (Button)this.findViewById(R.id.m2_button1);
}
}


Easy thing to forget, but now that we're introducing a new Activity you must define it in the manifest (line 14).

$ user@River:~HolaAndroid$ cat AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.example.holaandroid"
4 android:versionCode="1"
5 android:versionName="1.0">
6 <application android:label="@string/app_name">
7 <activity android:name=".HolaAndroid"
8 android:label="@string/app_name">
9 <intent-filter>
10 <action android:name="android.intent.action.MAIN" />
11 <category android:name="android.intent.category.LAUNCHER" />
12 </intent-filter>
13 </activity>
14 <activity android:name=".Menu2"/>
15 </application>
16 </manifest>


Since we're referencing a button in our source code, we need to have it defined in our layout xml. Create a new XML file which defines our button as follows:

user@River:~/HolaAndroid$ cat res/layout/menu2.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:text="M2.Button1"
android:id="@+id/m2_button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom ="true"/>
</LinearLayout>



The final main class follows, the updates include importing the newly relevant packages, creating a createMenu2() method and assigning the main menu button click to the generation of the submenu (lines 9-12, 18, 36-43 & 45-52).


user@River:~/HolaAndroid$ cat -n src/com/example/holaandroid/HolaAndroid.java
1 package com.example.holaandroid;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.widget.Button;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.util.Log;
9 import android.content.Intent;
10 import android.view.Menu;
11 import android.view.MenuItem;
12 import android.view.MenuInflater;
13
14 public class HolaAndroid extends Activity
15 {
16 private static final String ClassName = "HolaAndroid";
17 private Button b1_;
18 private Button b2_;
19
20 /** Called when the activity is first created. */
21 @Override
22 public void onCreate(Bundle savedInstanceState)
23 {
24 final String MethodName = "onStart";
25
26 super.onCreate(savedInstanceState);
27 setContentView(R.layout.main);
28
29 b1_ = (Button)this.findViewById(R.id.button1);
30 b1_.setOnClickListener(new OnClickListener() {
31 public void onClick (View v){
32 Log.d(ClassName+"::"+MethodName, "entry");
33 finish();
34 }
35 });
36 b2_ = (Button)this.findViewById(R.id.button2);
37 b2_.setOnClickListener(new OnClickListener() {
38 public void onClick (View v){
39 Log.d(ClassName+"::"+MethodName, "entry");
40 createMenu2();
41 Log.d(ClassName+"::"+MethodName, "entry");
42 }
43 });
44 }
45 private static final int ACTIVITY_CREATE=0;
46 private void createMenu2() {
47 final String MethodName = "createMenu2";
48 Log.d(ClassName+"::"+MethodName, "entry");
49 Intent i = new Intent(this, Menu2.class);
50 startActivityForResult(i, ACTIVITY_CREATE);
51 Log.d(ClassName+"::"+MethodName, "exit");
52 }
53
54 }



While you're still in a similar predicament as our previous post, namely a submenu button with no action defined, you can navigate to/from the submenu using the main button and the back keypad button.

Cheers.

05 October, 2010

Hola Android -- Stage 2

Ok, so you've got your first Android application that prints 'Hello World'; nothing to write home about.

Let's expand on it a bit and make use of some of the User Interface capabilities. First though, let's remove the printing of 'Hello World'.

If you search the code you'll find no reference to our elusive string, instead it's hiding in the resources layout definition file res/layout/main.xml.

user@River:~/HolaAndroid$ cat -n res/layout/main.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 >
7 <TextView
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 android:text="Hello World, HolaAndroid"
11 />
12 </LinearLayout>
13
user@River:~/HolaAndroid$


Removing line 10 and you'll now have an application that renders a blank screen. Rebuild and re-run and you'll get:

user@River:~/HolaAndroid$ vi res/layout/main.xml
user@River:~/HolaAndroid$ make
ant debug
Buildfile: build.xml
[setup] Android SDK Tools Revision 6
[setup] Project Target: Android 1.5
[setup] API level: 3
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup] Importing rules file: platforms/android-3/ant/ant_rules_r2.xml

-compile-tested-if-test:

-dirs:
[echo] Creating output directories if needed...

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...

-aidl:
[echo] Compiling aidl files into Java classes...

compile:
[javac] Compiling 1 source file to /home/user/HolaAndroid/bin/classes

-dex:
[echo] Converting compiled files and external libraries into /home/user/HolaAndroid/bin/classes.dex...

-package-resources:
[echo] Packaging resources
[aaptexec] Creating full resource package...

-package-debug-sign:
[apkbuilder] Creating HolaAndroid-debug-unaligned.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/user/.android/debug.keystore

debug:
[echo] Running zip align on final apk...
[echo] Debug Package: /home/user/HolaAndroid/bin/HolaAndroid-debug.apk

BUILD SUCCESSFUL
Total time: 1 second
user@River:~/HolaAndroid$ make run
adb install -r ./bin/HolaAndroid-debug.apk
97 KB/s (4342 bytes in 0.043s)
pkg: /data/local/tmp/HolaAndroid-debug.apk
Success
adb shell am start -a android.intent.action.HolaAndroid -n com.example.holaandroid/com.example.holaandroid.HolaAndroid
Starting: Intent { act=android.intent.action.HolaAndroid cmp=com.example.holaandroid/.HolaAndroid }
user@River:~/HolaAndroid$















Now, you can play with your screen design by editing the res/layout/main.xml file. Note below we've added lines 11-15 to add a button to the main window.

user@River:~/HolaAndroid$ cat -n res/layout/main.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 >
7 <TextView
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 />
11 <Button android:id="@+id/button1"
12 android:layout_width="fill_parent"
13 android:layout_height="wrap_content"
14 android:layout_alignParentBottom="true"
15 android:text="Menu1" />
16 </LinearLayout>
user@River:~/HolaAndroid$


Rebuild and run and you'll get:



Alas, while you've created a button, the button has no action associated with it. Press it as you'd like you'll never get it to do anything.

So, let's make it do something. In order to tie your newly created button to an action you'll need to edit the src/com/example/holaandroid/HolaAndroid.java source. We'll add a button member, or attribute, and assign an action method to be called on the button click.

Below is our modified source code:

user@River:~/HolaAndroid$ cat -n src/com/example/holaandroid/HolaAndroid.java
1 package com.example.holaandroid;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.widget.Button;
6 import android.view.View;
7 import android.view.View.OnClickListener;
8 import android.util.Log;
9
10 public class HolaAndroid extends Activity
11 {
12 private static final String ClassName = "HolaAndroid";
13 private Button b1_;
14
15 /** Called when the activity is first created. */
16 @Override
17 public void onCreate(Bundle savedInstanceState)
18 {
19 final String MethodName = "onStart";
20
21 super.onCreate(savedInstanceState);
22 setContentView(R.layout.main);
23
24 b1_ = (Button)this.findViewById(R.id.button1);
25 b1_.setOnClickListener(new OnClickListener() {
26 public void onClick (View v){
27 Log.d(ClassName+"::"+MethodName, "entry");
28 }
29 });
30 }
31 }
user@River:~/HolaAndroid$



Now, if you're running the debugger you'll notice upon button click the debugger will receive a 'D/HolaAndroid::onStart( 1525): entry' message. To make our action a bit more obvious, follow line 27 with:

..
..
25 b1_.setOnClickListener(new OnClickListener() {
26 public void onClick (View v){
27 Log.d(ClassName+"::"+MethodName, "entry");
28 finish();
29 }
30 });
..
..

Now, your application will terminate when you press the button.

03 October, 2010

Hola Android -- Stage 1

I've begun my upward journey developing Android applications for my Samsung Galaxy phone. My intention is to review some of what I've learned and follow on with posts as I learn more. I'll skip the development setup as I've documented that in previous posts.

As with every good Computer Science example, we'll begin with the infamous 'hello world'.

Our target, a simple application that prints 'hello world' to the screen. Slowly I intend on building on it with no clear final destination than playing with features as they present themselves.

Assuming you've got your Android development environment properly set up we embark by creating a new project:

user@River:~$ ./android-sdk-linux_86/tools/android create project --package com.example.holaandroid --activity HolaAndroid --target 2 --path ~/HolaAndroidCreated project directory: /home/user/HolaAndroid
Created directory /home/user/HolaAndroid/src/com/example/holaandroid
Added file /home/user/HolaAndroid/src/com/example/holaandroid/HolaAndroid.java
Created directory /home/user/HolaAndroid/res
Created directory /home/user/HolaAndroid/bin
Created directory /home/user/HolaAndroid/libs
Created directory /home/user/HolaAndroid/res/values
Added file /home/user/HolaAndroid/res/values/strings.xml
Created directory /home/user/HolaAndroid/res/layout
Added file /home/user/HolaAndroid/res/layout/main.xml
Added file /home/user/HolaAndroid/AndroidManifest.xml
Added file /home/user/HolaAndroid/build.xml
user@River:~$


Now we've got a nice clean project directory structure that looks like the following:

user@River:~$ cd HolaAndroid/
user@River:~/HolaAndroid$ find .
.
./build.xml
./bin
./default.properties
./libs
./build.properties
./AndroidManifest.xml
./local.properties
./res
./res/values
./res/values/strings.xml
./res/layout
./res/layout/main.xml
./src
./src/com
./src/com/example
./src/com/example/holaandroid
./src/com/example/holaandroid/HolaAndroid.java
user@River:~/HolaAndroid$


Since I don't utilize the Eclipse development environment (personal choice) I authored a Makefile to ease some of the routine tasks.

user@River:~/HolaAndroid$ cat Makefile
all:
ant debug

setup:
emulator -avd myAvd &
xterm -e "adb logcat" &

run:
adb install -r ./bin/HolaAndroid-debug.apk
adb shell am start -a android.intent.action.HolaAndroid -n com.example.holaandroid/com.example.holaandroid.HolaAndroid

clean:
adb shell rm data/app/com.example.holaandroid.apk
ant clean
user@River:~/HolaAndroid$


Attempting to build the application by issuing a 'make' command and you'll be met with success.

user@River:~/HolaAndroid$ make
ant debug
Buildfile: build.xml
[setup] Android SDK Tools Revision 6
[setup] Project Target: Android 1.5
[setup] API level: 3
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup] Importing rules file: platforms/android-3/ant/ant_rules_r2.xml

-compile-tested-if-test:

-dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: /home/user/HolaAndroid/gen
[mkdir] Created dir: /home/user/HolaAndroid/bin
[mkdir] Created dir: /home/user/HolaAndroid/bin/classes

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...

-aidl:
[echo] Compiling aidl files into Java classes...

compile:
[javac] Compiling 2 source files to /home/user/HolaAndroid/bin/classes

-dex:
[echo] Converting compiled files and external libraries into /home/user/HolaAndroid/bin/classes.dex...

-package-resources:
[echo] Packaging resources
[aaptexec] Creating full resource package...

-package-debug-sign:
[apkbuilder] Creating HolaAndroid-debug-unaligned.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/user/.android/debug.keystore

debug:
[echo] Running zip align on final apk...
[echo] Debug Package: /home/user/HolaAndroid/bin/HolaAndroid-debug.apk

BUILD SUCCESSFUL
Total time: 2 seconds


Running it and you'll get

user@River:~/HolaAndroid$ make run
adb install -r ./bin/HolaAndroid-debug.apk
99 KB/s (4385 bytes in 0.043s)
pkg: /data/local/tmp/HolaAndroid-debug.apk
Success
adb shell am start -a android.intent.action.HolaAndroid -n com.example.holaandroid/com.example.holaandroid.HolaAndroid
Starting: Intent { act=android.intent.action.HolaAndroid cmp=com.example.holaandroid/.HolaAndroid }
user@River:~/HolaAndroid$




Just about every Android introduction tutorial demonstrates this, but now you've got another.

Cheers.

13 September, 2010

Journey of Android Development -- First Emulator App

Still trying to get the feel for the development environment. Much of this is likely fully integrated with Eclipse, but Eclipse is historically a resource hog. 'sides, I more of a command line kinda guy.

I authored my very first application that entails multiple buttons and debug logging. The app simply creates three buttons, registers a click handler for each and demonstrates the ability to log to the adb logfile stream.

Feel free to download it here.


You may also find the Makefile useful, which supports:
1) setting up the environment (ie. starting AVD and logcat utility)
2) rebuilding the project
3) reinstalling and remotely starting the app on the emulator
4) cleanup

The project assumes you've greated an AVD called myAVD.

Cheers.

01 September, 2010

Android Development Setup -- Debian 5.0 Amd64

I've touted in previous posts that I've recently got a Samsung Galaxy phone, equipped with Android 2.1. The decision was pretty easy as I wanted an Android-based phone to develop applications for.

I'm embarking on establishing the development environment and thought it would be useful to record the steps.

I'm starting with a fresh installation of Debian 5.0 as a VirtualBox Guest. Before we delve into the Android setup I first installed the VirtualBox Additions to get better control of my mouse and keyboard. While not required directly by the Android development they're useful, but only applicable if you're running VirtualBox.

VirtualBox Additions Installation

# apt-get install gcc linux-headers-`uname -r` build-essential


Then select Devices->Install VirtualBox Additions to mount the disc image.

I've always had trouble running the installation script directly from the disc, so I have had to introduce an incremental step of copying to the file system before running.

# cp /media/cdrom0/VBoxLinuxAdditions-amd64.run /tmp
# /tmp/VBoxLinuxAdditions-amd64.run


Then reboot the system for the additions to take effect.

Now the preliminaries are complete, let's get to installing the Android development environment.

Install Sun Java
Update you're repository to utilize the non-free Sun packages.

# echo "deb http://ftp.de.debian.org/debian/ lenny main contrib non-free" >> /etc/apt/sources.list
# apt-get update
# apt-get install sun-java6-jdk sun-java6-jre


Since I'm running an AMD64 kernel I need to install the 32-bit libaries.

# apt-get install ia32-libs


Lastly, you need to ensure you're running the Sun Java utilities and not the Gcc versions. To ensure this, remove any unnecessary Gcc Java packages and ensure the symbolic links for the relevant Java utilities are pointing to the Sun packages.

# apt-get remove gcj-jdk
# update-alternatives --config javac
# update-alternatives --config java

On each of the update-alternatives ensure the selection is pointed toward the .../java-6-sun/... version. This killed me in my first attempt as the symbolic reference for the 'java' utility was pointing to '/usr/lib/jvm/java-gcj/jre/bin/java' and bad things happened (e.g. Null References when installing Android targets). Moral of the story, "check this".

Android SDK installation
Alright, we're ready to install the SDK having set up the Java environment.

Notice I'm running as a general user and will be installing in my home directory.


$ wget http://dl.google.com/android/android-sdk_r06-linux_86.tgz
$ tar -xvf ./android-sdk_r06-linux_86.tgz


Next, install the platforms by issuing the following command and selecting "SDK Platform Android 2.1 API 7, revision 1' (in my case anyway as my Galaxy is a Android 2.1 based). Then select the 'install' button. Then, exit as we'll proceed on with the command line.

user@debian:~$ ./android-sdk-linux_86/tools/android update sdk


You'll next need to create an Android Virtual Device. Note, the target 6 specifies an Android 2.1 target, applicable for my phone.

$ ./android-sdk-linux_86/tools/android create avd --target 6 --name myAvd



Create a new Android project by issuing the following command:

$ $ ./android-sdk-linux_86/tools/android create project --package com.example.helloandroid --activity HelloAndroid --target 2 --path ~/HelloAndroid


You'll find the example primed with a main routine:

user@debian:~$ cat /home/user/HelloAndroid/src/com/example/helloandroid/HelloAndroid.java
package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}



Now you're ready to compile this no-op application and run in the emulator.

This is the point I realized that Android development requires Ant, so I installed the package.


# apt-get install ant


You'll see that a build.xml file exists, the source for the Ant build.

user@debian:~$ cd /home/user/HelloAndroid/
user@debian:~/HelloAndroid$ ls
AndroidManifest.xml build.xml local.properties
bin default.properties res
build.properties libs src


Build the target by issuing 'ant debug' from the project directory.

user@debian:~/HelloAndroid$ pwd
/home/user/HelloAndroid
user@debian:~/HelloAndroid$ ant debug


The result is an *.apk file in the bin directory; this is the executable you'll be running in the emulator.

Running in the Emulator
You're last steps are to start the AVD and install the application within it.

Start the AVD by issuing the android tool, selecting the AVD, and clicking on the start button. In a few seconds you should get a virtual phone presented on the screen.

$ /home/user/android-sdk-linux_86/tools/android


In another window/terminal, you can list the available devices by issuing the following command. You should be met with a list that includes the AVD you just started.

$ /home/user/android-sdk-linux_86/tools/adb devices


Almost there; final steps are to install your app and run it.

user@debian:~/HelloAndroid$ /home/user/android-sdk-linux_86/tools/adb -s emulator-5554 install ./bin/HelloAndroid-debug.apk


Running the application just like you would on your phone, navigate to the applications and click on it.
























As you can see, you get a 'Hello World, HelloAndroid' on the screen. Not too exciting. If you're interested, and you should be, you'll find the text reference in the ~/HelloAndroid/res/layout/main.xml file.

Keep your stick on the ice.

Ellusive 'Error: java.lang.NullPointerException' for Android Development Installation

I just spent some time debugging why my android development setup was failing on Debian 5.0

I repeatedly got a "XML verification failed for https://dl-ssl.google.com/android/repository/repository.xml.Error: java.lang.NullPointerException" error.

After navigating to the referenced web site and confirmed it wasn't a web site mis-reference I consulted Google.

A couple forums elluded to updating the SDK and Java, but neither was the case for me. My problem was I failed to configure the Sun packages as the default java compiler. This is done by:

debian:/root# update-alternatives --config java

There are 3 alternatives which provide `java'.

Selection Alternative
-----------------------------------------------
1 /usr/bin/gij-4.3
*+ 2 /usr/lib/jvm/java-gcj/jre/bin/java
3 /usr/lib/jvm/java-6-sun/jre/bin/java

Press enter to keep the default[*], or type selection number: 3
Using '/usr/lib/jvm/java-6-sun/jre/bin/java' to provide 'java'.



Next issue a SDK update by issuing the 'android update sdk' command and install the targets.

The symptom of this issue was an unpopulated target list (e.g. 'android list targets' resulting in no targets available).

Kudos.

16 July, 2010

Easing System Setup with Debian Packages

Seems like every 6 months or so I feel like reinstalling Linux on my workstation. Not because I need to, but more because I want to.

Seems as my interests wander I find the need to install loads of packages for temporary tasks, once accomplished I want to remove them. Unfortunately, I don't keep track of the packages and as a result start a-fresh periodically.

I do it often enough that it doesn't take too much time. Much of it is just the identification and reinstallation of packages I regularly use.

Authoring a system installation package that identifies all my essential packages as a dependency seems as it would minimize this effort dramatically. Since packages can define dependencies and installing it can auto-resolve and install the required dependencies seems like if we authored a faux package with dependencies on the packages I want installed we'd be right on mark.

Let's start;

Start by creating a directory.

$ mkdir ~/myPackage


Next, create the necessary control file which will identify the dependencies.

$ mkdir ~/myPackage/DEBIAN
$ edit ~/myPackage/DEBIAN/control

Populate ~/myPackage/DEBIAN/control with the following:
Package: MyPackage
Version: 1.0
Section: web
Priority: optional
Architecture: all
Essential: no
Depends: gnuplot, tcl
Pre-Depends: gnuplot
Recommends:
Suggests:
Installed-Size: 1024
Maintainer: Joe Brockmeier [jzb@dissociatedpress.net]
Conflicts: wile-e-coyote
Replaces: sam-sheepdog
Provides: acme
Description: The description can contain free-form text
describing the function of the program, what
kind of features it has, and so on.

Pay special attention to the Depends: field, it's populated with tcl and gnuplot. That means, when we install this package we ask that these dependencies are installed as well.

Next, create the package by executing the following command:

$ dpkg -b ~/myPackage /tmp/myPackage.deb


All set, now just install the package as root and you'll achieve an indirect installation of the dependencies.


# gdebi /tmp/myPackage.deb


Cheers.

06 May, 2010

Installing WindowMaker on Debian

Real short, but it took me a bit of searching to find how to replace Gnome as my window manager.

Start by installing the WindowMaker package:

# apt-get install wmaker


Next, as the user that you wish to run WindowMaker as the window manager:

$ echo "exec wmaker" >> ~/.xsession
$ echo "exec wmaker" >> ~/.xinitrc


Log off, then back on for it to take effect.

Cheers.

30 December, 2009

Create ISO Image From Directory

Occasionally it's useful to create a CD/DVD ISO image from a list of files contained in a directory. For instance, if you're interested in archiving a bunch of files to be later burned to a CD/DVD.

This can be done by using the mkisofs command which stands for 'make ISO filesystem'.

If you have a list of directories like the following:

user@debian:/media/ehd/tmp$ ls -l
total 2802468
drwxr-xr-x 3 root root 4096 2009-12-29 13:01 disc01
drwxr-xr-x 3 root root 4096 2009-12-29 13:01 disc02
drwxr-xr-x 3 root root 4096 2009-12-29 13:02 disc03
drwxr-xr-x 3 root root 4096 2009-12-29 13:03 disc04
drwxr-xr-x 3 root root 4096 2009-12-29 13:05 disc05
drwxr-xr-x 3 root root 4096 2009-12-29 13:06 disc06
drwxr-xr-x 3 root root 4096 2009-12-29 13:08 disc07
drwxr-xr-x 3 root root 4096 2009-12-29 13:09 disc08
drwxr-xr-x 3 root root 4096 2009-12-29 13:10 disc09
drwxr-xr-x 3 root root 4096 2009-12-29 13:10 disc10
drwxr-xr-x 3 root root 4096 2009-12-29 13:12 disc11
user@debian:/media/ehd/tmp$


You can create individual ISO images for each directory by issuing the following command:

$ mkisofs -o disc02.iso -J disc02


The ISO image will preserve the directory structures and file names found under disc02.

Cheers

16 April, 2009

Xen 3.0 Installation - Debian 4.0

This morning I started my investigation of using Xen virtualization, this post will focus on the installation of Xen and the steps to create my first WinXp Professional guest OS.

Xen Installation
This installation took place on a Debian 4.0 AMD 64 distribution, with VT-X hardware support:

user@debian:~$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 CPU L7400 @ 1.50GHz
stepping : 6
cpu MHz : 1234.565
cache size : 4096 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
bogomips : 3180.78
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 CPU L7400 @ 1.50GHz
stepping : 6
cpu MHz : 1234.565
cache size : 4096 KB
physical id : 1
siblings : 1
core id : 0
cpu cores : 1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
bogomips : 3180.78
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
You can determine if your cpu supports virtualization extensions by issuing the following command. If your cpu does not support virtualization extensions it won't support full virtualization and therefore won't support Windows guest operating systems.

user@debian:~$ egrep '^flags.*(vmx|svm)' /proc/cpuinfo
flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
flags : fpu tsc msr pae mce cx8 apic mtrr mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm




Our journey begins by installing the appropriate Xen Debian packages using Synaptic; following is a screen shot of the packages I installed.


Install the above packages using Synaptic or apt-get; whichever you prefer.

After completing the installation of these packages, you'll need to reboot. You'll find that a new Xen-based kernel image has been installed and should be defined as the default boot image. You'll notice that some Xen-specific logging prior to the Linux boot sequence. After completion, you should boot to a familiar looking system....login prompt and similar desktop as you've grown to love.

WinXp Guest Installation
You should now be ready to install your first guest operating system. Xen refers to these as domains...really don't care as every other virtualization technology calls them virtual machines and I'll be sticking with that terminology.

If you're familiar with VirtualBox, or VMware you'll quickly notice that Xen configuration is less user-friendly. Gone are the GUI configuration utilities, gone are the virtual machine status displays, and gone are the single-click access to virtual machine consoles. No worries though, we'll work with what the good Xen developers gave us.

Guest OS Installation Media
The installation procedures I referenced made use of an ISO image of the WinXp installation cd. How exactly you'd do this with live media is left as an exercise to the reader :)

I created a raw copy of the WinXp Installation CD by using the dd utility as follows:
Note, you must unmount the cdrom BEFORE issuing this command.

$ dd if=/dev/scd0 of=/home/user/WinXpPro.iso
You'll notice that I was using an external usb cdrom by the /dev/scd0 device name.
Creation of the Virtual Machine Hard-Drive File System
# mkdir /home/xen/domains/win01
# dd if=/dev/zero of=/home/xen/domains/win01/win_vm.img bs=1M count=2048

Creation of Virtual Machine Configuration File
While the user-friendly configuration user interfaces are non-existant, you still have available a highly configurable virtual machine. Configuration is done by a text based configuration file that you must create prior to starting the machine. I used the following for my WinXp guest operating system installation. You'll need to create this as root in the specified directory.
debian:~# cat /etc/xen/win01.cfg
kernel = '/usr/lib/xen-3.0.3-1/boot/hvmloader'
builder = 'hvm'
memory = '1024'
device_model='/usr/lib/xen-3.0.3-1/bin/qemu-dm'

# Disks
disk = [ 'file:/home/xen/domains/win01/win_vm.img,ioemu:hda,w',
'file:/home/user/WinXpPro.iso,ioemu:hdc:cdrom,r' ]

# Hostname
name='win01'

# Networking
vif = ['type=ioemu, bridge=xenbr0']

# Behaviour
boot='d'
vnc=1
vncviewer=1
vncunused=0
sdl=0
debian:~#

One thing I found was I initially didn't install the Xen-IoEmu package which later gave me errors during booting of the VM so make sure you installed that package.

Note, that the disk field specifies a hard-drive file system image and the OS installation ISO image. First time booting of this VM will kick off the installation from the ISO image.

Booting the VM
You should now be ready to start the VM. You start (or create) the VM by issuing the following command:

# xen create win01.cfg -c


Pay special attention to the -c argument, otherwise this thing may fail silently. You should get a started win01
response from this command.

You next need to know how to query the status of the VM and connect to the VM console. You can query the status of running virtual machines by issuing the command:

debian:~# xm list
Name ID Mem(MiB) VCPUs State Time(s)
Domain-0 0 947 2 r----- 457.1
win01 3 1024 1 -b---- 17.6
debian:~#


This status tells you general info, but at this point you want to pay special attention to the ID as it is how you will connect to the VM.

VNC is integrated into Xen VMs and this is the means to connect to the machine. The VM ID indirectly tells you what port to connect to (by adding 5900+ID). You can connect to this machine by issuing:

$user@debian:~$ vncviewer 127.0.0.1:5903


During the installation process the machine reboots a couple times, each time a new ID is assigned so when you lose your connection repeat the xm list + vncviewer sequence again.

That's all for now.

13 April, 2009

Installing VirtualBox 2.2

I've been evaluating VirtualBox, comparing it to VMware Server.

One of my first discoveries is the extent of changes since VirtualBox OSE 1.6.6, the verified package of Debian.

I found it not to be worthwhile in comparing 1.6.6 to VMware 2.0 since the feature set has significantly evolved and it wouldn't be a fair comparison comparing the latest version of VMware to VirtualBox development months old.

First step; update the Debian sources to make VirtualBox 2.2 available. Start by editing the /etc/apt/sources.list, adding the line

deb http://download.virtualbox.org/virtualbox/debian/ etch non-free
Next, install virtualbox-2.2; you may need to uninstall any previous version.


# apt-get update
# apt-get install virtualbox-2.2


Start the interactive UI by invoking the command:

$ VirtualBox

15 February, 2009

VMWare Server Installation

I've been sucessfully running VmWare Server 2.0 on my Debian 4.0 workstation for the past couple months. Since I had a couple hic-ups during the installation I figure I'll document them here for my own personal use and the use of others.

1.Perform fresh installation of Debian 4.0

2.Change Web Browser Preferences to utilize IceWeasel (necessary for web-enabled UI)

3.Install necessary packages
  • xion:/var/tmp# apt-get install binutils-doc make manpages-dev autoconf automake1.9 libtool flex bison gdb gcc g++ linux-headers-`uname -r`
4.Enable sound card channel
  • xion $ alsamixer (analog F channel)
5.Download VMWare Server 2.0 (http://www.vmware.com/download/server/)
6.Untar server archive
  • xion:/var/tmp# tar -zxvf /media/usb0/VMware-server-2.0.0-122956.x86_64.tar.gz
7.Install VMWare Server
xion:/var/tmp/vmware-server-distrib# ./vmware-install.pl
Creating a new VMware Server installer database using the tar4 format.

Installing VMware Server.

In which directory do you want to install the binary files?
[/usr/bin]

What is the directory that contains the init directories (rc0.d/ to rc6.d/)?
[/etc]

What is the directory that contains the init scripts?
[/etc/init.d]

In which directory do you want to install the daemon files?
[/usr/sbin]

In which directory do you want to install the library files?
[/usr/lib/vmware]

The path "/usr/lib/vmware" does not exist currently. This program is going to
create it, including needed parent directories. Is this what you want?
[yes]

In which directory do you want to install the manual files?
[/usr/share/man]

In which directory do you want to install the documentation files?
[/usr/share/doc/vmware]

The path "/usr/share/doc/vmware" does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

The installation of VMware Server 2.0.0 build-122956 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command: "/usr/bin/vmware-uninstall.pl".

Before running VMware Server for the first time, you need to configure it by
invoking the following command: "/usr/bin/vmware-config.pl". Do you want this
program to invoke the command for you now? [yes]

Making sure services for VMware Server are stopped.

Stopping VMware autostart virtual machines:
Virtual machines failed
Stopping VMware management services:
VMware Virtual Infrastructure Web Access
VMware Server Host Agent failed
Stopping VMware services:
VMware Authentication Daemon done
Virtual machine monitor done

You must read and accept the End User License Agreement to continue.
Press enter to display it.

NOTICE: BY DOWNLOADING AND INSTALLING, COPYING OR OTHERWISE USING THE
SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS OF THIS VMWARE MASTER END
USER LICENSE AGREEMENT ("EULA"). IF YOU DO NOT AGREE TO THE TERMS OF
THIS EULA, YOU MAY NOT DOWNLOAD, INSTALL, COPY OR USE THE SOFTWARE, AND
YOU MAY RETURN THE UNUSED SOFTWARE TO THE VENDOR FROM WHICH YOU ACQUIRED
IT WITHIN THIRTY (30) DAYS AND REQUEST A REFUND OF THE LICENSE FEE, IF
ANY, ALREADY PAID UPON SHOWING PROOF OF PAYMENT. "YOU" MEANS THE
NATURAL PERSON OR THE ENTITY THAT IS AGREEING TO BE BOUND BY THIS EULA,
THEIR EMPLOYEES AND THIRD PARTY CONTRACTORS THAT PROVIDE SERVICES TO
YOU. YOU SHALL BE LIABLE FOR ANY FAILURE BY SUCH EMPLOYEES AND THIRD
PARTY CONTRACTORS TO COMPLY WITH THE TERMS OF THIS AGREEMENT.

1. DEFINITIONS

1.1 "Designated Administrative Access" means that access to the
standard user interfaces of a given instance of the Software
(designated in this section) that you may grant to a designated
third party (a) for which you have provided advance written notice
to VMware that you are providing outsourced services and (b) for
whose dedicated benefit you have licensed such instance of the
Software. Designated Administrative Access is applicable only
where you are 1) an IT outsourcing company that is providing
outsourced IT services to a client company and 2) applicable only

Do you accept? (yes/no) yes

Thank you.

None of the pre-built vmmon modules for VMware Server is suitable for your
running kernel. Do you want this program to try to build the vmmon module for
your system (you need to have a C compiler installed on your system)? [yes]

Using compiler "/usr/bin/gcc". Use environment variable CC to override.

What is the location of the directory of C header files that match your running
kernel? [/lib/modules/2.6.18-6-amd64/build/include]

Extracting the sources of the vmmon module.

Building the vmmon module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmmon-only'
make -C /lib/modules/2.6.18-6-amd64/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.18-6-amd64'
CC [M] /tmp/vmware-config0/vmmon-only/linux/driver.o
CC [M] /tmp/vmware-config0/vmmon-only/linux/driverLog.o
CC [M] /tmp/vmware-config0/vmmon-only/linux/hostif.o
CC [M] /tmp/vmware-config0/vmmon-only/common/comport.o
CC [M] /tmp/vmware-config0/vmmon-only/common/cpuid.o
CC [M] /tmp/vmware-config0/vmmon-only/common/hashFunc.o
CC [M] /tmp/vmware-config0/vmmon-only/common/memtrack.o
CC [M] /tmp/vmware-config0/vmmon-only/common/phystrack.o
CC [M] /tmp/vmware-config0/vmmon-only/common/task.o
CC [M] /tmp/vmware-config0/vmmon-only/common/vmx86.o
CC [M] /tmp/vmware-config0/vmmon-only/vmcore/moduleloop.o
LD [M] /tmp/vmware-config0/vmmon-only/vmmon.o
Building modules, stage 2.
MODPOST
CC /tmp/vmware-config0/vmmon-only/vmmon.mod.o
LD [M] /tmp/vmware-config0/vmmon-only/vmmon.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.18-6-amd64'
cp -f vmmon.ko ./../vmmon.o
make: Leaving directory `/tmp/vmware-config0/vmmon-only'
The vmmon module loads perfectly into the running kernel.

None of the pre-built vmci modules for VMware Server is suitable for your
running kernel. Do you want this program to try to build the vmci module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vmci module.

Building the vmci module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmci-only'
make -C /lib/modules/2.6.18-6-amd64/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.18-6-amd64'
CC [M] /tmp/vmware-config0/vmci-only/linux/driver.o
CC [M] /tmp/vmware-config0/vmci-only/linux/driverLog.o
CC [M] /tmp/vmware-config0/vmci-only/linux/vmciKernelIf.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciContext.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciDatagram.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciDriver.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciDs.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciEvent.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciGroup.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciHashtable.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciProcess.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciQueuePair.o
CC [M] /tmp/vmware-config0/vmci-only/common/vmciResource.o
LD [M] /tmp/vmware-config0/vmci-only/vmci.o
Building modules, stage 2.
MODPOST
CC /tmp/vmware-config0/vmci-only/vmci.mod.o
LD [M] /tmp/vmware-config0/vmci-only/vmci.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.18-6-amd64'
cp -f vmci.ko ./../vmci.o
make: Leaving directory `/tmp/vmware-config0/vmci-only'
The vmci module loads perfectly into the running kernel.

None of the pre-built vsock modules for VMware Server is suitable for your
running kernel. Do you want this program to try to build the vsock module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vsock module.

Building the vsock module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vsock-only'
make -C /lib/modules/2.6.18-6-amd64/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.18-6-amd64'
CC [M] /tmp/vmware-config0/vsock-only/linux/af_vsock.o
CC [M] /tmp/vmware-config0/vsock-only/linux/driverLog.o
CC [M] /tmp/vmware-config0/vsock-only/linux/util.o
CC [M] /tmp/vmware-config0/vsock-only/linux/vsockAddr.o
LD [M] /tmp/vmware-config0/vsock-only/vsock.o
Building modules, stage 2.
MODPOST
WARNING: "VMCIDatagram_CreateHnd" [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: "VMCIDatagram_DestroyHnd" [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: "VMCI_GetContextID" [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: "VMCIDatagram_Send" [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
CC /tmp/vmware-config0/vsock-only/vsock.mod.o
LD [M] /tmp/vmware-config0/vsock-only/vsock.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.18-6-amd64'
cp -f vsock.ko ./../vsock.o
make: Leaving directory `/tmp/vmware-config0/vsock-only'
The vsock module loads perfectly into the running kernel.

Do you want networking for your virtual machines? (yes/no/help) [yes]

Configuring a bridged network for vmnet0.

Please specify a name for this network.
[Bridged]

The following bridged networks have been defined:

. vmnet0 is bridged to eth0

All your ethernet interfaces are already bridged.

Do you want to be able to use NAT networking in your virtual machines? (yes/no)
[yes]

Configuring a NAT network for vmnet8.

Please specify a name for this network. [NAT]

Do you want this program to probe for an unused private subnet? (yes/no/help)
[yes]

Probing for an unused private subnet (this can take some time)...

The subnet 172.16.38.0/255.255.255.0 appears to be unused.

The following NAT networks have been defined:

. vmnet8 is a NAT network on private subnet 172.16.38.0.

Do you wish to configure another NAT network? (yes/no) [no]

Do you want to be able to use host-only networking in your virtual machines?
[yes]

Configuring a host-only network for vmnet1.

Please specify a name for this network.
[HostOnly]

Do you want this program to probe for an unused private subnet? (yes/no/help)
[yes]

Probing for an unused private subnet (this can take some time)...

The subnet 192.168.208.0/255.255.255.0 appears to be unused.

The following host-only networks have been defined:

. vmnet1 is a host-only network on private subnet 192.168.208.0.

Do you wish to configure another host-only network? (yes/no) [no]

None of the pre-built vmnet modules for VMware Server is suitable for your
running kernel. Do you want this program to try to build the vmnet module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vmnet module.

Building the vmnet module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmnet-only'
make -C /lib/modules/2.6.18-6-amd64/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.18-6-amd64'
CC [M] /tmp/vmware-config0/vmnet-only/driver.o
CC [M] /tmp/vmware-config0/vmnet-only/hub.o
CC [M] /tmp/vmware-config0/vmnet-only/userif.o
CC [M] /tmp/vmware-config0/vmnet-only/netif.o
CC [M] /tmp/vmware-config0/vmnet-only/bridge.o
CC [M] /tmp/vmware-config0/vmnet-only/filter.o
CC [M] /tmp/vmware-config0/vmnet-only/procfs.o
CC [M] /tmp/vmware-config0/vmnet-only/smac_compat.o
CC [M] /tmp/vmware-config0/vmnet-only/smac.o
CC [M] /tmp/vmware-config0/vmnet-only/vnetEvent.o
CC [M] /tmp/vmware-config0/vmnet-only/vnetUserListener.o
LD [M] /tmp/vmware-config0/vmnet-only/vmnet.o
Building modules, stage 2.
MODPOST
CC /tmp/vmware-config0/vmnet-only/vmnet.mod.o
LD [M] /tmp/vmware-config0/vmnet-only/vmnet.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.18-6-amd64'
cp -f vmnet.ko ./../vmnet.o
make: Leaving directory `/tmp/vmware-config0/vmnet-only'
The vmnet module loads perfectly into the running kernel.

Please specify a port for remote connections to use [902]

Please specify a port for standard http connections to use [8222]

Please specify a port for secure http (https) connections to use [8333]

The current administrative user for VMware Server is ''. Would you like to
specify a different administrator? [no]

Using root as the VMware Server administrator.

In which directory do you want to keep your virtual machine files?
[/var/lib/vmware/Virtual Machines]

The path "/var/lib/vmware/Virtual Machines" does not exist currently. This
program is going to create it, including needed parent directories. Is this
what you want? [yes]

Please enter your 20-character serial number.

Type XXXXX-XXXXX-XXXXX-XXXXX or 'Enter' to cancel: A8MAJ-FK34X-UCL11-4J3U0

Creating a new VMware VIX API installer database using the tar4 format.

Installing VMware VIX API.

In which directory do you want to install the VMware VIX API binary files?
[/usr/bin]

In which directory do you want to install the VMware VIX API library files?
[/usr/lib/vmware-vix/lib]

The path "/usr/lib/vmware-vix/lib" does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

In which directory do you want to install the VMware VIX API document pages?
[/usr/share/doc/vmware-vix]

The path "/usr/share/doc/vmware-vix" does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

The installation of VMware VIX API 1.6.0 build-122956 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command: "/usr/bin/vmware-uninstall-vix.pl".

Enjoy,

--the VMware team

Starting VMware services:
Virtual machine monitor done
Virtual machine communication interface done
VM communication interface socket family: done
Virtual ethernet done
Bridged networking on /dev/vmnet0 done
Host-only networking on /dev/vmnet1 (background) done
DHCP server on /dev/vmnet1 done
Host-only networking on /dev/vmnet8 (background) done
DHCP server on /dev/vmnet8 done
NAT service on /dev/vmnet8 done
VMware Server Authentication Daemon (background) done
Shared Memory Available done
Starting VMware management services:
VMware Server Host Agent (background) done
VMware Virtual Infrastructure Web Access
Starting VMware autostart virtual machines:
Virtual machines done

The configuration of VMware Server 2.0.0 build-122956 for Linux for this
running kernel completed successfully.

xion:/var/tmp/vmware-server-distrib#


WinXp Setup
1.When configuring a Win VM, configure NIC as bridged device so ip address is on local network, otherwise you won't have visibility to print server
2.Install samba
  • # apt-get install samba
3.xion:/var/tmp# smbpasswd -a user1
4.Configure cdrom to support multimedia demands
  • utilization of ATAPI interface appears too slow to support dvd playback, copy and the like. Configure to use the host device directly

09 February, 2009

Creating Debian Packages

I have to admit, one of the most appealing features of Debian is the ease of package management. While we've authored many tool suites to be used in analysis, field testing, or development I've yet to package them into a distribution package. While I've always wanted to, I've never taken the initiative to investigate how to do it. Today I'll be documenting my journey into authoring my first Debian distribution package.

Debian Packages
A package is a simple collection of files with instructions of what to do with them. While most often packages consist of executables, they may instead contain source code, window themes, or other file collections. Since I'm interested in maintaining executables I'll focus on the binary distribution package. I start my journey by issuing the command 'man deb'.

File Contents
All binary Debian packages consist of 3 basic files: 1 text file, and 2 compressed tarballs. You can examine the contents of a Debian package yourself by using the archive command to list the file contents. For example,


$ ar -t /var/cache/apt/archives/telnet_0.17-34_amd64.deb
debian-binary
control.tar.gz
data.tar.gz


You can examine the content of each file by extracting them from the archive, done by issuing the following command:

$ ar -x /var/cache/apt/archives/telnet_0.17-34_amd64.deb


debian-binary
This file contains the version number for the binary package, which should be 2.0.

control.tar.gz
This gzipped archive contains the control file, a postinst file, a prerm file and may optionally contain info about configuration files for the package and a MD5 checksums for the package. You can examine the contents of this archive by issuing:

$ tar -ztf ./control.tar.gz
./
./postinst
./prerm
./postrm
./md5sums
./control

The only mandatory file in this archive is the control file which contains the core control info for the package.
control
Issuing the command 'man deb-control' documents the contents of the mandatory and optional fields for the control file. The file consists of mandatory and optional fields. The mandatory fields are listed with brief descriptions of each.
Package: This value identifies the name of the package.
Version: This field identifies the version number. The use of a hyphen identifies the Debian revision number so the package author is restricted from using the hyphen the version number.
Maintainer: This should be defined in the format of full name followed by e-mail address 'Joe Bloggs '.
Description: This field should provide a brief description of the package as the first line. This should be followed by a more detailed package description where each line begins with a space.

data.tar.gz
This file contains the actual “payload” of the package. This means that it contains a filesystem with all the relevant files for the program that when installed will be placed in the appropriate spots on the destination systems file system.


$ tar -ztf ./data.tar.gz
./
./usr/
./usr/bin/
./usr/bin/telnet.netkit
./usr/share/
./usr/share/doc/
./usr/share/doc/telnet/
./usr/share/doc/telnet/README.telnet
./usr/share/doc/telnet/README.gz
./usr/share/doc/telnet/BUGS
./usr/share/doc/telnet/copyright
./usr/share/doc/telnet/changelog.gz
./usr/share/doc/telnet/README.telnet.old.gz
./usr/share/doc/telnet/changelog.Debian.gz
./usr/share/man/
./usr/share/man/man1/
./usr/share/man/man1/telnet.netkit.1.gz
./usr/share/menu/
./usr/share/menu/telnet


Building a Package
Now that you know what's in a Debian package building one is pretty simple. Start by creating a working directory where you'll store the contents of the package.

$ mkdir /var/tmp/deb

Next, create a subdirectory where the contents of the control file will be stored.

$ mkdir /var/tmp/deb/DEBIAN


Author the control file and locate it in the DEBIAN directory.

$ cat DEBIAN/control
Package: MyPackage
Version: 1.0
Maintainer: Fat Slow Kid
Description: A brief description.
A more thorough description with lines and charts
pictures and graphs with a 8x10 glossy photo
with descriptions and notations.


Next, create the directory structure of the binary file contents. In our example, we intend on installing a new script foo.sh in /usr/local/bin.

$ mkdir -p usr/local/bin


Create a foo.sh script in this directory, our contents are as follows:

$ cat usr/local/bin/foo.sh
#!/bin/sh

echo "running 'My Script'"

Lastly, move out of this working directory and build it with the Debian provided package utilities.

$ dpkg -b /var/tmp/deb MyPackage.deb


After this, a new MyPackage.deb file will exist in the present working directory. You can examine the intended installed files by issuing the command as follows:

$ dpkg --contents MyPackage.deb
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./usr/
drwxr-xr-x fsk/fsk 0 2009-02-08 23:11 ./usr/local/
drwxr-xr-x fsk/fsk 0 2009-02-08 23:12 ./usr/local/bin/
-rwxr-xr-x fsk/fsk 38 2009-02-08 23:12 ./usr/local/bin/foo.sh


Installing this package will now recreate the file system structure starting at the destination systems root file directory. Namely, foo.sh will be located in /usr/local/bin when installed.

# dpkg -i MyPackage.deb
Selecting previously deselected package mypackage.
(Reading database ... 79280 files and directories currently installed.)
Unpacking mypackage (from MyPackage.deb) ...
Setting up mypackage (1.0) ...
xion:/home/fsk#
xion:/home/fsk# which foo.sh
/usr/local/bin/foo.sh
xion:/home/fsk# foo.sh
running 'My Script'
xion:/home/fsk#

Granted the removal procedures aren't defined, but you've got the start of your very own Debian package.

You've achieved your Debian package yellow-belt.

30 November, 2008

Flash Player Installation on Debian 4.0 AMD64 Distro

I recently purchased a new computer, downgrading my now 4 year old processor to the closet. I was pleased to install my first 64-bit operating system, but found it a challenge installing a compliant flash-player plug-in. A breezy Google search resulted in the following Clif-notes:



# wget -O - http://backports.org/debian/archive.key | apt-key add -



# vi /etc/apt/sources.list

+ add the following line:
deb http://www.backports.org/debian etch-backports main contrib





# apt-get update
# apt-get install flashplugin-nonfree