blog.reis.se

It's all about looks

There is always a time, in configuring and setting up deployment with MSBuild, when you want to start and stop services on a specific machine. You could always run the sc command from an Exec task. But there must be a better way, an of course there is. For most things you need to do in MSBuild there seem to be a task for it in the MSBuild community task library.

So while poking around I find a couple of gems, ServiceQuery and ServiceController. Both are powerful tools in MSBuild deployment and works both locally and remote. The only problem is that the documentation is quite sparse, especially when handling remote services. So I Just figure I write down what I did to get it working in my scripts.

A little background: a web project that should be deployed to different sites, test, stage and production. The stage and production is redundant with clustering so its really stable, but need some extra attention for each node to be updated. You shut down one node, shut down the IIS and state services, clean out a few folders and then update with new web and finish up starting it all up again.

So to the script, add the community tasks to the script, go on with setting up some default properties and some paths and create a default target. After this you are ready to start and stop services:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\ MSBuild.Community.Tasks.Targets"/>
 
<PropertyGroup>
  <DeployFiles>$(MSBuildStartupDirectory)\DeployFiles.msbuild</DeployFiles>
  <Machine>localhost</Machine>
</PropertyGroup>

<Target Name="deploy">
  <CallTarget Targets="Shutdown"/>
  <MSBuild Projects="$(DeployTargets)" Properties="Machine=$(Machine)"/>
  <CallTarget Targets="Startup"/>
  <CallTarget Targets="CheckAccess"/>
</Target>

You see the basic structure here, shut down, call a separate MSBuild file that do the actual file copying the start up the services as well, and finally do a smoke test to test that the site is up and running again.

Next we see the actual shutdown part, first we do a ServiceQuery to check if there in fact is a SMTP service, if it reports other than Unknown, the service is in place. This makes it possible to do a conditional shutdown. The MachineName attribute is of course for remote shut down but works on localhost as well, making it possible to have the same script for local and remote handling. Make sure that the account that the TeamCity agent is running under, have access to perform shutdown/startup on the remote machine. Now we can go ahead and shut down the services:

<Target Name="Shutdown">
 <ServiceQuery MachineName="$(Machine)" ServiceName="smtpsvc">
   <Output TaskParameter="Status" PropertyName="SMTPPresent"/>
 </ServiceQuery>
 <ServiceController MachineName="$(Machine)" ServiceName="IISADMIN" Action="Stop"/> 
 <ServiceController MachineName="$(Machine)" ServiceName="W3SVC" Action="Stop"/>
 <ServiceController MachineName="$(Machine)" ServiceName="aspnet_state" Action="Stop"/>
 <ServiceController MachineName="$(Machine)" ServiceName="smtpsvc" Action="Stop" Condition="'$(SMTPPresent)'!='Unknown'"/>
</Target>

The actual deployments of the files are easy, you can just perform a copy task, as in the remote service handling, make sure you have access to the folder on the remote machine you are deploying to. After the deployment we do the Start action on each of the services we want to start up. Last, we do the smoke test. To do this we can use the task WebDownload, we just specify the URL and an output file and this step will fail if you don’t get any access. The other benefit is that you kick the first time JIT compilation here.

<Target Name="CheckAccess">
  <WebDownload FileUri="http://site.to.deply.com" FileName="test.html"/>
</Target>

Now go deploy something!

-----

PS: I have previously run a series on TeamCity and MSBuild in my private blog so if you are interested to learn more go ahead and read:

Artifact handling in TeamCity 4.0
Deploy with MSBuild and custom targets part 1
Deploy with MSBuild and custom targets part 2
Version handling in TeamCity part 1
Version handling in TeamCity part 2


This is a bit frustrating but planning can not help all the way. I have to tell you all that the session Continuation of continuous integration in Malmoe on Wednesday, April 1, have been moved to the day before. Tuesday, March 31. Nope no April fools day joke, I swear it’s the truth!

// Håkan Reis


Seminar in Gothenburg cancelled

Unfortunately I have to announce that the session Continuation of continuous integration has been cancelled for Gothenburg. I will still be in Malmoe, Linkoping and Stockholm, so now changes there.

I would love to give it in Gothenburg as well, but it’s out of my control. But who knows, I might show up in another context… :)

// Håkan Reis


TC-Logo_3I will be speaking  in Malmö, Göteborg, Linköping, and Stockholm in March/April. The subject will be build automation, some MSBuild and all done in TeamCity. The following abstract is in Swedish as the session will be in Swedish:

Continuation of continuous integration

Vad är nästa steg för dina automatiska byggen?

2009 års seminarier inleds med en närmare titt på hur man kan vidareutveckla automatiska bygge (Continuous Integration). I dag är de flesta medvetna om hur viktigt ett versionshanteringssystem som Subversion eller Team Foundation Server är. Oftast har man också insett hur viktigt det är att alltid ha byggbar kod, så man har gått vidare med periodiska, eller ännu hellre kontinuerliga byggen. Men i förlängningen vill man ständigt ha en leverans redo.

Vi tittar på hur man kan hantera kodanalys, integrationstester, release och automatisk installation. Fokus kommer att ligga på att utföra detta i en lösning från JetBrains - TeamCity. Men vi kommer inte ensidigt titta på TeamCity utan även på verktygen runt detta samt hur man kan utnyttja MSBuild för mer än att bara kompilera koden.

Bland annat kommer vi gå in på:

  • Vad kommer efter kontinuerliga byggen
  • Artifakthantering och beroende mellan byggen
  • Tricks MSBuild och custom tasks

If there are any other topics that are of interest I can still make room for changes in my material so feel free to contact me.

You can also register for any of the events, and don’t forget to mention where and date.

// Håkan Reis


We use TeamCity not only for the development builds and test execution, but also deployment to test and demo environments. The ultimate goal is to make it all the way into the stage environment. If we ever will get there I cannot tell, there are a number of obstacles like firewalls, port restrictions and good old access rights in the way but there are ideas on the drawing table how to solve that. As I was going through the deployment scripts I found that it needed an overview so I too the time to extract a few custom targets.

Background

The application is depending on three mechanisms: web, services and database. Web is deployed into IIS, a number of services are installed using MSI, and a database that are deployed using custom MSBuild tasks. This concoction is installed to three different machines for test and demo. Additionally some prerequisites around this are:

  • As TeamCity uses its own internal checkout paths, if not specified, all paths should be relative. This will ensure that its really simple to add more agents later on.
  • Naturally the scripts work for both 32bit and 64bit environments.
  • The artifact handling in TeamCity should be used as much as possible.

Go for absolute relativity

You should always use relative paths, absolute paths always make a mess of things. Making it hard to move script or folder structure. But it means you sometimes need to be able to find the absolute path at a given moment. for example command line often need the current working directory. A few useful reserved properties can take care of that, and two of them are:

  • $(MSBuildStartupDirectory) – the directory where the MSBuild execution was started
  • $(MSBuildProjectDirectory) – the directory where the current executing script is placed

About the 32/64 bit problem; on 64bit VisualStudio is in Program Files (x86) but on 32bit its in Program Files. This is a problem as we currently use VisualStudio in command line for building MSI packages

Well, an easiest way to get the path right is the registry to find out. And we are in luck, there are registry access in MSBuild 3.5. So to get the path use this syntax:

$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
VisualStudio\9.0\@InstallDir)

Artifact handling in TeamCity we know about from a previous post so I will not go into detail around that. However, one problem I run into is that using VisualStudio to build the install packages, means that we are not using TeamCity artifacts all the way. We are rebuilding the assemblies in this step. But hopefully WIX can help out here.

Stay on target

So with this background the following targets surface:

  • MSI package building
  • Database deploy
  • Service installation
  • Web deploy

There reason for the selection of these parts was not only to avoid repetition. This will also give much more readable and maintainability of scripts. And if we move to WIX or change database deployment we only have one place to update the scripts.

In the title I promised you custom targets and deployment, and I will give you that, but not until the next part.

// Håkan Reis


It was time, the old layout and colors wasn’t working but I haven’t gotten around to fix it, especially the comment section looked really bad. Then I found out about blogengine.net. After experimenting with it for a while I found that it had what I liked:

  • The code was readable and easy to get into for modification
  • It wasn’t depending on a database for storage (how many bloggers are really creating that much information that calls for a full fledge database?). But it could be added.
  • It had a clear separation of the view and presentation that makes it easy to build and expand themes.
  • I found a good looking basic view that I could modify for my needs.
  • It has easy export/import functionality through the standardized BlogML format (it handles posts, comments and images just right, really powerful).

So after tweaking the view a bit (more is coming) I decided to make the switch. And as you can se it’s up and running. Hope you like the new look.

All that happen to subscribe should really shift to the feedburner link instead of the old web link. But for those who are still using the old one I found an easy solution. I used built in syndication http handler and some configuration.

Normally, blogengine is configured so that a call to syndication.axd is fed to a HttpHandler called SyndicationHandler. So I just added the old SyndicationService.asmx (without the extra GetRSS part) to point to the same piece of code. In the web.config I added the following line to the <httpHandlers> section of web.config:

<add verb="*"
path="SyndicationService.asmx"
type="BlogEngine.Core.Web.HttpHandlers.SyndicationHandler,
    BlogEngine.Core"
validate="false" />

And that was all I had to do. Now I just have to get going with some more CSS and images to spice things up a a bit…

// Håkan Reis