protected override void OnLockAcquired() { OperationManager.SafeExecute(() => { // Create Sentinel file for DWAS to check // DWAS will check for presence of this file incase a an app setting based recycle needs to be performed in middle of deployment // If this is present, DWAS will postpone the recycle so that deployment goes through first if (!String.IsNullOrEmpty(siteRoot)) { FileSystemHelpers.CreateDirectory(Path.Combine(siteRoot, @"ShutdownSentinel")); string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (!FileSystemHelpers.FileExists(sentinelPath)) { var file = FileSystemHelpers.CreateFile(sentinelPath); file.Close(); } // DWAS checks if write time of this file is in the future then only postpones the recycle FileInfoBase sentinelFileInfo = FileSystemHelpers.FileInfoFromFileName(sentinelPath); sentinelFileInfo.LastWriteTimeUtc = DateTime.UtcNow.AddMinutes(20); } }); IRepositoryFactory repositoryFactory = RepositoryFactory; if (repositoryFactory != null) { IRepository repository = repositoryFactory.GetRepository(); if (repository != null) { // Clear any left over repository-related lock since we have the actual lock repository.ClearLock(); } } }
public static void Extract(this ZipArchive archive, string directoryName) { foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write)) { zipStream.CopyTo(fileStream); } fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; } } }
public static void Extract(this ZipArchive archive, string directoryName, ITracer tracer, bool doNotPreserveFileTime = false) { const int MaxExtractTraces = 5; var entries = archive.Entries; var total = entries.Count; var traces = 0; using (tracer.Step(string.Format("Extracting {0} entries to {1} directory", entries.Count, directoryName))) { foreach (ZipArchiveEntry entry in entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); string message = null; // tracing first/last N files if (traces < MaxExtractTraces || traces >= total - MaxExtractTraces) { message = string.Format("Extracting to {0} ...", fileInfo.FullName); } else if (traces == MaxExtractTraces) { message = "Omitting extracting file traces ..."; } ++traces; using (!string.IsNullOrEmpty(message) ? tracer.Step(message) : null) { if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write)) { zipStream.CopyTo(fileStream); } // this is to allow, the file time to always be newer than destination // the outcome is always replacing the destination files. // it is non-optimized but workaround NPM reset file time issue (https://github.com/projectkudu/kudu/issues/2917). if (!doNotPreserveFileTime) { fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; } } } } } }
public static void RequestContainerRestart(IEnvironment environment, string reason) { if (OSDetector.IsOnWindows() && !EnvironmentHelper.IsWindowsContainers()) { throw new NotSupportedException("RequestContainerRestart is only supported on Linux and Windows Containers"); } var restartTriggerPath = Path.Combine(environment.SiteRootPath, CONFIG_DIR_NAME, TRIGGER_FILENAME); FileSystemHelpers.CreateDirectory(Path.GetDirectoryName(restartTriggerPath)); var fileContents = String.Format( FILE_CONTENTS_FORMAT, DateTimeOffset.UtcNow.ToString("o", CultureInfo.InvariantCulture), reason); FileSystemHelpers.WriteAllText(restartTriggerPath, fileContents); }
public static void RequestContainerRestart(IEnvironment environment, string reason, ITracer tracer) { if (OSDetector.IsOnWindows() && !EnvironmentHelper.IsWindowsContainers()) { tracer.Trace("Ignoring FS watcher based recycle request as this is a classic Windows app."); return; } var restartTriggerPath = Path.Combine(environment.SiteRootPath, CONFIG_DIR_NAME, TRIGGER_FILENAME); FileSystemHelpers.CreateDirectory(Path.GetDirectoryName(restartTriggerPath)); var fileContents = String.Format( FILE_CONTENTS_FORMAT, DateTimeOffset.UtcNow.ToString("o", CultureInfo.InvariantCulture), reason); FileSystemHelpers.WriteAllText(restartTriggerPath, fileContents); }
public bool Acquire(ITracer tracer) { lock (_lock) { try { // No timeout makes this call instant. No waiting for acquistion bool acquired = _shutdownSemaphore.Wait(millisecondsTimeout: 0); if (!acquired) { tracer.Trace("Could not acquire shutdown semaphore", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); return(false); } //tracer.Trace("Acquired shutdown semaphore", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); OperationManager.SafeExecute(() => { if (Environment.IsAzureEnvironment() && OSDetector.IsOnWindows()) { string siteRoot = PathUtilityFactory.Instance.ResolveLocalSitePath(); // Create Sentinel file for DWAS to check // DWAS will check for presence of this file incase a an app setting based recycle needs to be performed in middle of deployment // If this is present, DWAS will postpone the recycle so that deployment goes through first if (!string.IsNullOrEmpty(siteRoot)) { FileSystemHelpers.CreateDirectory(Path.Combine(siteRoot, @"ShutdownSentinel")); string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (!FileSystemHelpers.FileExists(sentinelPath)) { //tracer.Trace("Creating shutdown sentinel file", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); var file = FileSystemHelpers.CreateFile(sentinelPath); file.Close(); } tracer.Trace("Updating shutdown sentinel last write time", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); // DWAS checks if write time of this file is in the future then only postpones the recycle FileInfoBase sentinelFileInfo = FileSystemHelpers.FileInfoFromFileName(sentinelPath); sentinelFileInfo.LastWriteTimeUtc = DateTime.UtcNow.AddMinutes(20); } } }); } catch (Exception ex) { tracer.TraceError(ex); return(false); } return(true); } }
public static IDictionary <string, string> Extract(this ZipArchive archive, string directoryName, bool preserveSymlinks = false) { IDictionary <string, string> symLinks = new Dictionary <string, string>(); bool isSymLink = false; foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { zipStream.CopyTo(fileStream); } isSymLink = false; string originalFileName = string.Empty; if (!OSDetector.IsOnWindows()) { try { using (Stream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] buffer = new byte[4]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var str = System.Text.Encoding.Default.GetString(buffer); if (preserveSymlinks && str.StartsWith("../")) { using (StreamReader reader = fileInfo.OpenText()) { symLinks[entry.FullName] = reader.ReadToEnd(); } isSymLink = true; } } } catch (Exception ex) { throw new Exception("Could not identify symlinks in zip file : " + ex.ToString()); } } try { fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; } catch (Exception) { //best effort } if (isSymLink) { fileInfo.Delete(); } } } return(symLinks); }
public static void Extract(this ZipArchive archive, string directoryName) { foreach (ZipArchiveEntry entry in archive.Entries) { string path = Path.Combine(directoryName, entry.FullName); if (entry.Length == 0 && (path.EndsWith("/", StringComparison.Ordinal) || path.EndsWith("\\", StringComparison.Ordinal))) { // Extract directory FileSystemHelpers.CreateDirectory(path); } else { FileInfoBase fileInfo = FileSystemHelpers.FileInfoFromFileName(path); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } using (Stream zipStream = entry.Open(), fileStream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) { zipStream.CopyTo(fileStream); } bool createSymLink = false; string originalFileName = string.Empty; if (!OSDetector.IsOnWindows()) { try { using (Stream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] buffer = new byte[10]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var str = System.Text.Encoding.Default.GetString(buffer); if (str.StartsWith("../")) { string fullPath = Path.GetFullPath(str); if (fullPath.StartsWith(directoryName)) { createSymLink = true; originalFileName = fullPath; } } } } catch (Exception ex) { throw new Exception("Could not identify symlinks in zip file : " + ex.ToString()); } } fileInfo.LastWriteTimeUtc = entry.LastWriteTime.ToUniversalTime().DateTime; if (createSymLink) { try { fileInfo.Delete(); Mono.Unix.UnixFileInfo unixFileInfo = new Mono.Unix.UnixFileInfo(originalFileName); unixFileInfo.CreateSymbolicLink(path); } catch (Exception ex) { throw new Exception("Could not create symlinks : " + ex.ToString()); } } } } }