My experience with upgrading TFS 2005 to TFS 2008

I can describe my feeling of mgration from TFS 2005 to TFS 2008 in one word-NIGHTMARE.
 

Summary of recommendations.

1.Create combined TFS 2008+SP1 setup as described in http://www.woodwardweb.com/vsts/creating_a_tfs.html and in the latest Team Foundation Installation Guide
3. If you are using fully-qualified domain names (FQDN, e.g., tfsserver.mycompany.com) , replace  the FQDN with NetBios name before update and restore after update.
4. Install SP2 for the SQL Server. 
5.In case of errors review C:Documents and SettingsMyUSERLocal SettingsVSMsiLog####.txt . It is usually quite detailed. 

Problems in a sequence.

I’ve read a few links with tips about conversion and thought that I am ready:
 
 
Unrelated: If you need to migrate or synchronize with other version control (VC) and work-item tracking (WIT) systems , look at  CodePlex TFS Migration and Synchronization Toolkit   
 
I’ve done all preliminary work as it was recommended.
When I’ve started installation, I’ve got TF220066 error.
The article Visual Studio 2008 Team Foundation Server – Error TF220066 and TF30170 among others suggests to install SP2 for the SQL Server (TFS documentation requires only SP1).
I’ve install it and also uninstall TFS 2005(not mandatory, but recommended step).
And TF220066 error has been replaced with new one- TF220064 
 

 
In the database TfsIntegration..tbl_service_interface replace 3 ReportsService  with Netbios name
 
The next error I noticed  in the log C:Documents and SettingsMyUSERLocal Settingsdd_install_vstf_at_90.txt.
MS post  TFS/Team Explorer 2008 Troubleshooting Guide suggests to look fot logs in both %temp% and %temp%.. (the parent dir of %temp%). 
 
[09/23/08,00:07:22] TFSUI: getcurrenttfsproperties.exe: === WARNING: Unable to retrieve service account from the database. Failed to find TfsServiceAccount in database TfsIntegration table tbl_registration_extended_attributes
[09/23/08,00:07:22] TFSUI: getcurrenttfsproperties.exe: === WARNING: Unable to determine TfsServiceAccount.
In the  TfsIntegration.tbl_registration_extended_attributes  table I manually added fk_registration_entry_id=1, name=TfsServiceAccount value= TfsService
 
 
Next error:
[09/23/08,00:17:55] vs70uimgr: DisplayMessage_START:Setup has detected that the specified database server is already in use by another Team Foundation Server (services) computer. Click OK to configure this computer as a stand-by Team Foundation Server (services) computer. Click Cancel to specify a different database server.
In the same TfsIntegration.tbl_registration_extended_attributes I replaced for ATMachineName FQDN to NetBios name
The fix is described by  sdneel in the thread 
 
The next error message:
Error 32000.The Commandline ‘”d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsTfsDb.exe” upgrade /server:”MyServer” /property:”TFS_SERVICE_ACCOUNT=MyDomainTFSSERVICE;TFS_REPORTING_ACCOUNT=MyDomainTFSREPORTS;LCID=1033;
VSTF_AS_INSTANCE=MyServer;VSTF_AS_DATABASE=TFSWarehouse;VSTF_AS_ACCOUNT=” /showui:394070′ returned non-zero value: 100.
Upgrading TFS 2005 to TFS 2008 shows how to grant domainTFSReports and MyDomainTFSSERVICE the appropriate permissions.
But it didn’t help for me.
 
I found from http://support.microsoft.com/kb/955008 that VSMsiLog####.txt located in C:Documents and SettingsMyUSERLocal Settings (note not in Temp subfolder) folder already has detailed info. If it is not enough, a few articles suggest to run the TFSdb tool from the command line (e.g. here ), Note that you should it when  “Retry   Cancel” message  still open.
Another article TFS 2008 Installation Escapades & Errors suggest to use verbose TFS installation logging
 
 So details of the Error 32000 are the following:
 

Upgrading the Warehouse Database (TfsWarehouse)

 d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsSetupWarehouse.exe
 -upgrade -int TfsIntegration -s WEBJET011 -d TfsWarehouse -c “d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsWarehouseschema.xml” -a “MyDomainTFSSERVICE” -ra “MyDomainTFSREPORTS” -asinst “WEBJET011” -asdbname “TFSWarehouse” -asacct “”
 d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsSetupWarehouse.exe -upgrade -int TfsIntegration -s WEBJET011 -d TfsWarehouse -c “d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsWarehouseschema.xml” -a “MyDomainTFSSERVICE” -ra “MyDomainTFSREPORTS” -asinst “WEBJET011” -asdbname “TFSWarehouse” -asacct “”
 An unexpected error occurred: XML parsing failed at line 1, column 0: A document must contain exactly one root element.
 .
 Errors in the metadata manager. An error occurred when instantiating a metadata object from the file, ‘\?D:Program FilesMicrosoft SQL ServerMSSQL.2OLAPDataTFSWarehouse.0.dbOutcome.622.dim.xml’.
 5
 d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsSetupWarehouse.exe 5 20547
 Microsoft.TeamFoundation.DatabaseInstaller.DatabaseException: d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsSetupWarehouse.exe 5 20547
   at Microsoft.TeamFoundation.DatabaseInstaller.ProcessDeployer.ExecuteCommand(String filePath, String arguments, Boolean continueOnError)
Microsoft.TeamFoundation.DatabaseInstaller.DatabaseException: d:Program FilesMicrosoft Visual Studio 2008 Team Foundation ServerToolsSetupWarehouse.exe 5 20547
   at Microsoft.TeamFoundation.DatabaseInstaller.ProcessDeployer.ExecuteCommand(String filePath, String arguments, Boolean continueOnError)
   at Microsoft.TeamFoundation.DatabaseInstaller.Installer.RunDbActions(InstallerMode mode, String server, Boolean preview)
   at Microsoft.TeamFoundation.DatabaseInstaller.Installer.RunSteps(InstallerMode mode, String server, IPropertyCollection properties, Boolean preview)
   at Microsoft.TeamFoundation.DatabaseInstaller.Installer.Upgrade(String server, IPropertyCollection properties, Boolean preview)
   at Microsoft.TeamFoundation.DatabaseInstaller.CommandLine.Commands.CommandUpgrade.OnRun()
   at Microsoft.TeamFoundation.DatabaseInstaller.CommandLine.Commands.InstallerCommand.Run()
   at Microsoft.TeamFoundation.DatabaseInstaller.CommandLine.CommandLine.RunCommand(String args)
 
As it suggested in

http://translate.google.com.au/translate?hl=en&sl=fr&u=http://batswirl.com/blogs/batswirl_fr/archive/2008/04/29/erreur-32000-lors-de-la-migration-de-tfs-2008.aspx&sa=X&oi=translate&resnum=7&ct=result&prev=/search%3Fq%3DTFSWarehouse%2BXML%2BTfsDb%26hl%3Den%26sa%3DG

 
I’ve just deleted the problematic xml file.
 
The next issue:Upgrade hang after “Starting execution of steps from step06_MigrateOpenedWorkItems.sql.resources”, 
According to the thread http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3910016&SiteID=1&mode=1  Microsoft “have identified a fix and are currently testing the fix.  Please contact Customer Support for this issue.  It’s currently be tracked under Escalation ID:  372448.” 
But Customer Support  was not aware about the number.
The install failed after 6 hours and growing TEMPDB to more than 50GB with “Disk Full” message.
Fortunately Buck Hodges was so nice to suggest how to install combined TFS 2008+SP1 setup as described in http://www.woodwardweb.com/vsts/creating_a_tfs.html and in the latest Team Foundation Installation Guide.
 
I installed VS 2008 with SP1 prior to the running combined TFS 2008+SP1 setup

 
The setup failed with Error 29250.Team Build Upgrade failed to complete successfully.
 
I was able to hack the errors by manually adding missing columns tbl_Build.DropLocationRoot and REASON and tbl_Schedule.LastEvaluatedOn
 
After this the TFS 2008 setup has been completed successfully.
Later, when we tried to use builds, we’ve got the errors related to tbl_Build.REASON column.
Buck Hodges  suggested to ” drop the columns that you hacked in and run repair”. (Back up TFS databases is a must before repair).
I ‘ve dropped hacked columns:
USE TFSBuild
GO
Alter table tbl_Build
drop COLUMN DropLocationRoot –nvarchar(260) NULL
GO
Alter table tbl_Build
drop COLUMN REASON –int NULL
GO
Alter table tbl_Schedule
drop CONSTRAINT DF__tbl_Sched__LastE__5A1A5A11
GO
Alter table tbl_Schedule
drop COLUMN LastEvaluatedOn –[datetime] NULL Default(GetDate())
GO
 and ‘ve run  Setup.exe to repair the TFS installation. It fixed the database, but when a build was run, it coused the error.

Detailed Message: TF50309: The following account does not have sufficient permissions to complete the operation: NT AUTHORITYNETWORK SERVICE. Check the permissions for the account and grant the appropriate permissions to perform this operation. 

TF215085: An error occurred while connecting to agent TfsServerTfsServer011: TF209009: The account NT AUTHORITYNETWORK SERVICE is not authorized to communicate with Team Foundation Server TfsServer011. Verify that the account is a member of the Build Services security group for the appropriate team project on the Team Foundation Server and that the account’s password has not expired.

I’ve found that after repair Visual Studio Team Foundation Build Windows Service(TFSBuildService.exe) was running under  NT AUTHORITYNETWORK SERVICE.I’ve changed it to TfsServerTFSBuild  (TFSService account didn’t have Remoting permissions, and wasn’t able to create drop folders)

 
To restore fully-qualified domain names (FQDN, e.g., tfsserver.mycompany.com) for TFS 
But command “tfsadminutil activateat <FullyQualifiedDomainName>” changed all references and Team client on my TFS server didn’t see connection using Netbios name(e.g. http://tfsserver).
and for  (FQDN, e.g., tfsserver.mycompany.com) it wasn’t able to authenticate user (Logon failure for NTLM).
So I had manually in  TfsIntegration.tbl_registration_extended_attributes replace for ATMachineName back to FQDN
Install removed SSL settings on the TFS virtual directory, and I had to restore reference to certificates.
 
Actually I tried to use http: instead of https, but for remote machines outside TFS domain I wasn’t able to pass domain credentials(the same login failure).
Fortunately  for remote machines  connection https://tfsserver.mycompany.com works (as it worked before. I still not sure why http doesn’t work.
 
Surprisely, installation of TFS build and upgrade WSS 2.0 to WSS 3.0 was done without any issues.
But after this I am not able to open Project Portals(access is denied for the user).
  • /SharepointURI:http://wssserver:80 
  • /SharepointSitesUri:http://<wssserver:80/sites
  • /SharepointAdminUri:http://wssserver:adminport
  • /SharepointUnc:\wssserversites

and do not forget to  Migrate content or sites after upgrade (Windows SharePoint Services).

Advertisements

Set div to the vertical middle of the browser window

Our application shows custom HTML confirm message box, that we wanted to locate in the middle of the browser window.
If I would start from the scratch, I would use Ajax Control Toolkit  ModalPopup  
 
However, because the proprietary code to show div has been already written, I wanted just to set vertical position of the div.
 
I’ve created a function based on code from AlwaysVisibleControlExtender.js.
Initially it didn’t work, because common.JS getClientBounds : function()  returned 0 clientHeight and clientWidth.
It is actually a known bug in ASP.NET AJAX documentation Control Toolkit, because for  

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” > it is required to use

document.body.clientWidth instead of document.documentElement.clientWidth.

 

 
The created function is below. (I hope that I am compliant with http://www.codeplex.com/AjaxControlToolkit/license)
 

function SetVerticalMiddle(element)

{

    //Derived from http://www.asp.net/AJAX/AjaxControlToolkit/Samples/AlwaysVisibleControl/AlwaysVisibleControl.aspx AjaxControlToolkit.VerticalSide.Middle

    var y = 0;

    // Compute the width and height of the client

    // var CommonToolkitScripts = new AjaxControlToolkit._CommonToolkitScripts();

    // var clientBounds = CommonToolkitScripts.getClientBounds();

    // debugger;

    // var width = clientBounds.width;

    var height = getClientHeight();//clientBounds.height;

    if (document.documentElement && document.documentElement.scrollTop) {

        // x = document.documentElement.scrollLeft;

        y = document.documentElement.scrollTop;

    }

    else {

        // x = document.body.scrollLeft;

        y = document.body.scrollTop;

    }

    // Compute the coordinates

    // x = Math.max(0, Math.floor(x + width / 2.0 – element.offsetWidth / 2.0 ));

    y = Math.max(0, Math.floor(y + height / 2.0 – element.offsetHeight / 2.0 ));

    // element.style.left = x + ‘px’;

    element.style.top = y + ‘px’;

}

//copied from AjaxControlToolkitCommonCommon.js, fix from http://forums.asp.net/p/1002123/1323677.aspx#1323677

function getClientHeight() {

    /// <summary>

    /// Gets the height of the browser client window (excluding scrollbars)

    /// </summary>

    /// Browser’s client height

    /// </returns>

    // var clientWidth;

 

    var clientHeight;

    switch(Sys.Browser.agent) {

    case Sys.Browser.InternetExplorer:

    // if (document.documentElement && document.documentElement.clientWidth)

    // clientWidth = document.documentElement.clientWidth;

    // else if (document.body)

    // clientWidth = document.body.clientWidth;

 

        if (document.documentElement && document.documentElement.clientHeight)

            clientHeight = document.documentElement.clientHeight;

        else if (document.body)

            clientHeight = document.body.clientHeight;

    break;

        // clientWidth = document.documentElement.clientWidth;

        clientHeight = document.documentElement.clientHeight;

    break;

    case Sys.Browser.Safari:

        // clientWidth = window.innerWidth;

        clientHeight = window.innerHeight;

    break;

    case Sys.Browser.Opera:

        // clientWidth = Math.min(window.innerWidth, document.body.clientWidth);

        clientHeight = Math.min(window.innerHeight, document.body.clientHeight);

    break;

    default: // Sys.Browser.Firefox, etc.

        // clientWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);

        clientHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);

    break;

    }

    return clientHeight;//new Sys.UI.Bounds(0, 0, clientWidth, clientHeight);

}

 

I wasn’t able to use position:fixed (that supported by FireFox and IE 7) because the existing div is already inside DOM and not positioned properly without major changes of existing code.(There a a few posts describing hacks(too complicated and restrictive), how to emulate “fixed” in older browsers, e.g. IE 6 workaround for position:fixed,  Making IE 5.5+ use position: fixed ;position:fixed for Internet Explorer)
  
A few links about ASP.NET AJAX documentation Control Toolkit  ModalPopup:
 

Javascript variable declaration scope is different from C#.

It’s well known that JavaScript is similar to C++/C#, but doesn’t required explicit declaration of the variables.

However, it worth to read specification(e.g.  http://jennifermadden.com/javascript/variables.html )  to understand subtle differences.
 
I didn’t know, that a variable implicitly declared within a function is  a global variable.
For example,
function foo() {
        g= 17;//it’s global, will be visible outside the function after the function will be executed

          var x = 17;//local, not visible outside the function

}
          foo();
          println(g);//17
          println(x);//undefined
 
another rule(UPDATE:known browsers do not support it) : Depending on the system in which JavaScript is embedded, other objects whose scopes enclose the function currently executing (if any) are searched, starting from the innermost object, for a property identified by the simple name. If found, the simple name’s scope is the object containing the property.
I understood the rule as it is not nesessary to pass local variables as parameters to calling function, but the calling function can see parents variables.
 
function foo() {
         var x = 17;//local, but should be visible in calling function according to the rule
         foo1();   

}
function foo1() {
          println(x);//should be 17 if called from foo, but known browsers do not support it.

}

However as it was pointed by Nitin Reddy Katkam,  neither Firefox’s nor Internet Explorer’s nor Safari implementation of Javascript  support this rule.
Also note, that in JavaScript constructor var can be used to implement private members and this to implement public fields. See “Private Members in JavaScript” article.