public void ShouldRemoveArtifactsWhenDaysSpecified() { result = Clean("retentionPolicySet1", 3, null); result.AssertSuccess(); Assert.False(fileSystem.DirectoryExists(Path.Combine(stagingDirectory, "Acme.1.0.0"))); Assert.False(fileSystem.FileExists(Path.Combine(packagesDirectory, "Acme.1.0.0.nupkg"))); }
public ConfigurationTransformTestCaseBuilder FileExists(string fileName) { fileSystem.FileExists(fileName).Returns(true); var directory = Path.GetDirectoryName(fileName); fileSystem.DirectoryExists(directory).Returns(true); files.Add(fileName); return(this); }
public void ShouldUseUserSpecifiedConfigurationFile(string customRelativePath) { variables.Set(SpecialVariables.Action.Azure.CloudServiceConfigurationFileRelativePath, customRelativePath); var expectedAbsolutePath = Path.Combine(StagingDirectory, customRelativePath); fileSystem.FileExists(expectedAbsolutePath).Returns(true); convention.Install(deployment); Assert.That(GetResolvedPathFromVariables(), Is.EqualTo(expectedAbsolutePath)); }
public void ShouldUpdatePath() { const string websiteName = "AcmeOnline"; variables.Set(SpecialVariables.Package.UpdateIisWebsite, true.ToString()); variables.Set(SpecialVariables.Package.UpdateIisWebsiteName, websiteName); fileSystem.FileExists(Path.Combine(stagingDirectory, "Web.config")).Returns(true); iis.OverwriteHomeDirectory(websiteName, stagingDirectory, false).Returns(true); CreateConvention().Install(deployment); iis.Received().OverwriteHomeDirectory(websiteName, stagingDirectory, false); }
string GetRootMostDirectoryContainingWebConfig(RunningDeployment deployment) { // Optimize for most common case. if (fileSystem.FileExists(Path.Combine(deployment.CurrentDirectory, "Web.config"))) { return(deployment.CurrentDirectory); } // Find all folders under package root and sort them by depth var dirs = fileSystem.EnumerateDirectoriesRecursively(deployment.CurrentDirectory).ToList(); return(dirs.OrderBy(x => x.Count(c => c == '\\')).FirstOrDefault(dir => fileSystem.FileExists(Path.Combine(dir, "Web.config")))); }
public void Install(RunningDeployment deployment) { Log.Info("Config file: " + deployment.Variables.Get(SpecialVariables.Action.Azure.Output.ConfigurationFile)); Log.SetOutputVariable("OctopusAzureServiceName", deployment.Variables.Get(SpecialVariables.Action.Azure.CloudServiceName), deployment.Variables); Log.SetOutputVariable("OctopusAzureStorageAccountName", deployment.Variables.Get(SpecialVariables.Action.Azure.StorageAccountName), deployment.Variables); Log.SetOutputVariable("OctopusAzureSlot", deployment.Variables.Get(SpecialVariables.Action.Azure.Slot), deployment.Variables); Log.SetOutputVariable("OctopusAzurePackageUri", deployment.Variables.Get(SpecialVariables.Action.Azure.UploadedPackageUri), deployment.Variables); Log.SetOutputVariable("OctopusAzureDeploymentLabel", deployment.Variables.Get(SpecialVariables.Action.Name) + " v" + deployment.Variables.Get(SpecialVariables.Release.Number), deployment.Variables); Log.SetOutputVariable("OctopusAzureSwapIfPossible", deployment.Variables.Get(SpecialVariables.Action.Azure.SwapIfPossible, defaultValue: false.ToString()), deployment.Variables); Log.SetOutputVariable("OctopusAzureUseCurrentInstanceCount", deployment.Variables.Get(SpecialVariables.Action.Azure.UseCurrentInstanceCount), deployment.Variables); // The script name 'DeployToAzure.ps1' is used for backwards-compatibility var scriptFile = Path.Combine(deployment.CurrentDirectory, "DeployToAzure.ps1"); // The user may supply the script, to override behaviour if (!fileSystem.FileExists(scriptFile)) { fileSystem.OverwriteFile(scriptFile, embeddedResources.GetEmbeddedResourceText("Calamari.Azure.Scripts.DeployAzureCloudService.ps1")); } var result = scriptEngine.Execute(scriptFile, deployment.Variables, commandLineRunner); fileSystem.DeleteFile(scriptFile, FailureOptions.IgnoreFailure); if (result.ExitCode != 0) { throw new CommandException(string.Format("Script '{0}' returned non-zero exit code: {1}", scriptFile, result.ExitCode)); } }
public void ShouldNotDeleteDirectoryWhereRetainedDeployedToSame() { var journalEntries = new List <JournalEntry> { fourDayOldDeployment, fourDayOldSameLocationDeployment, twoDayOldDeployment, }; deploymentJournal.GetAllJournalEntries().Returns(journalEntries); fileSystem.FileExists(fourDayOldSameLocationDeployment.Package.DeployedFrom).Returns(true); fileSystem.DirectoryExists(fourDayOldSameLocationDeployment.ExtractedTo).Returns(true); const int days = 3; retentionPolicy.ApplyRetentionPolicy(policySet1, days, null); // Ensure the directories are the same Assert.AreEqual(twoDayOldDeployment.ExtractedTo, fourDayOldSameLocationDeployment.ExtractedTo); // The old directory was not removed... fileSystem.DidNotReceive().DeleteDirectory(Arg.Is <string>(s => s.Equals(fourDayOldSameLocationDeployment.ExtractedTo))); // ...despite being removed from the journal deploymentJournal.Received().RemoveJournalEntries(Arg.Is <IEnumerable <string> >(ids => ids.Contains(fourDayOldSameLocationDeployment.Id))); // and unique directory still removed fileSystem.Received().DeleteDirectory(Arg.Is <string>(s => s.Equals(fourDayOldDeployment.ExtractedTo))); }
public void ApplyRetention() { try { using (AcquireSemaphore()) { journalRepository.Load(); var packagesToRemove = retentionAlgorithm.GetPackagesToRemove(journalRepository.GetAllJournalEntries()); foreach (var package in packagesToRemove) { if (string.IsNullOrWhiteSpace(package.Path.Value) || !fileSystem.FileExists(package.Path.Value)) { log.Verbose($"Package at {package.Path} not found."); } else { Log.Verbose($"Removing package file '{package.Path}'"); fileSystem.DeleteFile(package.Path.Value, FailureOptions.IgnoreFailure); } journalRepository.RemovePackageEntry(package); } journalRepository.Commit(); } } catch (Exception ex) { Log.Info(ex.Message); } }
public void Install(RunningDeployment deployment) { Log.SetOutputVariable("OctopusAzureServiceName", deployment.Variables.Get(SpecialVariables.Action.Azure.CloudServiceName), deployment.Variables); Log.SetOutputVariable("OctopusAzureStorageAccountName", deployment.Variables.Get(SpecialVariables.Action.Azure.StorageAccountName), deployment.Variables); Log.SetOutputVariable("OctopusAzureSlot", deployment.Variables.Get(SpecialVariables.Action.Azure.Slot), deployment.Variables); Log.SetOutputVariable("OctopusAzureDeploymentLabel", deployment.Variables.Get(SpecialVariables.Action.Name) + " v" + deployment.Variables.Get(SpecialVariables.Release.Number), deployment.Variables); Log.SetOutputVariable("OctopusAzureSwapIfPossible", deployment.Variables.Get(SpecialVariables.Action.Azure.SwapIfPossible, defaultValue: false.ToString()), deployment.Variables); var tempDirectory = fileSystem.CreateTemporaryDirectory(); var scriptFile = Path.Combine(tempDirectory, "SwapAzureCloudServiceDeployment.ps1"); // The user may supply the script, to override behaviour if (!fileSystem.FileExists(scriptFile)) { fileSystem.OverwriteFile(scriptFile, embeddedResources.GetEmbeddedResourceText("Calamari.Azure.Scripts.SwapAzureCloudServiceDeployment.ps1")); } var result = scriptEngine.Execute(scriptFile, deployment.Variables, commandLineRunner); fileSystem.DeleteDirectory(tempDirectory, FailureOptions.IgnoreFailure); if (result.ExitCode != 0) { throw new CommandException($"Script '{scriptFile}' returned non-zero exit code: {result.ExitCode}"); } var swapped = deployment.Variables.GetFlag(SpecialVariables.Action.Azure.Output.CloudServiceDeploymentSwapped); if (swapped) { deployment.Variables.Set(SpecialVariables.Action.SkipRemainingConventions, "true"); } }
/// <summary> /// Uploads a single file with the given properties /// </summary> /// <param name="clientFactory"></param> /// <param name="deployment"></param> /// <param name="selection"></param> public Task <S3UploadResult> UploadSingleFileSelection(Func <AmazonS3Client> clientFactory, RunningDeployment deployment, S3SingleFileSelectionProperties selection) { Guard.NotNull(deployment, "Deployment may not be null"); Guard.NotNull(selection, "Single file selection properties may not be null"); Guard.NotNull(clientFactory, "Client factory must not be null"); var filePath = Path.Combine(deployment.StagingDirectory, selection.Path); if (!fileSystem.FileExists(filePath)) { throw new FileNotFoundException($"The file {selection.Path} could not be found in the package."); } if (selection.PerformVariableSubstitution) { substituteInFiles.Substitute(deployment.CurrentDirectory, new List <string> { filePath }); } if (selection.PerformStructuredVariableSubstitution) { structuredConfigVariablesService.ReplaceVariables(deployment.CurrentDirectory, new List <string> { filePath }); } return(CreateRequest(filePath, GetBucketKey(filePath.AsRelativePathFrom(deployment.StagingDirectory), selection), selection) .Tee(x => LogPutObjectRequest(filePath, x)) .Map(x => HandleUploadRequest(clientFactory(), x, ThrowInvalidFileUpload))); }
public void SetUp() { fileSystem = Substitute.For <ICalamariFileSystem>(); deploymentJournal = Substitute.For <IDeploymentJournal>(); clock = Substitute.For <IClock>(); retentionPolicy = new RetentionPolicy(fileSystem, deploymentJournal, clock); now = new DateTimeOffset(new DateTime(2015, 01, 15), new TimeSpan(0, 0, 0)); clock.GetUtcTime().Returns(now); // Deployed 4 days prior to 'now' fourDayOldDeployment = new JournalEntry("fourDayOld", "blah", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-4).LocalDateTime, "C:\\packages\\Acme.1.0.0.nupkg", "C:\\Applications\\Acme.1.0.0", null, true); // Deployed 4 days prior to 'now' but to the same location as the latest successful deployment fourDayOldSameLocationDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-4).LocalDateTime, "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true); // Deployed 3 days prior to 'now' threeDayOldDeployment = new JournalEntry("threeDayOld", "blah", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-3).LocalDateTime, "C:\\packages\\Acme.1.1.0.nupkg", "C:\\Applications\\Acme.1.1.0", null, true); // Deployed 2 days prior to 'now' twoDayOldDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-2).LocalDateTime, "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true); // Deployed (unsuccessfully) 1 day prior to 'now' oneDayOldUnsuccessfulDeployment = new JournalEntry("oneDayOldUnsuccessful", "blah", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-1).LocalDateTime, "C:\\packages\\Acme.1.3.0.nupkg", "C:\\Applications\\Acme.1.3.0", null, false); // Deployed 5 days prior to 'now', but has a different policy-set fiveDayOldNonMatchingDeployment = new JournalEntry("fiveDayOld", "blah", "blah", "blah", "blah", "blah", policySet2, now.AddDays(-5).LocalDateTime, "C:\\packages\\Beta.1.0.0.nupkg", "C:\\Applications\\Beta.1.0.0", null, true); var journalEntries = new List <JournalEntry> { fiveDayOldNonMatchingDeployment, fourDayOldDeployment, threeDayOldDeployment, twoDayOldDeployment, oneDayOldUnsuccessfulDeployment }; deploymentJournal.GetAllJournalEntries().Returns(journalEntries); foreach (var journalEntry in journalEntries) { fileSystem.FileExists(journalEntry.ExtractedFrom).Returns(true); fileSystem.DirectoryExists(journalEntry.ExtractedTo).Returns(true); } Environment.SetEnvironmentVariable("TentacleHome", @"Q:\TentacleHome"); }
void ArrangeOriginalConfigurationFileForSuccess(string configurationFilePath, string content, Action <string> captureResultingConfiguration) { variables.Set(SpecialVariables.Action.Azure.Output.ConfigurationFile, configurationFilePath); fileSystem.FileExists(configurationFilePath).Returns(true); fileSystem.ReadFile(configurationFilePath).Returns(content); fileSystem.OverwriteFile(configurationFilePath, Arg.Do <string>(captureResultingConfiguration)); }
public void Dispose() { if (AttachLogFile) { if (fileSystem.FileExists(logPath)) { Log.NewOctopusArtifact(fileSystem.GetFullPath(logPath), fileSystem.GetFileName(logPath), fileSystem.GetFileSize(logPath)); } //When terraform crashes, the information would be contained in the crash.log file. We should attach this since //we don't want to blow that information away in case it provides something relevant https://www.terraform.io/docs/internals/debugging.html#interpreting-a-crash-log if (fileSystem.FileExists(crashLogPath)) { Log.NewOctopusArtifact(fileSystem.GetFullPath(crashLogPath), fileSystem.GetFileName(crashLogPath), fileSystem.GetFileSize(crashLogPath)); } } }
void ReadUnencryptedVariablesFromFile(CommonOptions options, CalamariVariables variables) { var variablesFile = options.InputVariables.VariablesFile; if (string.IsNullOrEmpty(variablesFile)) { return; } if (!fileSystem.FileExists(variablesFile)) { throw new CommandException("Could not find variables file: " + variablesFile); } var readVars = new VariableDictionary(variablesFile); variables.Merge(readVars); }
private string GetChartLocation(RunningDeployment deployment) { var packagePath = deployment.Variables.Get(Deployment.SpecialVariables.Package.Output.InstallationDirectoryPath); var packageId = deployment.Variables.Get(Deployment.SpecialVariables.Package.NuGetPackageId); if (fileSystem.FileExists(Path.Combine(packagePath, "Chart.yaml"))) { return(Path.Combine(packagePath, "Chart.yaml")); } packagePath = Path.Combine(packagePath, packageId); if (!fileSystem.DirectoryExists(packagePath) || !fileSystem.FileExists(Path.Combine(packagePath, "Chart.yaml"))) { throw new CommandException($"Unexpected error. Chart.yaml was not found in {packagePath}"); } return(packagePath); }
private static void MockSearchableFiles(ICalamariFileSystem fileSystem, string parentDirectory, string[] files, string searchPattern) { fileSystem.EnumerateFilesRecursively(parentDirectory, Arg.Is <string[]>(x => new List <string>(x).Contains(searchPattern))).Returns(files); foreach (var file in files) { fileSystem.FileExists(file).Returns(true); } }
public Maybe <ResolvedTemplatePath> MaybeResolve(string relativeFilePath, bool inPackage, IVariables variables) { var absolutePath = relativeFilePath.ToMaybe().Select(path => inPackage ? Path.Combine(variables.Get(KnownVariables.OriginalPackageDirectoryPath), variables.Evaluate(path)) : Path.Combine(Environment.CurrentDirectory, path)); return(absolutePath.SelectValueOr(x => !filesystem.FileExists(x) ? Maybe <ResolvedTemplatePath> .None : new ResolvedTemplatePath(x).AsSome(), Maybe <ResolvedTemplatePath> .None )); }
public void ShouldCreateScriptFileIfNotExists() { const string deployStage = "BeforePostDeploy"; const string feature = "doTheThing"; var scriptPath = Path.Combine(stagingDirectory, FeatureScriptConvention.GetScriptName(feature, deployStage, "ps1")); variables.Set(SpecialVariables.Package.EnabledFeatures, feature); Arrange(new List <string> { feature }, deployStage); fileSystem.FileExists(scriptPath).Returns(false); var convention = CreateConvention(deployStage); scriptEngine.Execute(scriptPath, variables, commandLineRunner).Returns(new CommandResult("", 0)); convention.Install(deployment); fileSystem.Received().OverwriteFile(scriptPath, scriptContents); }
void DeleteExtractionSource(DeployedPackage deployedPackage, List <JournalEntry> preservedEntries) { if (string.IsNullOrWhiteSpace(deployedPackage.DeployedFrom) || !fileSystem.FileExists(deployedPackage.DeployedFrom) || preservedEntries.Any(entry => entry.Packages.Any(p => deployedPackage.DeployedFrom.Equals(p.DeployedFrom, StringComparison.Ordinal)))) { return; } Log.Info($"Removing package file '{deployedPackage.DeployedFrom}'"); fileSystem.DeleteFile(deployedPackage.DeployedFrom, FailureOptions.IgnoreFailure); }
public IEnumerable <string> DetermineTransformFileNames(string sourceFile, XmlConfigTransformDefinition transformation) { var defaultTransformFileName = DetermineTransformFileName(sourceFile, transformation, true); var transformFileName = DetermineTransformFileName(sourceFile, transformation, false); string fullTransformPath; if (Path.IsPathRooted(transformFileName)) { fullTransformPath = Path.GetFullPath(GetDirectoryName(transformFileName)); } else { var relativeTransformPath = fileSystem.GetRelativePath(sourceFile, transformFileName); fullTransformPath = Path.GetFullPath(Path.Combine(GetDirectoryName(sourceFile), GetDirectoryName(relativeTransformPath))); } if (!fileSystem.DirectoryExists(fullTransformPath)) { yield break; } // The reason we use fileSystem.EnumerateFiles here is to get the actual file-names from the physical file-system. // This prevents any issues with mis-matched casing in transform specifications. foreach (var transformFile in fileSystem.EnumerateFiles(fullTransformPath, GetFileName(defaultTransformFileName), GetFileName(transformFileName))) { var sourceFileName = (transformation?.SourcePattern?.Contains(Path.DirectorySeparatorChar) ?? false) ? fileSystem.GetRelativePath(transformFile, sourceFile).TrimStart('.', Path.DirectorySeparatorChar) : GetFileName(sourceFile); if (transformation.Advanced && !transformation.IsSourceWildcard && !string.Equals(transformation.SourcePattern, sourceFileName, StringComparison.InvariantCultureIgnoreCase)) { continue; } if (transformation.Advanced && transformation.IsSourceWildcard && !DoesFileMatchWildcardPattern(sourceFileName, transformation.SourcePattern)) { continue; } if (!fileSystem.FileExists(transformFile)) { continue; } if (string.Equals(sourceFile, transformFile, StringComparison.InvariantCultureIgnoreCase)) { continue; } yield return(transformFile); } }
public void Dispose() { var attachLogFile = variables.GetFlag(TerraformSpecialVariables.Action.Terraform.AttachLogFile); if (attachLogFile) { var crashLogPath = Path.Combine(deployment.CurrentDirectory, "crash.log"); if (fileSystem.FileExists(logPath)) { log.NewOctopusArtifact(fileSystem.GetFullPath(logPath), fileSystem.GetFileName(logPath), fileSystem.GetFileSize(logPath)); } //When terraform crashes, the information would be contained in the crash.log file. We should attach this since //we don't want to blow that information away in case it provides something relevant https://www.terraform.io/docs/internals/debugging.html#interpreting-a-crash-log if (fileSystem.FileExists(crashLogPath)) { log.NewOctopusArtifact(fileSystem.GetFullPath(crashLogPath), fileSystem.GetFileName(crashLogPath), fileSystem.GetFileSize(crashLogPath)); } } }
void DeleteExtractionSource(JournalEntry deployment, List <JournalEntry> preservedEntries) { if (string.IsNullOrWhiteSpace(deployment.ExtractedFrom) || !fileSystem.FileExists(deployment.ExtractedFrom) || preservedEntries.Any(entry => deployment.ExtractedFrom.Equals(entry.ExtractedFrom, StringComparison.Ordinal))) { return; } Log.VerboseFormat("Removing package file '{0}'", deployment.ExtractedFrom); fileSystem.DeleteFile(deployment.ExtractedFrom, FailureOptions.IgnoreFailure); }
protected void Run(RunningDeployment deployment) { var features = deployment.Variables.GetStrings(SpecialVariables.Package.EnabledFeatures).Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); if (!features.Any()) { return; } var assembly = typeof(FeatureScriptConventionBase).GetTypeInfo().Assembly; var embeddedResourceNames = new HashSet <string>(embeddedResources.GetEmbeddedResourceNames(assembly)); foreach (var featureScript in features.SelectMany(GetScriptNames)) { // Determine the embedded-resource name var scriptEmbeddedResource = GetEmbeddedResourceName(featureScript); // If there is a matching embedded resource if (!embeddedResourceNames.Contains(scriptEmbeddedResource)) { continue; } var scriptFile = Path.Combine(deployment.CurrentDirectory, featureScript); // To execute the script, we need a physical file on disk. // If one already exists, we don't recreate it, as this provides a handy // way to override behaviour. if (!fileSystem.FileExists(scriptFile)) { Log.VerboseFormat("Creating '{0}' from embedded resource", scriptFile); fileSystem.OverwriteFile(scriptFile, embeddedResources.GetEmbeddedResourceText(assembly, scriptEmbeddedResource)); } else { Log.WarnFormat("Did not overwrite '{0}', it was already on disk", scriptFile); } // Execute the script Log.VerboseFormat("Executing '{0}'", scriptFile); var result = scriptEngine.Execute(new Script(scriptFile), deployment.Variables, commandLineRunner); // And then delete it Log.VerboseFormat("Deleting '{0}'", scriptFile); fileSystem.DeleteFile(scriptFile, FailureOptions.IgnoreFailure); if (result.ExitCode != 0) { throw new CommandException(string.Format("Script '{0}' returned non-zero exit code: {1}", scriptFile, result.ExitCode)); } } }
void StagePackageReferences(RunningDeployment deployment) { var variables = deployment.Variables; // No need to check for "default" package since it gets extracted in the current directory in previous step. var packageReferenceNames = variables.GetIndexes(PackageVariables.PackageCollection) .Where(i => !string.IsNullOrEmpty(i)); foreach (var packageReferenceName in packageReferenceNames) { Log.Verbose($"Considering '{packageReferenceName}' for extraction"); var sanitizedPackageReferenceName = fileSystem.RemoveInvalidFileNameChars(packageReferenceName); var packageOriginalPath = variables.Get(PackageVariables.IndexedOriginalPath(packageReferenceName)); if (string.IsNullOrWhiteSpace(packageOriginalPath)) { Log.Info($"Package '{packageReferenceName}' was not acquired or does not require staging"); continue; } packageOriginalPath = Path.GetFullPath(variables.Get(PackageVariables.IndexedOriginalPath(packageReferenceName))); // In the case of container images, the original path is not a file-path. We won't try and extract or move it. if (!fileSystem.FileExists(packageOriginalPath)) { Log.Verbose($"Package '{packageReferenceName}' was not found at '{packageOriginalPath}', skipping extraction"); continue; } var shouldExtract = variables.GetFlag(PackageVariables.IndexedExtract(packageReferenceName)); if (forceExtract || shouldExtract) { var extractionPath = Path.Combine(deployment.CurrentDirectory, sanitizedPackageReferenceName); ExtractPackage(packageOriginalPath, extractionPath); Log.SetOutputVariable(SpecialVariables.Packages.ExtractedPath(packageReferenceName), extractionPath, variables); } else { var localPackageFileName = sanitizedPackageReferenceName + Path.GetExtension(packageOriginalPath); var destinationPackagePath = Path.Combine(deployment.CurrentDirectory, localPackageFileName); Log.Info($"Copying package: '{packageOriginalPath}' -> '{destinationPackagePath}'"); fileSystem.CopyFile(packageOriginalPath, destinationPackagePath); Log.SetOutputVariable(SpecialVariables.Packages.PackageFilePath(packageReferenceName), destinationPackagePath, variables); Log.SetOutputVariable(SpecialVariables.Packages.PackageFileName(packageReferenceName), localPackageFileName, variables); } } }
public void ShouldCopyFilesToCustomInstallationDirectory() { // Set-up a custom installation directory string customInstallDirectory = Path.Combine(Path.GetTempPath(), "CalamariTestInstall"); fileSystem.EnsureDirectoryExists(customInstallDirectory); // Ensure the directory is empty before we start fileSystem.PurgeDirectory(customInstallDirectory, FailureOptions.ThrowOnFailure); variables.Set(SpecialVariables.Package.CustomInstallationDirectory, customInstallDirectory); var result = DeployPackage("Acme.Web"); // Assert content was copied to custom-installation directory Assert.IsTrue(fileSystem.FileExists(Path.Combine(customInstallDirectory, "assets", "styles.css"))); }
string GetChartLocation(RunningDeployment deployment) { var installDir = deployment.Variables.Get(PackageVariables.Output.InstallationDirectoryPath); var packageId = deployment.Variables.Get(PackageVariables.IndexedPackageId(string.Empty)); // Try the root directory if (fileSystem.FileExists(Path.Combine(installDir, "Chart.yaml"))) { return(Path.Combine(installDir, "Chart.yaml")); } // Try the directory that matches the package id var packageIdPath = Path.Combine(installDir, packageId); if (fileSystem.DirectoryExists(packageIdPath) && fileSystem.FileExists(Path.Combine(packageIdPath, "Chart.yaml"))) { return(packageIdPath); } /* * Although conventions suggests that the directory inside the helm archive matches the package ID, this * can not be assumed. If the standard locations above failed to locate the Chart.yaml file, loop over * all subdirectories to try and find the file. */ foreach (var dir in fileSystem.EnumerateDirectories(installDir)) { if (fileSystem.FileExists(Path.Combine(dir, "Chart.yaml"))) { return(dir); } } // Nothing worked throw new CommandException($"Unexpected error. Chart.yaml was not found in {packageIdPath}"); }
// When a package has been installed once, Octopus gives users the ability to 'force' a redeployment of the package. // This is often useful for example if a deployment partially completes and the installation is in an invalid state // (e.g., corrupt files are left on disk, or the package is only half extracted). We *can't* just uninstall the package // or overwrite the files, since they might be locked by IIS or another process. So instead we create a new unique // directory. static string EnsureTargetPathExistsAndIsEmpty(string desiredTargetPath, ICalamariFileSystem fileSystem) { var target = desiredTargetPath; using (Semaphore.Acquire("Octopus.Calamari.ExtractionDirectory", "Another process is finding an extraction directory, please wait...")) { for (var i = 1; fileSystem.DirectoryExists(target) || fileSystem.FileExists(target); i++) { target = desiredTargetPath + "_" + i; } fileSystem.EnsureDirectoryExists(target); } return(target); }
public void Install(RunningDeployment deployment) { // Validate we actually have a real path to the real config file since this value is potentially passed via variable or a previous convention var configurationFilePath = deployment.Variables.Get(SpecialVariables.Action.Azure.Output.ConfigurationFile); if (!fileSystem.FileExists(configurationFilePath)) { throw new CommandException("Could not find the Azure Cloud Service Configuration file: " + configurationFilePath); } var configuration = XDocument.Parse(fileSystem.ReadFile(configurationFilePath)); UpdateConfigurationWithCurrentInstanceCount(configuration, configurationFilePath, deployment.Variables); UpdateConfigurationSettings(configuration, deployment.Variables); SaveConfigurationFile(configuration, configurationFilePath); }
void ApplyTransformations(string sourceFile, XmlConfigTransformDefinition transformation, ISet <Tuple <string, string> > transformFilesApplied, ICollection <XmlConfigTransformDefinition> transformDefinitionsApplied) { if (transformation == null) { return; } foreach (var transformFile in DetermineTransformFileNames(sourceFile, transformation)) { var sourceFileName = (transformation?.SourcePattern?.Contains(Path.DirectorySeparatorChar) ?? false) ? fileSystem.GetRelativePath(transformFile, sourceFile).TrimStart('.', Path.DirectorySeparatorChar) : GetFileName(sourceFile); if (transformation.Advanced && !transformation.IsSourceWildcard && !string.Equals(transformation.SourcePattern, sourceFileName, StringComparison.InvariantCultureIgnoreCase)) { continue; } if (transformation.Advanced && transformation.IsSourceWildcard && !DoesFileMatchWildcardPattern(sourceFileName, transformation.SourcePattern)) { continue; } if (!fileSystem.FileExists(transformFile)) { continue; } if (string.Equals(sourceFile, transformFile, StringComparison.InvariantCultureIgnoreCase)) { continue; } var transformFiles = new Tuple <string, string>(transformFile, sourceFile); if (transformFilesApplied.Contains(transformFiles)) { continue; } Log.Info("Transforming '{0}' using '{1}'.", sourceFile, transformFile); configurationTransformer.PerformTransform(sourceFile, transformFile, sourceFile); transformFilesApplied.Add(transformFiles); transformDefinitionsApplied.Add(transformation); } }
private IEnumerable <XElement> Read() { if (!fileSystem.FileExists(JournalPath)) { yield break; } using (var file = fileSystem.OpenFile(JournalPath, FileAccess.Read)) { var document = XDocument.Load(file); foreach (var element in document.Element("Deployments").Elements()) { yield return(element); } } }
private static void MockSearchableFiles(ICalamariFileSystem fileSystem, string parentDirectory, string[] files, string searchPattern) { fileSystem.EnumerateFilesRecursively(parentDirectory, Arg.Is<string[]>(x => new List<string>(x).Contains(searchPattern))).Returns(files); foreach (var file in files) { fileSystem.FileExists(file).Returns(true); fileSystem.EnumerateFiles(Path.GetDirectoryName(files[0]), Arg.Is<string[]>(s => s.Contains(GetRelativePathToTransformFile(files[0], file)))).Returns(new[] {file}); } }
public void SetUp() { fileSystem = Substitute.For<ICalamariFileSystem>(); deploymentJournal = Substitute.For<IDeploymentJournal>(); clock = Substitute.For<IClock>(); retentionPolicy = new RetentionPolicy(fileSystem, deploymentJournal, clock); now = new DateTimeOffset(new DateTime(2015, 01, 15), new TimeSpan(0, 0, 0)); clock.GetUtcTime().Returns(now); // Deployed 4 days prior to 'now' fourDayOldDeployment = new JournalEntry("fourDayOld", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-4).LocalDateTime, "C:\\packages\\Acme.1.0.0.nupkg", "C:\\Applications\\Acme.1.0.0", null, true); // Deployed 3 days prior to 'now' threeDayOldDeployment = new JournalEntry("threeDayOld", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-3).LocalDateTime, "C:\\packages\\Acme.1.1.0.nupkg", "C:\\Applications\\Acme.1.1.0", null, true); // Deployed 2 days prior to 'now' twoDayOldDeployment = new JournalEntry("twoDayOld", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-2).LocalDateTime, "C:\\packages\\Acme.1.2.0.nupkg", "C:\\Applications\\Acme.1.2.0", null, true); // Deployed (unsuccessfully) 1 day prior to 'now' oneDayOldUnsuccessfulDeployment = new JournalEntry("oneDayOldUnsuccessful", "blah", "blah", "blah", "blah", policySet1, now.AddDays(-1).LocalDateTime, "C:\\packages\\Acme.1.3.0.nupkg", "C:\\Applications\\Acme.1.3.0", null, false); // Deployed 5 days prior to 'now', but has a different policy-set fiveDayOldNonMatchingDeployment = new JournalEntry("fiveDayOld", "blah", "blah", "blah", "blah", policySet2, now.AddDays(-5).LocalDateTime, "C:\\packages\\Beta.1.0.0.nupkg", "C:\\Applications\\Beta.1.0.0", null, true); var journalEntries = new List<JournalEntry> { fiveDayOldNonMatchingDeployment, fourDayOldDeployment, threeDayOldDeployment, twoDayOldDeployment, oneDayOldUnsuccessfulDeployment }; deploymentJournal.GetAllJournalEntries().Returns(journalEntries); foreach (var journalEntry in journalEntries) { fileSystem.FileExists(journalEntry.ExtractedFrom).Returns(true); fileSystem.DirectoryExists(journalEntry.ExtractedTo).Returns(true); } }
VariableDictionary LoadVariables(ICalamariFileSystem fileSystem) { if (variablesFile != null && !fileSystem.FileExists(variablesFile)) throw new CommandException("Could not find variables file: " + variablesFile); if (!string.IsNullOrEmpty(sensitiveVariablesPassword)) { if (string.IsNullOrWhiteSpace(sensitiveVariablesSalt)) throw new CommandException("sensitiveVariablesSalt option must be supplied if sensitiveVariablesPassword option is supplied."); return new SensitiveVariables(fileSystem).IncludeSensitiveVariables(variablesFile, sensitiveVariablesPassword, sensitiveVariablesSalt); } return new VariableDictionary(variablesFile); }