Пример #1
0
        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")));
        }
Пример #2
0
        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));
        }
Пример #4
0
        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"))));
        }
Пример #6
0
        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));
            }
        }
Пример #7
0
        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)));
        }
Пример #8
0
        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");
            }
        }
Пример #10
0
        /// <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)));
        }
Пример #11
0
        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");
        }
Пример #12
0
        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));
        }
Пример #13
0
        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));
                }
            }
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }
Пример #16
0
        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);
            }
        }
Пример #17
0
        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
                                              ));
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
        }
Пример #20
0
        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);
            }
        }
Пример #21
0
        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));
                }
            }
        }
Пример #22
0
        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));
                }
            }
        }
Пример #24
0
        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);
                }
            }
        }
Пример #25
0
        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);
        }
Пример #28
0
        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);
            }
        }
Пример #30
0
        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});
            }
        }
Пример #32
0
        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);
            }
        }
Пример #33
0
        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);
        }