Lotus, Linux, Apple, Australia and whatever else crosses my mind...

Book recommendation: jQuery in Action

Michael Brown  July 15 2010 06:14:13 AM
If you're dabbling in jQuery - and if not, why not? - then you seriously need to buy this book:

jQuery in Action, Second Edition by Bear Bibeault and Yehuda Katz


I'm only half way though it now.  I've been slowed down by having to stop and slap myself in the head every three or four pages.  That's slapping my head in disgust at the reams of crappy JavaScript code that I've written in the past that I didn't even need to write at all (let alone write crappily!)  jQuery just makes it all so easy, and this is the book to holds your hand all the way through it.

This afternoon, for example, I knocked up a modal dialog box using jQueryUI.  It took me about an hour, and works in all browsers, including IE6.  That work probably would have taken me the best of part of week previously; that's if I'd have had the chops to tackle something like that in the first place.  (And even then, it still wouldn't have worked in IE6.)

One of the things I like about the book is it's constant castigating of Internet Explorer for being the piece of shit that it is, although the authors aren't as rude *as me) about it.  They actually handle that subject, as with all their subjects, with a welcome dash of humour, e.g:

Internet Explorer, always the life of the party, does things in its own proprietary way


One other thing that I really liked is that you get rights to a PDF version when you buy the paper copy of the book.  Inside the book, there's a URL and sealed page containing some codes.  You enter the codes on the form at the URL and also enter your email address.  You'll get a  confirmation email with another URL on it.  Click on that, and you get to download the PDF version.  The clever bit is that your email address gets added to every page of the PDF version of the book, so you're not tempted to post it on BitTorrent (not that you'd ever do such a thing, of course!)  So, I keep the real book at home, and a printed out copy of the PDF for reference at work.  I think that's a nice compromise way of the authors protecting their work.  Far better than any pain in the arse DRM system, anyway.

If you are buying the book, make sure you get the Second Edition, which only came out in the last month or two.  This version covers jQuery 1.4 and jQueryUI 1.8, so it's bang up to date as I write this.

Dynamic fields with jQuery

Michael Brown  June 23 2010 03:06:31 AM



The more that use the jQuery add-on library, along with its associated add-on libraries, the more I wonder how I've coped with JavasScript development up to now.

I'm working on an application form where I need to associate one or more addresses with a company group.  (The form's in Domino, but much of the code is applicable whatever your back end is.)  I want the user to enter each address on a single TextArea field, rather than on multiple "Address1", "Address2" lines.

One way to do this in Domino would be to create as many Address fields as I think the form might ever need, and then hide the ones that I don't need.  This is a clunky method though; if you create five such fields, you know it's only a matter of time before the users will want a sixth one!  I'm after something more dynamic and without limits.


Setting Up the First Field

It's easy enough to set up the first address field on the form.  Here's the HTML (angled brackets replaced with square ones to stop the code from parsing):

[div id="divAddressesEditMode"]
[textarea name="taAddress1" id="taAddress1" rows="5" cols="75"][/textarea]
[/div]


It's a simple TextArea field that's inside a div.  The div is important.

(Note how I've done this as raw HTML rather than use a Domino field. That's because to get a TextArea from a Domino field I'd have to define the field as a Rich Text, which is a pain that I can do without!  There's other reasons not to use a Domino field, and these should become clear as you read on.)


The Add Address Button

That's fine if the user has only one address to associate with this form.  What I want now is an Add Address button, in case the user wants to associate other addresses with that form.  Here's the JavaScript code for my Add Address button:

$("textarea#taAddress1").clone(true).val('').appendTo("div#divAddressesEditMode");


Using jQuery, it makes a clone of the my "taAddress1" TextArea tag, sets its value to an empty string and appends it to the "divAddressesEditMode" div.  That's one line of jQuery to do that, although it's actually a number of jQuery instructions chained on that one line.  You might find it easy to read like this:

$("textarea#taAddress1")
.clone(true)
.val('')
.appendTo("div#divAddressesEditMode");


This does exactly the same as the single-lined version listed above.

There's a problem with this initial code though: the clone() parameter, if left to its own devices, will clone everything from the source field, including its ID and NAME parameters if present.  (And you do need the ID parameter to be present to do anything with jQuery).  Here's the HTML that we'll end up with after clicking the Address button the first time:

[div id="divAddressesEditMode"]
[textarea name="taAddress1" id="taAddress1" rows="5" cols="75"][/textarea]
[textarea name="taAddress1" id="taAddress1" rows="5" cols="75"][/textarea][/div]


(Note: I'm using the the View->Generated Source Code function of FireFox's Web Developer Toolbar to see this generated HTML.  An ordinary View->Source only shows the HTML that was there when the page was first loaded.)

Yep, we've now got two "taAddress1" fields, and a heap of problems!  What we need is to manually set the ID and NAME parameters after cloning the first field and before we append it to the div.  Here's a modified version of the Add Address button that does just that:

$("textarea#taAddress1")
.clone(true)
.attr({'id': 'taAddress' + (taCount + 1), 'name': 'taAddress' + (taCount + 1)})
.val('').
appendTo("div#divAddressesEditMode");

The attr() function here incements the cloned field's ID and NAME values - "taAddress2", "taAddress3" etc - as determined by the taCount counter variable.  Now our generated source code looks a lot more useful:

[div id="divAddressesEditMode"]
[textarea name="taAddress1" id="taAddress1" rows="5" cols="75"][/textarea]
[textarea name="taAddress2" id="taAddress2" rows="5" cols="75"][/textarea][/div]


But how to set the value of taCount?  Well, we could keep that as a global variable, and keep track of how many times the user's clicked the button during that session, but that kind of dead reckoning code is severely error prone, IMHO.  It's also unnecessary, because jQuery gives us another single line way of tracking this:

var taCount = $("div#divAddressesEditMode > textarea").size();


This code gets a count of how many textarea elements are directly inside the "divAddressesEditMode" div. Problem solved.  Put the code together and we now have a working Add Address button:

var taCount = $("div#divAddressesEditMode > textarea").size();
$("textarea#taAddress1")
.clone(true)
.attr({'id': 'taAddress' + (taCount + 1), 'name': 'taAddress' + (taCount + 1)})
.val('').
appendTo("div#divAddressesEditMode");



One last, optional refinement.  As written, the code will append the TextArea fields directly after each other.  This means that they will go side by side, depending on how wide the div and/or the browser page is.  I want the TextArea fields to go underneath each other though, so I need to a append a BR tag before each TextArea that I'm appending cloning.  Here's the final version Add Address button code with this a new line to do this:

var taCount = $("div#divAddressesEditMode > textarea").size();
$('
').appendTo("div#divAddressesEditMode");
$("textarea#taAddress1")
.clone(true)
.attr({'id': 'taAddress' + (taCount + 1), 'name': 'taAddress' + (taCount + 1)})
.val('').
appendTo("div#divAddressesEditMode");


And here's the HTML that it generates:

[div id="divAddressesEditMode"]
[textarea name="taAddress1" id="taAddress1" rows="5" cols="75"][/textarea]
[br id="addressBR1"]
[textarea name="taAddress2" id="taAddress2" rows="5" cols="75"][/textarea]
[br id="addressBR2"]
[textarea name="taAddress3" id="taAddress3" rows="5" cols="75"][/textarea][/div]


The new jQuery line creates a new BR tag and appends it to the div before the TextArea is appended.  You'll note how the BR tag is given an ID paramater of its own - yes, even a humble BR tag can have an ID!!  We'll need to use this ID field when we want to get rid of the generated tags with our Delete Address button, speaking of which....



The Delete Address Button

We'll assume that our Delete Address button will remove the last TextArea that's in our div.  Here's the initial code to do that:

var taCount = $("div#divAddressesEditMode > textarea").size();
var $currentTextArea = $("textarea#taAddress" + taCount);
$currentTextArea.remove();
$('br#addressBR' + (taCount - 1)).remove();


We count the number of TextAreas on the div again; use that number to work out the ID of the highest placed one; and then delete it. Finally, we also delete the preceding BR tag, using its ID parameter.

We need to put some error checking into the above code though.  For one thing, there is nothing to stop the user clicking the Delete Address button to eventually remove the original TextArea too.  And when that happens, the Add Address button will no longer work because there will be nothing left for it to clone.  Also, we don't really want to be removing any TextAreas that have data in them, at least not without consulting the user first.  So, let's cut to the chase.  Here's the final version of the Delete Address button:

var taCount = $("div#divAddressesEditMode > textarea").size();

// Remove the last TextArea as long it's not also the *first* one.
if (taCount > 1) {
var $currentTextArea = $("textarea#taAddress" + taCount);
if($currentTextArea.val() !== '') {                // Check if there's a value in there, and warn the user if there is
    if(confirm('Address ' + taCount + ' currently contains an entry, which will be wiped if you proceed.  Is this okay?')) {
            $currentTextArea.remove();
            $('br#addressBR' + (taCount - 1)).remove();  //  need to get rid of the preceding
tag
    }
}
else {
    $currentTextArea.remove();
    $('br#addressBR' + (taCount - 1)).remove();    //  need to get rid of preceding
tag
}
}
else {
alert('Cannot remove first address field');
}



This version first checks if the count of TextAreas currently on the Div is equal to 1, and immediately exits if that's the case.

If we've more than one TextArea present, it checks to see if there's any data in the one with the highest ID number.  If there's data present in it, then the user gets a confirm() dialog that asks if they really want to delete the field.  If there's no data present, the field is deleted without any prompting.  In both cases, the preceding BR tag is also deleted.



Working Example









Problems - Saving the Data

There's a tiny, tiny problem with not using Notes fields: the data doesn't get saved!  No, Domino does not automatically create equivalent Notes fields for all the HTML fields that we've dynamically generated with our buttons.  If you save the web form, there will no "taAddress1" or "taAddress2" fields to be seen at the Notes back end; you've got nothing!  And you want to make some kind of issue out of that?

Okay, we're going to have to do some extra work to get the data saved, and also to get it the fields repopulated from that data when our web form is re-opened.  This is a topic in its own right, so it's going on a post of its own.  (Watch this space).









Avoid using JavaScript getYear() function

Michael Brown  June 21 2010 04:09:19 AM
This is is what happens when you design for a monoculture - especially one as godawful as Microsoft's - instead of designing to standards.

The JavaScript function getYear() is supposed to return the year from a date value, but relative to the year 1900.  So, if you ran the code below:

var todayVar = new Date; // Initialised to today's date
alert(todayVar.getYear());


on today's date, 21st June 2010, it should return the number "110".  And on any browser other than IE, that's exactly what it does.  IE on the other hand, returns the full, four-digit year, "2010"; that's on all versions of IE, up to and including version 8.

Why is this a problem?  Well, it's not if all you're ever planning to use is IE.  And if that describes you, then you seriously need shooting.  The problem occurs, of course, if you use any browser other than IE.  For example, I've just seen an application that relied on getYear() returning a four-digit date to do its thing.  The developer had seen getYear() do that in IE and simply assumed that's what the function is supposed to do rather than looking the function up.  The end result was that IE appeared to be the only browser that worked correctly, whereas other browsers produced screwy results.

If that developer had tested with just one other browser, he'd have spotted his mistake and rectified it.  The correct function to use, by the way, is getFullYear(), which returns a four-digit year on any browser.  

JavaScript links and right-click annoyances!

Michael Brown  May 27 2010 06:49:44 AM
Scenario
Sometimes you want the user to be warned in some way before (s)he clicks on a URL on your web page; e.g. if it's going to lose them all the data that they've entered on a form there.  The usual way to do this is to use the onclick event to call a JavaScript function to do the work.

Here's an example of such a JavaScript function:

function navigateToNewDoc() {
    if(confirm('This will create a new calculation form, so losing all the values that you have currently set. Continue?')) {
          location.href = newCalcURL;   // Assume newCalcURL has been preset to the URL that we need
    }
}


And here's the HTML code that calls it.  (NB: I've replaced the angled brackets with square ones to stop the code from rendering):

[a href="#" onclick="navigateToNewDoc();"][img src='button_new_01.gif?OpenImageResource' alt="Back" border="0"][/a]


The "a href" URL is replaced by a dummy one, because it's no longer used.   Instead, we use the onclick call to the navigateToNewDoc function to forward us to the new URL, but only after the user has clicked "OK" on our warning dialog.

So far, so standard.


Problem

Where this technique comes unstuck is when you try to right click on such a link and have it open in a new window or tab.  In this case the browser will ignore the onclick event and will try to open the actual URL, which in the example above doesn't exist (we replaced it with "#").  Either that or will try to open the JavaScript code itself as the actual URL!!  We'll either get a browser error or at best, it will simply open the current tab's URL in the new tab. You'll see a bazillion examples of this on the interweb every day.  And don't you just hate, hate hate it!  I know I do.

If we try to get around this by restoring the real URL into the "a href=" statement, then we will get the right-click behaviour that we need but that messes up the left-click behaviour!  What will happen now is that the main URL will be always be followed on a left-click, regardless of how we answered the JavaScript confirmation dialog.


Solution

The trick to making it work both ways is to put a "return false;" statement as the last statement of the onclick call.  This prevents the main "a href=" URL from being followed for a left-click (but not for a right-click + Open in New Tab), so leaving the onclick call to take care of the left-click scenario, as it did before.

Here's the revised HTML:

[a href="/mydb.nsf/myForm?OpenForm"  onclick="navigateToNewDoc(); return false;"][img src='button_new_01.gif?OpenImageResource' alt="Back" "border"=0][/a]


Now we can have our cake an eat it too.  We get our warning dialog on a left-click, but can still open the new form

Shock! Horror! Man responsible for OOXML admits "failure"

Michael Brown  April 3 2010 07:12:56 PM
Alex Brown, the man who is largely responsible for the passing of Microsoft's OOXML "standard", IMHO, has just made an amazing blog post, in which he admits, in effect, that Microsoft used him.

Yep, it seems that since Microsoft got the coveted ISO stamp of approval, it's made pretty much zero attempts to fix all the problems in it like it promised to.  Really, Microsoft lied?  You could have knocked me down with a feather when I found out.

So shout it from the rooftops!  Whenever anybody, Microsoft or otherwise, bangs on about the standards support in Microsoft Office, you can plainly contradict them.  Microsoft does not support any standards, not even its own.  Not in Office 2007 and not, it appears, in Office 2010 either.





My own comment, which I've posted as response on Alex's site, is as follows:

@Alex,
Standardizers should be skeptical of corporations ... I think the view that reduces corporate disputes to some kind of soap opera with "goodies" and "baddies" is reductive and unintelligent

I appreciate that treating the likes of Microsoft with a Jeremy "why is this lying bastard lying to me?" Paxman approach is a luxury not available to a neutral body such as ISO. Even if that had been your thoughts at the time, you still had to treat all parties fairly and equally.  It's like how we vote for politicians based on what's in their manifestos, even though we know that they probably won't keep too many of their promises once they're in power.  (Just occasionally though, they do come through, e.g. Obama's Health Bill.)

By the same token, however, you didn't have to bend over backwards to help Microsoft get their standard approved either.  For surely, that is what you did.  Rather than following your own (very sound) advice to be "skeptical of corporations", you displayed an unbelievable naivety in trusting that Microsoft would make any serious attempt to fix its problems once the company had obtained the coveted ISO stamp of approval.

By any objective view of the text, as it existed at the time of the BRM, the standard should have failed.  Five days was never enough time to fix its mountain of problems.  Game over.  Do not pass Go.  Do not collect $200.  Fail.

But by splitting the standard into Transitional and Strict versions, the BRM found a way, perhaps the only way, of getting it through.  You also proposed the "all or nothing" vote, when it became clear that there was not enough time to discuss all the NB's issues on an individual basis.  Did ISO rules require you to come up with this?  I think that they did not.  You appear to have interpreted your role as to find the best way to get the standard passed, come whatever.  That was *your* choice and ultimately it was your failure.

Domino image now on Amazon EC2... errmm, I think! (Updated)

Michael Brown  April 1 2010 10:30:00 AM
Update 1st April 2010
As I suspected, IBM's EC2 guide wasn't supposed to have been released just yet.  See comment from IBM's Mike Masterson on this post, and also on the IBM guide itself  (URL below).

Thanks to Mike for the update.




Since writing my post Setting up Domino on Amazon's EC2 cloud servers only a few weeks ago, IBM has released its first Domino AMI image on the Amazon's EC2 cloud server.  See IBM Lotus Domino 8.5.1 on Amazon Web Services: A getting started guide for details and thanks to Mikkel for the tip-off on this.

I'm damned if I can get the thing to work though.

I ran through the process of setting up such an EC2 image and found the Domino AMI with no problem.  But at the last step on the setup dialog, it failed with the error "Subscription to ProductCode 00E2F293 required".  WTF does that mean, I wonder?  I can not see a reference to any extra sign-up on the Lotus info page.

What that page does say, rather ominously, is "Amazon AMIs that are preloaded with IBM software must be purchased before use".  Then, in the very next sentence, it says "Independent Software Vendors (ISVs) may use the Development AMIs for no additional fee above the normal Amazon EC2 charge."  Hello, boys!  The AMIs are either free or they "must be purchased before use"; both statements can't be true.  If it's only for ISVs, then how does one set oneself up as an ISV for EC2 purposes?

For further information, the documentation links to a page of IBM for EC2 pricing, which, to my complete lack of surprise, doesn't mention Domino at all.

I'm wondering if this getting started guide wasn't supposed to be released just yet.  Most of the screen-caps are near illegible.

Update and upgrade Ubuntu in one command

Michael Brown  March 31 2010 02:59:26 AM
I tend to use the command line to keep Unbuntu up-to-date these days.  Note: it's not because I have to, Microsoft boys, but because I just find it easier.

Still it's a bit of pain having to it in three steps

First, you need to refresh your packages:
sudo apt-get update



When that's finished, you need to start the update itself:
sudo apt-get upgrade


Finally, you need to be there to hit the "y" key for any questions that you're asked; e.g. about installing from repositories for which you've not install keys.  (Yes, I know I should install the keys, but I don't always get around to it.)

So, here's how to the do the whole thing in one go:
sudo apt-get update; sudo apt-get upgrade -y --force-yes



Setting up Domino on Amazon’s EC2 cloud servers

Michael Brown  March 18 2010 01:45:00 PM
A tutorial for how to set up a Domino server on Amazon's Elastic Cloud Computing (EC2) infrastructure.  Note that much of this is relevant to other types of application server too.  In fact, you can find a lot of pre-configured server images - known as AMIs in the EC2 world - for different types of application server.  But there's none for Domino yet.  These are coming though.  See Ed Brill's post for details.


Basics

I've chosen Linux as my server because:
  1. It's cheaper to run on EC2 than the equivalent Windows server
  2. Windows is a poor operating system in just about every regard that I can think of.  Windows' only (dubious) advantage is that there's a lot of so-called administrators around that claim to know how to run it properly.  (They don't.  Nobody does.  Nobody can, in fact.)  Thankfully, I've no need of any Windows server "expertise" for this particular project.
I'm going to pick Fedora 8 for my Linux server 8, merely because it's the the default Linux OS when you're setting up a new EC2 server.  Why Amazon has picked such a old version of Fedora for this, I've no idea, but they have.  Fedora in any version is not a supported platform for Domino, but I managed to get it run okay.


Before You Start

You will need:
  1. The Domino server installer for Linux.  I'm using 8.5.  Don't ask me where to get this from, let alone to post the code somewhere for you.
  2. A Notes Administrator client to do the Domino server post-setup configuration.  I'm using version 8.5, but an earlier version should suffice.  The Notes Administrator only runs in Windows, of course, so you'll need that too.  I ran XP in VirtualBox VM on a Ubuntu host for this purpose.  You'll also need to have the Remote Server Setup option installed.  This will appear as a separate option in your Lotus Applications menu folder in Windows.  If you don't see it there then you'll have to re-run the Notes installer and select it.  It's not installed by default.  (That's the Notes/Designer/Admin client installer.)
  3. Your credit card.  Sorry, EC2 servers are not free.  If you're an Amazon customer already - is there anybody that's not? - then they likely have your cc details already.  You can find EC2 pricing at http://aws.amazon.com/ec2/pricing/ and you'll immediately see how Linux is cheaper: 8.5 cents per hour Vs 12 cents per hour for Windows (that's US cents).  That's for the smallest on-demand instance, which is all we'll need here.
  4. A Linux workstation with SSH installed.  Most Linux workstation distributions will already have SSH installed.  If not, issue "sudo apt-get install openssh-client" (without the quotes) into a terminal to install  it (or "yum install" if you're using an RPM-based distribution).

If you want to use Windows as your workstation for this then time to get real.  The mechanisms for interacting with EC2 are heavily slanted towards *NIX-based systems and involve getting your hands dirty with the command line.  The server that I'm setting up in this example has no GUI, so you're not going to be pushing any shiny Windows 7 buttons to do anything with it.  Okay, if you really want to use Windows then you'll need to install Putty, which gives you SSH on Windows.  That's all the help you're getting on the Windows side though because, to be honest, that's about all I know!  (That's the last of the Windows bashing for this article, I promise!)



Signing Up

Get thee to http://aws.amazon.com/ec2/ and click the Sign up to Amazon EC2 button.  It should not take too long, especially if you're already an Amazon customer.  You will need to flash your credit card if Amazon's not already holding info on one for you already.

Once you've gone through the registration process, you'll need to link on the Sign in to the AWS Management Console link.  Here's how it looks

Main EC2 Console Screen

Or here's how it looks for me  I should say.   All the numbers on the My Resources section at the right hand side will read as zero for you because you've not set anything up yet!


Setting up an Instance
  1. To launch a new instance, you need to click on the (wait for it) Launch Instance button.  This will kick of the Request Instances Wizard, displayed below:

    Request EC2 Instance

    See what I mean about Fedora 8?  Oh yeah, that other OS is there too.  We don't need anything special on our Fedora server, so pick "Basic Fedora Core 8" and click its corresponding Select button.

  2. Take the defaults on the Instance Details dialog that comes up next, then click Continue.  Do the same for the second Instance Details dialog.

  3. On the Create Key Pair dialog that comes up next, click on the Create Key Pair radio button, if it's not already selected.  The name will default to "ec2-keypair" so let's take that and then click on the "Create & Download your Key Pair" link.  You'll be prompted for a save location; remember where you put it!!  And keep it safe.  Put a back up on another drive somewhere, such as a USB key.  If you lose this key then you'll be unable to access any instances that are associated with it!

  4. Create a new security group.  You should open up the following ports in order to access a Domino server:

    • SSH - Port 22
    • HTTP - Port 80
    • HTTPS - Port 443 (only necessary if you're using SSL)
    • Notes Client access - Port 1352
    • Notes remote setup access - Port 8585

    At this point, however, you'll only be able to enter the first three.  (SSH should be already done for you, in fact.)  This is because there's no "Custom..." option in the dialog.  We'll have to add the two Notes protocols later on.

  5. Click Continue to go to the Review dialog.  Here you can change anything that you need to, but you shouldn't need too.  Click on the Launch button and you're off!

Congratulations, your new instance should be up and running in a minute or two.  Warning: the clock is ticking against your credit card from this point onwards.


Post Config 1 - Finish off your security group

While you're waiting for your instance to come up, you can add the two Notes protocols to your security groups:
  1. Back in the AWS console, click on Security Groups on the left hand side. then click on your security group from the list.
  2. Drag the middle window up (just like it was a previewed email in Lotus Notes) so you can see it properly.  Notice that the drop-down on the left now has the "Custom..." option, which wasn't there when we were setting up on the Security Group in the Setup Wizard.
  3. First we'll do the Notes client protocol.  Change the the Protocol to "TCP" and both the From and To Ports to 1352.  The Source IP field should be set to 0.0.0.0/0, as it is on the three protocols that you already have.  When every field is completed, the Save button should become enabled, so go ahead and click it.
  4. Now we'll do the Notes Remote Setup protocol.  Repeat the process in the step above, only this time set your From and To Ports to 8585.  Click on the Refresh button at the top if not all of your protocols show in the list.  It should look as below:

    EC2 Security Groups

That's your security setup.  Time to connect to your instances.


Post Config 2 - Set permissions on your key pair file

SSH won't connect to your instances if the permissions on key file are not set correctly.  So, open a terminal console and type in the following:

chmod 400 /pathtoyourkeyfile/ec2_keypair.pem


Replace "pathtoyourkeyfile" with the ermm... path to your files!

If you don't do this step then you'll get the error "WARNING: UNPROTECTED PRIVATE KEY FILE!" when you try to SSH into your instance (see next) and your connection will be dropped.



SSH into your instance

Still in your terminal console, enter the code to connect to your instances.  The syntax will look like something like this:

ssh -i /pathtoyourkeyfile/ec2-keypair.pem root@ec2-174-129-63-93.compute-1.amazonaws.com


To get the exact string to connect to your instances is easy.  Find your instance in the instances list in the AWS Console and right-click on it, then pick "Connect" from the pop-up menu.  A dialog will appear containing the connection string for your instance.  Simply copy and paste it into an terminal console to make the connection.  Note though that the connection string that copy assumes that you've already changed (cd) to your keyfile's folder in the terminal before pasting in the string.  If you've not done that, then you need to prepend to the keyfile's path to its name, as I did in my example above.

When you hit enter into the console, you should see a message about "the authenticity of host" and the "RSA key fingerprint", and you'll be asked if you want to continue.  Just type "yes" (no "y" on its own) and hit enter.  You should now have connected to your instance.



Setting up an Elastic IP address for your instance

I was hoping to explain this part later as an optional (but very useful) tip.  But it seems that you need to assign an Elastic IP address to your instance in order to complete the Domino server's setup, so I'll explain it now.

Elastic IPs are a way of assigning apparently fixed IP addresses to your instances.  I say "apparently fixed" because you can assign them to different instances on the fly.  These re-assignments take effect almost immediately, and with no need to reconfigure any DNS anywhere.  You get five of them for free with your Amazon EC2 account.

To assign one to your instance:
  1. Log into the Amazon AWS Console and then click on Elastic IPs on the left hand side.
  2. Click on the Allocate New Address button at the top.  This should add a new IP address in the list.  (Click on the Refresh button if it doesn't.)
  3. Right-click on the IP address in the list and pick "Associate Address" from the pop-up.
  4. A dialog should appear with a drop-down field that shows you a list of all your running instance IDs.  Since you should only have one running at this point, select that one and click the Associate button.

You're done.  Painless, wasn't it?

You can now use the Elastic IP to refer to your instance in place of the full EC2 Public DNS address that we've been doing up to now.  E.g.:

ssh -i /pathtoyourkeyfile/ec2-keypair.pem root@1.2.3.4

assuming that 1.2.3.4 is your assigned Elastic IP address.

Note that when SSHing into your instance with the Elastic IP address, you'll get prompted about the "RSA key fingerprint" again.  Just answer "yes" when the prompt appears.




Setting up the Notes user on your instance

Initially, you'll only be to connect to your instance as the root user (hence "root@") because that's the only user that's setup by default.  You don't want to be running your Domino server as root though, so time set up a new user called "notes".

While connected to your instance, enter the following:

useradd notes
passwd notes


This will create a new user called "notes" and then prompt your to enter a password for it.

You still can't connect to your instance as "notes" until you've set up server-side SSH files for it.  While still connected to your instances as root, enter the following:

mkdir /home/notes/.ssh
cp /root/.ssh/authorized_keys /home/notes/.ssh


That's copied over the SSH keys to the correct place for the "notes" but the ownership of that folder and its files are still set to "root".   Typing the code below will make the "notes" user the owner of its files:

chown -R notes:notes /home/notes/.ssh


You can test it now.  Fire up another terminal console, and paste in your connection string again.  Before hitting enter though, replace "root@" with "notes@", so you have something like this:

ssh -i /pathtoyourkeyfile/ec2-keypair.pem notes@1.2.3.4




Getting the Domino Installer file onto your instance

Before you can install Domino, you need to get the Domino installer file on it.  We'll use SSHFS for this.  SSHFS is the file transfer equivalent of SSH.  It's a bit like FTP, only far more secure.  If it's not installed on your system, you'll need to type:

sudo apt-get install sshfs

into a local terminal console window to install it.

Also, before you can attach to your instance, you need to create a folder on your local workstation where you're going to mount the instance.  In a (local) terminal console, type the following:

mkdir ~/mountec2


That will create a folder called "mountec2" as a sub-folder of your current local user's home folder.  (The tilde character is a substitute for "/home/yourusername".)  Below is the syntax that I used to mount my instance's /home/notes folder at the new folder that I just created on my workstation:

sshfs -o IdentityFile=~/Desktop/ec2/ec2-keypair.pem root@1.2.3.4:/home/notes ~/mountec2


The ~/mountec2 folder on your workstation is now mapped to the /home/notes folder on your instances.  All you need to now is open the ~/mountec2 folder in Nautilus or Dolphin (or whatever your preferred file manger is) and drag the Domino installer file over to it.  Copying should now begin and it's time to put on a DVD... a long one.  On my ADSL2+ line, the Domino installer took two hours to copy to my instance.  That's from Australia though.  Your kilometrage may vary.



Installing Domino

While SSHed into your instance as the root user, change directory (cd) to the /home/notes folder and enter:

tar -xf *.tar


to extract the files from the .tar file installer.  When it's done - it will take a minute - type in the following to start the installer:

cd domino/linux
./install

and let the install routine do its thing.  You should take all the defaults that the installer offers.  It will take about five minutes to run though.  (See Installing Domino on Fedora Linux for more details on the running through the Domino installer's questions and answers.)



Configuring the Domino server

You'll need to use Windows (ugh!) for this next bit.  You'll need to be able to SSH into your instance at the same time.  This might be a bit awkward if you've only one machine to work on.  You'll either have to do everything Windows, using Putty for your SSH needs, or you can run Windows inside a Virtual Machine (which is my own preference).

Within Windows, launch the Remote Server Setup application, which is under the Lotus Applications menu group in Windows.  (Refer to the Before You Start section at the top of this article if you can't find the Remote Server Setup app.)  When the dialog pops up, paste in the Elastic IP address of your EC2 instance, but don't hit OK just yet.  You should leave it looking like so:

Domino's Remote Admin Setup tool

Now SSH into your instance as the notes users (that's "notes@" and not "root@").  We need to launch the Domino server in "listen mode", for which we'll need to append the parameter -listen.  Before that though, we'll need to switch into Domino's data folder, otherwise it will complain that it cannot find the notes.ini file.  Still logged into your instance as the notes user, type in the following:

cd /local/notesdata
/opt/ibm/lotus/bin/server -listen


The Domino server is now in listening mode.

Switch back to your Remote Serverr Setup app in Windows and hit the OK button.  All being well, the Server Setup routine should start.  I hope you've thought of a name for your Domain, Organisation and your first server!

When you get to the dialog that says "Make optional copies of ID files", make sure that you tick the checkbox of the bottom.  You can then save all your IDs to your local Windows machine or VM, rather than having to hunt around on your server instance for them.

When you get to the last dialog, answer "Yes" when it asks you if the server listener should be stopped.

You'll need to use your Elastic IP address when accessing your Domino server afterwards.




Starting and stopping your Domino server - Screen

You can start your Domino server from the instance's command line, as we did earlier.  Only now, we don't need to use the -listen parameter to start it in "listen mode", i.e.:

cd /local/notesdata
/opt/ibm/lotus/bin/server


When you start the Domino server in this way, you'll soon notice a problem though: whenever you logout of your SSH session, the Domino server stops!!! And you can't get around this problem by leaving yourself logged into it, even if that were desirable (which it isn't).  I tried several ways around this, including Daniel Nashed's startup script, but I could not persuade it to work on Fedora 8.  What did work is Screen.

Screen is a program that allows you launch programs in the background, which is what we want to do with our Domino server.  It's not installed by default on Fedora 8.  To install it, you need to SSH into your instances as the root user and then type:

yum install screen


(If you were using a Debian-based server, that would be "sudo apt-get install screen".)

Now open another local terminal window and SSH into your instance as the notes user.  (We don't want to launch Domino as the root user, remember.)  This is how to launch Domino using Screen:

screen
cd /local/notesdata
/opt/ibm/lotus/bin/server


This launches the Domino server but in a different Screen session.  To return to your original terminal session, simply hit CTRL->D on your keyboard.  You can now logout of your SSH session without shutting down the Domino server.

You can use the Notes Admin client, including the web version thereof, to stop your Domino server.  The syntax for the web version is 1.2.3.4/webadmin.nsf where 1.2.3.4 is your Elastic IP address.


Congrats!  You now have your very own Domino server in the cloud.  Enjoy.  Just remember that it's costing you money for every hour it's up there!



Two-thirds of XP apps not natively supported on Windows 7?

Michael Brown  February 17 2010 04:10:01 AM
Yep, APC magazine is quoting a Forrester report that says that you can expect two-thirds of your XP apps to have problems running on Windows 7.

These are scary numbers, if true.

A long way from the glory days of Windows 95 for Microsoft.  Back then, it could hold back Designed for Windows 95 stickers for applications unless they also ran without modification on Windows NT.  In a flash, NT, which had been struggling for apps, suddenly had thousands of them!  A genius move on Microsoft's part.

So, how come it can't manage the same trick between XP and 7?  Remember, 95 and NT had completely different underlying architectures.  95 was still not much more than graphical front-end for MS-Dos, and contained tons of 16-bit code, whereas NT was designed from the ground-up to be proper 32-bit, pre-emptive, multi-tasking OS.  And yet, apps that ran on 95 could still run natively on NT.  XP and Windows 7, on the other hand, are both based on that same NT architecture.  There's been some changes along the way, but surely XP and 7 are closer together than 95 and NT ever were?  Yet it seems that the majority of XP apps won't run on 7.  Bizarre.

And no way is 7's "XP Mode" the answer.  You think businesses are going to support users supporting two operating systems, when most of them struggle to understand even one?  I think not.

In fact, I went through something similar when my then company were contemplating the move from Mac OS 8/9 to Mac OS X.  Mac OS X had an OS 9 emulation mode called "Classic".  (This was far more justifiable than Windows 7's XP Mode, because Mac OS X was completely and utterly different to its predecessors).  Still, we wanted nothing to do with it, for the reason that I've already given.  We told our vendors to either provide OS X versions of their apps or we'd find other vendors that did.

That's okay for bought-in apps though.  It's your own, in-house developed stuff that's usually the problem.

The perfect opportunity to investigate a move to Ubuntu, IMHO!!



Citrix remote desktop (RDP) on a Macintosh

Michael Brown  February 5 2010 02:35:43 AM
You probably know that there's a full Citrix client for the Mac (and Linux for that matter) but I've always had a real problem when I used the Mac version of Remote Desktop (RDP) to remotely login to my work desktop.  The problem was that I could never enter my password correctly, and I couldn't work out why.  I could always enter it correctly on the Windows and Linux versions of Citrix RDP but not on the Mac.  I've actually ended up locking myself out of Windows several times because of this, and then had to ring the IT helpdesk to reset the password.

Finally, this week, I found the problem: by default, the Shift key on the Mac doesn't work properly.  And because my Windows password (for my work desktop that I'm logging into) contains a character that needs the Shift key to type, there was no way I could ever enter it properly.

Here's the solution to the problem.

When you get to the RDP dialog (below) click on the Options button:

RDP Login dialog


Click on the Local Resources tab and switch the Keyboard drop-down to say
"On the local computer".

RDP Login options dialog



Your Mac Shift key should now work properly with Citrix Remote Desktop.