Wednesday, July 29, 2009

Sticking with XP

I was reading this CodingHorror piece, and for the most part thought it was ho-hum. Windows 7 is nice, and he finds a nice way to dig at it ("Vista service pack"). Clever, or would be if I hadn't heard it a few times already. Maybe it's new to you, I dunno, that's not the point.

There was a bit in it that I totally disagreed with:

It's important to me not because I am an operating system fanboy, but mostly because I want the world to get the hell off Windows XP. A world where people regularly use 9 year old operating systems is not a healthy computing ecosystem. Nobody is forcing anyone to use Windows, of course, but given the fundamental inertia in most people's computing choices, the lack of a compelling Windows upgrade path is a dangerous thing.

Different definitions of "dangerous".


How is slow change dangerous to an ecosystem? It might be dangerous for itself, i.e., the Windows franchise, but the ecosystem seems to have not only survived, but thrived. Not only did Apple take total advantage of MS' lapse, but the Linux desktop looks better and better (typing this on Ubuntu). Within the Windows' desktop universe, there is a huge software library specific to XP, not just Windows. Tweaks, utilities, and documentation galore.

XP was some good shit.

Now? Now I'm going to keep any XP machines around, until they absolutely have to be upgrade to gain functionality. Just out of spite. Er, if I can find any, that is.

Tuesday, July 28, 2009

Redmine on Glassfish

Okay, this took me a couple of days to piece together, so here it is for posterity.

Redmine is a software-development project management system, written in Ruby on Rails. The demo looks good, I tried it out on a small scale, liked it, and am ready to really use it.

I like my RoR running under Java where I can keep an eye on it, and normally this isn't a problem. Just warble it up, and deploy. Nothing to it.

However, this time around was a little more interesting.

Get everything working per these instructions, running Webrick, etc., under jruby instead of ruby.

The .jar that comes with the latest stable JRuby (as of this writing) has a bug. There's a newer one here which works. It should be replace whatever jruby-completes are in jruby-1.3.0\lib\ruby\gems\1.8\gems\warbler-0.9.13\lib. Thanks to this little post for that fix.

Next, run warble config, and modify the newly-created config/warble.rb. Make whatever other changes you might want (like including your jdbc driver in config.gems), and add lang to config.dirs.

Then warble it up, and away you go.

Also, it really helps if you don't have some weird file corruption issue to help you misdiagnose things, spin your wheels, and get needlessly frustrated for a day and a half. Really, try to avoid that part. Just try it on one of the other ten zillion machines you've got laying around a little sooner, dumbass.

Update

If you happen to be using redmine not only in this configuration, but behind nginx as a proxy, here's a trick to get around the non-relative paths you find all over the place:
        
server {
listen 80;
server_name whatever.example.com;
location / {
proxy_pass http://server/redmine;
}
location /redmine {
proxy_pass http://server/redmine;
}


Hope this helps.

Free Book: Pro Git

I've been using git for my version control needs for awhile, so I was happy to not only see a book on it, but that it is free: Pro Git.

Saturday, July 25, 2009

Java XML "support"

Like many software projects written these days, I'm finding using XML unavoidable. I'd always wondered why Java programmers always seemed so grumpy about XML, and now I know.

Java XML support sucks.

I'd never really appreciated .NET's support for XML. A few pain-in-the-ass points, but for the most part pretty easy to use. Ruby makes it way too easy, and comes closest to how it "should" be done.

It started with serialization. I need some way to store the state of an object so I can send it over the wire. Java has a built-in binary serializer which works very well. It doesn't matter if the fields are private, or whatever, it'll dump them out and read them back in. A couple of pain points, but pretty easy to use, much like .NET's serialization. I figured that serializing to XML would be just as easy.

I can be so naive.

Everyplace I looked said to use XMLEncoder. Okee dokee, except that the equivalent code doesn't give equivalent results. Do some digging, and it turns out the binary and XML serializers use completely different mechanisms. Now, there's probably some pointy-headed academic someplace who is satisfied that the XML serializer meets some standard. If it means re-writing your code in such a way as to make it more difficult to maintain, then you're doing it wrong. Especially when a not only do competing languages do it in an elegantish manner, but you have an implementation which does it well, too.

You know, the source code is open. Someone with more time oughta look into that.

Anyways, since it all blows so hard, I've got some extra work implementing my own serialization conventions. I've got it implemented about halfway through at the time of this writing. It shouldn't take much longer to finish.

Thursday, July 23, 2009

Learning Java, Still

I've been hammering away at both getting the project along (and it is coming along nicely), while learning Java (also coming along nicely). I've done enough that I've got some opinions about Java. Maybe I'm just doing things wrong, and whatever old Java sages stumble across this post will just shake their heads at the n00b.

Today's complaint - exceptions

First, I wanna complain about exceptions in Java. I like exceptions. I like code that blows up in a predictable, informative, and containable manner. At first, when I was having to declare all the potential exceptions a method could throw, I was annoyed. Then, I came to appreciate it. I had a detailed list of broad categories of things that could go kerblooie.

That is totally awesome.

So, there I was, hard at work, not understanding why I wasn't getting the results I was expecting. Then I noticed the log saying something about an exception, and continuing.

I looked, but I wasn't catching it anywhere. It was an unhandled exception, or at least I wasn't handling it, and I'm the only person I care about when it comes to code.

Dammit, things should blow up, not just continue. What the hell kind of "exception" is that, anyway? They call it "unchecked" (or is it the other way around?). I guess I'm just not smart enough for Java.

All is not suckitude

I'm using NetBeans, this go-round. It runs really well, handles my multi-mon just fine, and holds my hand without getting in the way too much. It isn't as good as Visual Studio - VS just has a bit more "polish" to it (much better autocomplete, for example), but it is easier to get to the guts of NetBeans.

Refactoring in Java is awesome. I have absolutely no fear about renaming things, moving them around, whatever. Since laying things out in both agiley and enterprisey fashion means a lot of little files, this is pretty important. I've been burned by refactoring in VS (but not a recent version), but not once in NetBeans.

Things could be easier, dammit!

Documentation is all over the map. The linux distros used to have this problem (they've gotten much better), where there were just so many options, and no clear consolidated approach. NetBeans packages as much as it can together, of course. This doesn't cover moving to production, or anything like that. I guess it is expecting too much to find documentation geared towards someone who is intent on learning an entire stack at once.

I'll get over the smell

As usual, I'm having fun learning. I've got enough of the basic patterns down that I'm getting a lot done fairly quickly. I'm sure I'm making dozens of beginner mistakes, but hopefully I'm doing a good enough job that those things are easy to find and fix.

I keep getting stuck on the server deployment scenarios. There's just too many of them. Not just app servers, but what those app servers need to provide. The acronyms are very thick.

Just more stuff to hammer on through. I'll keep you posted, of course.

Monday, July 20, 2009

Powershell, and log4net

EZ money:

"--- Loading log4net ---"

[System.Reflection.Assembly]::LoadFrom("$pslib\log4net.dll") | out-null;
"Loaded log4net.dll"

[System.IO.FileInfo]$fi = new-object System.IO.FileInfo "$pslib\log4net.xml"
[log4net.Config.XmlConfigurator]::Configure( $fi )
"log4net configured with $pslib\log4net.xml"

$log = [log4net.LogManager]::getLogger("default")
"`$log = (new logger `"default`")"

""
'Cause sometimes we wanna be fancy...

Sunday, July 19, 2009

My Online Dumping Ground

I've written a bunch of stuff over the years, of various utility.

And I've lost most of it. No hardship, it is just a pain in the butt to keep track of it.

Anyway, some of it is marginally useful, so I thought I'd set up someplace to host it. It is all BSD-licensed.

You can find it here.

Featured projects (okay, the only projects):

  • IIS6 Cmdlets (cmdlets to administer remote IIS6 machines)

  • ServerInfo (detailed remote IIS6 configuration information GUI)

  • FileInfoExtensions (Things .NET's FileInfo should have, but doesn't)

  • Powershell Profile (My profile.ps1. Whoop. It was when the output of my profile exceeded the length of my original profile that I decided to move everything out there)

I can't attest to any great quality for these apps. If nothing else, at least I'll know where they are.

I've been putting snippets of code in this blog, but it isn't too long after that I've posted it that I'm updating the article with a much better script. Rather than do that, I'll just provide a link to the code in the project, with maybe some bits extracted. That FileInfo post was an excellent example: worthwhile code, but loooong.

Saturday, July 18, 2009

Some FileInfo Extensions

I kept on needing the same stuff regarding files when writing C#, so I came up with a set of helpers implemented as extensions to the FileInfo class.

Nothing particularly earth-shattering, but you might find them useful.

  • IsDirectory - does the obvious
  • GetMimeType - uses Windows' urlmon.dll to magically determine a file's mime type.
  • GetFileBytes - gets a chunk off the front of a file.
  • GetSha1, and friends - Computes the SHA1 hash of a file. Configurable buffer size.
  • ApplyToFolder - accepts a function to be applied to every file in a hierarchy.

Latest version here.

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace QSha
{
public static class FileInfoExtensions
{
public static bool IsDirectory( this FileInfo fi )
{
if ( !( ( FileAttributes.Directory & fi.Attributes ) == FileAttributes.Directory ) )
{
return false;
}
return true;
}


public static byte[] GetFileBytes( this FileInfo fi, long maxBufSize )
{
byte[] buffer = new byte[( fi.Length > maxBufSize ? maxBufSize : fi.Length )];
using ( FileStream fs =
new FileStream( fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, buffer.Length ) )
{
fs.Read( buffer, 0, buffer.Length );
fs.Close();
}

return buffer;
}

public static void ApplyToFolder( this FileInfo fi, Func fFileFound )
{
string[] subFolders;
try
{
subFolders = Directory.GetDirectories( fi.FullName );
}
catch ( UnauthorizedAccessException )
{
return;
}

string[] files;
foreach ( string folder in subFolders )
{
FileInfo tmpFi = new FileInfo( folder );
tmpFi.ApplyToFolder( fFileFound );

try
{
files = Directory.GetFiles( folder );
}
catch ( UnauthorizedAccessException )
{
continue;
}

foreach ( string file in files )
{
bool ffres = fFileFound( new FileInfo( file ) );

// we don't do any post-processing, so these are wasted cycles
/*
if ( !ffres )
continue;
*/
}
}
}

// mime-type stuff
public static string GetMimeType( this FileInfo fi )
{

if ( fi.IsDirectory() )
throw new FileNotFoundException( String.Format( "Is a directory, not a file: {0}", fi.FullName ) );

if ( !File.Exists( fi.FullName ) )
throw new FileNotFoundException( fi.FullName + " not found" );


byte[] buffer = new byte[256];
using ( FileStream fs = new FileStream( fi.FullName, FileMode.Open ) )
{
if ( fs.Length >= 256 )
fs.Read( buffer, 0, 256 );
else
fs.Read( buffer, 0, (int)fs.Length );
}
try
{
System.UInt32 mimetype;
FindMimeFromData( 0, null, buffer, 256, null, 0, out mimetype, 0 );
System.IntPtr mimeTypePtr = new IntPtr( mimetype );
string mime = Marshal.PtrToStringUni( mimeTypePtr );
Marshal.FreeCoTaskMem( mimeTypePtr );
return mime;
}
catch ( Exception )
{
return "unknown/unknown";
}
}

[DllImport( @"urlmon.dll", CharSet = CharSet.Auto )]
private extern static System.UInt32 FindMimeFromData(
System.UInt32 pBC,
[MarshalAs( UnmanagedType.LPStr )] System.String pwzUrl,
[MarshalAs( UnmanagedType.LPArray )] byte[] pBuffer,
System.UInt32 cbSize,
[MarshalAs( UnmanagedType.LPStr )] System.String pwzMimeProposed,
System.UInt32 dwMimeFlags,
out System.UInt32 ppwzMimeOut,
System.UInt32 dwReserverd
);
// /mime-type stuff

// hash stuff
public static string GetSha1Base64( this FileInfo fi, long maxBufSize )
{
return Convert.ToBase64String( fi.GetSha1( maxBufSize ) );
}

public static string GetSha1Hex( this FileInfo fi, long maxBufSize )
{
byte[] hash = fi.GetSha1(maxBufSize);
StringBuilder hex = new StringBuilder( hash.Length );
for ( int i = 0; i < hash.Length; i++ )
{
hex.Append( hash[i].ToString( "X2" ) );
}
return hex.ToString();
}

public static byte[] GetSha1( this FileInfo fi, long maxBufSize )
{
string ret = String.Empty;

if ( 0 == fi.Length )
return null;

if( 0 == maxBufSize )
{
maxBufSize = fi.Length;
}
byte[] buffer = fi.GetFileBytes( maxBufSize );

SHA1Managed sha1 = new SHA1Managed();
return sha1.ComputeHash( buffer );
}
}
}

Microsofting

Oh boy, coding on a Saturday night! What could be more fun?

Well, there's been a little tempest-in-a-teapot about some MS marketing blog being busted as an astroturfing site.

I like the response of the blog:

As for WordPress, I address using Microsoft competitor tools on my about page. Again, it’s not really a secret. You can see the flickr photos and youtube videos right there on the homepage.

All this is to say — you can hate on Microsoft and its advertising all you want … but I’m not sure it’s fair to act like it’s a big GOTCHA! to catch a marketing site being, well, a marketing site.


There's two bits I like about it. First, the obvious in-your-faceness of it.

Next, admitting that they use tools other than MS tools. You know, like the rest of the world. I've always found Redmond's self-rah-rahing and NIH attitude irritating. Microsoft's biggest weaknesses revolve around its isolation from the rest of the community. This is a welcome change. I wonder how long it will take for it to be beaten down?

Hash My Files

Not particularly revolutionary, but if you need a nice tool for getting the hashes of various files, HashMyFiles from Nirsoft is pretty nice, and best of all, free.

SHA1, CRC32, and MD5.

Friday, July 17, 2009

ZFS and Upgrading Drives

Yea, okay, so this is common. In fact, I've done it with VMs before. I still think it is neat that I was able to upgrade an array without any downtime.

Before:
root@bluelight:~# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
data 888G 511G 377G 57% DEGRADED -
rpool 298G 6.28G 292G 2% ONLINE -

After:
root@bluelight:~# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
data 2.73T 511G 2.23T 18% ONLINE -
rpool 298G 6.27G 292G 2% ONLINE -


I ran into one snag. When I issued zpool replace data c4d0s0, it gave me a message about there being no such device. The solution was zpool replace data c4d0. I suspect that "s0" at the end of the original disk was a slice, and probably an artifact of how I set the system up to begin with.

The larger impact is that I've got a lot of room at very little cost. There aren't as many advantages to the high-end gear that there used to be. Everything I used is commodity class, or free. It doesn't suit all situations, but there isn't a reason for small businesses to be paying a lot of money.

Monday, July 13, 2009

What If Microsoft Turned A Corner, and No One Was There?

(Disclaimer: MSFT from 1994-2003)

Ran into this today, which argues that Microsoft has turned the corner. Considering that blog tends to be critical of MS, it was worth a read.

Despite my history with MS, I've been pretty much all over the map when it comes to PC-based server tech. Even at MS, I was an early adopter of Linux, and ultimately started my own hosting service on FreeBSD (which failed, but that's another story).

That said, I recently took a new look at MS' 2008 stack (Windows 2008, SQL 2008, VS 2008). It doesn't suck. In fact, it is pretty darn good.

What I liked:
- Powershell. I don't like to throw the term "game changer" around much, but this one is. Between that, and a very rich .NET model, a lot of previously cumbersome tasks are now trivial.
- IIS7. Much more modular, much more programmable (more Powershell)
- VS2008. I've long like MS' IDEs, and this one kicks much butt. Add in ReSharper, and it totally rocks.
- SQL 2008. It scales better, it is easier to manage, and very configurable.
- C# 3.0. I'm a chump for simple lambda syntax.

The biggest difficulties I ran into stemmed not from Microsoft's tech, but from the ecosystem around their technology.

I have found plenty of neat stuff to use, but a lot of it runs under Java. Sure, I could build various bridges from .NET to those tools, but then I have a whole other chunk to maintain. Many of the projects have .NET client, but they tend to be second class.

Why would I want to do things half-ass like that, when I know all too well of the problems that causes?

There's just more happening in the Java/Linux world. If I want to maintain a competitive edge for my customers and myself, it behooves me to use and recommend the better technology. Right now, that isn't Microsoft - and it isn't because of Microsoft, itself.

When I wanted a search server, I could use MS', which works on Windows, or I could use Solr, which runs on Java. When I needed some form of network monitoring, I ran into OpenNMS, and didn't find a lot for Windows . Lately, I wanted a good message queue. Microsoft has one (and it works fine), Java has a selection.

Thus bringing me to the point: it may not matter if MS is getting it. MS isn't capable of doing everything, no matter how efficient and disciplined they get. They need everybody else in order to be a strong presence. Their heavy-handed tactics of the past may have deprived them of what they needed most: people.

They have a strong presence in the enterprise world, and this latest stack will help cement that position. The large organizations tend to move slow, anyway, so being a little behind isn't too big a deal. MS' best tools are best suited to that environment. They aren't going away.

They have the money to ride out their bad reputation. Maybe they can trim more of the fat, and focus a little bit better. In the meantime, they have a lot of ground to make up.

Sunday, July 12, 2009

Powershell $profile - Is This Great Filler, or What?

Some new java stuff, a couple of nice little helper functions: qfind, for searching the filesystem and title, to change the console title.
$projects = $env:USERPROFILE + "\Documents\Visual Studio 2008\Projects"
$sysdir = $env:USERPROFILE + "\sys"

# misc stuff
new-alias -name npp -value "C:\Program Files\Notepad++\notepad++.exe"
function qfind( $start, $like ) { get-childitem $start -name $like -recurse }

function title( $msg ) { $host.ui.RawUI.WindowTitle = $msg }

# git stuff

$gitexe = $sysdir + "\Git\bin\git.exe"
new-alias -name vi -value $sysdir\Vim\vim72\gvim.exe
$env:EDITOR = "npp"
new-alias -Name git -Value $gitexe

# java stuff

$jdk = "jdk1.6.0_12"
$java_home = "C:\Program Files\Java\$jdk"
$env:JAVA_HOME = $java_home

new-alias -name jruby -value $sysdir\jruby\bin\jruby.bat

new-alias -name jar -value "$java_home\bin\jar.exe"
new-alias -name ant -value "c:\sys\ant\bin\ant.bat"
new-alias -name javac -value "$java_home\bin\javac.exe"
function jetty() { java -jar start.jar etc/jetty.xml }
$env:CATALINA_HOME = "c:\sys\tomcat6"
new-alias -name tomcat -value "c:\sys\tomcat6\bin\startup.bat"

# MS Stuff

new-alias -name nant -value "$sysdir\nant\bin\nant.exe"
new-alias -name msbuild -value C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe

title( "General" )

Hope this helps. At least it is harder to lose :)

Update: Once I got to looking at it here, I decided it could be better laid out. So, it is a little prettier, now.

Saturday, July 11, 2009

Learning Java

Okay, so here I am, learning Java. I've put it off for many years. Learning Java has always been compelling, but more along academic lines: As pervasive as it is, I should just know it.

I tend to need to write stuff fairly quickly (misc tools don't need to be particularly well-written). So, I usually script my way out of trouble. When I need a GUI app, or just need to show additional polish, I reached for DevStudio - Microsoft makes those one-off apps easy.

My goals are pretty simple: learn enough to

  • Administer java application containers
  • Diagnose Java application problems
  • Understand it well enough to use a high-level language (Groovy, JRuby) effectively
I'm not unfamiliar with configuring Java containers, but I'm in no way an expert. I like the overall...explicitness?...of it. So far, I haven't seen anything that I couldn't really pull off on other platforms (Apache or IIS), and there is a cost of initial complexity.

However, as the overall configuration becomes more complex, java containers simplify things - all that explicitness pays off. Part of the appeal, given my current path, is that I can take a couple of these java based OSS projects (OpenNMS, ActiveMQ, Solr), and stuff them all into one JVM. Or not. (and I really look forward to learning how many problems doing it causes :) )

One thing Java got right was that it was all-Java right from the beginning. If you were coding a Java EE app, you were writing in Java. Microsoft's decision to foster backward-compatibility by encouraging interop wrappers around existing Win32 dlls has been a huge headache. While appserver admins were wrestling with classpaths (and arguing with devs about the location of physical files which are being written to), MS admins were building dozens of small machines because native.dll from vendor A's ".NET application" collided with native.dll from vendor B, who actually went out of business three years ago. I've dumped too many things into VMs because of that crap.

MS and it's ecosphere has certainly gotten better, but there's still sticking points (do we really need a Global Assembly Cache?).

What about the language? Surely I can't talk about "Learning Java" without talking about the language!

Well, I can't talk much; I've only been at it for about eight hours. A nice chunk of that was spent learning about classpaths, and changing the location of where apps were writing files on the physical disk. I'm being all old-skool about it, too. I've got Notepad++, the JDK, and a couple of powershell scripts as my dev environment. I know there's better and easier ways to do get things done, and I'll get to using them eventually. For now, I want to know what's going on under the covers.

For my first trick, I created a bunch of unnecessary abstraction ultimately resulting in getting some rows from a database, and dumping them to the console.

Why do I have to declare my potential exceptions? If the compiler knows enough to know that I didn't declare an exception when I should have, why doesn't it just stick it in there for me?

I thought it was neat that I didn't necessarily have to include, er, import namespaces. (At least I didn't need to with the Postgres adapter; I don't know all the rules to this, yet.) It was neat until I had to start adding "throw ClassNotFoundException" on all of my functions, anyway.

Having one general abstraction for databases is nice, too ("java.sql.*", vs. "SQL and OLEDB" everything). In fact, there's some nice generalizations for just about everything to accomodate that EE specification.

Anyway, I'm having fun, and I'll keep y'all posted.

Thursday, July 9, 2009

The State of Hypervisors: Meh

I've been dinking around with the various virtualization technologies: VMWare ESX, Solaris xvm, MS Hyper-V, and Ubuntu/Linux kvm (I still have VirtualBox on the todo list).

kvm and xvm, despite different underlying technologies, are pretty similar. They get the job done, but they aren't much fun to manage. The various crowds are making it better, everyday (eucalyptus, which uses Xen on Linux, is especially promising, but personally untested).

VMWare wins the management crown, hands down. Highly complex configurations, an abundance of tools, simple administration, and well-known in the industry.

They need to be doing a lot more, though. MS' Hyper-V 2.0 promises to have live migrations (a big selling point for VMWare), and is nearly as easy to manage. It won't take long for MS to catch up, and it is almost free with Windows.

Here's something that kills me for all of them, though. It can be difficult to move VMs from one version of the software to another version, which kills flexibility. If I want to run the VM on my laptop on a big fat server for awhile, moving it from the workstation version to the server was not simple.

It should be simple. I realize that if I wanted to do something similar on a large scale, I could do it by implementing some conventions and standards, with a bunch of scripts to hold it together. I'm lazy. That's the point here.

My Hypervisor Grail is this: a seamless transition from any hardware, to any hardware. At the moment, I'm whining about moving from my laptop to a server, but I'd like to be able to move it out to a cloud of some flavor also (right now, I'm using AWS EC2, and it is sufficient).

It would be super-cool if I could choose among images at boot, and have it backed up at shutdown, without the compromise of hard drive space and/or performance.

We're getting there, at least:

Xen 3.3 also contains a wealth of new features contributed by vendors collaborating in the new Xen Client Initiative (XCI), a Xen.org community effort to accelerate and coordinate the development of fast, free, compatible embedded Xen hypervisors for laptops, PCs and PDAs. The XCI is targeting three use cases: using Xen to run "embedded IT" VMs that allow remote support, security and service of PCs through embedded IT applications without any impact on the user's primary desktop OS;
"instant on" applications that can be immediately available as separate VMs from the user's primary desktop OS; and "application compatibility" VMs, which allow legacy PC applications to run as VMs, alongside the user's primary desktop OS. XCI member companies are already shipping Xen client hypervisors embedded in chipsets, PCs and laptops.


I think, for my next build-out, I'm going to try Eucalyptus on a server (sacrificing the Win2008 machine - good OS, but not as good as Solaris, which stays and gets big fat hard drives). I like the idea of being able to push VMs from inside the datacenter (okay, in this case, my closet) to the cloud.

Wednesday, July 8, 2009

MSBuild, and Cancelling Long Running Processes

I really like the syntax and organization associated with the various build tools for getting stuff done. I'd hoped to leverage those qualities to handle some system tasks - and I will, anyway.

I ran into a snag, though. If a task involves a long-running external process - say, robocopy'ing a large directory structure, killing the msbuild process doesn't kill the child process. Robocopy keeps on running, leading to a lot of cursing about how slow the network is until you notice it running two dozen times.

BTW, here's a powershell snippet to kill all robocopy processes:
get-process -Name robocopy | foreach-object { $_.Kill() }

Under normal circumstances, the runaway processes shouldn't be a problem. Under other circumstances, this could be a big deal.

MSBuild exposes its object model. It should be possible to either write a wrapper, or a better exec task. One way or the other, it isn't as cut and dried as I'd hoped.

Monday, July 6, 2009

SocketShifter - Redirect Sockets on Windows

A trick I've often used to get around firewalls is ssh port forwarding. Basically, after SSH connects to a server, you can get it to forward local ports through the tunnel to arbitrary ports on the other end.

So, if I connect from work to my ssh server listening on my home router, I can forward my local port 1000 (which isn't being used) to port 80 on one of my internal machines, and connect to that webserver via http://localhost:1000.

Windows servers don't have many good options for an ssh server. The only one I've used was the version that comes with Cygwin, and it wasn't really all that good (hangs, crashes, non-killable).

Introducing SocketShifter, an app that performs a similar magic, only on Windows.

But wait, there's more!

It uses something called the .NET Service Bus, an offering from Microsoft's Azure. This promises to allow two machines to connect, regardless of intermediate firewalls (and how do I prevent this?). It also means you have to sign up for an account in order to use it.

I'll be sticking with ssh, for now, but this service bus thing looks kind of interesting.

Saturday, July 4, 2009

msbuildtasks - A collection of MSBuild Tasks (duh)

I'm starting to use MSBuild for some system-level stuff. I've been torn between that, NAnt, and Powershell for commonly executed admin tasks (backups, deploys, things like that).

The most tempting choice was PowerShell. It can do just about anything I'd need it to. That flexibility creates a problem, too: I don't want to have to maintain these things. If I use a full-featured language, then follow up maintainers will fall into two camps: the ones who add more complexity until it becomes too hard to maintain, and the ones who won't understand any of it at all.

I was a little jealous of NAnt, because it has matured very nicely. That has to be installed - never mind how easy - and needs to be justified.

Then I ran across msbuildtasks, from the same people who brought us Subversion. Lots of shiny stuff (I love it!) including tasks for IIS sites (I don't know if it does IIS7), a slew of build and deploy related tasks, SQL tasks, Registry tasks, and more.

Then I found the MSBuild Extension Pack, which is chock-full of shiny promise, too.

So, MSBuild is our winner (found a good tutorial, and yet another). It comes with .Net 2.0, which is installed anyway (okay, you have to copy those extensions, but that could be the first task :) ), it has the features I'm looking for, thanks to Tigris, and it is proven in the field. I'm sure it will suck, too, but at least I'll know how much and in what ways it sucks. If it doesn't work out, I'll look for something else.

Update: Despite the title of this article, I'm not even using the msbuildtasks package, yet. The MSBuild Extension Pack has a lot more goodies, and everything that I've needed so far.

Wednesday, July 1, 2009

Unattended, A Windows Deployment System

Unattended. From their site:

Features include:

  • Automated install of operating system, hotfixes and applications.
  • Full documentation and source code.
  • Support for floppy, CD-ROM, and "nothing but net" installs.
  • True unattended installation, not disk imaging.
  • No Windows servers required; use your Unix servers instead.
  • No Unix servers required; use your Windows servers after all.
  • Completely free.

When you are finished setting up Unattended, you will be able to boot any PC from a floppy, from a CD-ROM, or directly from the network, answer a few questions, and come back an hour or two later to a fully-installed Windows workstation.


Update: I gave it a look-see, and it looks like it would be useful for Windows 2003, and that's about it. Considering deployments of that are dropping off of a cliff, it doesn't look useful.