Working in miniature

Working with computers day in and day out can leave me burned out.  I’ve tried a variety of ways to deal with this over the years, and about 7 years ago, I keyed in on one of my other passions and leveraged that as a way to “unplug” (so to speak).  I am fascinated with the age of sail.  To me, tall ships are some of the most majestic things that have ever been built by man.  While I am aware of the grim realities of life in that era, it is still possible to romanticize it.  However, I digress.  I leveraged this passion and began building model ships.  I started with plastic models and quickly burned through a variety of models due to the relative simplicity of putting together a plastic model.  Then, I few years ago, my father gave me a wooden ship model.  I loved it.  That is when I truly began to turn to model ship building as a way to turn off my digital life.  Since each model takes months and in some cases years to finish, there is always something there waiting for me.

I’ve built several more wood models since that first one that my father gave me, and I have been slowly learning tricks and techniques to add more and more detail to each subsequent model.  Most recently I have been working on a cross section of the H.M.S. Victory.  As I have been tying down the rigging, I started thinking about ways to up the level of detail on this model.  One of the ways that I am trying to accomplish this is by adding the rope coils that would exist on the pins and decking of a working ship.  At the scale that I am working, this proved to be an interesting exercise.  I wanted to make two different types of coils.  the first is the type that all of us are familiar with, the type that most of us use to bundle extension cords and lengths of rope that we have laying about the house.  The second type are a spiral that would lay flat on the deck and out of the way.

The first type of coil is relatively easy.  You need scale rope (thread will work), tweezers and some glue.  Toward the narrow end of the tweezers, start wrapping the thread around using your thumb to hold the loops in place.  Depending on the size of the coil you want to make, add additional loops.  Don’t wrap too tightly so that you don’t start compressing the tweezers.  To help with this, depending on how dexterous you are, you can use one of the fingers your are holding the tweezers with to keep them separated.  Once you have the correct amount of loops (I recommend 4-6), take the thread and wrap it once lengthwise inside the tweezers around the coil that you just created.  Start pulling that single lengthwise loop tight as you slowly move the coil toward the end of the tweezers.  DO NOT take the coil off the tweezers yet.  By moving the coil toward the end of the tweezers, it should allow you to fully tighten the lengthwise loop around the coil.  Continue wrapping additional lengthwise loops until you are content with the finished product.  At this point, you should have something that resembles the picture.  For the final loop, cross the thread back under itself (just like you would on a larger version of the coil).  With the coil still on the tweezers, apply some glue to the lengthwise coils and then set it aside to let it dry. 

The second type of coil is our flat spiral.  If you are familiar with sailing lexicon, this is called a Flemish Flake.  Normally, these are started from the outside in, but in our case, we are going to start them from the inside out.  We are going to need wide packing or masking tape, tweezers, scale rope (thread will work again), and some white glue.  Tear off a piece of tape about 2-3 inches long.  With a length of rope/thread use the tweezers and press it down onto the tape.  Using the tweezers to keep the rope pinned against the tape, start wrapping the rope around the center point.  Once you have a full revolution around the center point, pull up the tweezers and press out the circle you have made so that it is flat against the tape.  Again, use the tweezers to hold the center and start wrapping the rope around the coil keeping the rope as close to parallel to the tape as possible.  What you are trying to do is pull the rope tight against the previous round of the coil using the tweezers to create a barrier between the rope and the table that the tape is laying on without letting the rope to double up on itself.  The first few rounds of the coil are the most delicate, the most you have, the easier the going.  After you have created a coil / flake of the desired size, take some white glue and sub it across the surface.  Once it dries, you will be able to pull the coil off of the tape and it will stay in the desired shape.

From here, it is up to your imagination about where to place your new creations.  In both of the above, it is advantageous to leave a length of rope/thread off of the end of your coil so that you can use that to blend your coil in with the rigging that you have run on your model.

Rope coilsFlemish FlakesFinished coils

Monitor Windows EC2 Instance Free Drivespace via Cloudwatch

Amazon offers a lot of great CloudWatch metrics out of the box for EC2 instances, but there is a key metric that is missing.  Remaining available drive space.

Luckily, there is a relatively easy way to resolve this.  AWS offers us the ability to add in our own metrics that allow us to monitor pretty much anything we want.  In this case, we are going to create something to report back to CloudWatch about the free drivespace on our EC2 instance.

In preparation for this exercise, we are going to do a little prep work.

To start, ensure that the AWS SDK for .Net is available on your EC2 instance.  It should exist in “C:\Program Files (x86)\AWS SDK for .NET\” by default.  If it doesn’t for whatever reason, download and install it.

Next, collect your Access Key and the Access Key Secret and put them to the side.  They’ll be used shortly.

The last thing you will need to gather is the instance ID for the EC2 instance that we’re going to collect metrics for.  If you are uncertain what this is, there are a few different ways to find it.  If you are running a more recent image, it is in the top right corner on the background image.  The best way to get the instance ID however is to log in to the AWS Management Console, go to the EC2 section and the instance ID will be shown in the grid.  It should start with a lowercase “i” followed by a dash and a hex string. e.g. i-a1b2c3d4

The next step is putting together a PowerShell script that will utilize all of the things that we have collected to this point to gather and report on the metrics that we’re after.

So, let’s get started.

Open your preferred PowerShell script editor and create a new ps1 file.  It doesn’t matter what it is called. I named mine updatedrivespacemetrics.ps1 for clarity.

At the top of the script, we are going to import the AWS assembly and set the access key values.

#Import the AWS SDK assembly
Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\AWSSDK.dll" #Credentials $secretAccessKeyID="1234567890ABCDEF1234567890ABCDEF12345678" $secretKeyID="ABCDEF1234567890ABCD" #Get Instance ID $instanceId="i-a1b2c3d4"

Next, create a request object to store the new Metrics and give it a name that you will be able to easily recognize later on.

#Create request
$request = New-Object -TypeName Amazon.CloudWatch.Model.PutMetricDataRequest $request.NameSpace = "CUSTOM-Freespace"

Time to collect the values.  We are going to use WMI to get the freespace from the drives on our instance.

#Get Free Space
$freeSpace=Get-WmiObject -Class Win32_LogicalDisk | Select-Object -Property DeviceID, @{Name='FreeSpaceGB';Expression={$_.FreeSpace/1GB}} | Where-Object {$_.DeviceID -eq "C:" -or $_.DeviceID -eq "D:" }

Let’s look at what this statement is doing.

Get-WmiObject -Class Win32_LogicalDisk

This will return an array of all of the drives on the machine with their DeviceID, DriveType, Freespace, Size and VolumeName

From this array, we are going to select the DeviceID and the FreeSpace.  However, FreeSpace is returning bytes and we need something that is a little easier to parse, so we are going to turn it into gigabytes.  To do this we are going to use an expression to modify the property value before we pull it back.

@{Name='FreeSpaceGB';Expression={$_.FreeSpace/1GB}}

Last, we are going to limit the drives that we pull back.  This part is optional, but can be useful if there are only specific drives that you are interested in.  In this case, I have narrowed it down to the C and D drives.

Where-Object {$_.DeviceID -eq "C:" -or $_.DeviceID -eq "D:" }

Time to start collecting this information into a way that AWS can parse it.  The first step to do this is creating some basic dimensions that will differentiate our custom metric.  To keep things simple we are going to create two dimensions, Role and InstanceID

#Create dimensions
$dimensions = New-Object System.Collections.ArrayList
$dimension1 = New-Object -TypeName Amazon.CloudWatch.Model.Dimension
$dimension2 = New-Object -TypeName Amazon.CloudWatch.Model.Dimension

$dimension1.Name = "Role"
$dimension1.Value = "Test Server"
$dimension2.Name = "InstanceID"
$dimension2.Value = $instanceId

$dimensions.Add($dimension1)
$dimensions.Add($dimension2)

With the dimensions in hand we are going to put everything together into a metric.  For each drive that we collected information on earlier, we are going to create a MetricDatum and populate it with the appropriate values. 

#Create metrics
$metrics = New-Object System.Collections.ArrayList

Foreach ($item in $freeSpace) 
{
	$metric = New-Object -TypeName Amazon.CloudWatch.Model.MetricDatum
	$metric.MetricName = $item.DeviceID + "free space"
	$metric.Value = $item.FreeSpaceGB
	$metric.Unit = "Gigabytes"
	$metric=$metric.WithDimensions($dimensions)
	$metrics.Add($metric)
}

After the metrics are created, we need to update the request object that we created earlier with the metrics data

$request = $request.WithMetricData($metrics)

Finally, we are going to submit all of this information back to AWS.

#Perform the request
$client=[Amazon.AWSClientFactory]::CreateAmazonCloudWatchClient($secretKeyID,$secretAccessKeyID)
$response=$client.PutMetricData($request)

That’s it!  Now we have a script that will push information on available drivespace up to CloudWatch.  The first time it is run it will create the metric if it doesn’t exist.  Each subsequent time, it will just add a new data point to the existing metric.

The final step is scheduling this so that it runs consistently.  The easiest way to accomplish this is the built in Windows Task Scheduler.  I won’t go through the steps for that here, but I would suggest setting it up to run every 5 minutes.  If you are uncertain how to call your script, “powershell c:\jobs\updatedrivespacemetrics.ps1” will get the job done (replace c:\jobs\ with the location of your script).

cloudwatchNow that you have everything set up, you can go into the AWS management console, go to the CloudWatch page and you should see your new metric. 

Note:  You will need to set this up for each instance that you want to gather drivespace on.  Each instance will need its own copy of the script and have the task scheduler set up appropriately.  As you copy the script from instance to instance, you will need to change the InstanceID in the script to reflect the appropriate instance.

Small Design decisions with a large impact

I checked into a nice hotel yesterday. I was very impressed with the room and promptly set about unpacking my things. Because I had been traveling for nearly 20 hours straight, my devices were desperately in need of power.

The lamp next to the bed conveniently had an outlet in the base of the lamp.

20130303-065721.jpg

I do not have a US spec power supply for my laptop, so I am forged to use an adaptor. Now, granted, the adaptor that I have is rather comically large, (my primary one broke and I was forced to find this rather inadequate replacement) but it does serve to illustrate a point.

20130303-070014.jpg

By simply rotating the outlet 90 degrees, this problem would not exist. Again, I realize this is a somewhat extreme use case, but in the instance where the plug was directly on the power brick, as is the case with many devices, this would still be an issue.

S3 directory browsing from a custom subdomain

This week I was asked to set up a site on our server with directory browsing enabled.  They also wanted to be able to upload files to said site.  Since we are already hosting our servers on AWS, I suggested to them that rather than expending the effort to write code to allow them to manage everything via the web, we set up an S3 bucket and allow them to manage the files directly from their desktop.

Somehow I had gotten to this point in time without working with S3.  I am aware of the principle behind it however and I knew it was capable of doing what I had proposed.

Creating a new bucket was easy. Configuring the permissions on the bucket to allow anonymous users was also easy.  Mapping the bucket to a sub-domain and enabling file browsing is where everything started to fall apart on me.

I logged on to AWS and created the bucket.  For the sake of example, let’s say it was called assets.mysite.com.  Something important to note here.  If you are planning on mapping the bucket to a sub-domain like I am in this example, it is typically best practice to make the name of the bucket the same as the sub-domain.

From there I set the permissions to enable everyone to be able to list the contents of the bucket.

Since I knew that my ultimate goal was to map this bucket to a sub-domain on the site, I immediately clicked down to the next tab “Static Website Hosting”, checked “Enable website hosting”, added an index document and clicked “Save”.  I copied the Endpoint that was provided on that tab assets.mysite.com.s3-website-us-east-1.amazonaws.com, jumped over to Route53 and added a CNAME for assets.mysite.com and dropped in the provided Endpoint.

Because I do my research, I knew that to get a list of files to show up, I would need to drop in some javascript to parse the XML content.  I grabbed some bucket listing code from the AWS community and uploaded it to the bucket.

Simple. Right?

Wrong.

The listing page loaded, but it didn’t show any of the content that I knew had been uploaded to the bucket.  I start going back through everything I had done, checking for the mistake.  I couldn’t find anything wrong.  I dug through the permissions thinking that perhaps something was off there.  Nothing.  So, I started going through the script and decomposing it to see if perhaps something was not working correctly with the script.  I found the following line where it pulls the list of available content:

http.open('get', location.protocol+'//'+location.hostname);

Aha!  So, I tried browsing to assets.mysite.com and all I got was a 404 error.  Thinking at this point that perhaps configuring things as a website is what caused the problem, I went back in and disabled the website hosting feature.  I tried again and got a 404 error again.  That was obviously not the issue.

Eventually, after poking around for a while, I stumbled across a different endpoint assets.mysite.com.s3.amazonaws.com.  This returned the XML that I was expecting!  Armed with this new information, I went back and modified the line from the script that was reaching out for the XML to:

http.open('get', 'http://assets.mysite.com.s3.amazonaws.com');

Surely this was going to solve my problem … or not.

This time I am getting a 405 error.  I immediately start googling and digging through the documentation and discover that the issue I am running into is because I am trying to do cross site scripting.  assets.mysite.com needs permission to talk to assets.mysite.com.s3.amazonaws.com. Armed with a little more information now, I run back into the S3 management console and start looking at the options available to me in the permissions tab.  I click on the “Edit CORS Configuration” button and edited the rules to include:

<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>

Now when I go to the listing page, I see all of my files!  Mission successful.

Hopefully this can help some of you out.  Myself and a coworker tore (what’s left of) our hair out for a while going through all of the motions on this.

Email Templates and MailTo Syntax

The mailto prefix in hyperlinks.  Everyone knows about it, everyone uses it.  Not very many people are aware however that it can do more than just pass an email address to your user’s favorite email program. 

I was in a situation the other day where I needed to prompt a user for specific information, but I did not want / need to go to the effort of writing a contact form.  Yes, I realize writing a contact form would have only taken a few minutes, but sometimes being a little bit lazy can work out well. 

So, just to remind everybody and give us a starting place, let’s create a basic mailto link

<a href=”mailto:youremail@domain.com”>Contact Us</a>

First, let’s look at adding in more than just s single address.  There are two options here.  We can simply add multiple addresses divided by commas, or we can specify CC and BCC.

<a href=”mailto:youremail@domain.com, youremail2@domain.com”>Contact Us</a>
<a href=”mailto:youremail@domain.com?cc=yourccemail@domain.com”>Contact Us</a>
<a href=”mailto:youremail@domain.com?bcc=yourbccemail@domain.com”>Contact Us</a>

Now, let’s take a look at passing through a subject.  It is essentially the same principle as the CC and BCC options.

<a href=”mailto:youremail@domain.com?subject=Please write me back”>Contact Us</a>

Finally, the body of the email.  This is where my unwillingness to write a contact form comes into play.

<a href=”mailto:youremail@domain.com?body=Sample Body Content”>Contact Us</a>

I can hear you now, that’s great, but what if I want more complicated substance to my email body?  What if I need multiple paragraphs.  Well, you can do that, but it is not completely supported in every email client yet.  All of the more recent iterations of the email clients should have no issues however.  The trick to passing paragraph information is obviously URL encoding a line break.  You can accomplish this by placing %0A where you would like a line break.  Extrapolating that, %0A%0A would give us a paragraph break.  Let’s look at an example.

<a href=”mailto:youremail@domain.com?body=Sample Paragraph One%0A%0ASample Paragraph Two”>Contact Us</a>

Ok.  We’ve looked at all the options, so, now we can chain all of these together into our Contact Form link.  To chain multiple items together, utilize the & character just like you would in a URL.

<a href=”mailto:youremail@domain.com?cc=yourccemail@domain.com&subject=Please write me back&body==Sample Paragraph One%0A%0ASample Paragraph Two”>Contact Us</a>

There you have it.

Remote Reboot of Windows 7

I ran into an interesting problem recently where I was (admittedly) too lazy to walk upstairs and reboot my desktop that I use as a home server.

I connected via remote desktop only to discover that I was not able to reboot the machine from the start menu via a RDC. 

Curiosity, persistence (and laziness) prevailed and I spent some time researching to figure out how to get around this pesky issue.

Being a lover of most things related to the command prompt, I fired one up in admin mode (since like a good user, my account is not an administrator by default) and tried to reboot using

shutdown /r /t 0 only to be thwarted with aAccess is Denied(5). message. 

Researching this told me what was already plainly obvious, it was a permissions issue and I did not have permissions to do what I wanted.

Digging a little further, I came across the solution.

  1. Open the policy editor (secpol.msc)
  2. Expand Local Policies
  3. Select User Rights Assignment
  4. Find the Force shutdown from a remote system policy and add your account.
  5. Once this is done, go to a command prompt and run gpupdate

Now, when you run shutdown /r /t 0, your remote computer will promptly heed your wishes and restart.

Sorting a .Net list with lambdas

I love linq.  I would wager that most developers who have done much with it share a similar love.

It makes our lives easier.  It eliminates writing copies amounts of loops, parsing xml, interacting with databases, you name it.  It’s great.

When I run into a situation where linq does not have an obvious tie in, I start to get a little anxious,  (pathetic I realize).

Today I was faced with a situation where I had a list of custom classes that I needed to sort. 

This being a list, OrderBy was nowhere to be found.

So, I returned to my roots and started writing a compare for my class so that I could use the Sort command that is part of the List generic type.  That is when it struck me that I could probably accomplish this using a lambda.  It turns out that I was correct.  Lambda’s were a perfect fit for this scenario.  The code remained clean and concise and I was saved having to write additional methods just to accomplish a one-off scenario on what was a otherwise complete project.

Lamdas are a progression in C# past anonymous methods.  In the code below, I show how the code would be implemented with separate function, an anonymous method and finally, with a Lambda expression.

First, the test class that we’ll be working with:

public class MyClass
{
    public int propA { get; set; }
    public int propB { get; set; }
    public int propC { get; set; }
}

Our test class:

public class Tester
{
    public void Main()
    {
        List list = new List();
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 });
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 });
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 });
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 });        
    }
}

Now then, we write a custom comparer.  Not a lotof code, but you can imagine how this extrapolates over various properties for large classes.

public class Tester
{
    private static int CompareByPropA(MyClass a, MyClass b)
    {
        return a.propA.CompareTo(b.propA);
    }
    public void Main()
    {
        List list = new List();
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 });
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 });
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 });
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 });

        //Using the comparer built into the MyClass method
        list.Sort(CompareByPropA);        
    }
}

This time, we drop the custom comparer and implement the sort using an anonymous method.

public class Tester
{
    public void Main()
    {
        List list = new List();
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 });
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 });
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 });
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 });

        //Using an anonymous method
        list.Sort(delegate(MyClass a, MyClass b) { return a.propA.CompareTo(b.propA); });
    }
}

Finally, we rewrite the anonymous method into a Lambda.  It is still easy to read and much more concise.

public class Tester
{
    public void Main()
    {
        List list = new List();
        list.Add(new MyClass() { propA = 1, propB = 2, propC = 3 });
        list.Add(new MyClass() { propA = 2, propB = 3, propC = 4 });
        list.Add(new MyClass() { propA = 3, propB = 4, propC = 5 });
        list.Add(new MyClass() { propA = 4, propB = 5, propC = 6 });

        //Using a Lambda
        list.Sort((a, b) => a.propA.CompareTo(b.propA));
    }
}

So, next time you go to write custom compare code, step back and see if you can do it a little more simply.  If you are going to be using your comparison code in more than one place, then perhaps it is still a better idea to implement it using that route vs the lambda.  If it is a one-off thing, then a lambda and some linq can be a beautiful thing!

Categories

Archives