Failing copy files when using handle to remove locks in PreDeploy.ps1

This is an intermittent issue, usually if I re-run the same release it will succeed, but as this is suppose to be a continuous delivery project I need to understand why and hopefully stop it from occurring.

In the PreDeploy.ps1 script handle.exe is called and unlocks any locks on the target directory, when handle.exe is executed on a x64 machine a handle64.exe file is automatically created. Sometimes after the PreDeploy.ps1 script has completed successfully and the Copy files step starts I get the following error : -

@@@
| Failed: Copy files to D:\wwwroot\appmagic
09:53:09 Info | Purging the directory 'D:\wwwroot\appmagic’
09:53:09 Info | Copying package contents to 'D:\wwwroot\appmagic’
09:53:12 Error | Unable to copy the package to the specified directory ‘D:\wwwroot\appmagic’. One or more files in the directory may be locked by another process. You could use a PreDeploy.ps1 script to stop any processes that may be locking the file. Error details follow.
| Could not find file ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’.
| System.IO.FileNotFoundException: Could not find file ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’.
| File name: ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’
| at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
| at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyFile(String sourceFile, String targetFile, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 324
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyDirectory(String sourceDirectory, String targetDirectory, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 299
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyDirectory(String sourceDirectory, String targetDirectory, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 306
| at Octopus.Tentacle.Deployment.Conventions.Implementations.CopyPackageConvention.<>c__DisplayClass1.b__0(IConventionContext cc) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Tentacle\Deployment\Conventions\Implementations\CopyPackageConvention.cs:line 60
09:53:12 Fatal | Could not find file ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’.
| System.IO.FileNotFoundException: Could not find file ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’.
| File name: ‘D:\Octopus2.0\Applications\SystemTest3\Hiscox.Underwriting.Server\3.9.3772.94_3\bin\handle64.exe’
| at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
| at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyFile(String sourceFile, String targetFile, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 324
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyDirectory(String sourceDirectory, String targetDirectory, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 299
| at Octopus.Platform.Util.OctopusPhysicalFileSystem.CopyDirectory(String sourceDirectory, String targetDirectory, Int32 overwriteFileRetryAttempts) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Platform\Util\OctopusPhysicalFileSystem.cs:line 306
| at Octopus.Tentacle.Deployment.Conventions.Implementations.CopyPackageConvention.<>c__DisplayClass1.b__0(IConventionContext cc) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Tentacle\Deployment\Conventions\Implementations\CopyPackageConvention.cs:line 65
| at Octopus.Tentacle.Deployment.Conventions.ConventionContextExtensions.RunChildOperation(IConventionContext context, String friendlyName, Action`1 operation) in c:\TeamCity\buildAgent\work\1116bd9da9e239fd\source\Octopus.Tentacle\Deployment\Conventions\ConventionContextExtensions.cs:line 15
|
@@@

If I view the OctopusOriginalPackageDirectoryPath location the handle64.exe is no longer there.

My assumption is that the Copy files step creates a list of the files in the OctopusOriginalPackageDirectoryPath location at the point when handle64.exe exists and that this file is removed after the handle unlocking process has finished, meaning when the Copy files step actually runs it is against an out-of-date list of files.

If you could help me understand more around the Copy files step or any other possible explanation for this error occurring I would really appreciate it.

Cheers

Steve

Hi Steve,

I’ve just looked at the code for this. When we copy files, we don’t make a list of files when we extracted etc.; instead we simply attempt to copy whatever files are in the original path to the target path.

Perhaps there’s a delay between issuing the call to delete the file, and the file not appearing when we list the files to copy. We simply list the files to copy right before copying them like this:

 Directory.GetFiles(sourceDirectory, "*");

Is there a virus scanner or something else that might be preventing the file from being deleted immediately?

Perhaps at the end of your PreDeploy you could try adding a sleep for a second or two before continuing to see if that resolves the problem.

Paul