/// <summary> /// Do not deploy applications if we are short on disk space. /// /// Throws an exception if size is below minSize /// </summary> /// <param name="minSize">Defaults to 500Mb</param> protected void CheckDiskSpace(long minSize = 524288000) { var applicationPath = this.GlobalSettings.GetDefaultApplicationStorage().path; long freeSpaceBytes = UtilsSystem.GetTotalFreeSpace(applicationPath); if (freeSpaceBytes < minSize) { throw new Exception($"Insuficient storage [{UtilsSystem.BytesToString(freeSpaceBytes)}] to run deployments in: {applicationPath}"); } }
/// <summary> /// Downloads (And extracts) single artifacts from jobs. /// </summary> /// <param name="applicationId"></param> /// <param name="build"></param> /// <param name="artifactRegex"></param> /// <param name="destinationPath"></param> /// <param name="logger"></param> public void DownloadSingleArtifactFromBuild( string applicationId, Build build, string artifactRegex, string destinationPath, ILoggerInterface logger) { UtilsSystem.EnsureDirectoryExists(destinationPath, true); // Use the first job in the build... var job = build.jobs.First(); var artifact = this.FindDefaultArtifactForBuild(job, build, artifactRegex); var filename = artifact.fileName; var extension = Path.GetExtension(filename); string downloadTemporaryDir = UtilsSystem.EnsureDirectoryExists(UtilsSystem.CombinePaths(this.TempDir, "_appveyor", "dld", applicationId), true); int artifactRetentionNum = 5; int artifactAgeHoursForStale = 24; // Do not touch the latest artifactRetentionNum artifacts or artifacts that are not older than artifactAgeHoursForStale hours var staleFiles = Directory.EnumerateFiles(downloadTemporaryDir) .Select((i) => new FileInfo(i)) .Where((i) => i.Extension.Equals(".zip", StringComparison.CurrentCultureIgnoreCase)) .OrderByDescending((i) => i.CreationTimeUtc) .Skip(artifactRetentionNum) .Where((i) => (DateTime.UtcNow - i.LastWriteTime).TotalHours > artifactAgeHoursForStale) .ToList(); foreach (var f in staleFiles) { // Make this fail proof, it's just a cleanup. try { this.Logger.LogInfo(true, "Removing stale artifact cache file {0}", f.FullName); f.Delete(); } catch { // ignored } } // Use a short hash as the temporary file name, because long paths can have issues... var tmpFile = UtilsSystem.CombinePaths(downloadTemporaryDir, UtilsEncryption.GetShortHash(JsonConvert.SerializeObject(build) + filename) + extension); if (Path.GetExtension(tmpFile)?.ToLower() != ".zip") { throw new NotImplementedException("AppVeyor artifacts should only be Zip Files."); } if (!File.Exists(tmpFile)) { // Use an intermediate .tmp file just in case the files does not finish to download, // if it exists, clear it. string tmpFileDownload = tmpFile + ".tmp"; if (File.Exists(tmpFileDownload)) { UtilsSystem.RetryWhile(() => File.Delete(tmpFileDownload), (e) => true, 4000, this.Logger); } var url = $"/api/buildjobs/{job.jobId}/artifacts/{filename}"; logger.LogInfo(true, "Downloading artifact from: '{0}' to '{1}'", url, tmpFileDownload); this.ExecuteApiCallToFile(url, tmpFileDownload); // Rename to the final cached artifact file logger.LogInfo(true, "Download succesful, moving to '{0}'", tmpFile); UtilsSystem.RetryWhile(() => File.Move(tmpFileDownload, tmpFile), (e) => true, 4000, this.Logger); } else { logger.LogInfo(true, "Skipping artifact download, already in local cache: {0}", tmpFile); } logger.LogInfo(true, "Unzipping {1} file to '{0}'...", destinationPath, UtilsSystem.BytesToString(new FileInfo(tmpFile).Length)); ZipFile.ExtractToDirectory(tmpFile, destinationPath); logger.LogInfo(true, "Unzipping finished."); }