diff --git a/DNN Platform/Library/Services/Installer/Installers/CleanupInstaller.cs b/DNN Platform/Library/Services/Installer/Installers/CleanupInstaller.cs index 267ff0a8022..3763c79dc8a 100644 --- a/DNN Platform/Library/Services/Installer/Installers/CleanupInstaller.cs +++ b/DNN Platform/Library/Services/Installer/Installers/CleanupInstaller.cs @@ -201,7 +201,7 @@ protected bool CleanupFile(InstallFile insFile) try { // Backup File - if (File.Exists(this.PhysicalBasePath + insFile.FullName)) + if (File.Exists(this.PhysicalBasePath + insFile.FullName) && this.BackupFiles) { Util.BackupFile(insFile, this.PhysicalBasePath, this.Log); } diff --git a/DNN Platform/Library/Services/Installer/Installers/FileInstaller.cs b/DNN Platform/Library/Services/Installer/Installers/FileInstaller.cs index fced96c85f5..0958874ce20 100644 --- a/DNN Platform/Library/Services/Installer/Installers/FileInstaller.cs +++ b/DNN Platform/Library/Services/Installer/Installers/FileInstaller.cs @@ -32,6 +32,9 @@ public class FileInstaller : ComponentInstallerBase /// Gets the name of the Item Node (file). protected virtual string ItemNodeName => "file"; + /// Gets or sets a value indicating whether any existing files should be backed up during installation. + protected bool BackupFiles { get; set; } = true; + /// Gets the PhysicalBasePath for the files. protected virtual string PhysicalBasePath { @@ -177,7 +180,7 @@ protected virtual bool InstallFile(InstallFile insFile) if (this.Package.InstallerInfo.IgnoreWhiteList || Util.IsFileValid(insFile, this.Package.InstallerInfo.AllowableFiles)) { // Install File - if (File.Exists(this.PhysicalBasePath + insFile.FullName)) + if (File.Exists(this.PhysicalBasePath + insFile.FullName) && this.BackupFiles) { Util.BackupFile(insFile, this.PhysicalBasePath, this.Log); } diff --git a/DNN Platform/Library/Services/Installer/Installers/ResourceFileInstaller.cs b/DNN Platform/Library/Services/Installer/Installers/ResourceFileInstaller.cs index 3119af9dabd..abe193ad312 100644 --- a/DNN Platform/Library/Services/Installer/Installers/ResourceFileInstaller.cs +++ b/DNN Platform/Library/Services/Installer/Installers/ResourceFileInstaller.cs @@ -122,7 +122,7 @@ protected override bool InstallFile(InstallFile insFile) writer.WriteElementString("name", fileName); var physicalPath = Path.Combine(this.PhysicalBasePath, entry.FullName); - if (File.Exists(physicalPath)) + if (File.Exists(physicalPath) && this.BackupFiles) { Util.BackupFile( new InstallFile(entry.FullName, this.Package.InstallerInfo), diff --git a/DNN Platform/Library/Services/Installer/LocalUpgradeService.cs b/DNN Platform/Library/Services/Installer/LocalUpgradeService.cs index a8bdc560458..82b194a4ecc 100644 --- a/DNN Platform/Library/Services/Installer/LocalUpgradeService.cs +++ b/DNN Platform/Library/Services/Installer/LocalUpgradeService.cs @@ -187,6 +187,7 @@ public async Task StartLocalUpgrade(IReadOnlyList upgrades, Ca /// public async Task StartLocalUpgrade(LocalUpgradeInfo upgrade, CancellationToken cancellationToken) { + this.SetAppOffline(); var upgradeZipPath = Path.Combine(this.UpgradeDirectoryPath, upgrade.PackageName + ".zip"); using var fileStream = File.OpenRead(upgradeZipPath); using var archive = new ZipArchive(fileStream, ZipArchiveMode.Read); @@ -218,6 +219,7 @@ await FileSystemUtils.UnzipResourcesAsync( .Where(entry => !upgradeSettings.UpgradeExclude.Any(filter => entry.FullName.StartsWith(filter, StringComparison.OrdinalIgnoreCase))), this.appStatus.ApplicationMapPath, cancellationToken); + this.SetAppOnline(); } private static async Task ReadZippedAssemblyVersion(ZipArchiveEntry assemblyEntry, CancellationToken cancellationToken) @@ -246,12 +248,37 @@ await assemblyStream.CopyToAsync( } } + private void SetAppOffline() + { + var appOfflineFile = Path.Combine(Globals.HostMapPath, "AppOffline", "App_Offline.htm"); + if (!File.Exists(appOfflineFile)) + { + appOfflineFile = Path.Combine(this.appStatus.ApplicationMapPath, "Resources", "AppOffline", "App_Offline.htm"); + } + + var targetFile = Path.Combine(this.appStatus.ApplicationMapPath, "App_Offline.htm"); + if (!File.Exists(targetFile)) + { + File.Copy(appOfflineFile, targetFile); + } + } + + private void SetAppOnline() + { + var appOfflineFile = Path.Combine(this.appStatus.ApplicationMapPath, "App_Offline.htm"); + if (File.Exists(appOfflineFile)) + { + File.Delete(appOfflineFile); + } + } + private class LocalUpgradeAssemblyInstaller : AssemblyInstaller { public LocalUpgradeAssemblyInstaller(InstallerInfo installerInfo) { this.Package = new PackageInfo(); this.Package.AttachInstallerInfo(installerInfo); + this.BackupFiles = false; } public async Task AddFiles(IEnumerable assemblyEntries, CancellationToken cancellationToken) diff --git a/DNN Platform/Website/DotNetNuke.Website.csproj b/DNN Platform/Website/DotNetNuke.Website.csproj index f8e658b25ab..054deb3b834 100644 --- a/DNN Platform/Website/DotNetNuke.Website.csproj +++ b/DNN Platform/Website/DotNetNuke.Website.csproj @@ -767,6 +767,7 @@ + diff --git a/DNN Platform/Website/Resources/AppOffline/App_Offline.htm b/DNN Platform/Website/Resources/AppOffline/App_Offline.htm new file mode 100644 index 00000000000..cdd647e8b9b --- /dev/null +++ b/DNN Platform/Website/Resources/AppOffline/App_Offline.htm @@ -0,0 +1,200 @@ + + + + + + Site Offline - Upgrade in Progress + + + + + + + + + + + + + + + + + + + + + + + + + We'll be right back + The site is currently being upgraded + + Our application is temporarily offline while we perform an upgrade. + Thank you for your patience — the site will be back online again soon. + + + + + + + + + +
The site is currently being upgraded
+ Our application is temporarily offline while we perform an upgrade. + Thank you for your patience — the site will be back online again soon. +