Archive for November 2009

Ant script, build Apache 2.2 and Mod_ssl

A friend of mine wanted to run the latest Aspache Mod_ssl available as some vulnerable holes have been patched in OpenSsl, but in order to do that you need to build it your self. Can you take a look he said, sure why not, he gave me a couple of links for instructions which is really all you need.

Instructions
Apachelounge
Devside

Source code(s)
OpenSsl
Apache
Zlib

Now I’m expecting my friend will need to do this again with another version in the future. So I figured why don’t we just create Ant script out of it. That way next time around we only need to change a couple of params about the source packages and we are off to the races. One click ant script should do the trick.

There are a couple of things that you have to have installed first on your system before you start. One is perl, I’m using ActivePerl but you should also be able to use other compatible perl packages. Another is awk, you might have to use gawk which you can then rename as awk on you computer before you start. Both of those need to be installed and available in the system path. I also have Vs2005 installed and that’s the one that will be used to do the compile. Also Zdll.lib was extracted from the Zlib binary as I got up against naming conflict on that one, put that one in \lib\zlib

Of course a simple Ant script to compile those would be impossible without the instructions mentioned before. And of course above all the people that put in the work to create the make files etc. Without them I would still be lost !

Here is the Ant script,

<project name=“nativeIndian” default=“ApacheBuild” basedir=“.”>

        <!–
    11/2009 – ORN
    ===
    – Apache -
    http://www.apachelounge.com/viewtopic.php?t=778
    http://www.devside.net/guides/windows/apache
    -
    http://www.openssl.org/source/
    http://httpd.apache.org/download.cgi
    http://www.zlib.net/

    ****
      Note –
      ActivePerl and Awk need to be present and available in the path.
      VS2005 is used to compile.
    ****

    This script will attempt the following
    ==========================================
    * Unzip sources
    * Set sources in place for compile
    * Compile OpenSsl
    * Test OpenSsl
    * Compile Apache
        –>

        <!– set global properties for this build –>
  <property name=“ApacheName” value=“Apache22″ />
  <property name=“srcDir” location=“${basedir}/../” />
  <property name=“libDir” location=“${basedir}/../lib/” />
  <property name=“zipLibDir” location=“${basedir}/../lib/zlib/” />
  <!– Source –>
  <property name=“OpenSslTop” value=“openssl-0.9.8l” />
  <property name=“OpenSslSourceGz” location=“${basedir}/../${OpenSslTop}.tar.gz” />
  <property name=“OpenSslSourceTar” location=“${basedir}/../${OpenSslTop}.tar” />
  <property name=“ZlibTop” value=“zlib-1.2.3″ />
  <property name=“ZlibSourceGz” location=“${basedir}/../${ZlibTop}.tar.gz” />
  <property name=“ZlibSourceTar” location=“${basedir}/../${ZlibTop}.tar” />
  <property name=“ApacheSourceTop” value=“httpd-2.2.14″ />
  <property name=“ApacheSource” location=“${basedir}/../${ApacheSourceTop}-win32-src.zip” />
  <property name=“ApacheBin” value=“Apache_bin.zip” />
  <!– Build dirs–>
  <property name=“buildDir” location=“${basedir}/aphache/” />
  <property name=“buildLibDir” location=“${buildDir}/${ApacheSourceTop}/srclib/” />
  <property name=“buildLibZlibDir” location=“${buildDir}/${ApacheSourceTop}/srclib/zlib/” />
  <property name=“buildLibOpenSslDir” location=“${buildDir}/${ApacheSourceTop}/srclib/OpenSsl/” />

  <!– Hardcoded, VS2005 location –>
  <property name=“VsEnvir” location=“D:\apps\dev\Ide\vs2005\VC\vcvarsall.bat” />

  <!– TIMESTAMPS –>
        <tstamp>
                <format property=“TheStartTime” pattern=“dd-MM-yyyy hh:mm aa” />
        </tstamp>

 
  <!– DEFAULT RUN TARGETS  –>
  <target name=“ApacheBuild” depends=“startme,cleanUp,setup,compile,zipbin” >
    <echo message=“– Ending=${TheStartTime}” />
    <echo message=“– Done !” />
  </target>

 
  <!– Startup –>
  <target name=“startme” >
    <echo message=“– Start startme:” />
    <echo message=“– ${TheStartTime}” />
    <mkdir dir=“${buildDir}” />
  </target>

  <!– Fails on cleanup, as it might be clean already, or never created –>
        <target name=“cleanUp” >
    <echo message=“– Start cleanup:” />
                <delete dir=“${buildDir}” failonerror=“yes”/>
    <delete file=“${basedir}/${ApacheBin}” />
        </target>

  <!– Unzip and copy –>
  <target name=“setup” >
    <echo message=“– Start setup:” />
   
    <!– make sure the build dir is present –>
    <mkdir dir=“${buildDir}” />
   
    <!– Apache source –>
    <unzip src=“${ApacheSource}” dest=“${buildDir}”/>
   
    <!– OpenSsl source –>
    <gunzip src=“${OpenSslSourceGz}”/>
    <untar src=“${OpenSslSourceTar}” dest=“${buildDir}”/>
    <!– Add openssl to source dir –>
    <move todir=“${buildLibOpenSslDir}”>
      <fileset dir=“${buildDir}/${OpenSslTop}”/>
    </move>

    <!– Zlib source –>
    <gunzip src=“${ZlibSourceGz}”/>
    <untar src=“${ZlibSourceTar}” dest=“${buildDir}”/>
    <!– Add Zlib to source dir –>
    <move todir=“${buildLibZlibDir}”>
      <fileset dir=“${buildDir}/${ZlibTop}”/>
    </move>
    <!– Add zlib lib to source dir as well –>
    <copy file=“${zipLibDir}/zdll.lib” todir=“${buildLibZlibDir}”/>

  </target>
 
 
 
  <!– Compile packages  –>
  <target name=“compile” >
    <echo message=“– Start compile:” />

    <!– Vs2005 environment variables –>
    <exec executable=“cmd”>
      <arg value=“/c”/>
      <arg value=“${VsEnvir}”/>
    </exec>

    <!– Build OpenSsl –>
    <echo message=“– Start compile OpenSsl:” />
    <exec executable=“cmd” dir=“${buildLibOpenSslDir}” >
      <arg value=“/c”/>
      <arg value=“perl Configure VC-WIN32″/>
    </exec>
    <exec executable=“cmd” dir=“${buildLibOpenSslDir}”>
      <arg value=“/c”/>
      <arg value=“ms\do_masm”/>
    </exec>
    <exec executable=“cmd” dir=“${buildLibOpenSslDir}”>
      <arg value=“/c”/>
      <arg value=“nmake -f ms\ntdll.mak”/>
    </exec>
    <!– Test OpenSsl –>
    <echo message=“– Start test OpenSsl:” />
    <exec executable=“cmd” dir=“${buildLibOpenSslDir}/out32dll”>
      <arg value=“/c”/>
      <arg value=“..\ms\test”/>
    </exec>

   
    <!– Build Apache with the default localhost, port 80 –>
    <echo message=“– Start compile Apache:” />
    <exec executable=“cmd” dir=“${buildDir}/${ApacheSourceTop}”>
      <arg value=“/c”/>
      <arg value=“nmake /f Makefile.win SERVERNAME=localhost PORT=80 INSTDIR=${buildDir}/../${ApacheName} installr”/>
    </exec>

  </target>

  <!– Zip up the Apache  –>
  <target name=“zipbin” >
    <zip
      destfile=“${basedir}/${ApacheBin}”
      basedir=“${buildDir}/../${ApacheName}”
    />

  </target>

</project>

UnitTesting a door

I was explaining to somebody from non development world some time back what unittesting is about. At the time the best thing I could come up with was something along the way. Well if your building a house and then you install a door. Now you have to make sure the door works. In case of the door we write Unittest that makes sure that the door nob turns and does actually open the door. We also make sure that the door latches when it’s shut, further we make sure that the door fully opens and closes without any trouble. We make sure the key fits and can lock and unlock the door. Since we are at it we might as well shake the door and make sure nothing is rattling, that all screws were tightened up properly. Further if the door gets replaced it has to be verified that it works as well and the same key can be used as before.

The good part is once you have written the unittest it will work for the replacement door as well. This is where you get the most bang for you buck. Unless you never rewrite your software, that’s another story then. So let’s say your interior designer came up with a new door, a sliding door. Now your tests fail of course and they should, the function of the door has changed and it’s time to update the unittest. The base will stay the same the same key might still fit, the door should shut properly, etc. One of the new functions might be that the door slides open when a person walks into the sensor that triggers the door etc.

So how does it look when you need to unittest objects in your new webserver project. It’s similar but it’s a little different the problem is when you are running on a webserver you are running in a container. The container is the webserver. So logically you can’t test the door as the door can only be accessed when inside the container ( installed in the house ). The problem with that is that you do not want to unittest against a live webserver. As you can not get down to the object level to address the door directly. Therefor the trick is to setup a unittest environment that can fake the container / house. Once you do that your door thinks that it’s installed in a house and you can verify that the door functions as expected.

There is only one thing left to say, Jawoll Mein Agile F├╝hrer

Build .Net 3.5 code with Nant, MsBuild on build server without installing VS2008

If you don’t have enough space to install Visual Studio 2008 on your build machine to build .Net 3.5 solution you can do the following. Most likely you will run into the same obstacles as I did, maybe others as well.

First download Windows SDK for Windows Server 2008 and .NET Framework 3.5
http://www.microsoft.com/downloads/details.aspx?FamilyId=E6E1C3DF-A74F-4207-8586-711EBE331CDC&displaylang=en

When you install you can skip the documentation and samples, it will bring the install down from 2.4GB ! down to about 525MB, not bad.


If you get the following error when you set the framework to Net-3.5 from Nant

System.NullReferenceException: Object reference not set to an instance of an object. at NAnt.Core.FrameworkInfo.get_Version()

You have a certain version of Nant around 0.86 that has old version of the path for the SDK. In your nant.exe.config under net-3.5 look for this section

<project>
    <readregistry
        property=“installRoot”
        key=“SOFTWARE\Microsoft\.NETFramework\InstallRoot”
        hive=“LocalMachine” />

    <readregistry
        property=“sdkInstallRoot”
        key=“SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A\WinSDKNetFxTools\InstallationFolder”
        hive=“LocalMachine”
        failonerror=“false” />

    <property name=“frameworkDirectoryV35″ value=“${path::combine(installRoot, ‘v3.5′)}” />
    <fail if=“${not(directory::exists(frameworkDirectoryV35))}”>The Framework directory for .NET 3.5 does not exist.</fail>
    <property name=“referenceV35″ value=“${environment::get-folder-path(‘ProgramFiles’)}/Reference Assemblies/Microsoft/Framework/v3.5″ />
    <fail if=“${not(directory::exists(referenceV35))}”>The Reference Assemblies directory for .NET 3.5 does not exist.</fail>
</project>

change the sdkInstallRoot key v6.0A value to the following
key=”SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.1\WinSDKNetFxTools\InstallationFolder”


If you get the following as well
MY.Web.csproj(364, 11): error MSB4019: The imported project “C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

No problem, copy the content of your v9.0 directory from your dev box under C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0 to your build server, these are just configuration files.


Then if your using the Microsoft test extensions you might get this one as well
App\DataAccess\CaseDataAccessTest.cs(5, 17): error CS0234: The type or namespace name ‘VisualStudio’ does not exist in the namespace ‘Microsoft’ (are you missing an assembly reference?)

We will simply solve this one by copying the MS test dll’s from the dev machine and install them in the Gac on the build machine.
C:\tmp>gacutil /i Microsoft.VisualStudio.QualityTools.Resource.dll
C:\tmp>gacutil /i Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll


Now you should be good to go and ready to build on the build server without the heavy VS2008 install.

TeamCity update to version 4.5.5

I Just updated our TeamCity environment to version 4.5.5 today, we were running 3.1 before. I had resisted an update as I always do because things just break when you update software. Since we are having some network issues it was a perfect time to take the plunge. That is after we discovered that TC 4.5+ can use Team Foundation Server repository. As the MsBuild just is not mature enough yet and there are weird quirks all around we are going to use combo TC and TFS setup for a new project we just started. Mainly running the build using nant and nunit of course.
Back to the update, I took a backup of the TC server directory just in case. Then fired up the install, the install recognized the old version and offered to get rid of it for me. The install ran fairly quickly and picked up all the configurations from the last install. After the server was up the build agents got pushed to the new version and came online in a matter of couple of minutes, now that is sweet. No manual installs on the build agent machines, its auto ! Then I just kicked off a build and everything was business as usual, it can’t get any better than this.

Nant SVN changes between two revisions checkout

I went looking for a nant script to checkout changed files between two revisions from SVN. I found some Ant / Java based solutions. As we are using nant I figured I would give it a shot writing it myself. It is easy to get a list of files from SVN using diff. However that doesn’t do you any good if you need to get them from SVN by hand one by one. The trick is to use the list you get from SVN diff and then loop each file and bring it down to the local machine. The biggest gotcha was of course space in file or directory names. If you notice in the script that’s taken care of by inserting %20 in the URL location and local file names are quoted with double quote when doing the SVN export. List of deleted files are written to deletedfiles.txt in the checkout directory, Enjoy !

<?xml version=“1.0″?>
<!–
  Exports changes between revision from the given repository URL to checkout Directory
–>
<project name=“SVN_changes”
   default=“getChanges”
   basedir=“.”>

  <!–
   Register the sys.* properties; most specifically, sys.env.* for all environment vars
  –>
  <sysinfo/>

  <!– Properties / defaults –>
  <property name=“checkoutDir” value=“svnchanges”/>
  <property name=“changelog” value=“${checkoutDir}\changelog.txt”/>
  <property name=“delLog” value=“${checkoutDir}\deletedfiles.txt”/>
  <property name=“delFile” value=“”/>
  <property name=“deleteIndicator” value=“D      “/>

  <!– url to svn repository –>
  <property name=“repoURL” value=“http://10.10.10.10/svn/myproject/trunk”/>
  <property name=“repoUser” value=“testUser” dynamic=“true” />
  <property name=“repoPassword” value=“testPassword” dynamic=“true” />
  <property name=“startingRevision” value=“29455″ />
  <property name=“endingRevision” value=“30692″ />

  <target name=“getChanges” description=“Get changes from Subversion given two revisions “  >

    <echo message=“Exporting files between revisions ${startingRevision} and ${endingRevision}” />
    <echo message=“from ${repoURL}” />
    <echo message=“to ${checkoutDir}/” />
    <echo message=“——-” />
    <echo message=“stand by….. “ />
    <echo message=“——-” />

    <!– Start with a fresh local checkout directory –>
    <mkdir dir=“${checkoutDir}” />

    <!– creates log file comparison from start to end revision –>
    <exec program=“svn”
      commandline=“diff -r ${startingRevision}:${endingRevision} –summarize ${repoURL}”
      output=“${changelog}” />

    <!– Loop the files in the changelog and process –>
    <foreach item=“Line” in=“${changelog}” delim=“,” property=“svnfile”>

      <!– Extract the file name –>
      <property name=“startpos” value=“${string::index-of(svnfile, repoURL) +  string::get-length(repoURL) }” />
      <property name=“length” value=“${string::get-length(svnfile) – int::parse(startpos)}” />
      <property name=“tmpFile” value=“${string::substring( svnfile, startpos, length)}” />
      <!– Space in URL covered –>
      <property name=“repoFile” value=“${string::replace( tmpFile, ‘ ‘, ‘%20′)}” />
      <!– Extract the dir –>
      <property name=“endpos” value=“${string::last-index-of( tmpFile, ‘/’)}” />
      <property name=“localDir” value=“${string::substring( tmpFile, 0, int::parse(endpos))}” />

      <!– Sep –>
      <echo message=“—”/>
     
      <!– Advertise deleted files between revisions –>
      <if test=“${ string::contains(svnfile, deleteIndicator)}”>
          <echo message=“Deleted file=${tmpFile}”/>
          <property name=“delFile” value=“${tmpFile}”/>
          <call target=“WriteToTextFile” />
      </if>

      <!– Files to bring down from repository  –>
      <if test=“${ not string::contains(svnfile, deleteIndicator)}”>
          <!–
            Create the dir before checkout, this might happen multible times
            for files in the same dir, don‘t fail it.
          –>
          <mkdir dir="${checkoutDir}${localDir}" failonerror="false"/>
       
          <!– Check out the file –>
          <echo message="svn export ${repoURL}${repoFile} &quot;${checkoutDir}${tmpFile}&quot; -r ${endingRevision} –force " />
          <exec program="svn"
                commandline="export ${repoURL}${repoFile} &quot;${checkoutDir}${tmpFile}&quot; -r ${endingRevision} –force"
                            failonerror="true"
          />
      </if>
    </foreach>

    <!– Show user that it’s all done –>
    <echo message=“   ” />
    <echo message=“——-” />
    <echo message=“Changed and new files have been exported to the ${checkoutDir} directory” />
    <echo message=“List of deleted files can be found in the ${delLog} file” />
    <echo message=“——-” />
    <echo message=“Done !” />
  </target>

  <!– Appends deleted files to text file –>
  <target name=“WriteToTextFile” >
    <script language=“C#” mainclass=“writeToDelLog”>
      <references>
        <include name=“System.Management.dll” />
      </references>
      <div class=“codesnip-container” ><![CDATA[
            class writeToDelLog
            {       
                public static void ScriptMain(Project project)
                {       
                                      PropertyDictionary pd = project.Properties;       
                    string sDeletedFile = pd[“delLog”];
                    string sDeletedEntry = pd[“delFile”];
                   
                    FileStream stream = new FileStream(sDeletedFile, FileMode.Append );
                    StreamWriter writer = new StreamWriter(stream);

                    try
                    {
                      writer.WriteLine(sDeletedEntry);
                    }
                    catch( Exception ex )
                    {
                      Console.WriteLine( “NOT able to write to file, error=” + ex );
                    }
                    finally
                    {
                      if( writer != null ) writer.Close();
                      if( stream != null ) stream.Close();
                    }
                           
                }
            }
        ]]></div>
    </script>
  </target>

</project>