mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 19:32:10 +00:00
Renamed the plugin root of enterprise configurations to say what it holds
This commit is contained in:
parent
357eadd12d
commit
d4f0c650fc
@ -269,12 +269,13 @@ public static partial class ManagedConfiguration
|
||||
/// change it at all.
|
||||
/// </remarks>
|
||||
/// <param name="availablePlugins">The collection of available plugins to check against.</param>
|
||||
/// <param name="deployedConfigPluginIds">
|
||||
/// The IDs of all configuration plugins which are deployed on this machine, including those which
|
||||
/// could not be loaded. A deployed plugin was not removed, so its settings must stay untouched.
|
||||
/// <param name="deployedEnterpriseConfigPluginIds">
|
||||
/// The IDs of the configuration plugins which an organization deployed on this machine, including
|
||||
/// those which could not be loaded. A deployed plugin was not removed, so its settings must stay
|
||||
/// untouched.
|
||||
/// </param>
|
||||
/// <returns>True when at least one setting was changed, otherwise false.</returns>
|
||||
public static bool CleanupLeftOverManagedConfigurations(IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedConfigPluginIds)
|
||||
public static bool CleanupLeftOverManagedConfigurations(IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedEnterpriseConfigPluginIds)
|
||||
{
|
||||
var wasChanged = false;
|
||||
var registeredSettingNames = new HashSet<string>(StringComparer.Ordinal);
|
||||
@ -293,7 +294,7 @@ public static partial class ManagedConfiguration
|
||||
configMeta.RestoreLockedConfiguration();
|
||||
|
||||
// Check the locked state:
|
||||
if (configMeta.IsLocked && configMeta.LockedByConfigPluginId != Guid.Empty && !IsPluginPresent(configMeta.LockedByConfigPluginId, availablePlugins, deployedConfigPluginIds))
|
||||
if (configMeta.IsLocked && configMeta.LockedByConfigPluginId != Guid.Empty && !IsPluginPresent(configMeta.LockedByConfigPluginId, availablePlugins, deployedEnterpriseConfigPluginIds))
|
||||
{
|
||||
Log.LogInformation($"Resetting the setting '{configMeta.SettingName}': it was locked by the configuration plugin '{configMeta.LockedByConfigPluginId}', which is not available anymore.");
|
||||
configMeta.ResetLockedConfiguration();
|
||||
@ -301,11 +302,11 @@ public static partial class ManagedConfiguration
|
||||
}
|
||||
|
||||
// Check the editable default state:
|
||||
if (CleanupEditableDefaultState(configMeta, availablePlugins, deployedConfigPluginIds))
|
||||
if (CleanupEditableDefaultState(configMeta, availablePlugins, deployedEnterpriseConfigPluginIds))
|
||||
wasChanged = true;
|
||||
|
||||
// Check the additive plugin contribution:
|
||||
if (configMeta.HasPluginContribution && configMeta.PluginContributionByConfigPluginId != Guid.Empty && !IsPluginPresent(configMeta.PluginContributionByConfigPluginId, availablePlugins, deployedConfigPluginIds))
|
||||
if (configMeta.HasPluginContribution && configMeta.PluginContributionByConfigPluginId != Guid.Empty && !IsPluginPresent(configMeta.PluginContributionByConfigPluginId, availablePlugins, deployedEnterpriseConfigPluginIds))
|
||||
{
|
||||
Log.LogInformation($"Clearing the plugin contribution for the setting '{configMeta.SettingName}': the configuration plugin '{configMeta.PluginContributionByConfigPluginId}' is not available anymore.");
|
||||
configMeta.ClearPluginContribution();
|
||||
@ -328,7 +329,7 @@ public static partial class ManagedConfiguration
|
||||
/// The latter matters for organizations: a broken configuration plugin is still in charge, so we
|
||||
/// must not treat its settings as left over.
|
||||
/// </remarks>
|
||||
private static bool IsPluginPresent(Guid configPluginId, IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedConfigPluginIds) => deployedConfigPluginIds.Contains(configPluginId) || availablePlugins.Any(x => x.Id == configPluginId);
|
||||
private static bool IsPluginPresent(Guid configPluginId, IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedEnterpriseConfigPluginIds) => deployedEnterpriseConfigPluginIds.Contains(configPluginId) || availablePlugins.Any(x => x.Id == configPluginId);
|
||||
|
||||
/// <summary>
|
||||
/// Removes persisted managed states which belong to settings that are not registered anymore.
|
||||
@ -390,7 +391,7 @@ public static partial class ManagedConfiguration
|
||||
|
||||
private static bool ClearEditableDefaultState(string settingName) => SettingsManagerAccess.ConfigurationData.ManagedEditableDefaults.Remove(settingName);
|
||||
|
||||
private static bool CleanupEditableDefaultState(ConfigMetaBase configMeta, IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedConfigPluginIds)
|
||||
private static bool CleanupEditableDefaultState(ConfigMetaBase configMeta, IReadOnlyCollection<IAvailablePlugin> availablePlugins, IReadOnlySet<Guid> deployedEnterpriseConfigPluginIds)
|
||||
{
|
||||
if (!TryGetEditableDefaultState(configMeta.SettingName, out var editableDefaultState))
|
||||
{
|
||||
@ -401,7 +402,7 @@ public static partial class ManagedConfiguration
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsPluginPresent(editableDefaultState.ConfigPluginId, availablePlugins, deployedConfigPluginIds))
|
||||
if (IsPluginPresent(editableDefaultState.ConfigPluginId, availablePlugins, deployedEnterpriseConfigPluginIds))
|
||||
return false;
|
||||
|
||||
Log.LogInformation($"Clearing the editable default of the setting '{configMeta.SettingName}': the configuration plugin '{editableDefaultState.ConfigPluginId}' is not available anymore.");
|
||||
|
||||
@ -255,10 +255,10 @@ public sealed record PluginConfigurationObject
|
||||
/// <param name="configObjectType">The type of configuration object to process.</param>
|
||||
/// <param name="configObjectSelection">A selection expression to retrieve the configuration objects from the main configuration.</param>
|
||||
/// <param name="availablePlugins">A list of currently available plugins.</param>
|
||||
/// <param name="deployedConfigPluginIds">
|
||||
/// The IDs of all configuration plugins which are deployed on this machine, including those which
|
||||
/// could not be loaded. Objects of a deployed plugin are never removed, because the plugin was not
|
||||
/// removed either.
|
||||
/// <param name="deployedEnterpriseConfigPluginIds">
|
||||
/// The IDs of the configuration plugins which an organization deployed on this machine, including
|
||||
/// those which could not be loaded. Objects of a deployed plugin are never removed, because the
|
||||
/// plugin was not removed either.
|
||||
/// </param>
|
||||
/// <param name="configObjectList">A list of all existing configuration objects.</param>
|
||||
/// <param name="secretStoreType">An optional parameter specifying the type of secret store to use for deleting associated API keys from the OS keyring, if applicable.</param>
|
||||
@ -268,7 +268,7 @@ public sealed record PluginConfigurationObject
|
||||
PluginConfigurationObjectType configObjectType,
|
||||
Expression<Func<Data, List<TClass>>> configObjectSelection,
|
||||
IList<IAvailablePlugin> availablePlugins,
|
||||
IReadOnlySet<Guid> deployedConfigPluginIds,
|
||||
IReadOnlySet<Guid> deployedEnterpriseConfigPluginIds,
|
||||
IList<PluginConfigurationObject> configObjectList,
|
||||
SecretStoreType? secretStoreType = null,
|
||||
bool deleteSecret = false) where TClass : IConfigurationObject
|
||||
@ -295,7 +295,7 @@ public sealed record PluginConfigurationObject
|
||||
// the organization's providers and data sources, including their secrets, although the
|
||||
// organization still manages this AI Studio instance:
|
||||
//
|
||||
if(deployedConfigPluginIds.Contains(configObjectSourcePluginId) && availablePlugins.All(plugin => plugin.Id != configObjectSourcePluginId))
|
||||
if(deployedEnterpriseConfigPluginIds.Contains(configObjectSourcePluginId) && availablePlugins.All(plugin => plugin.Id != configObjectSourcePluginId))
|
||||
continue;
|
||||
|
||||
// Is the source plugin still available? If not, we can be pretty sure that this configuration object is left
|
||||
|
||||
@ -45,7 +45,7 @@ public static partial class PluginFactory
|
||||
|
||||
LOG.LogInformation($"Try to download configuration plugin with ID='{configPlugId}' from server='{configServerUrl}' (GET {downloadUrl})");
|
||||
var tempDownloadFile = Path.GetTempFileName();
|
||||
var stagedDirectory = Path.Join(CONFIGURATION_PLUGINS_ROOT, $"{configPlugId}.staging-{Guid.NewGuid():N}");
|
||||
var stagedDirectory = Path.Join(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT, $"{configPlugId}.staging-{Guid.NewGuid():N}");
|
||||
string? backupDirectory = null;
|
||||
var wasSuccessful = false;
|
||||
try
|
||||
@ -66,10 +66,10 @@ public static partial class PluginFactory
|
||||
|
||||
ExtractConfigPluginArchive(tempDownloadFile, stagedDirectory);
|
||||
|
||||
var configDirectory = Path.Join(CONFIGURATION_PLUGINS_ROOT, configPlugId.ToString());
|
||||
var configDirectory = Path.Join(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT, configPlugId.ToString());
|
||||
if (Directory.Exists(configDirectory))
|
||||
{
|
||||
backupDirectory = Path.Join(CONFIGURATION_PLUGINS_ROOT, $"{configPlugId}.backup-{Guid.NewGuid():N}");
|
||||
backupDirectory = Path.Join(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT, $"{configPlugId}.backup-{Guid.NewGuid():N}");
|
||||
Directory.Move(configDirectory, backupDirectory);
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ public static partial class PluginFactory
|
||||
{
|
||||
LOG.LogError(e, "An error occurred while downloading or extracting the enterprise configuration plugin.");
|
||||
|
||||
var configDirectory = Path.Join(CONFIGURATION_PLUGINS_ROOT, configPlugId.ToString());
|
||||
var configDirectory = Path.Join(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT, configPlugId.ToString());
|
||||
if (!string.IsNullOrWhiteSpace(backupDirectory) && Directory.Exists(backupDirectory) && !Directory.Exists(configDirectory))
|
||||
{
|
||||
try
|
||||
|
||||
@ -140,7 +140,7 @@ public static partial class PluginFactory
|
||||
else if (isConfigurationPluginInConfigDirectory)
|
||||
{
|
||||
isManagedByConfigServer = true;
|
||||
LOG.LogWarning($"The configuration plugin '{plugin.Id}' does not define 'DEPLOYED_USING_CONFIG_SERVER'. Falling back to the plugin path and treating it as managed because it is stored under '{CONFIGURATION_PLUGINS_ROOT}'.");
|
||||
LOG.LogWarning($"The configuration plugin '{plugin.Id}' does not define 'DEPLOYED_USING_CONFIG_SERVER'. Falling back to the plugin path and treating it as managed because it is stored under '{ENTERPRISE_CONFIGURATION_PLUGINS_ROOT}'.");
|
||||
}
|
||||
}
|
||||
else if (plugin is PluginAssistants assistantPlugin)
|
||||
@ -192,40 +192,40 @@ public static partial class PluginFactory
|
||||
//
|
||||
|
||||
//
|
||||
// Configuration plugins which are deployed but could not be loaded count as present: they
|
||||
// were not removed, so everything they manage must stay as it is. Otherwise, one broken
|
||||
// configuration plugin would wipe the entire organization configuration:
|
||||
// Enterprise configuration plugins which are deployed but could not be loaded count as
|
||||
// present: they were not removed, so everything they manage must stay as it is. Otherwise,
|
||||
// one broken configuration plugin would wipe the entire organization configuration:
|
||||
//
|
||||
var deployedConfigPluginIds = GetDeployedConfigPluginIds();
|
||||
var unloadedConfigPluginIds = deployedConfigPluginIds.Where(x => AVAILABLE_PLUGINS.All(plugin => plugin.Id != x)).ToList();
|
||||
foreach (var unloadedConfigPluginId in unloadedConfigPluginIds)
|
||||
LOG.LogWarning($"The configuration plugin '{unloadedConfigPluginId}' is deployed, but was not loaded. Everything it manages stays unchanged, because the plugin was not removed. Please check the errors above and fix the plugin.");
|
||||
var deployedEnterpriseConfigPluginIds = GetDeployedEnterpriseConfigPluginIds();
|
||||
var unloadedEnterpriseConfigPluginIds = deployedEnterpriseConfigPluginIds.Where(x => AVAILABLE_PLUGINS.All(plugin => plugin.Id != x)).ToList();
|
||||
foreach (var unloadedEnterpriseConfigPluginId in unloadedEnterpriseConfigPluginIds)
|
||||
LOG.LogWarning($"The configuration plugin '{unloadedEnterpriseConfigPluginId}' is deployed, but was not loaded. Everything it manages stays unchanged, because the plugin was not removed. Please check the errors above and fix the plugin.");
|
||||
|
||||
// Check LLM providers:
|
||||
var wasConfigurationChanged = await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.LLM_PROVIDER, x => x.Providers, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList, SecretStoreType.LLM_PROVIDER);
|
||||
var wasConfigurationChanged = await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.LLM_PROVIDER, x => x.Providers, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList, SecretStoreType.LLM_PROVIDER);
|
||||
|
||||
// Check transcription providers:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER, x => x.TranscriptionProviders, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList, SecretStoreType.TRANSCRIPTION_PROVIDER))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER, x => x.TranscriptionProviders, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList, SecretStoreType.TRANSCRIPTION_PROVIDER))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check embedding providers:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.EMBEDDING_PROVIDER, x => x.EmbeddingProviders, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList, SecretStoreType.EMBEDDING_PROVIDER))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.EMBEDDING_PROVIDER, x => x.EmbeddingProviders, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList, SecretStoreType.EMBEDDING_PROVIDER))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check data sources:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DATA_SOURCE, x => x.DataSources, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList, SecretStoreType.DATA_SOURCE, deleteSecret: true))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DATA_SOURCE, x => x.DataSources, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList, SecretStoreType.DATA_SOURCE, deleteSecret: true))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check chat templates:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.CHAT_TEMPLATE, x => x.ChatTemplates, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.CHAT_TEMPLATE, x => x.ChatTemplates, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check profiles:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.PROFILE, x => x.Profiles, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.PROFILE, x => x.Profiles, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check document analysis policies:
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, AVAILABLE_PLUGINS, deployedConfigPluginIds, configObjectList))
|
||||
if(await PluginConfigurationObject.CleanLeftOverConfigurationObjects(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY, x => x.DocumentAnalysis.Policies, AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds, configObjectList))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Check left-over mandatory info acceptances:
|
||||
@ -234,11 +234,11 @@ public static partial class PluginFactory
|
||||
|
||||
// Check all managed settings, i.e. settings which a configuration plugin can lock,
|
||||
// provide as an editable default, or contribute to:
|
||||
if(ManagedConfiguration.CleanupLeftOverManagedConfigurations(AVAILABLE_PLUGINS, deployedConfigPluginIds))
|
||||
if(ManagedConfiguration.CleanupLeftOverManagedConfigurations(AVAILABLE_PLUGINS, deployedEnterpriseConfigPluginIds))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
// Compatibility shim, see documentation/compatibility-shims/2026-08-orphaned-config-locks.md (remove after 2027-08-06):
|
||||
if (RepairLegacyConfigOnlySettings(unloadedConfigPluginIds.Count > 0))
|
||||
if (RepairLegacyConfigOnlySettings(unloadedEnterpriseConfigPluginIds.Count > 0))
|
||||
wasConfigurationChanged = true;
|
||||
|
||||
if (wasConfigurationChanged)
|
||||
@ -249,9 +249,11 @@ public static partial class PluginFactory
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the IDs of all configuration plugins which are deployed on this machine.
|
||||
/// Determines the IDs of all configuration plugins which an organization deployed on this machine.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Local configuration plugins are not part of this: they belong to the user, not to an
|
||||
/// organization, and they can live in any directory below the plugins root.<br/><br/>
|
||||
/// We read these IDs from the file system instead of taking them from the loaded plugins. A
|
||||
/// configuration plugin might be present but not loadable, e.g. due to invalid Lua code, a
|
||||
/// missing `plugin.lua`, or an incomplete download. Such a plugin still manages this AI Studio
|
||||
@ -259,13 +261,13 @@ public static partial class PluginFactory
|
||||
/// configuration server live in a directory named after their ID, which is the only information
|
||||
/// left when the plugin itself cannot be read.
|
||||
/// </remarks>
|
||||
private static HashSet<Guid> GetDeployedConfigPluginIds()
|
||||
private static HashSet<Guid> GetDeployedEnterpriseConfigPluginIds()
|
||||
{
|
||||
var deployedConfigPluginIds = new HashSet<Guid>();
|
||||
if (!Directory.Exists(CONFIGURATION_PLUGINS_ROOT))
|
||||
return deployedConfigPluginIds;
|
||||
var deployedEnterpriseConfigPluginIds = new HashSet<Guid>();
|
||||
if (!Directory.Exists(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT))
|
||||
return deployedEnterpriseConfigPluginIds;
|
||||
|
||||
foreach (var configPluginDirectory in Directory.EnumerateDirectories(CONFIGURATION_PLUGINS_ROOT))
|
||||
foreach (var configPluginDirectory in Directory.EnumerateDirectories(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT))
|
||||
{
|
||||
if (!Guid.TryParse(Path.GetFileName(configPluginDirectory), out var configPluginId) || configPluginId == Guid.Empty)
|
||||
continue;
|
||||
@ -274,10 +276,10 @@ public static partial class PluginFactory
|
||||
if (!Directory.EnumerateFileSystemEntries(configPluginDirectory).Any())
|
||||
continue;
|
||||
|
||||
deployedConfigPluginIds.Add(configPluginId);
|
||||
deployedEnterpriseConfigPluginIds.Add(configPluginId);
|
||||
}
|
||||
|
||||
return deployedConfigPluginIds;
|
||||
return deployedEnterpriseConfigPluginIds;
|
||||
}
|
||||
|
||||
/// <param name="pluginPath">The directory the plugin is located in, or null when the code has no directory yet.</param>
|
||||
|
||||
@ -22,9 +22,9 @@ public static partial class PluginFactory
|
||||
|
||||
// Case 2: Startup cleanup before the initial plugin load.
|
||||
// In this case, we inspect the .config directories directly.
|
||||
if (Directory.Exists(CONFIGURATION_PLUGINS_ROOT))
|
||||
if (Directory.Exists(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT))
|
||||
{
|
||||
foreach (var pluginDirectory in Directory.EnumerateDirectories(CONFIGURATION_PLUGINS_ROOT))
|
||||
foreach (var pluginDirectory in Directory.EnumerateDirectories(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT))
|
||||
{
|
||||
var directoryName = Path.GetFileName(pluginDirectory);
|
||||
if (!Guid.TryParse(directoryName, out var pluginId))
|
||||
@ -36,7 +36,7 @@ public static partial class PluginFactory
|
||||
var deployFlag = ReadDeployFlagFromPluginFile(pluginDirectory);
|
||||
var isManagedByConfigServer = deployFlag ?? true;
|
||||
if (!deployFlag.HasValue)
|
||||
LOG.LogWarning($"Configuration plugin '{pluginId}' does not define 'DEPLOYED_USING_CONFIG_SERVER'. Falling back to the plugin path and treating it as managed because it is stored under '{CONFIGURATION_PLUGINS_ROOT}'.");
|
||||
LOG.LogWarning($"Configuration plugin '{pluginId}' does not define 'DEPLOYED_USING_CONFIG_SERVER'. Falling back to the plugin path and treating it as managed because it is stored under '{ENTERPRISE_CONFIGURATION_PLUGINS_ROOT}'.");
|
||||
|
||||
if (isManagedByConfigServer)
|
||||
pluginIdsToRemove.Add(pluginId);
|
||||
@ -106,7 +106,7 @@ public static partial class PluginFactory
|
||||
|
||||
private static void DeleteConfigurationPluginDirectory(Guid pluginId)
|
||||
{
|
||||
var pluginDirectory = Path.Join(CONFIGURATION_PLUGINS_ROOT, pluginId.ToString());
|
||||
var pluginDirectory = Path.Join(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT, pluginId.ToString());
|
||||
if (!Directory.Exists(pluginDirectory))
|
||||
{
|
||||
LOG.LogWarning($"Plugin directory '{pluginDirectory}' does not exist.");
|
||||
|
||||
@ -11,7 +11,16 @@ public static partial class PluginFactory
|
||||
private static string DATA_DIR = string.Empty;
|
||||
private static string PLUGINS_ROOT = string.Empty;
|
||||
private static string INTERNAL_PLUGINS_ROOT = string.Empty;
|
||||
private static string CONFIGURATION_PLUGINS_ROOT = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The directory the config server downloads the configuration plugins of an organization into.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is not the home of configuration plugins in general: a local configuration plugin can
|
||||
/// live in any directory below the plugins root. Only the IT department of an organization
|
||||
/// deploys plugins here, each in a directory named after its configuration ID.
|
||||
/// </remarks>
|
||||
private static string ENTERPRISE_CONFIGURATION_PLUGINS_ROOT = string.Empty;
|
||||
private static string HOT_RELOAD_LOCK_FILE = string.Empty;
|
||||
private static FileSystemWatcher HOT_RELOAD_WATCHER = null!;
|
||||
|
||||
@ -65,7 +74,7 @@ public static partial class PluginFactory
|
||||
PLUGINS_ROOT = Path.Join(DATA_DIR, "plugins");
|
||||
HOT_RELOAD_LOCK_FILE = Path.Join(PLUGINS_ROOT, ".lock");
|
||||
INTERNAL_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".internal");
|
||||
CONFIGURATION_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".config");
|
||||
ENTERPRISE_CONFIGURATION_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".config");
|
||||
|
||||
if (!Directory.Exists(PLUGINS_ROOT))
|
||||
Directory.CreateDirectory(PLUGINS_ROOT);
|
||||
@ -89,12 +98,12 @@ public static partial class PluginFactory
|
||||
/// <returns>True when the directory is nested in the enterprise configuration directory.</returns>
|
||||
private static bool IsEnterpriseConfigurationPath(string? pluginPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pluginPath) || string.IsNullOrWhiteSpace(CONFIGURATION_PLUGINS_ROOT))
|
||||
if (string.IsNullOrWhiteSpace(pluginPath) || string.IsNullOrWhiteSpace(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var configurationRoot = Path.GetFullPath(CONFIGURATION_PLUGINS_ROOT).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
var configurationRoot = Path.GetFullPath(ENTERPRISE_CONFIGURATION_PLUGINS_ROOT).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
var pluginDirectory = Path.GetFullPath(pluginPath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
||||
return pluginDirectory.StartsWith(configurationRoot, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user