2019-08-10 19:41:42 +03:00
|
|
|
using Scalar.Common.FileSystem;
|
|
|
|
using Scalar.Common.Git;
|
|
|
|
using Scalar.Common.Tracing;
|
2019-01-24 16:00:40 +03:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2019-06-08 00:36:42 +03:00
|
|
|
using System.ComponentModel;
|
2019-01-24 16:00:40 +03:00
|
|
|
using System.IO;
|
|
|
|
using System.IO.Pipes;
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
namespace Scalar.Common
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract class ScalarPlatform
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
2019-08-10 19:41:42 +03:00
|
|
|
public ScalarPlatform(UnderConstructionFlags underConstruction)
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
|
|
|
this.UnderConstruction = underConstruction;
|
|
|
|
}
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public static ScalarPlatform Instance { get; private set; }
|
2019-01-24 16:00:40 +03:00
|
|
|
|
|
|
|
public abstract IGitInstallation GitInstallation { get; }
|
|
|
|
public abstract IPlatformFileSystem FileSystem { get; }
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract ScalarPlatformConstants Constants { get; }
|
2018-12-07 02:18:35 +03:00
|
|
|
public UnderConstructionFlags UnderConstruction { get; }
|
2019-04-15 00:23:42 +03:00
|
|
|
public abstract string Name { get; }
|
2019-05-13 21:19:32 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract string ScalarConfigPath { get; }
|
2018-12-07 02:18:35 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public static void Register(ScalarPlatform platform)
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
2019-08-10 19:41:42 +03:00
|
|
|
if (ScalarPlatform.Instance != null)
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
|
|
|
throw new InvalidOperationException("Cannot register more than one platform");
|
|
|
|
}
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
ScalarPlatform.Instance = platform;
|
2019-01-24 16:00:40 +03:00
|
|
|
}
|
|
|
|
|
2019-06-08 00:36:42 +03:00
|
|
|
/// <summary>
|
2019-08-10 19:41:42 +03:00
|
|
|
/// Starts a Scalar process in the background.
|
2019-06-08 00:36:42 +03:00
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// This method should only be called by processes whose code we own as the background process must
|
|
|
|
/// do some extra work after it starts.
|
|
|
|
/// </remarks>
|
2019-08-12 04:37:38 +03:00
|
|
|
public abstract void StartBackgroundScalarProcess(ITracer tracer, string programName, string[] args);
|
2019-06-08 00:36:42 +03:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Adjusts the current process for running in the background.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
2019-08-12 04:37:38 +03:00
|
|
|
/// This method should be called after starting by processes launched using <see cref="ScalarPlatform.StartBackgroundScalarProcess"/>
|
2019-06-08 00:36:42 +03:00
|
|
|
/// </remarks>
|
|
|
|
/// <exception cref="Win32Exception">
|
|
|
|
/// Failed to prepare process to run in background.
|
|
|
|
/// </exception>
|
|
|
|
public abstract void PrepareProcessToRunInBackground();
|
|
|
|
|
2019-01-24 16:00:40 +03:00
|
|
|
public abstract bool IsProcessActive(int processId);
|
|
|
|
public abstract void IsServiceInstalledAndRunning(string name, out bool installed, out bool running);
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract string GetScalarServiceNamedPipeName(string serviceName);
|
2019-01-24 16:00:40 +03:00
|
|
|
public abstract NamedPipeServerStream CreatePipeByName(string pipeName);
|
|
|
|
|
|
|
|
public abstract string GetOSVersionInformation();
|
2019-12-19 21:00:28 +03:00
|
|
|
public abstract string GetCommonAppDataRootForScalar();
|
|
|
|
public abstract string GetCommonAppDataRootForScalarComponent(string componentName);
|
|
|
|
public abstract string GetSecureDataRootForScalar();
|
|
|
|
public abstract string GetSecureDataRootForScalarComponent(string componentName);
|
|
|
|
public abstract string GetLogsDirectoryForGVFSComponent(string componentName);
|
2019-01-24 16:00:40 +03:00
|
|
|
public abstract void InitializeEnlistmentACLs(string enlistmentPath);
|
|
|
|
public abstract bool IsElevated();
|
|
|
|
public abstract string GetCurrentUser();
|
2019-04-18 20:19:18 +03:00
|
|
|
public abstract string GetUserIdFromLoginSessionId(int sessionId, ITracer tracer);
|
2019-05-30 17:58:45 +03:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Get the directory for upgrades that is permissioned to
|
|
|
|
/// require elevated privileges to modify. This can be used for
|
|
|
|
/// data that we don't want normal user accounts to modify.
|
|
|
|
/// </summary>
|
|
|
|
public abstract string GetUpgradeProtectedDataDirectory();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Directory that upgrader log directory should be placed
|
|
|
|
/// in. There can be multiple log directories, so this is the
|
|
|
|
/// containing directory to place them in.
|
|
|
|
/// </summary>
|
|
|
|
public abstract string GetUpgradeLogDirectoryParentDirectory();
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Directory that contains the file indicating that a new
|
|
|
|
/// version is available.
|
|
|
|
/// </summary>
|
|
|
|
public abstract string GetUpgradeHighestAvailableVersionDirectory();
|
|
|
|
|
2019-01-24 16:00:40 +03:00
|
|
|
public abstract void ConfigureVisualStudio(string gitBinPath, ITracer tracer);
|
|
|
|
|
|
|
|
public abstract bool TryVerifyAuthenticodeSignature(string path, out string subject, out string issuer, out string error);
|
|
|
|
|
|
|
|
public abstract Dictionary<string, string> GetPhysicalDiskInfo(string path, bool sizeStatsOnly);
|
|
|
|
|
2019-02-22 13:09:42 +03:00
|
|
|
public abstract bool IsConsoleOutputRedirectedToFile();
|
|
|
|
|
2019-02-11 21:06:58 +03:00
|
|
|
public abstract bool TryKillProcessTree(int processId, out int exitCode, out string error);
|
|
|
|
|
2019-04-09 01:45:58 +03:00
|
|
|
public abstract bool TryGetDefaultLocalCacheRoot(string enlistmentRoot, out string localCacheRoot, out string localCacheRootError);
|
2019-01-24 16:00:40 +03:00
|
|
|
|
|
|
|
public abstract FileBasedLock CreateFileBasedLock(
|
|
|
|
PhysicalFileSystem fileSystem,
|
|
|
|
ITracer tracer,
|
|
|
|
string lockPath);
|
|
|
|
|
2019-05-30 17:57:25 +03:00
|
|
|
public abstract ProductUpgraderPlatformStrategy CreateProductUpgraderPlatformInteractions(
|
|
|
|
PhysicalFileSystem fileSystem,
|
|
|
|
ITracer tracer);
|
|
|
|
|
2019-01-24 16:00:40 +03:00
|
|
|
public bool TryGetNormalizedPathRoot(string path, out string pathRoot, out string errorMessage)
|
|
|
|
{
|
|
|
|
pathRoot = null;
|
|
|
|
errorMessage = null;
|
|
|
|
string normalizedPath = null;
|
|
|
|
|
|
|
|
if (!this.FileSystem.TryGetNormalizedPath(path, out normalizedPath, out errorMessage))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pathRoot = Path.GetPathRoot(normalizedPath);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract class ScalarPlatformConstants
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
|
|
|
public static readonly char PathSeparator = Path.DirectorySeparatorChar;
|
2019-07-10 18:00:10 +03:00
|
|
|
public abstract int MaxPipePathLength { get; }
|
2019-04-18 20:19:18 +03:00
|
|
|
public abstract string ExecutableExtension { get; }
|
|
|
|
public abstract string InstallerExtension { get; }
|
2019-05-13 17:55:20 +03:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Indicates whether the platform supports running the upgrade application while
|
|
|
|
/// the upgrade verb is running.
|
|
|
|
/// </summary>
|
|
|
|
public abstract bool SupportsUpgradeWhileRunning { get; }
|
2019-01-24 16:00:40 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract string ScalarBinDirectoryPath { get; }
|
2019-01-24 16:00:40 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract string ScalarBinDirectoryName { get; }
|
2019-01-24 16:00:40 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public abstract string ScalarExecutableName { get; }
|
2019-01-24 16:00:40 +03:00
|
|
|
|
2019-05-08 00:13:19 +03:00
|
|
|
public abstract string ProgramLocaterCommand { get; }
|
|
|
|
|
2019-05-07 23:45:43 +03:00
|
|
|
/// <summary>
|
|
|
|
/// Different platforms can have different requirements
|
|
|
|
/// around which processes can block upgrade. For example,
|
2019-08-10 19:41:42 +03:00
|
|
|
/// on Windows, we will block upgrade if any Scalar commands
|
2019-05-07 23:45:43 +03:00
|
|
|
/// are running, but on POSIX platforms, we relax this
|
|
|
|
/// constraint to allow upgrade to run while the upgrade
|
|
|
|
/// command is running. Another example is that
|
|
|
|
/// Non-windows platforms do not block upgrade when bash
|
|
|
|
/// is running.
|
|
|
|
/// </summary>
|
|
|
|
public abstract HashSet<string> UpgradeBlockingProcesses { get; }
|
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public string ScalarUpgraderExecutableName
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
2019-08-10 19:41:42 +03:00
|
|
|
get { return "Scalar.Upgrader" + this.ExecutableExtension; }
|
2019-01-24 16:00:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-07 02:18:35 +03:00
|
|
|
public class UnderConstructionFlags
|
2019-01-24 16:00:40 +03:00
|
|
|
{
|
|
|
|
public UnderConstructionFlags(
|
2019-08-10 19:41:42 +03:00
|
|
|
bool supportsScalarUpgrade = true,
|
|
|
|
bool supportsScalarConfig = true,
|
2020-01-29 20:11:53 +03:00
|
|
|
bool supportsNuGetEncryption = true,
|
|
|
|
bool supportsNuGetVerification = true)
|
2018-12-07 02:18:35 +03:00
|
|
|
{
|
2019-08-10 19:41:42 +03:00
|
|
|
this.SupportsScalarUpgrade = supportsScalarUpgrade;
|
|
|
|
this.SupportsScalarConfig = supportsScalarConfig;
|
2019-06-07 20:51:45 +03:00
|
|
|
this.SupportsNuGetEncryption = supportsNuGetEncryption;
|
2020-01-29 20:11:53 +03:00
|
|
|
this.SupportsNuGetVerification = supportsNuGetVerification;
|
2019-01-24 16:00:40 +03:00
|
|
|
}
|
2018-12-07 02:18:35 +03:00
|
|
|
|
2019-08-10 19:41:42 +03:00
|
|
|
public bool SupportsScalarUpgrade { get; }
|
|
|
|
public bool SupportsScalarConfig { get; }
|
2019-06-07 20:51:45 +03:00
|
|
|
public bool SupportsNuGetEncryption { get; }
|
2020-01-29 20:11:53 +03:00
|
|
|
public bool SupportsNuGetVerification { get; }
|
2019-08-08 16:10:21 +03:00
|
|
|
}
|
|
|
|
}
|
2019-01-24 16:00:40 +03:00
|
|
|
}
|