S h o r t S t o r i e s

// Tales from software development

Archive for September 2008

What account should you run Perforce server under ?

leave a comment »

Excluding files

I’m using Perforce as SCM for my private source code. I’ve used Microsoft’s own internally licenced and developed version of Perforce, Source Depot, on the project that I’ve been working on for the past 21 months. When using Perforce, I’ve been missing a feature that Source Depot implements but Perforce doesn’t – being able to reject certain file types from being submitted to the depot.

Triggers

Perforce implements triggers that run macros, scripts, or programs when certain events occur. As there is a ‘change-submit’ trigger that fires when a submit command is issued to check in code, this seemed to be the obvious mechanism to implement a solution to block a check-in if it includes a prohibitied file.

All I wanted to do was exclude *.suo and *.csproj.user files (user preference files for Visual Studio solutions and C# projects). It would have been easy enough to write a VBScript or JScript script to do this.  Actually, even an MS-DOS batch file could have done the job. However, I decided to write the trigger in C# 2.0 to give me a chance to try out the .NET interface for Perforce being developed at http://p4dotnet.sourceforge.net/.

P4SubmitFilter

P4SubmitFilter took a couple of hours to write and uses values in its config file to specify the settings to be used when connecting to the Perforce server and a list of semicolon delimited filemasks for the files that are to be blocked from check-in, e.g. “*.suo;*.csproj”.

The program is passed the changelist number and then issues a Perforce “describe -s” command to get a list of the files that the changelist contains. The list of files is checked against the list of filemasks for blocked files and exits with a non-zero return code and a message to SYSOUT if a match is made.

I tested the program in a command window against previously submitted changelists and everything seemed to work as expected. The program exited quietly with rc=0 for changelists that did not contain any files that matched the exclusion filemask list but exited with rc=1 and a message when a match was made.

Next, I started a virtual machine running Windows XP that had a copy of Perforce installed. I configured the trigger using the Perforce “triggers” command. The following line was added to the trigger specifications file:

P4SubmitFilter    change-submit    //depot/...    "P4SubmitFilter %changelist%"

The first item is an arbitrary name for the trigger and the second is the trigger type. The third item is the depot file specification for files that the trigger is to be applied to. The specification used indicates that the trigger is to be applied to all files in the depot. The last item is the command to be executed with ‘%changelist%’ being a Perforce token that is replaced with the changelist number when the command is executed.

Testing

I created a changelist that contained a .suo file and attempted to submit it. The trigger worked as expected – the submit command was rejected and a message was displayed indicating that *.suo files were blocked. I removed the .suo file from the changelist and ran the submit command again. This time the changelist was successfully submitted.

Thinking that I now had a production ready program, I recompiled the program in Release configuration and copied it to the server running my Perforce depot. I ran the ‘triggers’ command again and configured the new trigger as before. I then ran a test “submit” command against a changelist containing a .suo file. After a bit of a wait an error message was displayed indicating that the P4SubmitFilter command had failed and that no output was available. Strange… What was wrong ?

I ran the P4SubmitFilter program in a command window on the server and it executed as expected. I checked the trigger specification file and confirmed that there weren’t any typos. I re-tried the submit command and it failed as before. At this point I thought that the problem was somewhere in my code so I compiled a new version that included debug output.

I copied the new version to the server and started SysInternals’ DbgView on the server. I ran the submit command again but instead of seeing at least some debug output, the DbgView output window remained blank. So, the problem appeared to be that P4SubmitFilter wasn’t being successfully invoked by Perforce.

I checked the event logs but there was no indication of a problem with Perforce or P4SubmitFilter. I began to suspect the the issue was security and wondered if the Perforce server was running under different accounts on my server and my XP virtual machine. I checked but found that both machines were configured for Perforce to run under the Local System account.

What other differences were there between the two machines ? Well, the most obvious one was that my server is running Windows Server 2008 and the virtual machine is running Windows XP. Was that the problem ? Logically, it seemed unlikely but my gut feeling was that it was quite possible that Windows Server’s tighter security might be the cause of the problem.

Local System account

The quickest way to test this was to run the Perforce service under a local Administrator account rather than the Local System account. I made the change and re-started the Perforce service. I attempted to submit the changelist again… Success! This time the submit command was rejected with a message indicating that the .suo file could not be submitted.

This still seemed a little odd but a quick search on the internet showed that Microsoft has made some changes to at least one of the API functions used to start a process with the result that a process running under the Local System account can no longer start another process. The documentation for the CreateProcessWithLogonW function now includes this caveat:

Windows XP SP2 and Windows Server 2003:  You cannot call CreateProcessWithLogonW from a process that is running under the LocalSystem account, because the function uses the logon SID in the caller token, and the token for the LocalSystem account does not contain this SID. As an alternative, use the CreateProcessAsUser and LogonUser functions.

So, if you’re running Perforce under Windows Server 2003 or Windows Server 2008 then you may need to configure the service to run under a different account from the default Local System account.

Written by Sea Monkey

September 21, 2008 at 9:00 pm

Posted in Development

Tagged with , ,

How green is internet shopping ?

leave a comment »

My five year old DVD player has been misbehaving recently and this provided the excuse I needed to upgrade to a Blu-Ray player. I spent a couple of days researching the latest models on the market and then ordered my choice from a leading UK based internet retailer.

I checked back the next day to confirm that the order had been processed and found that the player had been despatched. When I checked the package tracking information I saw this:

Location Date Local Time Description
CRAWLEY,
GB
09/04/2008 6:46 A.M. OUT FOR DELIVERY
  09/04/2008 6:46 A.M. IMPORT SCAN
STANSTED AIRPORT,
GB
09/04/2008 3:36 A.M. ARRIVAL SCAN
KOELN (COLOGNE),
DE
09/04/2008 3:34 A.M. DEPARTURE SCAN
  09/04/2008 3:23 A.M. DEPARTURE SCAN
KOELN (COLOGNE),
DE
09/03/2008 11:58 P.M. ARRIVAL SCAN
ROISSY, PARIS,
FR
09/03/2008 10:51 P.M. DEPARTURE SCAN
CHILLY MAZARIN, PARI,
FR
09/03/2008 3:04 P.M. EXPORT SCAN
  09/03/2008 3:04 P.M. ORIGIN SCAN
FR 09/03/2008 1:53 P.M. BILLING INFORMATION RECEIVED

The package was delivered at 9:45AM the same day, 4 September 2008. So, in less than 24 hours the package had been despatched from Paris, sent by air to Cologne, then onto Stansted by air, then by road to Crawley, and was delivered by a UPS van a couple of hours later.

I’m impressed and appalled at the same time. Impressed at the logistics of moving a DVD player from Paris via Cologne to my home in 20 hours and appalled at the carbon footprint this implies.

Written by Sea Monkey

September 4, 2008 at 10:27 am

Posted in Comment

Tagged with