What I've been doing. Breakdown

Friday May 02, 2008

One of my tasks at the moment is to run tests on Solaris Nevada, running as a domu on a Linux dom0.

What follows is a howto for installing hvm(Hardware Virtual Machine) guests on Ubuntu Linux, 8.04 (Hardy Heron) server-64.

Now in my case this is a build of Solaris Nevada(please see here for more information on OpenSolaris), and throughout this howto I will refer to it as snv, please feel free to switch this with your own OS name (or whatever you like really).

The machine I'm using is a Sun Fire X4150 (one of the servers on which 8.10 is certified), this machine has 8 cores (2x Quadcore Xeon x64 processors), which have Intels virtualisation extensions(Intel VT). And with plenty of RAM and 4 hard drives this machine is great for running many guests.

To be able to Xen for full virtualisation (hvm) you need a processor that has the needed extensions. Either AMD-V or Intel VT, if you don't have a chip with these extensions you might take a look at using virtualbox.

Dom0 setup

During install manually assign network info for primary network card and dns servers so as to resolve the package repositories.

Install Xen (version 3.2)
sudo apt-get install ubuntu-xen-server
sudo reboot

You should now have booted the kernel with Xen extensions.

uname -a should return
Linux hostname 2.6.24-16-xen #1 SMP Thu Apr 10 14:35:03 UTC 2008 x86_64 GNU/Linux

ps -A|grep xen should return
46 ? 00:00:00 xenwatch
47 ? 00:00:00 xenbus
5264 ? 00:00:00 xenstored
5272 ? 00:00:00 xenconsoled

xm list should return
Name ID Mem VCPUs State Time(s)
Domain-0 0 7933 8 r----- 24.0

Great, were all set to get started.

vi /etc/modules
change loop to
[...]
loop max_loop=64
[...]

####### Not exactly needed ########
One of the handy tools available on Solaris is mkfile, which you can use to create a file of whichever size. The closest Linux has to this is dd, which is a bit more ugly. However if you want to keep using dd, then by all means do.

So below is a simple zsh script which give you a nicer interface for creating files of specific sizes.
apt-get install zsh

save to /usr/bin/mkfile
#!/usr/bin/zsh
echo "mkfile [new_file_name] [filesize in Mb]"
dd if=/dev/zero of=$1 oflag=direct bs=1M count=$2

sudo chmod +x /usr/bin/mkfile

###################################
Create a hard drive for our Xen guest using mkfile (use dd if you prefer).
mkfile /mnt/sdb/snv.img 8000

*/mnt/sdb is the mount point of one of my systems drives, I intend to have one drive for each guest, thereby not killing performance by over using one disc.

We'll be using VNC to connect to get a screen from our guests so we install xvnc.
sudo apt-get install xvnc4viewer

Our plan is to install directly from an iso file, however there is currently a bug in Xen on 8.04 (or is it in 8.04, I don't know), which prevent us from doing that (the normal way) or even using our newly created .img file.

https://bugs.launchpad.net/ubuntu/+source/xen-3.2/+bug/211726
https://bugs.launchpad.net/ubuntu/+source/xen-3.2/+bug/211728

However below is the(a) workaround.

We mount our iso file to a loopback device (/dev/loop)
losetup /dev/loop0 /export/xen/isos/snv.i386.iso

And the same again for our .img file
losetup /dev/loop1 /mnt/sdb/snv.img

Now we create our guest(domu) configuration file, this is what Xen will use when the guest is created.
add below to /etc/xen/snv

kernel = "/usr/lib/xen/boot/hvmloader"
builder = 'hvm'
memory = 1024
name = "snv"
vcpus = 1
vif = [ 'type=ioemu, bridge=xenbr0' ]
disk = [ 'phy:/dev/loop1,ioemu:hda,w','phy:/dev/loop0,hdc:cdrom,r' ]
device_model = '/usr/lib/xen/bin/qemu-dm'
cdrom='/dev/hda'
ne2000=0
sdl=0
vnc=1
boot='d'

We then use xm to create our newly configured DomU

xm create snv

We now want to connect to our newly created guest and finish the install process, we do this with vnc.
vncviewer localhost

If your lucky, and have had no errors up to this point a window with the install screen should pop up.
Once you've finished the install you'll want your guest to boot off the .img file with the newly installed OS instead of the install cd/iso.

First shutdown your guest
xm shutdown snv

Edit your /etc/xen/snv file
change boot='d' boot='c' (were telling Xen to boot from drive c, instead of drive d)

Now start up your domu
xm create snv

Reconnect to your guest with vncviewer, and you should, if your lucky, be booting into your guest OS.

This is full virtualisation, as far as the OS your install is concerned, it's being installed on a real PC.

Well it seems that although the install process was easy, actually going about and using Netbeans, Java, and GlassFish from the Ubuntu package repositories wasn't quite so.

As pointed out in one of the comments in the last post the versions available as Ubuntu packages are fairly old. So I had to go ahead, download & install the latest versions anyway.

Wednesday Mar 26, 2008

One of the patterns you may notice in my ZSH posts is trying to get it to behave more like Ruby/Perl when scripting.

As they say you can write Java in any language, but replace Java with Perl or Ruby and you'll be closer to describing myself. I can't help the fact that Ruby has influenced the way I think about programming so much, it has been my first love in languages (and still holds that spot).

One of the things I like about using Ruby is that every function returns a value, usually the result or nill. It makes it much simpler when structuring code to see where functions return their results to, rather than having to look through the function to see what side effects it has (I believe the term for this is functional programming).

So why not see what it's like to program in this style with ZSH?

Lets say we want to create a function that adds two numbers, and returns the results, now it seems there is no direct way to store the results with result=function 1 2, so we pass the function the name of the variable we would like it to store the results in, which has the same result.

myfun () {
local result_name=$1 #first argument is the name of the variable the results are stored in
local a=$2 #the first number
local b=$3 #the second number
(( ${result_name}= $a + $b )) #the math part of the function
}

myfun MY_RESULT 12 3
print $MY_RESULT
15

${result_name} is expanded & replaced with whatever is in result_name, which in this case is MY_RESULT.

A more compact version would look like:
myfun () {
local result_name=$1 #first argument is the name of the variable the results are stored in
(( ${result_name}= $2 + $3 )) #the math part of the function
}

############## BASH EQUIVALENT #####################
Something similar in bash, although numeric handling isn't as nice
function returnOtherStuff() {
echo "foo bar baz 12354"
}

myStuff="`returnOtherStuff`"

I recently bought a folding bike on Ebay (pretty happy with it) and and got an email yesterday from Ebay with a question from another user. Asking what my experience with the bike was since he was thinking of getting one.


Click image for full size

Fine no problem, I hit the answer link and was ready to tell him what I thought. It then asks me for credit card info to "verify my details".


Click image for full size
The first thing I thought was "how stupid is this, man what an inconvenience for users" *as I reached into my wallet for my credit card*, and then I got a smack of sense *put card back in wallet*.

I had a look around Ebay itself(tried to find the member manually & contact him that way) and sure enough they really do want your credit card for you to make contact.

Talk about helping scammers, Ebay actually send out unsolicited mails that ask for credit card details when responding. Isn't this a big no no on todays internet?

Pics related.

Tuesday Mar 25, 2008

One of the array methods in Ruby that's quite handy is the collect! method, which will invoke a block on each element in the array and replace it with the result.

Here's a slightly less pretty way to do the same thing in ZSH, our script below will add 5 to each element in the array.

myarray=(1 2 3 4 5 6 8)
mycounter=1
length=$#myarray
while [[ $mycounter < $length ]]
do
(( myarray[$mycounter] = $myarray[$mycounter] + 5 ))
(( mycounter = $mycounter + 1 ))
done
print $myarray
6 7 8 9 10 11 8

***************************** Note *****************************
Unlike arrays in Ruby or Perl, ZSH arrays begin with 1 instead of 0.
So in Ruby where array[0] is the first element, ZSH is array[1]
****************************************************************

Tuesday Mar 18, 2008

Since ZSH comes with arrays (like Ruby or Perl, but a little different) you might want to start using this functionality in some of your scripts.

In this post I'm going to cover how to explicitly create an empty array, accessing elements, and adding or removing elements.

Create, add, remove, access
Firstly to create an empty array the command is very simple:
myvar=()
You now have an empty array called $myvar to which you can add or remove elements.

To create an array with elements is as simple, put the elements inside the parenthesis like so:
myvar=(1 2 3 4)
With elements separated with spaces.

********************************** Sidenote ***********************************************
Something that I found/find a little unintuitive (with shell scripting) is that when creating/setting variables you don't put $ in front of the variable name, however $ is needed when reading a variable.
Example:
var=5
print var
var
print $var
5
*******************************************************************************************

So to add a variable (lets say the number 5) to our new array($myvar) we would do this:
myvar[5]=5

Note to Ruby/Perl users the index in ZSH arrays start from 1, instead of the first element being numbered 0.

print $myvar
1 2 3 4 5

ZSH arrays also have negative /reverse indexes for accessing & changing(already existing elements).
Where normally $myvar[1] results in 5 we can use $myvar[-1] which results in 4 or the last element in the array, and continues counting down the array.... -2,-3, etc.

print $myvar[-1]
5
print $myvar[-2]
4

To delete elements from the array is like creating an empty array, except we specify the element to set.

myvar[2]=()
print $myvar
1 3 4 5

Looping over arrays
ZSH is more like perl or Ruby when it comes to array's, you don't need counters to access the arrays elements. So as an example we'll loop over an array and print out it's elements.

myarray=(1 2 3 4 7)
for i in $myarray
do
print $i
done

1
2
3
4
7

Nice and clean, very Perl|Ruby/ish, currently there is no built in method(that I know of) to work on array elements in place in a non c-ish style.

Hashes/hashtables/hictionaries/associative arrays
As far as ZSH is concerned you can treat any normal array as a hash as well(in the ZSH documentation they're called associative arrays), mixing is not advised since any elements you add to an indexed array via key/value pair will just store the item in the first element of the array, overwriting whatever is there, and will repeat this process for each pair you add, continually overwriting the first element.

You need to tell ZSH that an array is actually a hash before you can use it as such:
typeset -A hash
hash=(key value husband james wife emily)
print $hash
value james emily
print $hash[husband]
james

Adding new elements is fairly intuitive:
hash[child]=kevin
print $hash
value james emily kevin
print $hash[child]

To remove elements from a hash:
unset "hash[key]"
print $hash
james emily kevin

I'm used to(read, this is how I like it) using push/pop, que/deque, front/end methods for manipulating arrays in Ruby but you could create ZSH functions that would do this. But that's something for another post.

Friday Mar 14, 2008

It's all open.
OpenSolaris, OpenJDK, OpenSparc, OpenOffice.org and at this point pretty much everything else.

How cool is it that the latest chip designes Sun developed are available for anyone to have a peek. No one else does that.

Looks like I started with them at the right time. I only started with Sun a little over a week ago and I'm already excited on what the company is doing (from a technology point of view) and where it's going ("from a business point of view). I'm excited, I believe. This is a company that I can believe in.

Tuesday Mar 11, 2008

Building on from my previous post on getting a list of files into an array were going to try and get each filename individually (without the full path) and without the file extension.

Now that we have our list of files lets do something to them

files=($(pwd)/*) #gets the list of files in the present working directory
for file in $files; do
item=$file:t #removes the full path so we are only left with the filename

if [[ $item == (*.c||*.cpp) ]];then #so were looking for files that end with .c or .cpp
print This is a C/C++ file: $item

print Item without file extension: $item[(ws:.:)1]#this splits the string into an array with a "." sepatator
fi
done

when you run this code it should look something like this:

Item without file extension: cpptest
This is a C file: testaux.c
Item without file extension: testaux
This is a C file: test.cpp
Item without file extension: test

as long as you have some .c files in your current directory.

To get a file list from a directory into an array

files=(/your/path/to/directory/*)
for file in $files; do
print This is $file
done