Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tja-develop branch PR (When a Sitecore instance is selected you can install/uninstall SPS) #489

Open
wants to merge 55 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
3012eed
created Install PS button, enabled it as long as an instance is selec…
sc-TylerJass Nov 13, 2020
b8aef0a
Added first Wizard step page (not completed, not visible)
sc-TylerJass Nov 13, 2020
6372657
Completed wizard pipeline (bare minumum required, second page to come…
sc-TylerJass Nov 17, 2020
ff9c599
Added a new first wizard page to select PS version and provide links …
sc-TylerJass Nov 18, 2020
fd6a992
Pipeline processors are working, installation seems good. Project ef…
sc-TylerJass Nov 20, 2020
58dbeea
Added Install Publishing Service button to right click context menu
sc-TylerJass Nov 20, 2020
d2c681e
Fixed bug where moving back and forward in wizard incorrectly adds mo…
sc-TylerJass Nov 20, 2020
df2f4f4
Added another processor to check the status endpoint after installati…
sc-TylerJass Nov 20, 2020
1168c05
Added completion instructions for installing the PS module afterward
sc-TylerJass Nov 20, 2020
06d6b23
Fixed a typo and added an overwrite option (work in progress)
sc-TylerJass Nov 20, 2020
fa65944
Finished overwrite functionality
sc-TylerJass Nov 21, 2020
b19b3b8
Finished overwrite functionality
sc-TylerJass Nov 21, 2020
05fa0e0
Created uninstall publishing service button
sc-TylerJass Nov 21, 2020
bf278df
Renamed class names and members to use 'SPS' instead of 'PublishingSe…
sc-TylerJass Nov 21, 2020
aec2399
Fixed merge conflicts from tja-develop-sps-install branch
sc-TylerJass Nov 21, 2020
a81936f
First wizard page created for sps uninstall (work in progress)
sc-TylerJass Nov 21, 2020
644a047
Added sps uninstall to right-click context menu
sc-TylerJass Nov 21, 2020
83f2ced
Cleaned up some code, attempted to add port, but now bad gateway issu…
sc-TylerJass Nov 21, 2020
c928506
Resolved bad gateway issue (not caused by port, it was missing connec…
sc-TylerJass Nov 21, 2020
27c9b22
resolved merge
sc-TylerJass Nov 21, 2020
3de75b3
Fixed class name
sc-TylerJass Nov 21, 2020
de03f6e
joining branches
sc-TylerJass Nov 21, 2020
be23467
Uninstall sps wizard essentially complete (want to pull site name fro…
sc-TylerJass Nov 21, 2020
62849d9
Finished uninstall pipeline
sc-TylerJass Nov 25, 2020
1539d02
Pulled develop branch, resolving final merge conflicts before pull re…
sc-TylerJass Dec 3, 2020
2ebbdfd
Pulled and merged develop into this 'tja-develop' branch to resolve m…
sc-TylerJass Jan 25, 2021
c3294ac
Removing exception stacktrace from WindowHelper popup message (previo…
sc-TylerJass Jan 25, 2021
b0e6c91
Extended Instance class to return a collection of Roles, and bool pro…
sc-TylerJass Feb 6, 2021
4cd73e2
Install group of Edit tab is no longer visible for all instances, mov…
sc-TylerJass Feb 6, 2021
b2f3f4c
Preventing potential NullRefenceExceptions if a package is not selected
sc-TylerJass Feb 6, 2021
0ec9fbd
Removed '#' from wizard pipeline step names
sc-TylerJass Feb 6, 2021
0e1c0ea
SPS Installer now looks for packages in the SIM local repo and any su…
sc-TylerJass Feb 6, 2021
6a69d06
Only display Sitecore Publishing Service packages that are compatible…
sc-TylerJass Feb 6, 2021
17ca458
Fixed visibility for install/uninstall button given the selected inst…
sc-TylerJass Mar 7, 2021
1b80d85
Fixed some potential nullreferenceexceptions, and cleaned up unused u…
sc-TylerJass Mar 7, 2021
3310e93
Removed code that was intended only for debugging
sc-TylerJass Mar 7, 2021
311b466
Removed install/uninstall buttons from context menu
sc-TylerJass Mar 7, 2021
bef9012
Made install/uninstall wizard arg titles shorter
sc-TylerJass Mar 7, 2021
a4d3116
Initial sps name generated from cm instance name
sc-TylerJass Mar 7, 2021
e2721e5
Removed empty region
sc-TylerJass Mar 7, 2021
6b69cbd
Added special case for SPS 312 package name, wrapped IsCompatible bod…
sc-TylerJass Mar 20, 2021
ba829ca
Filtered connectionstring selection options and fixed typo
sc-TylerJass Mar 20, 2021
5b3310a
Removed overwrite functionality
sc-TylerJass Mar 20, 2021
491247d
Removed overwrite functionality (last commit, committed too early, no…
sc-TylerJass Mar 20, 2021
e993155
Updated instance roles logic
sc-TylerJass Mar 20, 2021
a33dbed
Changed auto generated SPS name
sc-TylerJass Mar 20, 2021
e446ee0
updated abstract SPSProcessor class
sc-TylerJass Mar 20, 2021
15e3857
Changed directory in the powershell context instead of changing the a…
sc-TylerJass Mar 20, 2021
4cdb9f1
added try-catch around instance role resolving logic
sc-TylerJass Mar 20, 2021
bf0f52a
Moved old compatibility to globalsettings config file
sc-TylerJass Mar 28, 2021
e223036
Add SPS to environment group when installed, and remove when uninstalled
sc-TylerJass Mar 28, 2021
d771238
Fixed bug where SPS instance only joined environment group if the gro…
sc-TylerJass Mar 28, 2021
a9f7d78
Instane list refreshes after sps install/uninstall
sc-TylerJass Mar 28, 2021
65c1294
Reorganized SPS Pipeline processors files
sc-TylerJass Mar 28, 2021
1bc8332
Moved all compatibility to globalsettings.config, added compatibility…
sc-TylerJass Mar 29, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/SIM.Instances/Instance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,67 @@ public InstanceType Type
}
}

/// <summary>
/// A collection of server roles this instance is defined as
/// </summary>
public ICollection<InstanceRole> Roles
{
get
{
ICollection<InstanceRole> InstanceRoles = new List<InstanceRole>();

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getter will allocate in the RAM a new list of the InstanceRoles every time when we access the roles property.
It may cause performance issues.

Please consider caches the 'InstanceRoles' list once it is fulfilled.

For example:

    private ICollection<InstanceRole> _instanceRoles;

    /// <summary>
    /// A collection of server roles this instance is defined as
    /// </summary>
    public ICollection<InstanceRole> Roles
    {
      get
      {
        if (_instanceRoles != null)
        {
          return _instanceRoles;
        }

        ICollection<InstanceRole> instanceRoles = new List<InstanceRole>();

...
        _instanceRoles = instanceRoles;

        return _instanceRoles;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now here e993155

//Find role by name
string instanceName = this.Name;
if (instanceName.Contains(".identityserver"))
{
InstanceRoles.Add(InstanceRole.IdentityServer);
return InstanceRoles;
}
if (instanceName.Contains(".xconnect"))
{
InstanceRoles.Add(InstanceRole.XConnect);
return InstanceRoles;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that resolving the instance name is not relay reliable approach.
Please consider removing the 'Find role by name' piece of code, and let's try to resolve the role from the Web.config file only.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now here e993155

Except xconnect still uses the site name. I agree it is not a good solution, however the xconnect web.config file doesn't really have a unique identifier in the xml like SPS and IdentityServer do, so I don't see an elegant way to do this.

Do you have any suggestions for an attribute from the web.config that I should use?
Or perhaps we need to consider a different approach for xconnect.


//Find role by 'role:define' key in web.config
string roleDefine = this.GetWebConfig().GetElementAttributeValue("/configuration/appSettings/add[@key='role:define']", "value").ToLower();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code throws the exception if one clicks on the instance deployed to the container.
Please see the attached screencast: https://www.screencast.com/t/xbOQH5R1

In case we either cannot resolve the role, or the exception happens, we need to use the InstanceRole.Unknown

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now here 4cdb9f1

if (string.IsNullOrEmpty(roleDefine))
{
InstanceRoles.Add((InstanceRole.Unknown)); //If 'role:define' is not present, this is likely a pre-version 9 solution, and we don't know the role
return InstanceRoles;
}
if (roleDefine.Contains("standalone"))
{
InstanceRoles.Add(InstanceRole.Standalone);
}
if (roleDefine.Contains("contentmanagement"))
{
InstanceRoles.Add(InstanceRole.ContentManagement);
}
if (roleDefine.Contains("contentdelivery"))
{
InstanceRoles.Add(InstanceRole.ContentDelivery);
}
if (roleDefine.Contains("reporting"))
{
InstanceRoles.Add(InstanceRole.Reporting);
}
if (roleDefine.Contains("processing"))
{
InstanceRoles.Add(InstanceRole.Processing);
}
if (roleDefine.Contains("indexing"))
{
InstanceRoles.Add(InstanceRole.Indexing);
}

return InstanceRoles;
}
}
public bool IsContentManagementInstance => this.Roles.Contains(InstanceRole.Standalone) ||
this.Roles.Contains(InstanceRole.ContentManagement) ||
this.Roles.Contains(InstanceRole.Unknown);

public enum InstanceType
{
Sitecore8AndEarlier,
Expand All @@ -503,6 +564,19 @@ public enum InstanceType
Unknown
}

public enum InstanceRole
{
Standalone,
ContentManagement,
ContentDelivery,
Reporting,
Processing,
Indexing,
XConnect,
IdentityServer,
Unknown
}
AndreyFilchenkov marked this conversation as resolved.
Show resolved Hide resolved

#endregion

#region Public methods
Expand Down
46 changes: 46 additions & 0 deletions src/SIM.Pipelines/InstallPublishingService/Commands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Threading.Tasks;
AndreyFilchenkov marked this conversation as resolved.
Show resolved Hide resolved

namespace SIM.Pipelines.InstallPublishingService
{
public static class Commands
{
private const string SET_CONNECTION_STRING = "configuration setconnectionstring {0} \"{1}\"";
private const string SCHEMA_UPGRADE = "schema upgrade --force";
private const string SCHEMA_RESET = "schema reset --force";
private const string IIS_INSTALL = "iis install --sitename \"{0}\" --apppool \"{1}\" --port \"{2}\" --hosts --force";

public static void SetConnectionString(string connectionStringName, string connectrionStringValue)
AndreyFilchenkov marked this conversation as resolved.
Show resolved Hide resolved
{
ExecuteCommand(SET_CONNECTION_STRING, connectionStringName, connectrionStringValue);
}

public static void SchemaUpgrade()
{
ExecuteCommand(SCHEMA_UPGRADE);
}

public static void SchemaReset()
{
ExecuteCommand(SCHEMA_RESET);
}

public static void IISInstall(string siteName, string appPoolName, int port)
{
ExecuteCommand(IIS_INSTALL, siteName, appPoolName, port);
}

private static void ExecuteCommand(string commandArgs, params object[] args)
{
using (PowerShell PS = PowerShell.Create())
{
PS.AddScript(string.Format(".\\Sitecore.Framework.Publishing.Host.exe " + commandArgs, args)).Invoke();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class CreateIISiteProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
Commands.IISInstall(args.SPSSiteName, args.SPSSiteName, args.SPSPort);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using SIM.Pipelines.Processors;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class InstallSPSProcessorArgs : ProcessorArgs
{
#region Properties
//Populated from InstallPublishingServiceWizardArgs
public string InstanceName { get; set; }
public string InstanceFolder { get; set; }
public string SPSInstanceFolder { get; set; }
public string SqlAdminUsername { get; set; }
public string SqlAdminPassword { get; set; }
public string SPSPackagePath { get; set; }
public string SPSSiteName { get; set; }
public string SPSAppPoolName { get; set; }
public string SPSWebroot { get; set; }
public int SPSPort { get; set; }
public Dictionary<string, SqlConnectionStringBuilder> SPSConnectionStrings { get; set; }
public bool OverwriteExisting { get; set; }

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using JetBrains.Annotations;
using Microsoft.Web.Administration;
using SIM.Adapters.WebServer;
using SIM.Pipelines.UninstallPublishingService;
using Sitecore.Diagnostics.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class RemoveExistingSPSProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
if (!args.OverwriteExisting)
{
return;
}

UninstallSPSProcessorArgs uninstallArgs = new UninstallSPSProcessorArgs()
{
SPSSiteName = args.SPSSiteName,
SPSAppPoolName = args.SPSAppPoolName,
SPSWebroot = args.SPSWebroot,
SkipSPSSite = false,
SkipSPSAppPool = false,
SkipSPSWebroot = false
};

new RemoveIISSiteProcessor().DoProcess(uninstallArgs);
new RemoveAppPoolProcessor().DoProcess(uninstallArgs);
new RemoveWebrootFolderProcessor().DoProcess(uninstallArgs);
}
AndreyFilchenkov marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class ResetDatabaseSchemaProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
//Resetting the schema is done to clear any potentially existing Publishing tables
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
Directory.SetCurrentDirectory(args.SPSWebroot);
Commands.SchemaReset();
}
}
}
48 changes: 48 additions & 0 deletions src/SIM.Pipelines/InstallPublishingService/SPSProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using JetBrains.Annotations;
using SIM.Pipelines.Processors;
using Sitecore.Diagnostics.Logging;
using System;
using System.Collections.Generic;
using System.Deployment.Internal;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public abstract class SPSProcessor<T> : Processor where T : ProcessorArgs
AndreyFilchenkov marked this conversation as resolved.
Show resolved Hide resolved
{
protected static bool AbortPipeline = false;

protected override void Process([NotNull] ProcessorArgs args)
{
T processorArgs = args as T;

if (AbortPipeline)
{
Log.Warn($"The {this.GetType().Name} processor was skipped.");
this.Skip();
return;
}

try
{
this.ProcessCore(processorArgs);
}
catch (Exception ex)
{
AbortPipeline = true;
Log.Error($"Publishing Service Pipeline was aborted. The remaining steps were skipped.");
throw ex;
}
}

protected abstract void ProcessCore([NotNull] T args);

//Kind of a hack so I can resure some of the uninstall sps processors in the RemoveExistingSPSProcessor class
internal void DoProcess([NotNull] T args)
{
this.Process(args);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class SetActualConnectionStringsProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
Directory.SetCurrentDirectory(args.SPSWebroot);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'Directory.GetCurrentDirectory()' API is widely used in the SIM. So, modification of the CurrentDirectory, may break the existing code.

Please avoid changing the current application directory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here 15e3857

foreach (KeyValuePair<string, SqlConnectionStringBuilder> connString in args.SPSConnectionStrings)
{
Commands.SetConnectionString(connString.Key, connString.Value.ToString());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class SetAdminConnectionStringsProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
//Using the admin credentials for connection strings is necessary to upgrade and reset the database schema
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
Directory.SetCurrentDirectory(args.SPSWebroot);
foreach (KeyValuePair<string, SqlConnectionStringBuilder> connString in args.SPSConnectionStrings)
{
string AdminConnString = new SqlConnectionStringBuilder(connString.Value.ToString())
{
UserID = args.SqlAdminUsername,
Password = args.SqlAdminPassword
}.ToString();

Commands.SetConnectionString(connString.Key, AdminConnString);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using JetBrains.Annotations;
using SIM.Pipelines.Processors;
using Sitecore.Diagnostics.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class UnzipSPSPackageProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
ZipFile.ExtractToDirectory(args.SPSPackagePath, args.SPSWebroot);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SIM.Pipelines.InstallPublishingService
{
public class UpgradeDatabaseSchemaProcessor : SPSProcessor<InstallSPSProcessorArgs>
{
protected override void ProcessCore(InstallSPSProcessorArgs args)
{
Directory.SetCurrentDirectory(args.SPSWebroot);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not change the Application Current Directory.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here 15e3857

Commands.SchemaUpgrade();
}
}
}
Loading