Search This Blog

14 August 2012

Multiple Accounts/SSH keys on BitBucket

Theoretically, I can add my SSH key to any server I have access to.  With BitBucket, that's not always true.

BitBucket does not allow the same key to be used for two different accounts.  Security measure, I'm sure.  It does make it difficult to access my company account and my personal account from the same machine.

The workaround is to do the initial download via https, then change the protocol.  More specifically....

Setup:

Assuming 'WORK' and 'HOME' are two separate BitBucket accounts and you are using a single client (laptop, whatever) to access them both...  Decide which one should be less effort -- in this case, I chose WORK.

1. Create an SSH key for WORK
ssh-keygen
Choose the default /home/username/.ssh/id_rsa
2. Copy id_rsa.pub into your BitBucket WORK account
3. Create an SSH key for HOME
ssh-keygen
Choose /home/username/.ssh/id_personal_rsa or something else obvious
4. Copy id_personal_rsa.pub into your BitBucket HOME account

The Good:

For WORK repos, you can simply do the normal
hg clone ssh://hg@bitbucket.org/WORK/REPO

The Ok, I Guess:

For HOME repos, you have to take an extra step.
hg clone https://USERNAME@bitbucket.org/USERNAME/REPO

Then, edit REPO/.hg/hgrc
Change
default = hg clone https://USERNAME@bitbucket.org/USERNAME/REPO
to
default = hg clone ssh://hg@bitbucket.org/USERNAME/REPO

Then, add this into that file:
[ui]
ssh = ssh -C -i ~/.ssh/id_personal_rsa.pub -o IdentitiesOnly=yes

Now you should be able to push/pull using SSH.


Conclusion

You are probably asking yourself why all of this is necessary.  From scavenging the web and looking at all the "Won't Fix" answers...  My best understanding is because the ssh url BitBucket gives out does not include the username.

17 December 2011

Canon PIXMA MX860 and Ubuntu 11.10

When I upgraded the laptop to Ubuntu 11.10, the Canon inkjet quit working.  I tried reinstalling the drivers, but it refused (even with --force-architecture).  I tried (for a few hours) building the drivers, but it was just one thing after another.

Eventually, I found this:
sudo add-apt-repository ppa:michael-gruz/canon
sudo apt-get update
sudo apt-get install cnijfilter-mx860series
sudo apt-get install scangearmp-mx860series

Good news is, it prints again. Bad news, no landscape or double-sided printing.

25 August 2011

Share your git hooks

At work, we are using git for one of our projects.  One of the problems we encountered is that people (including myself) regularly forget to put the branch name in their commit message.  Why is that a big deal?  Once merged back to master, you see a lot of comments that show no indication of what they were for (for example 'added .gitignore').  I'd like to simplify things so that no one has to remember.  No need to prevent the checkin - just fix the comment...

These steps will ignore the ACLs and which server, etc... just pseudo code it...

Step 1: Setup a repo to hold the new hooks
server:/srv $ git init --bare githooks.git

Step 2: Add a new hook
server:/usr/share/git-core/templates $ rm hooks
server:/usr/share/git-core/templates $ git clone /srv/githooks.git hooks
server:/usr/share/git-core/templates $ cd hooks
server:/usr/share/git-core/templates/hooks $ nano commit-msg

#!/bin/bash

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

OLD=`cat $1`
NEW="[$branch_name] $OLD"
echo "$NEW" > $1
exit 0

server:/usr/share/git-core/templates/hooks $ chmod a+x commit-msg
server:/usr/share/git-core/templates/hooks $ git add commit-msg
server:/usr/share/git-core/templates/hooks $ git commit -a -s -m "added commit-msg"
server:/usr/share/git-core/templates/hooks $ git push origin master

Step 3: User clones a new repo....
client:~/work $ git clone git://somerepo.git repo
client:~/work $ cd repo
client:~/work/repo $ echo "something" > test.txt
client:~/work/repo $ git add test.txt
client:~/work/repo $ git commit -a -s -m "added something"

Step 4: Checking that it worked...
client:~/work/repo $ git log

commit 07ed146319a2e45ea97b2ecaa4a1ea8d365b6b01
Author: Malachi de AElfweald <malachid@gmail.com>
Date:   Thu Aug 25 12:59:58 2011 -0700

    [master] added something
   
    Signed-off-by: Malachi de AElfweald <malachid@gmail.com>

Step 5: Updating the hook "server side"

server:/usr/share/git-core/templates/hooks $ nano commit-msg

#!/bin/bash

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

OLD=`cat $1`
NEW="$branch_name: $OLD"
echo "$NEW" > $1
exit 0

server:/usr/share/git-core/templates/hooks $ git commit -a -s -m "changed commit-msg"
server:/usr/share/git-core/templates/hooks $ git push

Step 5: Updating the hook "client side"
client:~/work/repo $ cd .git/hooks
client:~/work/repo/.git/hooks $ git pull

Step 6: Retest it...

client:~/work/repo $ echo "something else" > test.txt
client:~/work/repo $ git commit -a -s -m "changed something else"
client:~/work/repo $ git log

commit 7f381725dd2663728f11f08d08ed0c1d83608047
Author: Malachi de AElfweald <malachid@gmail.com>
Date:   Thu Aug 25 13:33:43 2011 -0700

    master: changed something else
   
    Signed-off-by: Malachi de AElfweald <malachid@gmail.com>



13 August 2011

Native ZFS for Linux

I miss OpenSolaris.  At work, the only options are Windows and Linux.  The other day, I was rm -rf'ing about 10 different copies of the Android tree and it reminded me how much quicker it was to wipe out a zfs filesystem than it was to rm -rf one "little" directory.  After many hours of waiting for access to my system, I decided to check on the state of ZFS on Linux again.

Last year, I had tried the FUSE port.  This time I decided to try zfsonlinux.  This comment on their page had me excited pretty early:
There is a lot of very good ZFS documentation already out there. Almost all of it should be applicable to this implementation because we have tried to conform to the Solaris behavior as much as possible.

 For installation, I followed the steps listed here:
sudo add-apt-repository ppa:dajhorn/zfs
sudo apt-get update
sudo apt-get install ubuntu-zfs

Installation went pretty smooth.  Trying to use it afterwards was a bit more tricky.  The module wasn't loaded so I tried to follow the instructions to do an insmod:

malachi@onyx:~$ sudo insmod /lib/modules/2.6.38-10-generic/updates/dkms/zfs.ko
insmod: error inserting '/lib/modules/2.6.38-10-generic/updates/dkms/zfs.ko': -1 Unknown symbol in module
Well, that's not good.  Luckily, there was a really simple workaround:
malachi@onyx:~$ sudo modprobe zfs
And voila.  It was loaded until next reboot.  I didn't have a spare drive in the laptop to convert to a root zfs drive, so I didn't worry about doing a grub setup... but I would like the module to auto-load on boot.  Turns out, that's pretty simple.  Simply add a line 'zfs' to /etc/modules.  While you are at it, modify /etc/default/zfs to enable auto (un)mounting:

malachi@onyx:~$ cat /etc/default/zfs
# Automatically run `zfs mount -a` at system startup if set non-empty.
ZFS_MOUNT='yes'
#ZFS_MOUNT=''

# Automatically run `zfs unmount -a` at system shutdown if set non-empty.
ZFS_UNMOUNT='yes'
#ZFS_UMOUNT=''
Currently, the /dev/zfs is owned by root:root with permissions set to 600. What this means is that to even do 'zfs list' or 'zpool status' you have to be root.  While I understand the logic there, I find it extremely annoying.  It may not go anywhere, but I submitted an enhancement request to allow admin group rw.  I realize that there are ACL mechanisms, but I do not believe those apply to the /dev/zfs special character device.


So, with no spare disk, how will I test it?  While I know that performance would suffer, I decided to try my testing with file-backed zfs.  I didn't want to keep doing it by hand, so created a script:

malachi@onyx:~$ cat /mnt/zfs-disks/createZFSFile
#!/bin/bash

FILE=$1
GIGS=$2
dd if=/dev/zero of=/mnt/zfs-disks/$FILE.zfs bs=1G count=$GIGS
ls -lh /mnt/zfs-disks/$FILE.zfs
Then created a few backing disks....

malachi@onyx:~$ createZFSFile disk1 10
10+0 records in
10+0 records out
10737418240 bytes (11 GB) copied, 114.092 s, 94.1 MB/s
-rw-r--r-- 1 malachi malachi 10G 2011-08-12 15:41 /mnt/zfs-disks/disk1.zfs
Repeat that for disk2,3,4...  For this testing, and especially since it was file-backed, I decided to not use raidz2 like I normally would so that I could easily add more space to the pool if necessary.

malachi@onyx:~$ sudo zpool create pool /mnt/zfs-disks/disk1.zfs
I then created a filesystem in the pool to work from:

malachi@onyx:~$ sudo zfs create pool/android
malachi@onyx:~$ sudo zfs list
NAME           USED  AVAIL  REFER  MOUNTPOINT
pool           128K  9.78G    30K  /pool
pool/android    30K  9.78G    30K  /pool/android
Now to test adding some disks to the pool...

malachi@onyx:~$ sudo zpool add pool /mnt/zfs-disks/disk2.zfs
malachi@onyx:~$ sudo zpool add pool /mnt/zfs-disks/disk3.zfs
malachi@onyx:~$ sudo zpool add pool /mnt/zfs-disks/disk4.zfs

malachi@onyx:~$ sudo zfs list
NAME           USED  AVAIL  REFER  MOUNTPOINT
pool           140K  39.1G    31K  /pool
pool/android    30K  39.1G    30K  /pool/android

malachi@onyx:~$ sudo zpool status
  pool: pool
 state: ONLINE
 scan: none requested
config:

    NAME                        STATE     READ WRITE CKSUM
    pool                        ONLINE       0     0     0
      /mnt/zfs-disks/disk1.zfs  ONLINE       0     0     0
      /mnt/zfs-disks/disk2.zfs  ONLINE       0     0     0
      /mnt/zfs-disks/disk3.zfs  ONLINE       0     0     0
      /mnt/zfs-disks/disk4.zfs  ONLINE       0     0     0

errors: No known data errors
That all looks good.  Downloading Android, built it, and then tried some timings...

root@onyx:~# annotate-output zfs snapshot pool/android@freshbuild
21:55:14 I: Started zfs snapshot pool/android@freshbuild
21:55:14 I: Finished with exitcode 0

root@onyx:~# zfs list -t all
NAME                      USED  AVAIL  REFER  MOUNTPOINT
pool                     10.1G  29.1G    31K  /pool
pool/android             10.1G  29.1G  10.1G  /pool/android
pool/android@freshbuild      0      -  10.1G  -

root@onyx:~# annotate-output zfs destroy pool/android@freshbuild
21:56:00 I: Started zfs destroy pool/android@freshbuild
21:56:00 I: Finished with exitcode 0

root@onyx:~# zfs list -t all
NAME           USED  AVAIL  REFER  MOUNTPOINT
pool          10.1G  29.1G    31K  /pool
pool/android  10.1G  29.1G  10.1G  /pool/android


root@onyx:~# annotate-output zfs destroy pool/android
21:59:54 I: Started zfs destroy pool/android
22:00:28 I: Finished with exitcode 0

root@onyx:~# zfs list -t all
NAME   USED  AVAIL  REFER  MOUNTPOINT
pool  1.52M  39.1G    30K  /pool


root@onyx:~# annotate-output zfs create pool/android
22:01:05 I: Started zfs create pool/android
22:01:06 I: Finished with exitcode 0

root@onyx:~# zfs list -t all
NAME           USED  AVAIL  REFER  MOUNTPOINT
pool          1.55M  39.1G    30K  /pool
pool/android    30K  39.1G    30K  /pool/android
Overall, I am really happy with these timings... Especially since it was running on file-backed zfs.

During all of my testing (I tried it 3-4 times) there was one gotcha.  During my first test, git locked up downloading Android.  Not sure what happened, but I couldn't even kill -9 it.  Even rebooting wouldn't work since it hung waiting for that process to die.  Since I had to hard power-cycle it, I am not surprised that the zfs system got corrupted.  When I rebooted, 'zfs list' and 'zpool status' locked up.  I was able to kill -9 the zfs list; but not the zpool status.  I deleted the /etc/zfs/zpool.cache and on reboot it no longer knew about the pool, but no longer locked up.  I was able to recreate everything and did not see that error happen again.  Maybe there was a better way to fix the problem.

I think for the next Linux system I build, I may try a root zfs partition using zfsonlinux.  Even with the one (serious) issue, I was pretty happy with the results of the testing.




Thanks to aarcane for finding a solution that allows you to give users access to the zfs/zpool commands.  Recapped here:

root@onyx:~# nano /etc/udev/rules.d/91-zfs-permissions.rules

#Use this to add a group and more permissive permissions for zfs
#so that you don't always need run it as root.  beware, users not root
#can do nearly EVERYTHING, including, but not limited to destroying
#volumes and deleting datasets.  they CANNOT mount datasets or create new
#volumes, export datasets via NFS, or other things that require root
#permissions outside of ZFS.
ACTION=="add", KERNEL=="zfs", MODE="0660", GROUP="zfs"
 
root@onyx:~# groupadd zfs
root@onyx:~# gpasswd -a username zfs 

Now, reboot.  Upon login, the specified user should be able to run zfs list and zpool status without using sudo.

22 March 2011

Open Indiana

Saw this... maybe I'll do this to the home server.

27 October 2010

In case anyone missed it... departures from Oracle...

I think this quote says it all:
Doug Lea resigns from the JCP
“I believe that the JCP is no longer a credible specification and standards body, and there is no remaining useful role for an independent advocate for the academic and research community on the EC.”
There are quite a few more as well.

08 October 2010

Update! Technology: Forecast -- increased chance of cloud...computing

I was recently interviewed by Justin Lacche, Managing Editor of  Update! regarding cloud computing.  Go have a gander :)

13 August 2010

Oracle kills OpenSolaris

I just have to wonder.  When Oracle is dead feasting on the dead Sun like a zombie; will there be anything left?  Do we even care anymore or do we move onto Life-After-Oracle by choosing a new OS platform, a new programming language, a new filesystem etc etc etc?

20 July 2010

zfs-fuse


I have recently been looking at using some low-power hardware that has Debian installed (and does not support OpenSolaris).  Combined with Oracle's demantling of Sun, I decided to test zfs-fuse.  These instructions are in no way supposed to indicate the correct or easiest way -- simply the way I managed to get it installed and tested.

  1. download the Debian Lenny installer
  2. create a new VirtualBox machine
    1. make sure to create some extra drives... so in addition to SCSI0/sda being set aside for a 20gig hard drive, I created SCSI1-SCSI5 (sdb-sdf) as 2gig drives labeled "ztest1" through "ztest5"
    2. keep track of those addition sdX names, you will need them later
  3. reboot when prompted; make sure to remove the installer CD
  4. su - root
  5. apt-get install sudo bzip2
  6. visudo
    1. uncomment the sudo group line at the bottom
  7. nano /etc/group
    1. add yourself to the sudo group
  8. apt-get install build-essential
  9. apt-get install libaio-dev libattr1-dev libacl1-dev libz-dev libfuse-dev libfuse2 scons libssl-dev
  10. exit
    1. to get back to your user
  11. mkdir work
  12. cd work
  13. wget http://zfs-fuse.net/releases/0.6.9/zfs-fuse-0.6.9.tar.bz2
  14. bunzip2 zfs-fuse-0.6.9.tar.bz2
  15. tar xvf zfs-fuse-0.6.9.tar
  16. rm zfs-fuse-0.6.9.tar
  17. cd zfs-fuse-0.6.9/src
  18. scons
  19. sudo scons install
  20. nano ~/.profile
    1. PATH="$PATH:/sbin:/usr/local/sbin"
  21. log out and back in
  22. modprobe fuse
  23. sudo nano /etc/fstab
    1. add this line:

      none /sys/fs/fuse/connections fusectl none 0 0
  24.  sudo mount -a -t fusectl
  25.  sudo zfs-fuse &
  26.  sudo zpool create rpool raidz2 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
  27. sudo zfs create rpool/data
On reboot, I had some issues (I need to write a proper boot script), but I did this to get it running again:
  1. su - root
  2. modprobe fuse
  3. mount -a -t fusectl
  4. zfs-fuse &
  5. zpool status
  6. zfs list
  7. zfs mount rpool/data
References:
http://zfs-fuse.net/
http://drwetter.org/blog/zfs_under_linux.en.html

    14 July 2010

    Slashdot: OpenSolaris Governing Board Closing Shop?

    Posted by CmdrTaco on Wednesday July 14, @11:27AM
    from the so-it-comes-to-this dept.
    echolinux writes "Frustrated by Oracle's refusal to interact with the OpenSolaris community or speak with the OpenSolaris Governing Board, the OGB has issued an ultimatum to Oracle: designate a liaison to the OGB by August 16th or the board will 'take action at the August 23 meeting to trigger the clause in the OGB charter that will return control of the community to Oracle.'"

    18 April 2010

    Galatea - A Maven/Android Archetype

    After my experience writing an archetype for Red Dwarf; I decided to do the same thing for Android.  This archetype is based on the maven-android-plugin. I'd like to thank Hugo for helping me get the configuration correct.   So let's get started.

    As before...
    F:\work>mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building Maven Stub Project (No POM) 1
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-archetype-plugin:2.0-alpha-5-SNAPSHOT:generate (default-cli) @ standalone-pom ---
    [INFO] Generating project in Interactive mode
    [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
    Choose archetype:
    1: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> ardor3d-archetype (null)
    2: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> kryten-archetype (null)
    3: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> galatea-archetype (null)
    4: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> kryten-archetype (null)
    Choose a number: : 3
    [INFO] snapshot org.eoti.galatea:galatea-archetype:1.0-SNAPSHOT: checking for updates from eoti-public
    [WARNING] *** CHECKSUM FAILED - Checksum failed on download: local = 'c4696ce0aeee29d53523e63f02230636518f8ad2'; remote = 'deb2361707aa66b51d4055be6452e818b9283be2' - RETRYING
    [WARNING] *** CHECKSUM FAILED - Checksum failed on download: local = 'c4696ce0aeee29d53523e63f02230636518f8ad2'; remote = 'deb2361707aa66b51d4055be6452e818b9283be2' - IGNORING
    Define value for property 'groupId': : org.eoti.android.test
    Define value for property 'artifactId': : TestAndroid
    Define value for property 'version':  1.0-SNAPSHOT: :
    Define value for property 'package':  org.eoti.android.test: :
    Confirm properties configuration:
    groupId: org.eoti.android.test
    artifactId: TestAndroid
    version: 1.0-SNAPSHOT
    (hit enter)
    package: org.eoti.android.test
    (hit enter)
     Y: : (hit enter)
    [WARNING] Don't override file F:\work\TestAndroid\src\main\android\res\values\strings.xml
    [WARNING] Don't override file F:\work\TestAndroid\src\main\android\res\layout\main.xml
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 1:02.860s
    [INFO] Finished at: Sun Apr 18 19:58:56 PDT 2010
    [INFO] Final Memory: 6M/11M
    [INFO] ------------------------------------------------------------------------

    F:\work> cd TestAndroid
    The resulting files:

    F:\work\TestAndroid>tree /F
    Folder PATH listing for volume WINDOWS
    Volume serial number is 9827-5E66
    F:.
    │   pom.xml

    └───src
        │   AndroidManifest.xml
        │
        └───main
            ├───android
            │   └───res
            │       ├───drawable
            │       │       icon.png
            │       │
            │       ├───layout
            │       │       main.xml
            │       │
            │       └───values
            │               strings.xml
            │
            └───java
                └───org
                    └───eoti
                        └───android
                            └───test
                                    MyActivity.java

    Make sure you have your emulator running (emulator -avd Device1, in my case):
    F:\work\TestAndroid>mvn install
    This will build, package and deploy it to your emulator.
     
    F:\work\TestAndroid>mvn clean
    In addition to cleaning your build tree, that will undeploy your app from the emulator.

    12 April 2010

    Et tu Java?

    We all know that Sun employees are dropping like flies (either by quitting or being laid off with their entire teams)...  It seems that shortly after finding out that Kohsuke quit, we find out that James Gosling has quit as well.

    Does anyone NOT fear the future of Java under Oracle's "leadership"?

    Project Darkstar, Red Dwarf, Kryten

    As you are probably aware, Project Darkstar is no more.  Owen and others have moved it over into a new project called Red Dwarf.  One of the things I noticed was that they have a maven plugin to ease quick development cycles.  I decided to spend some time this weekend getting associated with the plugin and the new project.

    I started off by redoing the original tutorial exercises from the Darkstar ServerAppTutorial and ClientTutorial.  One of the goals while doing this was to come up with a basic skeleton to get a RedDwarf project up and running quickly.  After getting each tutorial exercise running as a submodule in maven, I tweaked the pom's until I had a fairly clean approach.

    Originally I had planned on documenting those minimal steps here.  Instead, I chose to write my first maven archetype.  I'm sure there are errors and such, but as you will see below, this should give you an entry point very quickly.  (Getting the archetype catalog working in Nexus was another story because it took me a few hours to realize that you will get a 500 Server Error if you try to point to a repository group [like 'public'] instead of a specific repository [thus the long URL below]).

    Ok, let's get started.  First thing we need to do is use the archetype to create a basic structure:



    F:\work>mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building Maven Stub Project (No POM) 1
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-archetype-plugin:2.0-alpha-5-SNAPSHOT:generate (default-cli) @ standalone-pom ---
    [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
    [INFO] Setting property: velocimacro.messages.on => 'false'.
    [INFO] Setting property: resource.loader => 'classpath'.
    [INFO] Setting property: resource.manager.logwhenfound => 'false'.
    [INFO] Generating project in Interactive mode
    [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
    Choose archetype:
    1: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> ardor3d-archetype (null)
    2: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> kryten-archetype (null)
    Choose a number: : 2
    [INFO] snapshot com.example.myapp:kryten-archetype:1.0-SNAPSHOT: checking for updates from eoti-public
    [WARNING] *** CHECKSUM FAILED - Checksum failed on download: local = '218a428a68f50b483a388f7fee54d2bb1ceec981'; remote = 'f1bcef05eca9d0e230f5dc8ff1fa0b8af1e8ab53' - RETRYING
    [WARNING] *** CHECKSUM FAILED - Checksum failed on download: local = '218a428a68f50b483a388f7fee54d2bb1ceec981'; remote = 'f1bcef05eca9d0e230f5dc8ff1fa0b8af1e8ab53' - IGNORING
    Define value for property 'groupId': : org.eoti.kryten.test
    Define value for property 'artifactId': : TestApp
    Define value for property 'version':  1.0-SNAPSHOT: :
    Define value for property 'package':  org.eoti.kryten.test: :
    Confirm properties configuration:
    groupId: org.eoti.kryten.test
    artifactId: TestApp
    version: 1.0-SNAPSHOT (hit enter)
    package: org.eoti.kryten.test
    (hit enter)
     Y: : (hit enter)
    [INFO] Parent element not overwrited in F:\work\TestApp\api\pom.xml
    [INFO] Parent element not overwrited in F:\work\TestApp\client\pom.xml
    [INFO] Parent element not overwrited in F:\work\TestApp\server\pom.xml
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 25.844s
    [INFO] Finished at: Sun Apr 11 23:26:34 PDT 2010
    [INFO] Final Memory: 6M/11M
    [INFO] ------------------------------------------------------------------------
    F:\work>cd TestApp
    I have bold-faced the actual typing involved...  This will create a basic structure:
    F:\WORK\TESTAPP
    │   pom.xml

    ├───api
    │   │   pom.xml
    │   │
    │   └───src
    │       └───main
    │           └───java
    │               └───org
    │                   └───eoti
    │                       └───kryten
    │                           └───test
    │                               └───api
    │                                       MyApp.java

    ├───client
    │   │   pom.xml
    │   │
    │   └───src
    │       └───main
    │           └───java
    │               └───org
    │                   └───eoti
    │                       └───kryten
    │                           └───test
    │                               └───client
    │                                       MyClient.java

    └───server
        │   pom.xml
        │
        └───src
            └───main
                ├───java
                │   └───org
                │       └───eoti
                │           └───kryten
                │               └───test
                │                   └───server
                │                           MyServer.java
                │                           MyServerUser.java
                │
                └───resources
                    └───META-INF
                            app.properties

    As you can see, this makes a multimodule project.  The top-level pom specifies versions of libraries, repositories, etc.  The API module provides a common library to be used by both the client and server [in this case, it just converts Strings to/from ByteBuffers.  The server module is a minimalist server app and the client module is a minimalist client app (console i/o rather than swing from the tutorials).

    To get started, we first need to build it
    F:\work\TestApp>mvn clean install
    Next, we will startup a red dwarf server, deploy the app and dependencies to it, and then boot it.
    F:\work\TestApp>cd server
    F:\work\TestApp\server>mvn validate -Psgs-run
    This utilizes a maven profile (named 'sgs-run') to do all the heavy lifting via the red dwarf maven plugin.

    In another terminal, go to the client subdirectory and start the client:
    F:\work\TestApp\client>mvn validate -Pclient-run
    The client-run profile just executes the client module (executable jar) with the dependencies in the classpath.  When it starts up, it will log into the server then wait for you to type.  Every time you hit enter, it will send the text you had typed to the server.  The server will simply respond with a message telling you that it received the message.  When you are done, type 'quit' or 'exit' to stop the client.

    Once you are done and you want to stop the server, make sure to use the profile to stop it or you will have to kill it in the task manager (ie: do NOT use ctrl-c).
    F:\work\TestApp\server>mvn validate -Psgs-stop
    It will take about 1-2 minutes to shut down cleanly (in the 'sgs-run' window).

    Now that you have a basic structure that you can easily run and test, start editing the code =)

    NOTE: The URL has been changed:
    mvn archetype:generate -DarchetypeCatalog=http://repository-malachid.forge.cloudbees.com/public-snapshot/archetype-catalog.xml