From feb73de8a63e7aa40233d739a4e11f5c23db85f3 Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 17:13:05 +0300 Subject: [PATCH 1/5] update update_db.sql for WiX --- WebsitePanel/Database/wix_update_db.sql | 560 +++++++++++++++++++++--- 1 file changed, 487 insertions(+), 73 deletions(-) diff --git a/WebsitePanel/Database/wix_update_db.sql b/WebsitePanel/Database/wix_update_db.sql index 4f342f1d..c44654db 100644 --- a/WebsitePanel/Database/wix_update_db.sql +++ b/WebsitePanel/Database/wix_update_db.sql @@ -8910,6 +8910,12 @@ INSERT [dbo].[Quotas] ([QuotaID], [GroupID], [QuotaOrder], [QuotaName], [QuotaDe END GO +IF NOT EXISTS (SELECT * FROM [dbo].[Quotas] WHERE [QuotaID] = '572') +BEGIN + INSERT [dbo].[Quotas] ([QuotaID], [GroupID], [QuotaOrder], [QuotaName], [QuotaDescription], [QuotaTypeID], [ServiceQuota], [ItemTypeID], [HideQuota]) VALUES (572, 33, 20, N'VPS2012.ReplicationEnabled', N'Allow user to Replication', 1, 0, NULL, NULL) +END +GO + IF NOT EXISTS (SELECT * FROM [dbo].[Providers] WHERE [ProviderName] = 'HyperV2012R2') BEGIN INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery]) VALUES (350, 33, N'HyperV2012R2', N'Microsoft Hyper-V 2012 R2', N'WebsitePanel.Providers.Virtualization.HyperV2012R2, WebsitePanel.Providers.Virtualization.HyperV2012R2', N'HyperV2012R2', 1) @@ -9590,6 +9596,13 @@ IF EXISTS (SELECT * FROM ResourceGroups WHERE GroupName = 'SharePoint') BEGIN DECLARE @group_id INT SELECT @group_id = GroupId FROM ResourceGroups WHERE GroupName = 'SharePoint' + DELETE FROM PackageQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanQuotas WHERE QuotaID IN (SELECT QuotaID FROM Quotas WHERE GroupID = @group_id) + DELETE FROM HostingPlanResources WHERE GroupId = @group_id + DELETE FROM PackagesBandwidth WHERE GroupId = @group_id + DELETE FROM PackagesDiskspace WHERE GroupId = @group_id + DELETE FROM PackageResources WHERE GroupId = @group_id + DELETE FROM ResourceGroupDnsRecords WHERE GroupId = @group_id DELETE FROM Providers WHERE GroupID = @group_id DELETE FROM Quotas WHERE GroupID = @group_id DELETE FROM VirtualGroups WHERE GroupID = @group_id @@ -10020,6 +10033,145 @@ UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetLetterTextBo GO + + +DECLARE @UserPasswordResetSMSBody nvarchar(2500) + +Set @UserPasswordResetSMSBody = N'Password reset link: +#passwordResetLink# +' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetLetter', N'PasswordResetLinkSmsBody', @UserPasswordResetSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetLetter' AND [PropertyName]= N'PasswordResetLinkSmsBody' +GO + +-- USER PASSWORD RESET EMAIL PINCODE TEMPLATE + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'From' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'From', N'support@HostingCompany.com') +END +GO + +DECLARE @UserPasswordResetPincodeLetterHtmlBody nvarchar(2500) + +Set @UserPasswordResetPincodeLetterHtmlBody = N' + + Password reset notification + + + +
+
+ +
+

Password reset notification

+ + +

+Hello #user.FirstName#, +

+
+ +

+We received a request to reset the password for your account. Your password reset pincode: +

+ +#passwordResetPincode# + +

+If you have any questions regarding your hosting account, feel free to contact our support department at any time. +

+ +

+Best regards +

+
+'; + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'HtmlBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'HtmlBody', @UserPasswordResetPincodeLetterHtmlBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetPincodeLetterHtmlBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'HtmlBody' +GO + + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'Priority' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'Priority', N'Normal') +END +GO +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'Subject' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'Subject', N'Password reset notification') +END +GO +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'LogoUrl' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'LogoUrl', N'https://controlpanel.virtuworks.net/App_Themes/Default/Images/logo.png') +END +GO + + +DECLARE @UserPasswordResetPincodeLetterTextBody nvarchar(2500) + +Set @UserPasswordResetPincodeLetterTextBody = N'========================================= + Password reset notification +========================================= + + +Hello #user.FirstName#, + + +We received a request to reset the password for your account. Your password reset pincode: + +#passwordResetPincode# + +If you have any questions regarding your hosting account, feel free to contact our support department at any time. + +Best regards' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'TextBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'TextBody', @UserPasswordResetPincodeLetterTextBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordResetPincodeLetterTextBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'TextBody' +GO + +DECLARE @UserPasswordPincodeSMSBody nvarchar(2500) + +Set @UserPasswordPincodeSMSBody = N' +Your password reset pincode: +#passwordResetPincode#' + +IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' ) +BEGIN +INSERT [dbo].[UserSettings] ([UserID], [SettingsName], [PropertyName], [PropertyValue]) VALUES (1, N'UserPasswordResetPincodeLetter', N'PasswordResetPincodeSmsBody', @UserPasswordPincodeSMSBody) +END +ELSE +UPDATE [dbo].[UserSettings] SET [PropertyValue] = @UserPasswordPincodeSMSBody WHERE [UserID] = 1 AND [SettingsName]= N'UserPasswordResetPincodeLetter' AND [PropertyName]= N'PasswordResetPincodeSmsBody' +GO + -- Exchange setup EMAIL TEMPLATE @@ -10289,79 +10441,79 @@ GO DECLARE @ExchangeMailboxSetupLetterTextBody nvarchar(2500) -Set @ExchangeMailboxSetupLetterTextBody = N' -Hello #Account.DisplayName#, - -Thanks for choosing VirtuWorks as your Exchange hosting provider. - - -User Accounts - -The following user accounts have been created for you. - -Username: #Account.UserPrincipalName# -E-mail: #Account.PrimaryEmailAddress# - -Password Reset Url: #PswResetUrl# - - - -================================= -DNS -================================= - -In order for us to accept mail for your domain, you will need to point your MX records to: - -#SmtpServer# - -================================= -Webmail (OWA, Outlook Web Access) -================================= - -https://mail.virtuworks.net/owa - -================================= -Outlook (Windows Clients) -================================= - -To configure Outlook 2010 to work with VirtuWorks servers, please reference: - -https://portal.virtuworks.net/whmcs/knowledgebase.php?action=displayarticle&id=2 - -If you need to download and install the Outlook 2010 client: - -Outlook 2010 Download URL: -32 Bit - http://www.virtuworks.net/downloads/Outlook2010-32bit.zip -64 Bit - http://www.virtuworks.net/downloads/Outlook2010-64bit.zip -KEY: HXGFV-DY3HM-4W2BQ-3R7KQ-K8P49 - -================================= -ActiveSync, iPhone, iPad -================================= - -Server: #ActiveSyncServer# -Domain: #SamDomain# -SSL: must be checked -Your username: #SamUsername# - -================================= -Password Changes -================================= - -Passwords can be changed at any time using Webmail or the Control Panel (https://controlpanel.virtuworks.net). - - -================================= -Control Panel -================================= - -If you need to change the details of your account, you can easily do this using the Control Panel (https://controlpanel.virtuworks.net). - - -================================= -Support -================================= - +Set @ExchangeMailboxSetupLetterTextBody = N' +Hello #Account.DisplayName#, + +Thanks for choosing VirtuWorks as your Exchange hosting provider. + + +User Accounts + +The following user accounts have been created for you. + +Username: #Account.UserPrincipalName# +E-mail: #Account.PrimaryEmailAddress# + +Password Reset Url: #PswResetUrl# + + + +================================= +DNS +================================= + +In order for us to accept mail for your domain, you will need to point your MX records to: + +#SmtpServer# + +================================= +Webmail (OWA, Outlook Web Access) +================================= + +https://mail.virtuworks.net/owa + +================================= +Outlook (Windows Clients) +================================= + +To configure Outlook 2010 to work with VirtuWorks servers, please reference: + +https://portal.virtuworks.net/whmcs/knowledgebase.php?action=displayarticle&id=2 + +If you need to download and install the Outlook 2010 client: + +Outlook 2010 Download URL: +32 Bit - http://www.virtuworks.net/downloads/Outlook2010-32bit.zip +64 Bit - http://www.virtuworks.net/downloads/Outlook2010-64bit.zip +KEY: HXGFV-DY3HM-4W2BQ-3R7KQ-K8P49 + +================================= +ActiveSync, iPhone, iPad +================================= + +Server: #ActiveSyncServer# +Domain: #SamDomain# +SSL: must be checked +Your username: #SamUsername# + +================================= +Password Changes +================================= + +Passwords can be changed at any time using Webmail or the Control Panel (https://controlpanel.virtuworks.net). + + +================================= +Control Panel +================================= + +If you need to change the details of your account, you can easily do this using the Control Panel (https://controlpanel.virtuworks.net). + + +================================= +Support +================================= + You have 2 options, email help@virtuworks.com or use the web interface at http://www.virtuworks.com/contact/' IF NOT EXISTS (SELECT * FROM [dbo].[UserSettings] WHERE [UserID] = 1 AND [SettingsName]= N'ExchangeMailboxSetupLetter' AND [PropertyName]= N'TextBody' ) @@ -10674,3 +10826,265 @@ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER OFF GO + + +IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE type = 'P' AND name = 'GetSearchObject') +DROP PROCEDURE GetSearchObject +GO +CREATE PROCEDURE [dbo].[GetSearchObject] +( + @ActorID int, + @UserID int, + @FilterColumn nvarchar(50) = '', + @FilterValue nvarchar(50) = '', + @StatusID int, + @RoleID int, + @SortColumn nvarchar(50), + @StartRow int, + @MaximumRows int = 0, + @Recursive bit, + @ColType nvarchar(50) = '', + @FullType nvarchar(50) = '', + @OnlyFind bit +) +AS + +IF dbo.CheckActorUserRights(@ActorID, @UserID) = 0 +RAISERROR('You are not allowed to access this account', 16, 1) + +DECLARE @columnUsername nvarchar(20) +SET @columnUsername = 'Username' + +DECLARE @columnEmail nvarchar(20) +SET @columnEmail = 'Email' + +DECLARE @columnCompanyName nvarchar(20) +SET @columnCompanyName = 'CompanyName' + +DECLARE @columnFullName nvarchar(20) +SET @columnFullName = 'FullName' + +DECLARE @curUsers cursor +DECLARE @curSpace cursor + +DECLARE @sqlSpace nvarchar(2000) +DECLARE @sqlUsers nvarchar(2000) +DECLARE @sqlReturn nvarchar(4000) + +IF @FilterColumn = '' AND @FilterValue <> '' +SET @FilterColumn = 'TextSearch' + +SET @sqlUsers = ' +DECLARE @HasUserRights bit +SET @HasUserRights = dbo.CheckActorUserRights(@ActorID, @UserID) +DECLARE @Users TABLE +( + ItemPosition int IDENTITY(0,1), + UserID int +) +INSERT INTO @Users (UserID) +SELECT ' + +IF @OnlyFind = 1 +SET @sqlUsers = @sqlUsers + 'TOP ' + CAST(@MaximumRows AS varchar(12)) + ' ' + +SET @sqlUsers = @sqlUsers + 'U.UserID +FROM UsersDetailed AS U +WHERE + U.UserID <> @UserID AND U.IsPeer = 0 AND + ( + (@Recursive = 0 AND OwnerID = @UserID) OR + (@Recursive = 1 AND dbo.CheckUserParent(@UserID, U.UserID) = 1) + ) + AND ((@StatusID = 0) OR (@StatusID > 0 AND U.StatusID = @StatusID)) + AND ((@RoleID = 0) OR (@RoleID > 0 AND U.RoleID = @RoleID)) + AND @HasUserRights = 1 +SET @curValue = cursor local for +SELECT + U.ItemID, + U.TextSearch, + U.ColumnType, + ''Users'' as FullType, + 0 as PackageID, + 0 as AccountID +FROM @Users AS TU +INNER JOIN +( +SELECT ItemID, TextSearch, ColumnType +FROM( +SELECT U0.UserID as ItemID, U0.Username as TextSearch, @columnUsername as ColumnType +FROM dbo.Users AS U0 +UNION +SELECT U1.UserID as ItemID, U1.Email as TextSearch, @columnEmail as ColumnType +FROM dbo.Users AS U1 +UNION +SELECT U2.UserID as ItemID, U2.CompanyName as TextSearch, @columnCompanyName as ColumnType +FROM dbo.Users AS U2 +UNION +SELECT U3.UserID as ItemID, U3.FirstName + '' '' + U3.LastName as TextSearch, @columnFullName as ColumnType +FROM dbo.Users AS U3) as U +WHERE TextSearch<>'' '' OR ISNULL(TextSearch, 0) > 0 +) + AS U ON TU.UserID = U.ItemID' + +SET @sqlUsers = @sqlUsers + ' open @curValue' + +exec sp_executesql @sqlUsers, N'@UserID int, @FilterValue nvarchar(50), @ActorID int, @Recursive bit, @StatusID int, @RoleID int, @columnUsername nvarchar(20), @columnEmail nvarchar(20), @columnCompanyName nvarchar(20), @columnFullName nvarchar(20), @curValue cursor output', +@UserID, @FilterValue, @ActorID, @Recursive, @StatusID, @RoleID, @columnUsername, @columnEmail, @columnCompanyName, @columnFullName, @curValue=@curUsers output + +SET @sqlSpace = ' + DECLARE @ItemsService TABLE + ( + ItemID int + ) + INSERT INTO @ItemsService (ItemID) + SELECT ' + +IF @OnlyFind = 1 +SET @sqlSpace = @sqlSpace + 'TOP ' + CAST(@MaximumRows AS varchar(12)) + ' ' + +SET @sqlSpace = @sqlSpace + 'SI.ItemID + FROM ServiceItems AS SI + INNER JOIN Packages AS P ON P.PackageID = SI.PackageID + INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID + WHERE + dbo.CheckUserParent(@UserID, P.UserID) = 1 + DECLARE @ItemsDomain TABLE + ( + ItemID int + ) + INSERT INTO @ItemsDomain (ItemID) + SELECT + D.DomainID + FROM Domains AS D + INNER JOIN Packages AS P ON P.PackageID = D.PackageID + INNER JOIN UsersDetailed AS U ON P.UserID = U.UserID + WHERE + dbo.CheckUserParent(@UserID, P.UserID) = 1 + + SET @curValue = cursor local for + SELECT + + SI.ItemID as ItemID, + SI.ItemName as TextSearch, + STYPE.DisplayName as ColumnType, + STYPE.DisplayName as FullType, + SI.PackageID as PackageID, + 0 as AccountID + FROM @ItemsService AS I + INNER JOIN ServiceItems AS SI ON I.ItemID = SI.ItemID + INNER JOIN ServiceItemTypes AS STYPE ON SI.ItemTypeID = STYPE.ItemTypeID + WHERE STYPE.Searchable = 1 + UNION + SELECT + D.DomainID AS ItemID, + D.DomainName as TextSearch, + ''Domain'' as ColumnType, + ''Domain'' as FullType, + D.PackageID as PackageID, + 0 as AccountID + FROM @ItemsDomain AS I + INNER JOIN Domains AS D ON I.ItemID = D.DomainID + WHERE D.IsDomainPointer=0 + UNION + SELECT + EA.ItemID AS ItemID, + EA.AccountName as TextSearch, + ''ExchangeAccount'' as ColumnType, + ''ExchangeAccount'' as FullType, + SI2.PackageID as PackageID, + EA.AccountID as AccountID + FROM @ItemsService AS I2 + INNER JOIN ServiceItems AS SI2 ON I2.ItemID = SI2.ItemID + INNER JOIN ExchangeAccounts AS EA ON I2.ItemID = EA.ItemID +'; + +SET @sqlSpace = @sqlSpace + ' open @curValue' + +exec sp_executesql @sqlSpace, N'@UserID int, @FilterValue nvarchar(50), @ActorID int, @curValue cursor output', +@UserID, @FilterValue, @ActorID, @curValue=@curSpace output + +SET @sqlReturn = ' +DECLARE @ItemID int +DECLARE @TextSearch nvarchar(500) +DECLARE @ColumnType nvarchar(50) +DECLARE @FullType nvarchar(50) +DECLARE @PackageID int +DECLARE @AccountID int +DECLARE @EndRow int +SET @EndRow = @StartRow + @MaximumRows +DECLARE @ItemsAll TABLE + ( + ItemPosition int IDENTITY(1,1), + ItemID int, + TextSearch nvarchar(500), + ColumnType nvarchar(50), + FullType nvarchar(50), + PackageID int, + AccountID int + ) + +FETCH NEXT FROM @curSpaceValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +WHILE @@FETCH_STATUS = 0 +BEGIN +INSERT INTO @ItemsAll(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +VALUES(@ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID) +FETCH NEXT FROM @curSpaceValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +END + +FETCH NEXT FROM @curUsersValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +WHILE @@FETCH_STATUS = 0 +BEGIN +INSERT INTO @ItemsAll(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +VALUES(@ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID) +FETCH NEXT FROM @curUsersValue INTO @ItemID, @TextSearch, @ColumnType, @FullType, @PackageID, @AccountID +END + +DECLARE @ItemsReturn TABLE + ( + ItemPosition int IDENTITY(1,1), + ItemID int, + TextSearch nvarchar(500), + ColumnType nvarchar(50), + FullType nvarchar(50), + PackageID int, + AccountID int + ) +INSERT INTO @ItemsReturn(ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID) +SELECT ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID +FROM @ItemsAll AS IA WHERE (1 = 1) ' + + +IF @ColType <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.ColumnType in ( ' + @ColType + ' ) '; + +IF @FullType <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.FullType = ''' + @FullType + ''''; + +IF @FilterValue <> '' +SET @sqlReturn = @sqlReturn + ' AND IA.' + @FilterColumn + ' LIKE @FilterValue ' + +IF @SortColumn <> '' AND @SortColumn IS NOT NULL +SET @sqlReturn = @sqlReturn + ' ORDER BY ' + @SortColumn + ' ' +SET @sqlReturn = @sqlReturn + ' +SELECT COUNT(ItemID) FROM @ItemsReturn; +SELECT DISTINCT(ColumnType) FROM @ItemsReturn WHERE (1 = 1) '; +IF @FullType <> '' +SET @sqlReturn = @sqlReturn + ' AND FullType = ''' + @FullType + ''''; +SET @sqlReturn = @sqlReturn + '; '; +SET @sqlReturn = @sqlReturn + ' +SELECT ItemPosition, ItemID, TextSearch, ColumnType, FullType, PackageID, AccountID +FROM @ItemsReturn AS IR WHERE (1 = 1) +' + +IF @MaximumRows > 0 +SET @sqlReturn = @sqlReturn + ' AND IR.ItemPosition BETWEEN @StartRow AND @EndRow'; + +exec sp_executesql @sqlReturn, N'@StartRow int, @MaximumRows int, @FilterValue nvarchar(50), @curSpaceValue cursor, @curUsersValue cursor', +@StartRow, @MaximumRows, @FilterValue, @curSpace, @curUsers + +CLOSE @curSpace +DEALLOCATE @curSpace +CLOSE @curUsers +DEALLOCATE @curUsers +RETURN From b35dec4356bb7ceeaf38dfc2988d6b1a3dcbf748 Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 17:15:01 +0300 Subject: [PATCH 2/5] Fix sql update script --- WebsitePanel/Database/wix_update_db.sql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WebsitePanel/Database/wix_update_db.sql b/WebsitePanel/Database/wix_update_db.sql index c44654db..4131b41b 100644 --- a/WebsitePanel/Database/wix_update_db.sql +++ b/WebsitePanel/Database/wix_update_db.sql @@ -8197,11 +8197,13 @@ AS INNER JOIN PackagesTreeCache AS PT ON PIP.PackageID = PT.PackageID WHERE PT.ParentPackageID = @PackageID AND IP.PoolID = 3) ELSE IF @QuotaID = 558 BEGIN -- RAM of VPS2012 - DECLARE @Result1 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result1 int + SET @Result1 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN PackagesTreeCache AS PT ON SI.PackageID = PT.PackageID WHERE SIP.PropertyName = 'RamSize' AND PT.ParentPackageID = @PackageID) - DECLARE @Result2 int = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP + DECLARE @Result2 int + SET @Result2 = (SELECT SUM(CAST(SIP.PropertyValue AS int)) FROM ServiceItemProperties AS SIP INNER JOIN ServiceItems AS SI ON SIP.ItemID = SI.ItemID INNER JOIN ServiceItemProperties AS SIP2 ON SIP2.ItemID = SI.ItemID AND SIP2.PropertyName = 'DynamicMemory.Enabled' AND SIP2.PropertyValue = 'True' From ff7ccc7dab8f2db1bf1313d082711cde82aa7dde Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 20:50:54 +0300 Subject: [PATCH 3/5] Added file logger and default values for usernames, passwords. --- .../Sources/Setup.WIXInstaller/Product.wxs | 14 +++-- .../Common/WiXLogFileListener.cs | 55 +++++++++++++++++++ .../WebsitePanel.WIXInstaller/CustomAction.cs | 28 ++++++++++ .../WebsitePanel.WIXInstaller.csproj | 1 + 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index 82eef886..866e0a79 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -452,6 +452,7 @@ 1 1 + Please wait while [ProductName] Installer configures IIS & ASP.NET, this may take a few minutes. Thanks! @@ -476,7 +477,7 @@ - + @@ -503,7 +504,7 @@ - + @@ -512,7 +513,7 @@ - + @@ -522,7 +523,7 @@ - + @@ -590,9 +591,10 @@ WSP_ROOT + - + @@ -610,8 +612,10 @@ + 1 + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs new file mode 100644 index 00000000..623505fa --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/Common/WiXLogFileListener.cs @@ -0,0 +1,55 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using Microsoft.Deployment.WindowsInstaller; + +namespace WebsitePanel.WIXInstaller.Common +{ + public class WiXLogFileListener : TraceListener + { + public const uint FileFlushSize = 4096; + public const string DefaultLogFile = "WSPInstallation.log.txt"; + public static string LogFile { get; private set; } + private StringBuilder m_Ctx; + static WiXLogFileListener() + { + LogFile = Path.Combine(Path.GetTempPath() + DefaultLogFile); + } + public WiXLogFileListener(string LogFileName = DefaultLogFile) + : base("WiXLogFileListener") + { + m_Ctx = new StringBuilder(); + } + ~WiXLogFileListener() + { + Dispose(false); + } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + Flush(true); + } + public override void Write(string Value) + { + m_Ctx.Append(Value); + Flush(); + } + public override void WriteLine(string Value) + { + m_Ctx.AppendLine(Value); + Flush(); + } + private void Flush(bool Force = false) + { + if(m_Ctx.Length >= FileFlushSize || Force) + { + using (var FileCtx = new StreamWriter(LogFile, true)) + { + FileCtx.Write(m_Ctx.ToString()); + } + m_Ctx.Clear(); + } + } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index 2f652068..726ded67 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -54,6 +54,32 @@ namespace WebsitePanel.WIXInstaller #region CustomActions [CustomAction] + public static ActionResult PreFillSettings(Session session) + { + PopUpDebugger(); + var Ctx = session; + Ctx.AttachToSetupLog(); + Log.WriteStart("PreFillSettings"); + TryApllyNewPassword(Ctx, "PI_SERVER_PASSWORD"); + TryApllyNewPassword(Ctx, "PI_ESERVER_PASSWORD"); + TryApllyNewPassword(Ctx, "PI_PORTAL_PASSWORD"); + TryApllyNewPassword(Ctx, "SERVER_ACCESS_PASSWORD"); + TryApllyNewPassword(Ctx, "SERVERADMIN_PASSWORD"); + Log.WriteEnd("PreFillSettings"); + return ActionResult.Success; + } + private static void TryApllyNewPassword(Session Ctx, string Id) + { + var Pass = Ctx[Id]; + if(string.IsNullOrWhiteSpace(Pass)) + { + Pass = Guid.NewGuid().ToString(); + Ctx[Id] = Pass; + Ctx[Id + "_CONFIRM"] = Pass; + Log.WriteInfo("New password was applied to " + Id); + } + } + [CustomAction] public static ActionResult InstallWebFeatures(Session session) { var Msg = string.Empty; @@ -406,6 +432,7 @@ namespace WebsitePanel.WIXInstaller [CustomAction] public static ActionResult FillIpListUI(Session session) { + PopUpDebugger(); var Ctrls = new[]{ new ComboBoxCtrl(session, "PI_SERVER_IP"), new ComboBoxCtrl(session, "PI_ESERVER_IP"), new ComboBoxCtrl(session, "PI_PORTAL_IP") }; @@ -758,6 +785,7 @@ namespace WebsitePanel.WIXInstaller { WiXSetup.InstallLogListener(new WiXLogListener(Ctx)); WiXSetup.InstallLogListener(new InMemoryStringLogListener("WIX CA IN MEMORY")); + WiXSetup.InstallLogListener(new WiXLogFileListener()); } } diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj index 59ae4596..1a4b44b7 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/WebsitePanel.WIXInstaller.csproj @@ -63,6 +63,7 @@ + From 5ab109df9a05e0d107f3c9ac199672a6934ff75f Mon Sep 17 00:00:00 2001 From: McMak Date: Fri, 8 May 2015 21:55:14 +0300 Subject: [PATCH 4/5] Fix WSP registry locator. --- .../Sources/Setup.WIXInstaller/Product.wxs | 12 +++++----- .../WebsitePanel.WIXInstaller/CustomAction.cs | 23 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index 866e0a79..c22fd509 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -540,8 +540,8 @@ - - + + - WSP_ROOT + WSP_BASE @@ -684,9 +684,9 @@ - - + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index 726ded67..e14b3ce4 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -68,17 +68,6 @@ namespace WebsitePanel.WIXInstaller Log.WriteEnd("PreFillSettings"); return ActionResult.Success; } - private static void TryApllyNewPassword(Session Ctx, string Id) - { - var Pass = Ctx[Id]; - if(string.IsNullOrWhiteSpace(Pass)) - { - Pass = Guid.NewGuid().ToString(); - Ctx[Id] = Pass; - Ctx[Id + "_CONFIRM"] = Pass; - Log.WriteInfo("New password was applied to " + Id); - } - } [CustomAction] public static ActionResult InstallWebFeatures(Session session) { @@ -778,6 +767,17 @@ namespace WebsitePanel.WIXInstaller { Debugger.Launch(); } + private static void TryApllyNewPassword(Session Ctx, string Id) + { + var Pass = Ctx[Id]; + if (string.IsNullOrWhiteSpace(Pass)) + { + Pass = Guid.NewGuid().ToString(); + Ctx[Id] = Pass; + Ctx[Id + "_CONFIRM"] = Pass; + Log.WriteInfo("New password was applied to " + Id); + } + } } public static class SessionExtension { @@ -788,7 +788,6 @@ namespace WebsitePanel.WIXInstaller WiXSetup.InstallLogListener(new WiXLogFileListener()); } } - internal enum WiXInstallType: byte { InstallServer, From 473fd3c3ef2f75fc62660aa849defb64dae81ab9 Mon Sep 17 00:00:00 2001 From: McMak Date: Tue, 12 May 2015 23:44:49 +0300 Subject: [PATCH 5/5] WiX Update fixes. --- .../Sources/Setup.WIXInstaller/Product.wxs | 71 ++++++-- .../Common/InstallAction.cs | 3 +- .../Sources/WebsitePanel.Setup/Common/OS.cs | 18 ++ .../WebsitePanel.Setup/Internal/Adapter.cs | 160 ++++++++++++++---- .../Internal/BackupRestore.cs | 122 +++++++++++++ .../Internal/XmlDocumentMerge.cs | 139 +++++++++++++++ .../WebsitePanel.Setup.csproj | 2 + .../WebsitePanel.WIXInstaller/CustomAction.cs | 41 ++++- 8 files changed, 500 insertions(+), 56 deletions(-) create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs create mode 100644 WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs diff --git a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs index c22fd509..273fbfaf 100644 --- a/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs +++ b/WebsitePanel.Installer/Sources/Setup.WIXInstaller/Product.wxs @@ -331,11 +331,14 @@ 1 1 - &ServerFeature=3 - &EnterpriseServerFeature=3 - &PortalFeature=3 - &SchedulerServiceFeature=3 - &WDPortalFeature=3 + + + + + + + + 1 1 @@ -357,7 +360,10 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + 1 + + &EnterpriseServerFeature=3 AND VALIDATE_OK = "1" &PortalFeature=3 AND VALIDATE_OK = "1" &SchedulerServiceFeature=3 AND VALIDATE_OK = "1" @@ -389,7 +395,11 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + + 1 + + VALIDATE_OK="0" 1 @@ -437,16 +447,22 @@ ""]]> "" AND DSOP_UPN = ""]]> - 1 + + + + 1 1 1 - - - - 3]]> - 3 AND &PortalFeature<>3]]> + + + + + + + 3 AND COMPFOUND_ESERVER=0]]> + 3 AND &PortalFeature<>3 AND COMPFOUND_SERVER=0]]> 1 1 @@ -540,9 +556,15 @@ - + + + + + + + @@ -589,6 +611,13 @@ + + + + + + + WSP_BASE @@ -611,7 +640,15 @@ - + + + + + + + + + 1 @@ -634,7 +671,7 @@ - (NOT Installed OR NOT WIX_UPGRADE_DETECTED) AND NOT(DB_AUTH = "Windows Authentication") + (NOT Installed AND NOT WIX_UPGRADE_DETECTED) AND NOT(DB_AUTH = "Windows Authentication") - (NOT Installed OR NOT WIX_UPGRADE_DETECTED) AND (DB_AUTH = "Windows Authentication") + (NOT Installed AND NOT WIX_UPGRADE_DETECTED) AND (DB_AUTH = "Windows Authentication") /// LoadSetupVariablesFromParameters. @@ -393,6 +397,9 @@ namespace WebsitePanel.Setup.Internal case ActionTypes.ConfigureSecureSessionModuleInWebConfig: ConfigureSecureSessionModuleInWebConfig(); break; + case ActionTypes.RestoreConfig: + RestoreXmlConfigs(Execute.SetupVariables); + break; } } catch (Exception ex) @@ -402,7 +409,6 @@ namespace WebsitePanel.Setup.Internal } } } - protected virtual List GetActions(string ComponentID) { return new List(); @@ -843,7 +849,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // add node: @@ -993,7 +999,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // do Windows 2008 platform-specific changes bool iis7 = (Context.IISVersion.Major >= 7); @@ -1229,7 +1235,7 @@ namespace WebsitePanel.Setup.Internal private string GetConnectionString(string webConfigPath) { string ret = null; - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //connection string string xPath = "configuration/connectionStrings/add[@name=\"EnterpriseServer\"]"; @@ -1244,7 +1250,7 @@ namespace WebsitePanel.Setup.Internal private string GetCryptoKey(string webConfigPath) { string ret = null; - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //crypto key string xPath = "configuration/appSettings/add[@key=\"WebsitePanel.CryptoKey\"]"; @@ -1258,7 +1264,7 @@ namespace WebsitePanel.Setup.Internal private bool IsEncryptionEnabled(string webConfigPath) { - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); //encryption enabled string xPath = "configuration/appSettings/add[@key=\"WebsitePanel.EncryptionEnabled\"]"; @@ -2316,7 +2322,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating config.xml file"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlNode serversNode = doc.SelectSingleNode("//myLittleAdmin/sqlservers"); @@ -2429,7 +2435,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // Tighten WSE security on local machine @@ -2513,7 +2519,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Loading portal settings"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); string xPath = "configuration/connectionStrings/add[@name=\"SiteSqlServer\"]"; @@ -2605,7 +2611,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating site settings"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement urlNode = doc.SelectSingleNode("SiteSettings/EnterpriseServer") as XmlElement; @@ -3178,7 +3184,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating configuration file (server password)"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement passwordNode = doc.SelectSingleNode("//websitepanel.server/security/password") as XmlElement; @@ -3221,7 +3227,7 @@ namespace WebsitePanel.Setup.Internal } Log.WriteStart("Updating configuration file (service settings)"); - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(path); XmlElement ipNode = doc.SelectSingleNode("//configuration/appSettings/add[@key='WebsitePanel.HostIP']") as XmlElement; @@ -3881,7 +3887,7 @@ namespace WebsitePanel.Setup.Internal return; } // Load web.config - XmlDocument doc = new XmlDocument(); + var doc = new XmlDocument(); doc.Load(webConfigPath); // replace existing node: @@ -3915,8 +3921,63 @@ namespace WebsitePanel.Setup.Internal } #endregion #endregion + private void RestoreXmlConfigs(SetupVariables Ctx) + { + try + { + Log.WriteStart("RestoreXmlConfigs"); + var Backup = BackupRestore.Find(Ctx.InstallerFolder, "WebsitePanel", Ctx.ComponentName); + switch(Ctx.ComponentCode) + { + case "server": + { + Backup.XmlFiles.Add("Web.config"); + } + break; + case "enterpriseserver": + { + Backup.XmlFiles.Add("Web.config"); + } + break; + case "portal": + { + Backup.XmlFiles.Add("Web.config"); + Backup.XmlFiles.Add(@"App_Data\Countries.config"); + Backup.XmlFiles.Add(@"App_Data\CountryStates.config"); + Backup.XmlFiles.Add(@"App_Data\Ecommerce_Modules.config"); + Backup.XmlFiles.Add(@"App_Data\Ecommerce_Pages.config"); + Backup.XmlFiles.Add(@"App_Data\ESModule_ControlsHierarchy.config"); + Backup.XmlFiles.Add(@"App_Data\ModulesData.config"); + Backup.XmlFiles.Add(@"App_Data\SiteSettings.config"); + Backup.XmlFiles.Add(@"App_Data\SupportedLocales.config"); + Backup.XmlFiles.Add(@"App_Data\SupportedThemes.config"); + Backup.XmlFiles.Add(@"App_Data\WebsitePanel_Modules.config"); + Backup.XmlFiles.Add(@"App_Data\WebsitePanel_Pages.config"); + } + break; + } + var MainCfg = Path.Combine(Ctx.InstallerFolder, BackupRestore.MainConfig); + var XCfg = new XmlDocument(); + XCfg.Load(MainCfg); + if (XCfg.SelectSingleNode("//components").ChildNodes.Count == 0) + { + Log.WriteInfo("Restoring main config..."); + XmlDocumentMerge.Process(Backup.BackupMainConfigFile, MainCfg); + Context.ComponentId = WiXSetup.GetComponentID(Ctx); + AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = MainCfg }); + AppConfig.LoadComponentSettings(Ctx); + } + Log.WriteInfo(string.Format("Restoring xml config for component - {0}.", Ctx.ComponentFullName)); + Backup.Restore(); + Log.WriteEnd("RestoreXmlConfigs"); + } + catch (Exception ex) + { + Log.WriteError("RestoreXmlConfigs", ex); + throw; + } + } } - public class UninstallScript : SetupScript // UninstallPage { public UninstallScript(SetupVariables SessionVariables):base(SessionVariables) @@ -4117,12 +4178,22 @@ namespace WebsitePanel.Setup.Internal protected override List GetActions(string ComponentID) { var Scenario = base.GetActions(ComponentID); - var Act = new InstallAction(ActionTypes.UpdateConfig); - Act.Description = "Updating system configuration..."; - Scenario.Add(Act); - Act = new InstallAction(ActionTypes.StartApplicationPool); - Act.Description = "Starting IIS Application Pool..."; - Scenario.Add(Act); + Scenario.Add(new InstallAction(ActionTypes.RestoreConfig) { SetupVariables = Context, Description = "Restoring xml configuration files..." }); + Scenario.Add(new InstallAction(ActionTypes.UpdateConfig) { Description = "Updating system configuration..." }); + Scenario.Add(new InstallAction(ActionTypes.StartApplicationPool) { Description = "Starting IIS Application Pool..." }); + return Scenario; + } + } + public class MaintenanceScript: ExpressScript + { + public MaintenanceScript(SetupVariables SessionVariables):base(SessionVariables) + { + Context.SetupAction = SetupActions.Setup; + } + protected override List GetActions(string ComponentID) + { + var Scenario = base.GetActions(ComponentID); + Scenario.Add(new InstallAction(ActionTypes.UpdateConfig) { Description = "Updating system configuration..." }); return Scenario; } } @@ -4170,6 +4241,7 @@ namespace WebsitePanel.Setup.Internal else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4194,12 +4266,19 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateServerPassword) { Description = "Updating server password..." }); + Script.Run(); + } } - public class EServerSetup : WiXSetup { - public EServerSetup(SetupVariables Ctx) - : base(Ctx) + public EServerSetup(SetupVariables Ctx, ModeExtension Ext) + : base(Ctx, Ext) { } @@ -4210,7 +4289,7 @@ namespace WebsitePanel.Setup.Internal SetupVars.SetupAction = Action; SetupVars.IISVersion = Global.IISVersion; AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = GetFullConfigPath(SetupVars) }); - return new EServerSetup(SetupVars); + return new EServerSetup(SetupVars, GetModeExtension(Ctx)); } protected override void Install() { @@ -4240,6 +4319,7 @@ namespace WebsitePanel.Setup.Internal else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4264,12 +4344,19 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateServerAdminPassword) { Description = "Updating serveradmin password..." }); + Script.Run(); + } } - public class PortalSetup : WiXSetup { - public PortalSetup(SetupVariables Ctx) - : base(Ctx) + public PortalSetup(SetupVariables Ctx, ModeExtension Ext) + : base(Ctx, Ext) { } @@ -4280,7 +4367,7 @@ namespace WebsitePanel.Setup.Internal SetupVars.SetupAction = Action; SetupVars.IISVersion = Global.IISVersion; AppConfig.LoadConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = GetFullConfigPath(SetupVars) }); - return new PortalSetup(SetupVars); + return new PortalSetup(SetupVars, GetModeExtension(Ctx)); } protected override void Install() { @@ -4306,17 +4393,11 @@ namespace WebsitePanel.Setup.Internal } if (WiXThrow) InstallFailed(); - - else if (ModeExtension == ModeExtension.Restore) - { - Context.ComponentId = GetComponentID(Context); - AppConfig.LoadComponentSettings(Context); - new RestoreScript(Context).Run(); - } } else if (ModeExtension == ModeExtension.Restore) { Context.ComponentId = GetComponentID(Context); + Context.UpdateVersion = Context.Release; AppConfig.LoadComponentSettings(Context); new RestoreScript(Context).Run(); } @@ -4348,8 +4429,15 @@ namespace WebsitePanel.Setup.Internal } Script.Run(); } + protected override void Maintenance() + { + Context.ComponentId = GetComponentID(Context); + AppConfig.LoadComponentSettings(Context); + SetupScript Script = new MaintenanceScript(Context); + Script.Actions.Add(new InstallAction(ActionTypes.UpdateEnterpriseServerUrl) { Description = "Updating site settings..." }); + Script.Run(); + } } - #region WiXActionManagers public class WiXServerActionManager : BaseActionManager { diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs new file mode 100644 index 00000000..5778175f --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/BackupRestore.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Xml; +using Ionic.Zip; + +namespace WebsitePanel.Setup.Internal +{ + class BackupRestore + { + struct DirectoryTag + { + public string Name; + public DateTime Date; + public Version Version; + } + public const string MainConfig = "WebsitePanel.config"; + const string BackupDirectory = "Backup"; + const string ConfigDirectory = "Config"; + const string AppZip = @"App\app.zip"; + const string DateFormat = "yyyy-MM-dd"; + public BackupRestore() + { + XmlFiles = new List(); + } + public static BackupRestore Find(string Root, string Product, string Id) + { + var Result = default(BackupRestore); + var Dir = Path.Combine(Root, BackupDirectory); + var FullId = GetFullId(Product, Id); + if (Directory.Exists(Dir)) + { + var DirList = new List(); + foreach (var DateItem in Directory.GetDirectories(Dir)) + { + DateTime date; + var DateName = new DirectoryInfo(DateItem).Name; + if (DateTime.TryParseExact(DateName, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) + { + foreach (var VersionItem in Directory.GetDirectories(DateItem)) + { + var VersionName = new DirectoryInfo(VersionItem).Name; + if (VersionName.StartsWith(FullId, StringComparison.InvariantCultureIgnoreCase)) + { + Version BckpVersion; + var StrVersion = VersionName.Substring(FullId.Length); + if (Version.TryParse(StrVersion, out BckpVersion)) + { + DirList.Add(new DirectoryTag { Name = VersionItem, Date = date, Version = BckpVersion }); + } + } + } + } + } + var ByVersion = from i in DirList where i.Version == (from v in DirList select v.Version).Max() select i; + var ByDate = from i in ByVersion where i.Date == (from v in ByVersion select v.Date).Max() select i; + var SrcTag = ByDate.First(); + Result = new BackupRestore { Id = Id, Root = GetComponentRoot(SrcTag, Id), BackupFile = Path.Combine(SrcTag.Name, AppZip), BackupMainConfigFile = GetMainConfig(SrcTag) }; + } + return Result; + } + private static string GetComponentRoot(DirectoryTag DirTag, string Id) + { + var Cfg = GetMainConfig(DirTag); + if (string.IsNullOrWhiteSpace(Cfg)) + throw new Exception("Broken backup. Main config file not found."); + var XCfg = new XmlDocument(); + XCfg.Load(Cfg); + var Component = XCfg.SelectSingleNode(string.Format("//component[.//add/@key='ComponentName' and .//add/@value='{0}']", Id)); + var InstallFolder = Component.SelectSingleNode(".//add[@key='InstallFolder']"); + return InstallFolder.Attributes["value"].Value; + } + private static string GetMainConfig(DirectoryTag DirTag) + { + return Path.Combine(DirTag.Name, ConfigDirectory, MainConfig); + } + private static string GetFullId(string Product, string Id) + { + return string.Format("{0} {1}", Product, Id); + } + public virtual void Restore() + { + using (var Bckp = new ZipFile(BackupFile)) + { + foreach (var Xml in XmlFiles) + { + var SrcEntry = from Entry in Bckp.Entries where NormalizePath(Entry.FileName.ToLowerInvariant(), "/") == Xml.ToLowerInvariant() select Entry; + if (SrcEntry != null) + { + if (SrcEntry.LongCount() > 1) + throw new Exception(string.Format("Too many backup entries - {0}.", Xml)); + var FileEntry = SrcEntry.FirstOrDefault(); + if (FileEntry != null) + { + using (var InMem = new MemoryStream()) + { + FileEntry.Extract(InMem); + InMem.Seek(0, SeekOrigin.Begin); + using (var OutFile = new FileStream(Path.Combine(Root, Xml), FileMode.Open, FileAccess.ReadWrite)) + { + XmlDocumentMerge.Process(InMem, OutFile); + } + } + } + } + } + } + } + private string NormalizePath(string FilePath, string In) + { + return Path.Combine(FilePath.Split(new string[] { In }, StringSplitOptions.RemoveEmptyEntries)); + } + public string Id { get; set; } // Component full name. + public string Comment { get; set; } + public string BackupFile { get; set; } // Should be zip archive. + public string BackupMainConfigFile { get; set; } + public IList XmlFiles { get; set; } // Xml files (configs) to merge and update. + public string Root { get; set; } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs new file mode 100644 index 00000000..4c4511c4 --- /dev/null +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/Internal/XmlDocumentMerge.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.XPath; + +namespace WebsitePanel.Setup.Internal +{ + public static class XmlDocumentMerge + { + const string SuccessFormat = "Success: {0}."; + const string ErrorFormat = "Error: {0}."; + const string MergeCompleted = "XmlDocumentMerge completed"; + static XmlDocumentMerge() + { + KeyAttributes = new List { "name", "id", "key" }; + } + public static List KeyAttributes { get; set; } + public static string Process(string Src, string Dst, string SaveTo = "") + { + var Result = string.Empty; + if (!File.Exists(Src)) + Result = string.Format(ErrorFormat, string.Format("source document [{0}] does not exists", Src)); + else if (!File.Exists(Dst)) + Result = string.Format(ErrorFormat, string.Format("destination document [{0}] does not exists", Dst)); + else + { + try + { + var InStream = new FileStream(Src, FileMode.Open, FileAccess.Read); + var OutStream = new FileStream(Dst, FileMode.Open, FileAccess.ReadWrite); + Result = Process(InStream, + OutStream, + SaveTo); + InStream.Close(); + OutStream.Flush(); + OutStream.Close(); + } + catch (Exception ex) + { + Result = string.Format(ErrorFormat, ex.ToString()); + } + } + return Result; + } + public static string Process(Stream InSrc, Stream OutDst, string SaveTo = "") + { + var Result = string.Format(SuccessFormat, MergeCompleted); + try + { + var SrcDoc = new XmlDocument(); + SrcDoc.Load(InSrc); + var DstDoc = new XmlDocument(); + DstDoc.Load(OutDst); + var DstNavi = DstDoc.CreateNavigator(); + var DstIterator = DstNavi.SelectChildren(XPathNodeType.All); + while (DstIterator.MoveNext()) + Merge(DstIterator.Current.Clone(), SrcDoc, string.Empty); + if (string.IsNullOrWhiteSpace(SaveTo)) + { + OutDst.SetLength(0); + DstDoc.Save(OutDst); + } + else + DstDoc.Save(SaveTo); + } + catch (Exception ex) + { + Result = string.Format(ErrorFormat, ex.ToString()); + } + return Result; + } + private static string NodePath(string Parent, string Current) + { + var Result = string.Empty; + if (!string.IsNullOrWhiteSpace(Parent) && !string.IsNullOrWhiteSpace(Current)) + Result = string.Format("{0}/{1}", Parent, Current); + else if (!string.IsNullOrWhiteSpace(Parent)) + Result = Parent; + else if (!string.IsNullOrWhiteSpace(Current)) + Result = Current; + return Result; + } + private static string NodeView(XPathNavigator Navi) + { + foreach (var Attr in KeyAttributes) + { + var Value = Navi.GetAttribute(Attr, string.Empty); + if (!string.IsNullOrWhiteSpace(Value)) + return string.Format("{0}[@{1}='{2}']", Navi.Name, Attr, Value); + } + return Navi.Name; + } + private static void Merge(XPathNavigator DstNavi, XmlDocument SrcDoc, string Parent) + { + if (DstNavi.NodeType == XPathNodeType.Element) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, NodeView(DstNavi))); + if (SrcElem != null) + { + if (DstNavi.MoveToFirstAttribute()) + { + do + { + var SrcElemAttr = SrcElem.Attributes[DstNavi.LocalName]; + if (SrcElemAttr != null) + DstNavi.SetValue(SrcElemAttr.Value); + } + while (DstNavi.MoveToNextAttribute()); + DstNavi.MoveToParent(); + } + } + } + else if (DstNavi.NodeType == XPathNodeType.Text) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, NodeView(DstNavi))); + if (SrcElem != null) + DstNavi.SetValue(SrcElem.InnerText); + } + var Here = NodeView(DstNavi); + if (DstNavi.MoveToFirstChild()) + { + do + { + Merge(DstNavi, SrcDoc, NodePath(Parent, Here)); + } + while (DstNavi.MoveToNext()); + DstNavi.MoveToParent(); + } + else if (DstNavi.NodeType == XPathNodeType.Element) + { + var SrcElem = SrcDoc.SelectSingleNode(NodePath(Parent, Here)); + if (SrcElem != null && !string.IsNullOrWhiteSpace(SrcElem.InnerXml)) + foreach (XmlNode Child in SrcElem.ChildNodes) + DstNavi.AppendChild(Child.CloneNode(true).CreateNavigator()); + } + } + } +} diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj index 246d4850..864c3e5d 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj +++ b/WebsitePanel.Installer/Sources/WebsitePanel.Setup/WebsitePanel.Setup.csproj @@ -144,6 +144,8 @@ + + diff --git a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs index e14b3ce4..3bc32d46 100644 --- a/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs +++ b/WebsitePanel.Installer/Sources/WebsitePanel.WIXInstaller/CustomAction.cs @@ -54,6 +54,33 @@ namespace WebsitePanel.WIXInstaller #region CustomActions [CustomAction] + public static ActionResult MaintenanceServer(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenanceServer"); + Result = ProcessInstall(session, WiXInstallType.MaintenanceServer); + Log.WriteEnd("MaintenanceServer"); + return Result; + } + [CustomAction] + public static ActionResult MaintenanceEServer(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenanceEServer"); + Result = ProcessInstall(session, WiXInstallType.MaintenanceEnterpriseServer); + Log.WriteEnd("MaintenanceEServer"); + return Result; + } + [CustomAction] + public static ActionResult MaintenancePortal(Session session) + { + var Result = ActionResult.Success; + Log.WriteStart("MaintenancePortal"); + Result = ProcessInstall(session, WiXInstallType.MaintenancePortal); + Log.WriteEnd("MaintenancePortal"); + return Result; + } + [CustomAction] public static ActionResult PreFillSettings(Session session) { PopUpDebugger(); @@ -733,18 +760,27 @@ namespace WebsitePanel.WIXInstaller case WiXInstallType.RemoveServer: Install = ServerSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenanceServer: + Install = ServerSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; case WiXInstallType.InstallEnterpriseServer: Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Install); break; case WiXInstallType.RemoveEnterpriseServer: Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenanceEnterpriseServer: + Install = EServerSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; case WiXInstallType.InstallPortal: Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Install); break; case WiXInstallType.RemovePortal: Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Uninstall); break; + case WiXInstallType.MaintenancePortal: + Install = PortalSetup.Create(Ctx.CustomActionData, SetupActions.Setup); + break; default: throw new NotImplementedException(); } @@ -796,7 +832,8 @@ namespace WebsitePanel.WIXInstaller RemoveServer, RemoveEnterpriseServer, RemovePortal, - RemoveUpdate, - RestoreUpdate + MaintenanceServer, + MaintenanceEnterpriseServer, + MaintenancePortal } }