Blog Home  Home Feed your aggregator (RSS 2.0)  
.Net Jonesie - November, 2005
A simple programmers blog
 
# Wednesday, November 30, 2005
There's a bug in TFS Beta 3 that stops the Analysis Services updating the cubes for reports.  Apparently this is something to do with locales and date/time formats.  The fix is pretty simple.  See http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=103529 for a discussion and the solution.
Wednesday, November 30, 2005 10:05:38 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System  | 
# Tuesday, November 29, 2005
When my Team Build succeeds, it uses a custom task to publish a build so that users (testers) can execute the WinForms client.  This is presented to users in a single page web app that looks like this:
 
 
I did this for my 2003/1.1 apps and it works well.  Using it for the 2005/2.0 apps seems logical and easy.  However, as Team System creates a SharePoint site for each project it seemed more logical to publish the deployed builds there. So, that's what I did.  I need to document this more thoroughly but I wanted to get this down before it's spilled over the edge.

Windows SharePoint Services (WSS) Joy

Firstly, I created a new List in the SharePoint site and called this "Deployed Builds".  It looks like this:
 
Next, I created a small prototype console app to test creating items in the SharePoint list.  This was fun, NOT!  I had a couple of issues and teething problems:
  1. You would think you need an SDK for doing WSS programming.  When you look at the WSS Site you find a link to download the WSS SDK sure enough but you will also notice the "Sharepoint Products & Technologies SDK" which is a separate download.
  2. Both the SDK's are just help files - there is no libraries.  To get Microsoft.SharePoint.dll - the .Net API - you need to download and install the Web Part Templates for Visual Studio.
  3. Depending on what you want to do, you probably don't need this either.  You can use the web services directly, which is what I did.
  4. You will still need the WSSSDK though as it documents the web service API, CAML and related structures.
So, after a couple of hours of stuffing around, I had something that ran but produced the dreaded "Cannot complete action - Please Try Again" error.  This is a catch-all for a lot of errors in WSS.  After much reading and cursing and stomping of the keyboard, I found a blog entry that told me exactly what the problem was.  When you insert a URL field, you need to format it correctly as "url, description".
 

MSBuild WSS Task

Now I had the prototype working, I converted this to a MSBuild Task. I wanted the task to be generic so I could use it to populate any SharePoint list.  To use the task, you do something like this. 
 
Firstly create a list of name/value pairs that match the SharePoint list:
 
  <ItemGroup>
    <PortalListValues Include="URL">
      <FieldName>URL</FieldName>
      <FieldValue>file://$(ClientDeployDest)\airways.sums.exe, SUMS III</FieldValue>     
    </PortalListValues>
    <PortalListValues Include="Location">
      <FieldName>Location</FieldName>
      <FieldValue>TPK</FieldValue>
    </PortalListValues>
  </ItemGroup>
 
In my case, I'm leaving the Note field blank and the Active field will default to "No".  Notice that the URL is a file location and that the description is included.
 
Next, I call the task thus:
 
<UsingTask TaskName="Airways.Build.Tasks.WSS.AddListItem" AssemblyFile="Airways.Build.Tasks.dll"/>
 
...
 
<Target Name="AfterDropBuild">

  <AddListItem SiteURL="
http://myserver/sites/sums3
    ListName="Deployed Builds"
    FieldValues="@(PortalListValues)" />
</Target>
 

Viewing the List

When an item is added to the WSS list the Active field defaults to "No".  The default view in SharePoint excludes records that are not active.  I have another personal view that I use to edit the records and activate them for users.  This way I can build as often as I like and "release" when I'm ready.

Tuesday, November 29, 2005 4:30:54 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [1]   Team System  | 
# Thursday, November 24, 2005
I think this is a new feature, please tell me if it's not so I can kick myself.
 
When an exception occurs deep in some code, the reason is most likely at a much higher level, e.g.:
 
This exception occurred in DataSet code due to something wacky in the UI.  The call stack shows how we got here:
 
It's very easy to navigate back through the call stack and examine variable values etc, but often you have to restart the app with a break point set in a suitable place - at least that's what I thought till I noticed this:
 
 
When you select this it unwinds the execution of your application back to the selected Frame in the call stack.  How cool is that ?  Very cool I think.
Thursday, November 24, 2005 3:27:03 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Visual Studio  | 
# Monday, November 21, 2005
I've just added one more task to my Team Build and its done - for now.  Here's how the whole thing works.
  1. I execute a Team Build manually.
  2. When the project builds successfully, it copies the client and server outputs to a publically visible path.
  3. The build configures the web service virtual directory.
  4. The build updates the client .config to point to the new web service vdir.
  5. The build writes a record to a SQL table.
  6. Team build sends me an email alert to tell me the build completed successfully.
  7. I manaually edit the log table to release the build and enter a note.
  8. The user accesses the launch page and views the build details.
  9. The user launches a build for testing via a link on the launch page.
  10. I go home happy.
The last custom task I added was a SQL Command executor which I use for logging the successfull deployment.  The launch page uses this to display a menu of successful builds.  The application is launched from a UNC path so users need to configure some machine security settings, for which I provide an MSI.
 
Now back to finishing the (never ending) project.
Monday, November 21, 2005 2:45:23 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [3]   Team System  | 
The next step of my project deployment via Team Build is to update the exe.config file for the newly created web service.  To do this, I needed to create a task to edit an XML file.  Once again I looked at the SDC tasks, but found that it was easier to write my own.  I added the following to the build file.
<PropertyGroup>
   ...
  <TestDataUrl>http://blah/SUMSWS $(BuildNumber)/SUMSDataasmx</TestDataUrl>
  <TestSecurityUrl>http://blah/SUMSWS $(BuildNumber)/SUMSSecurity.asmx</TestSecurityUrl>
</PropertyGroup>
<UsingTask TaskName="AirwaysBuild.Tasks.XMLFile.ModifyXMLNode" AssemblyFile="Airways.Build.Tasks.dll"/>
<Target Name="AfterDropBuild">
  ... 
  <!-- update the app.config -->
  <ModifyXMLNode
    Filename="$(ClientDeployDest)\Airways.SUMS.exe.config"
    XPath="/configuration/applicationSettings/Airways.SUMS.Properties.Settings/setting[@name='WSDataURL']/value"
    NewValue="$(TestDataUrl)"
  />
  <ModifyXMLNode
    Filename="$(ClientDeployDest)\Airways.SUMS.exe.config"
    XPath="/configuration/applicationSettings/Airways.SUMS.Properties.Settings/setting[@name='WSSecurityURL']/value"
    NewValue="$(TestSecurityUrl)"
  />
  <ModifyXMLNode
    Filename="$(ClientDeployDest)\Airways.SUMS.exe.config"
    XPath="/configuration/applicationSettings/Airways.SUMS.Properties.Settings/setting[@name='BuildVersion']/value"
    NewValue="$(BuildNumber)"
  />

</Target>
 
The two new properties define the ASMX urls for the two services.  In the AfterDropBuild target I use these to update the exe.config file.  A third task updates a BuildVersion setting in the config which is displayed on the applications main window caption (so the user can clearly see which build they are running).
 
Each ModifyXMLNode task on the target defines the file name to modify, an XPath statement for the element or attribute and the new value to insert.  The new values are treated as text / strings and I use these in the task code thus:
XmlNode node = Document.DocumentElement.SelectSingleNode(XPath);
if (node != null)
{
  node.InnerText = NewValue;
}
I'm not sure if I should use InnerXml instead of InnerText - what I have now works well enough.
 
Once again, if you'd like the code for this task, shoot me an email or use the contact link on this blog or post a comment.  I'll probably be adding more tasks sooner or later.  When I get a bigger library of useful tasks I'll post it for download somewhere.
 
I must say that creating tasks for MSBuild is a lot of fun.  I'd be happy doing this all day every day.  You get to play with lots of different stuff, you don't have to create fancy UI and it's really very easy to do.  Back in NAnt days I never created a task - probably because there is already a vast library of free ones available, but also because I thought it was harder to do. 
Monday, November 21, 2005 9:53:52 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [1]   Team System  | 
# Friday, November 18, 2005
All my research and experimentation is starting to pay dividends.  I've managed to extend my Team Build to copy the project outputs from the drop location to a new folder structure and create an IIS virtual directory for the web service. 
 
So far, this is the steps I followed. 
 
Edit the TFSBuild.proj file
I added the following to the build:
 
  <PropertyGroup>
    <ClientDeploySource>$(DropLocation)\$(BuildNumber)\Debug</ClientDeploySource>
    <ServerDeploySource>$(DropLocation)\$(BuildNumber)\Debug\ PublishedWebsites\SUMSWS</ServerDeploySource>
    <ClientDeployDest>$(DropLocation)\test $(BuildNumber)</ClientDeployDest>
    <ServerDeployDest>$(DropLocation)\test $(BuildNumber)\SUMSWS</ServerDeployDest>
    <ServerLocalPath>D:\devweb\deployment\SUMS3\test $(BuildNumber)\SUMSWS</ServerLocalPath>

  </PropertyGroup>
  <UsingTask TaskName="Airways.Build.Tasks.IIS.CreateVDir" AssemblyFile="Airways.Build.Tasks.dll"/>
  <Target Name="AfterDropBuild">
    <CreateItem Include="$(ClientDeploySource)\*.dll">
      <Output TaskParameter="Include" ItemName="ClientDLLs"/>     
    </CreateItem>
    <CreateItem Include="$(ClientDeploySource)\*.exe">
      <Output TaskParameter="Include" ItemName="ClientEXEs"/>
    </CreateItem>
    <CreateItem Include="$(ClientDeploySource)\*.exe.config">
      <Output TaskParameter="Include" ItemName="ClientCONFIGs"/>
    </CreateItem>
    <CreateItem Include="$(ServerDeploySource)\**\*.*">
      <Output TaskParameter="Include" ItemName="ServiceFiles"/>
    </CreateItem>
    <!-- copy the client filed -->
    <Copy SourceFiles="@(ClientDLLs)" DestinationFolder="$(ClientDeployDest)" />
    <Copy SourceFiles="@(ClientEXEs)" DestinationFolder="$(ClientDeployDest)" />
    <Copy SourceFiles="@(ClientCONFIGs)" DestinationFolder="$(ClientDeployDest)" />
    <!-- copy the web service -->
    <Copy SourceFiles="@(ServiceFiles)" DestinationFiles="@(ServiceFiles->'$(ServerDeployDest)\%(RecursiveDir)%(Filename)%(Extension)')" />
   
    <!-- make the virtual dir -->
    <CreateVDir Server="localhost" Site="BSDTesting" PhysicalPath="$(ServerLocalPath)" VirtualPath="SUMSWS $(BuildNumber)" />
    <!-- create the test db ?? -->
    <!-- update the .config -->
    <!-- update the launcher XML file -->
   
  </Target>
The property group defines some source and destination folders.  These are based on the DropLocation which is defined at the top of the build file.  The destination folders for the client and server happen to be on the same machine to keep things simple, but these could (and probably should) be on another server.
 
Next, there is a new custom task I made for creating a virtual directory in IIS.  I search for a while without luck to find a built in solution for this or someone else's solution but in the end it was very easy and fun to create my own task.  My first attempt actually worked on the first execution!  Its not a very complete task - you can't do everything you might want to do with a VDIR but for me it's adequate.  If you want the code then shoot me an email or post a comment.  I had a look at .NET Solution Build, Deployment, Process & Tools but I found this too confusing at the time and thought it was easier and more enjoyable to create my own task.  Now I understand the process better I might take another look at this handy kit.
 
Next in the build file is a new Target.  This overrides the default AfterDropBuild target.  We need to use CreateItem as the items to be copied are produced by previous targets and don't exist when the build file is loaded.  If I had specified all the actual files by name rather than wildcard then I could have used an ItemGroup, but that would be tedious and error prone. The rest of the target is pretty self explanatory.
 
Checkin the TFSBuild and Custom Task
Once I made the changes I checked in the TFSBuild file and added the custom  task dll to the Team Build folder in Source Control.  When the Team Build executes, these files extracted to the build server so it's not necessary to put the custom task in the build server GAC or any such horrid stuff.
 
 
I've still a few more steps to complete before I can have new builds automatically published to users/testers but hopefully this will be as easy and fun as the rest of this.  I'll post an update when I've got the whole thing working.
Friday, November 18, 2005 12:18:15 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [2]   Team System  | 
# Tuesday, November 15, 2005
I've been trying to figure out how to extend my Team Build.  I need to package the binaries and other files as well as update .config files and deploy the outputs ready for user testing.  I've done this before with NAnt and Draco .Net but I'm finding it a lot harder to do this with MSBuild and Team Build - probably because there's a lot of new stuff to learn.
 
Here's a list of resources I've found so far.  Some of these are from other peoples blogs as I haven't found 1 single source that has everything.  I'll update this post as I find more. (* = Team Build Specific)
 
Blogs
Sites
Lists
Stuff
People
If you have any more I'd LOVE to know.
Tuesday, November 15, 2005 3:30:52 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [2]   Team System  | 
A friend and fellow Kiwi .Netter, Brent Clark, is repeating his popular web cast tommorow.  If you want to know more than your mother ever told you about building VB6 & VB.Net applications with lots of COM & VSSS then Brent is THE MAN!  Go Brent!
 
From a Microsoft .NET Framework build perspective, consuming evolving Component Object Models (COM) is not a trivial matter. This webcast describes how SunGard in Christchurch, New Zealand has extended its automated build processes to be able to interact with NET and COM components. Learn how SunGard was able to compile .NET solutions from Microsoft Visual Source Safe with strong naming, version stamping, and copyright stamping. You will also learn how SunGard automatically produced interoperability files for the ever-changing COM components. This webcast also describes how SunGard produced publisher policy files that allow the company to patch the minimum number of files in a client installation.
 
Presenter: Brent Clark, Build Process Architect, SunGard
 
Brent Clark manages the build process for a large 10-year-old system produced and maintained by SunGard in Christchurch, New Zealand. This system is made up of approximately three million lines of code  that are written mostly in Microsoft Visual Basic 6.0 but now extend into Microsoft Visual Basic .NET. Brent's responsibilities have included the automated analysis and compilation of Visual Basic 6.0 and .NET projects. He has also worked on deployment to internal clients and also branching and reintegrating separate subproject environments.

This can be found under http://go.microsoft.com/?linkid=4078252

 

Tuesday, November 15, 2005 2:37:25 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   General | Visual Studio  | 
Tuesday, November 15, 2005 10:23:11 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System  | 
Microsoft and INeta are doing a big push with the launch of Visual Studio, SQL Server and BizTalk.  They have sent us some goodies and training materials so Tim and I have decided to run a series of BYO PC Workshops. 
 
This is a great way to learn the technology in a quiet, interruption free environment.  We will give a brief overview the subject and then you get to spend 1 to 2 hours working on exercises.  You get to do this on your own machine so you can take the materials away with you and play later. 
 
We will also be giving away a copy of Visual Studio 2005 Standard and SQL Server 2005 Standard at each of the workshops to one lucky attendee.
 
We decided to run the workshops in the early morning (8am) so as to minimise the impact on your working day.  If this does not suite enough people or there is sufficient demand for a different time we can probably re-run the events at a more civilised time.
 
Workshop details and registration can be viewed on the NZ .Net Site home page.
 
Tuesday, November 15, 2005 10:12:16 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Visual Studio  | 
# Thursday, November 10, 2005
Sadly, I'm finding a few issues with Visual Studio 2005 and Team System. 
  • The ToolStrip designer is less than stable.  If a ToolStrip overflows to the drop down menu you can add new ToolStrip items but you cant move them or delete them.
  • The WebDev.WebServer STILL drops connections which makes it useless for debugging.  I logged this as a bug a while ago.  I also managed to speak to the chap in Redmond who wrote this (or is at least responsible for it) while I was there for the summit.  Sorry, can't remember his name now, but he knew nothing of the issue then.  It may be just an issue on our systems (I've seen it on 2 machines) or with our project.  Has anyone else seen this problem?
  • Visual Studio locks up frequently.  Actually, it's not dead, just not responding.  The Task Manager shows about 50% cpu activity on devenv.exe but I have to kill the process.  I'm not sure but I suspect this might be a Team System Source Control issue.
  • Help is very slow to load.
  • Visual Studio can be very slow to load.
  • I had an issue with a solution yestuday that wouldn't let me open the projects in it or re-add them.  I had to create a new SLN and add the projects back in.  I think Team System Source Control is/was caching an incorrect path so even though I had a proejct file in C:\SomePath and I selected the project to add, it would look in a different path (where the project once was). 
All of these things are a little annoying but certainly not show stoppers.  I'll research these a little more and then log bugs for whatever I can nail down.
 
Thursday, November 10, 2005 11:44:54 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System | Visual Studio  | 
# Wednesday, November 09, 2005
Microsoft has published a case system of our Team System implementation. 
Wednesday, November 09, 2005 11:15:53 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   General | Team System  | 
# Friday, November 04, 2005
Something to change the subject.  I ordered a solar water heating system for home yesturday. When I saw how much the Chief of Contact Energy got for a pay rise and how much our power bills have gone up in the last year I thought it was about time to get some money back.
 
We ordered the Sola 60 system.  In our new house it's a very easy install.  Sola 60 use our existing hot water cylinder where most of the other vendors replace this with a new one, so this helps keep the cost down.  The placement of the panel and the pitch and position of our roof make it a very easy install. 
 
 
It's costing us $NZ 5074 for a 4-5 person system.  Our monthly power bill averages $300 in winter - we have 3 kids who like loooooonnnnnngggggg showers!  The sales man from Sola 60 told us that the average power bill is 1/3 hot water and the new system will cover 75% of the electricity cost of this in winter and 100% in summer (this equates with other quotes and comments I've seen).  My rough estimate is that it will save us an average of $90 a month - call it $1000 a year.  So after 5 years we are in profit.  Better yet, there's an interest free loan of $3000 for 3 years so the initial expense won't hit the mortgage.  I wish we had done it when we built the house.
 
Now all I need is a system to generate hydrogen and a fuel cell car and I can give the single finger wave to the energy merchants!
Friday, November 04, 2005 3:31:17 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   General  | 
Having spent most of the day mucking with VS 05 RTM & Team System Beta 3 Refresh - here after called TSB3R - these are my initial observations and comparisons with Beta 2 - no particular order.
  • Source Control is wickedly fast!  Ok, so my database is probably pretty empty but it's at least as fast as Vault - maybe even faster if that is possible.
  • Creating a new Team Project is faster - ~30 seconds instead of 2 minutes.
  • The Agile process template and process guidance are much improved. 
  • The default new tasks for an Agile project - only 14 of them for a new project - include useful details and references to the process guidance (but these are not hyperlinks unfortunately).
  • Compiling a project does not check out the project file anymore.
  • When I edit a checked in file, focus shifts to somewhere else when it does the check out and I have to click back in the code window.  This may be because I have the tool windows undocked onto my 2nd monitor.  I'll experiment with this and log a bug.
  • There's a few new reports with interesting names, eg, "Unplanned Work", "Bugs found without corresponding tests", and "Regressions".
  • The Team Build progress & results window is WAY nicer than B2.
  • Code Analysis still slows down the build hugely - ~10 seconds without, ~120 seconds with.
  • There is a new Task type of Risk for Agile projects.
  • Test Controller and Agent setup is confusing - I think it's now part of the Team Suite install because there's nothing in the TFS install that looks relevant.
  • You get little pad-locks on the tab pages in VS so you can see if the file is checked in or not.
  • Refactor rename still tries to drill into code that it shouldn't. For example, renaming a private variable in a class library searches through web service code that in no way can ever see the var.  It is quicker but could be a lot quicker if it didn't do this.  Another bug to log.
  • The command line tools for TFS are simpler and easier to find but there's no project delete tool - maybe this will be in the SDK?
  • Despite my problems I think they have got the server install as simple as it can be.  Installing SQL Server is the hardest part really and that take about 5 minutes - not enough time for a game of Spider :{
So, after day 1, I'm very impressed. I've got lots of coding to do over the next few weeks so will reserve final judgement :}
Friday, November 04, 2005 2:55:06 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System  | 
I downloaded the correct version of Team Foundation Server Beta 3 Refresh  overnight and installed it in about 40 minutes this morning - client and server - and it seems to be working very sweetly so far.  Here's what I've found to make the install go smoothly (after 7 unsmooth attempts!).  This is for a single server install.
  1. Make sure you have the correct versions of everything - RTM SQL Standard, RTM VS Team Suite, Sharepoint with SP 2 and TFS Beta 3 REFRESH.
  2. Read through the TFS Install Guide as thoroughly as you can.
  3. Reformat your server, install Windows 2003 Server with SP1, IIS etc as per the TFS Install guide.
  4. Make sure your server is joined to the domain and the network configuration is correct (my Compaq DL 380 has dual Nic with separate IP's so I had to create a "Team" using the HP tool and set this as a fixed IP so that Windows Update would work (we block this normally)).
  5. Do all the windows updates you can - 18 critical updates for me.
  6. Create the 3 required accounts and add them to the machines Administrator group and add your own domain account to this group too (you can remove it later if you have to).
  7. Login to the server as TFS Setup.
  8. Install SQL, Sharepoint and TFS EXACTLY as the Install Guide says - don't trust your memory, read and follow the instructions a step at a time.
The only variation I made to the install was to change the data directories for SQL & Analysis Servers. Oh yeah, I also installed the SQL Workstation Tools so I could setup backup and so other maintenance (and play a little with SQL 2005).
 
I'm sure you can get this to work without having to reformat the server but it's a lot easier to start over when you know you can delete stuff without worry. 
 
For the client, the first part is to get VS.Net working correctly.  If you have had Beta 2 or RC on your workstation then you should make sure you uninstall this correctly.  I didn't and had to do it the hard way.  Read this!  Once you have it working then install the Team Explorer from the TFS install.  This is a separate install now rather than being included in Team Suite.
 
Because you added yourself to the servers admin group, you should be able to get into your system and configure security and groups, create projects etc.
 
For user permissions, I'm going to do everything in Active Directory.  I'm creating a structure like this:
  • OU: Our Team System
    • OU: Service Accounts
      • TFSService
      • TFSSetup
      • TFSReports
    • Group: TS Administrators
      • MyLogin
      • MyBossesLogin
      • OurITPeople Group
    • Group: TS Users
      • Group: All Developers Group
    • OU: TS Projects
      • OU: Some Big Project
        • Group: Some Big Project Administrators
          • MyLogin
          • MyBossesLogin
          • etc
        • Group: Some Big Project Contributors
          • UserLogins ...
        • Group: Some Big Project Readers
          • UserLogins ...
Well, that's the theory at this stage.  We control our AD pretty tightly here so without IT delegating me some rights to manage the OU it's going to be a pain but hopefully they'll allow this.
 
Now on with exploring the changes...
Friday, November 04, 2005 10:05:53 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System  | 
# Thursday, November 03, 2005

I think the source of all the problems with my Team Foundation Server install stem from the fact that I was using Beta 3, not Beta 3 Refresh. I'm very red faced - but in my defence, I must say that the download option from TAP was not that obivous - it is now, but when I downloaded it the only clue was a folder called "vstf.b3.rtm".  Anyways, I'm downloading the correct version now so by this time tommorow it should be working. .. (famous last words?).

On the up side, I'm getting very good at installing SQL Server!

Thursday, November 03, 2005 11:26:59 AM (New Zealand Daylight Time, UTC+13:00)  #    Comments [0]   Team System  | 
# Wednesday, November 02, 2005
Class designer won't load in Visual Studio
Wednesday, November 02, 2005 1:15:33 PM (New Zealand Daylight Time, UTC+13:00)  #    Comments [4]   Visual Studio  | 
Copyright © 2010 Peter G Jones. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: