migration personal: runner

This commit is contained in:
Anton Suhorukov 2022-08-15 01:12:59 +03:00
parent fde3c94bf9
commit 1a098875a6
13 changed files with 649 additions and 88 deletions

View File

@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Migration.Runner", "com
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ActiveDirectory", "common\ASC.ActiveDirectory\ASC.ActiveDirectory.csproj", "{DD482D67-F700-4C30-9AA6-A2BE7A1079B5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Migration.PersonalToDocspace.Creator", "common\Tools\ASC.MigrationPersonalToDocspace\ASC.Migration.PersonalToDocspace.Creator.csproj", "{9493BF4B-46DF-4BE7-AC63-83992B205A00}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Migration.PersonalToDocspace", "common\Tools\ASC.MigrationPersonalToDocspace\ASC.Migration.PersonalToDocspace.csproj", "{9493BF4B-46DF-4BE7-AC63-83992B205A00}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Common", "common\ASC.Common\ASC.Common.csproj", "{1C5691B2-4AB1-4D3C-931C-AF7AD9CE8241}"
EndProject

View File

@ -163,7 +163,7 @@ public abstract class BaseStartup
}
}
private IEnumerable<Assembly> GetAutoMapperProfileAssemblies()
public static IEnumerable<Assembly> GetAutoMapperProfileAssemblies()
{
return AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name.StartsWith("ASC."));
}

View File

@ -103,7 +103,11 @@ public class RestoreDbModuleTask : PortalTaskBase
}
private void RestoreTable(DbConnection connection, TableInfo tableInfo, ref int transactionsCommited, ref int rowsInserted)
{
{
if (tableInfo.Name == "files_file")
{
}
SetColumns(connection, tableInfo);
using var stream = _reader.GetEntry(KeyHelper.GetTableZipKey(_module, tableInfo.Name));

View File

@ -26,7 +26,7 @@
namespace ASC.Data.Storage;
static class Constants
public static class Constants
{
public const string ConfigDir = "CONFIG_DIR";
public const string StorageRootParam = "$STORAGE_ROOT";

View File

@ -28,24 +28,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Microsoft.Build" Version="17.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Backup.Core\ASC.Data.Backup.Core.csproj" />
<ProjectReference Include="..\ASC.Migration.Core\ASC.Migration.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="ASC.Common">
<HintPath>..\common\ASC.Common\bin\Debug\ASC.Common.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -1,16 +1,37 @@
global using ASC.Common.Logging;
global using System.Data;
global using System.Data.Common;
global using System.Xml.Linq;
global using ASC.Api.Core;
global using ASC.Api.Core.Extensions;
global using ASC.Common;
global using ASC.Common.Logging;
global using ASC.Core.Common.EF;
global using ASC.Core.Common.EF.Context;
global using ASC.Core.Common.Hosting;
global using ASC.Core.Data;
global using ASC.Core.Tenants;
global using ASC.Core.Users;
global using ASC.Data.Backup;
global using ASC.Data.Backup.EF.Context;
global using ASC.Data.Backup.Exceptions;
global using ASC.Data.Backup.Extensions;
global using ASC.Data.Backup.Tasks;
global using ASC.Data.Backup.Tasks.Data;
global using ASC.Data.Backup.Tasks.Modules;
global using ASC.Data.Storage;
global using ASC.Data.Storage.DiscStorage;
global using ASC.Data.Storage.S3;
global using ASC.EventBus.Abstractions;
global using ASC.EventBus.Events;
global using ASC.EventBus.Extensions.Logger;
global using ASC.Feed.Context;
global using ASC.Files.Core.EF;
global using ASC.MessagingSystem.EF.Context;
global using ASC.Migration.PersonalToDocspace;
global using ASC.Migration.PersonalToDocspace.Creator;
global using ASC.Migration.PersonalToDocspace.Runner;
global using ASC.Webhooks.Core.EF.Context;
global using Microsoft.EntityFrameworkCore;
global using Microsoft.Extensions.Hosting.WindowsServices;
global using Migration.Core.Utils;
global using DbContextActivator = Migration.Core.Utils.DbContextActivator;

View File

@ -24,27 +24,6 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using System.Data;
using System.Data.Common;
using System.Xml.Linq;
using ASC.Common;
using ASC.Core.Data;
using ASC.Core.Users;
using ASC.Data.Backup;
using ASC.Data.Backup.Exceptions;
using ASC.Data.Backup.Extensions;
using ASC.Data.Backup.Tasks;
using ASC.Data.Backup.Tasks.Data;
using ASC.Data.Backup.Tasks.Modules;
using ASC.Data.Storage;
using ASC.Data.Storage.DiscStorage;
using ASC.Data.Storage.S3;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
namespace ASC.Migration.PersonalToDocspace.Creator;
public class MigrationCreator
@ -52,6 +31,9 @@ public class MigrationCreator
private readonly IDbContextFactory<UserDbContext> _userDbContext;
private readonly IDbContextFactory<BackupsContext> _backupsContext;
private readonly IDbContextFactory<FilesDbContext> _filesDbContext;
private readonly IDbContextFactory<TenantDbContext> _tenantDbContext;
private readonly IHostEnvironment _hostEnvironment;
private readonly IConfiguration _configuration;
private readonly TempStream _tempStream;
private readonly DbFactory _dbFactory;
private readonly StorageFactory _storageFactory;
@ -59,6 +41,7 @@ public class MigrationCreator
private readonly List<IModuleSpecifics> _modules;
private readonly string _pathToSave;
private readonly string _configPath;
private readonly string _userName;
private readonly int _tenant;
private readonly int _limit = 1000;
private readonly List<ModuleName> _namesModules = new List<ModuleName>()
@ -70,45 +53,68 @@ public class MigrationCreator
ModuleName.WebStudio
};
public MigrationCreator(IServiceProvider serviceProvider, string pathToSave, int tenant)
public MigrationCreator(IServiceProvider serviceProvider, int tenant, string userName)
{
_userDbContext = serviceProvider.GetService<IDbContextFactory<UserDbContext>>();
_backupsContext = serviceProvider.GetService<IDbContextFactory<BackupsContext>>();
_filesDbContext = serviceProvider.GetService<IDbContextFactory<FilesDbContext>>();
_tenantDbContext = serviceProvider.GetService<IDbContextFactory<TenantDbContext>>();
_tempStream = serviceProvider.GetService<TempStream>();
_dbFactory = serviceProvider.GetService<DbFactory>();
_storageFactory = serviceProvider.GetService<StorageFactory>();
_storageFactoryConfig = serviceProvider.GetService<StorageFactoryConfig>();
_hostEnvironment = serviceProvider.GetService<IHostEnvironment>();
_configuration = serviceProvider.GetService<IConfiguration>();
var moduleProvider = serviceProvider.GetService<ModuleProvider>();
_modules = moduleProvider.AllModules.Where(m => _namesModules.Contains(m.ModuleName)).ToList();
_pathToSave = pathToSave;
_pathToSave = "";
_userName = userName;
_configPath = null;
_tenant = tenant;
CheckExistDataStorage();
}
public void Create()
private void CheckExistDataStorage()
{
var users = GetUsers();
foreach (var user in users)
var store = _storageFactory.GetStorage(_configPath, _tenant.ToString(), "files");
if (store is DiscDataStore)
{
var path = Path.Combine(_pathToSave, user.UserName + ".tar.gz");
using (var writer = new ZipWriteOperator(_tempStream, path))
var path = Path.Combine(_hostEnvironment.ContentRootPath, _configuration[Data.Storage.Constants.StorageRootParam]);
if (!Directory.Exists(path))
{
DoMigrationDb(user.Id, user.UserName, writer);
DoMigrationStorage(user.Id, writer);
throw new Exception("wrong $STORAGE_ROOT, change storage.json or $STORAGE_ROOT");
}
}
}
private List<User> GetUsers()
public void Create()
{
return _userDbContext.CreateDbContext().Users.Where(q => q.Tenant == _tenant && q.Status == EmployeeStatus.Active).ToList();
var id = GetId();
var path = Path.Combine(_pathToSave, _userName + ".tar.gz");
using (var writer = new ZipWriteOperator(_tempStream, path))
{
DoMigrationDb(id, writer);
DoMigrationStorage(id, writer);
}
}
private void DoMigrationDb(Guid id, string userName, IDataWriteOperator writer)
private Guid GetId()
{
try
{
return _userDbContext.CreateDbContext().Users.FirstOrDefault(q => q.Tenant == _tenant && q.Status == EmployeeStatus.Active && q.UserName == _userName).Id;
}
catch (Exception ex)
{
throw new Exception("username was not found");
}
}
private void DoMigrationDb(Guid id, IDataWriteOperator writer)
{
foreach (var module in _modules)
{
@ -149,7 +155,7 @@ public class MigrationCreator
if(data.TableName == "tenants_tenants")
{
data.Rows[0]["alias"] = userName;
ChangeAlias(data);
}
using (var file = _tempStream.Create())
@ -166,6 +172,25 @@ public class MigrationCreator
}
private void ChangeAlias(DataTable data)
{
var aliases = _tenantDbContext.CreateDbContext().Tenants.Select(t => t.Alias);
var newAlias = _userName;
if (aliases.Contains(_userName))
{
while (true)
{
Console.WriteLine($"\"{newAlias}\" is busy, write another alias");
newAlias = Console.ReadLine();
if (!aliases.Contains(newAlias))
{
break;
}
}
}
data.Rows[0]["alias"] = newAlias;
}
private void DoMigrationStorage(Guid id, IDataWriteOperator writer)
{
var fileGroups = GetFilesGroup(id);
@ -202,11 +227,6 @@ public class MigrationCreator
{
var files = GetFilesToProcess(id).ToList();
using var backupRecordContext = _backupsContext.CreateDbContext();
var exclude = backupRecordContext.Backups.AsQueryable().Where(b => b.TenantId == _tenant && b.StorageType == 0 && b.StoragePath != null).ToList();
files = files.Where(f => !exclude.Any(e => f.Path.Replace('\\', '/').Contains($"/file_{e.StoragePath}/"))).ToList();
return files.GroupBy(file => file.Module).ToList();
}
@ -231,11 +251,11 @@ public class MigrationCreator
.Select(path => new BackupFileInfo(string.Empty, module, path, _tenant)));
}
using var filesRecordContext = _filesDbContext.CreateDbContext();
files = files.Where(f => IsFileByUser(id, f, filesRecordContext)).ToList();
files = files.Where(f => UserIsFileOwner(id, f, filesRecordContext)).ToList();
return files.Distinct();
}
private bool IsFileByUser(Guid id, BackupFileInfo fileInfo, FilesDbContext filesDbContext)
private bool UserIsFileOwner(Guid id, BackupFileInfo fileInfo, FilesDbContext filesDbContext)
{
var stringId = id.ToString();
return filesDbContext.Files.Any(

View File

@ -0,0 +1,146 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Migration.PersonalToDocspace.Runner;
public class MigrationRunner
{
private readonly DbFactory _dbFactory;
private readonly StorageFactory _storageFactory;
private readonly StorageFactoryConfig _storageFactoryConfig;
private readonly ModuleProvider _moduleProvider;
private readonly ILogger<RestoreDbModuleTask> _logger;
private readonly string _backupFile;
private readonly string _configPath;
private readonly List<IModuleSpecifics> _modules;
private readonly List<ModuleName> _namesModules = new List<ModuleName>()
{
ModuleName.Core,
ModuleName.Files,
ModuleName.Files2,
ModuleName.Tenants,
ModuleName.WebStudio
};
public MigrationRunner(IServiceProvider serviceProvider, string backupFile)
{
_moduleProvider = serviceProvider.GetService<ModuleProvider>();
_dbFactory = serviceProvider.GetService<DbFactory>();
_storageFactory = serviceProvider.GetService<StorageFactory>();
_storageFactoryConfig = serviceProvider.GetService<StorageFactoryConfig>();
_logger = serviceProvider.GetService<ILogger<RestoreDbModuleTask>>();
_configPath = null;
_modules = _moduleProvider.AllModules.Where(m => _namesModules.Contains(m.ModuleName)).ToList();
_backupFile = backupFile;
}
public void Run()
{
var columnMapper = new ColumnMapper();
using (var dataReader = new ZipReadOperator(_backupFile))
{
foreach (var module in _modules)
{
var restoreTask = new RestoreDbModuleTask(_logger, module, dataReader, columnMapper, _dbFactory, false, false, _storageFactory, _storageFactoryConfig, _moduleProvider);
restoreTask.RunJob();
}
DoRestoreStorage(dataReader, columnMapper);
SetTenantActive(columnMapper.GetTenantMapping());
}
}
private void DoRestoreStorage(IDataReadOperator dataReader, ColumnMapper columnMapper)
{
var fileGroups = GetFilesToProcess(dataReader).GroupBy(file => file.Module).ToList();
foreach (var group in fileGroups)
{
foreach (var file in group)
{
var storage = _storageFactory.GetStorage(_configPath, columnMapper.GetTenantMapping().ToString(), group.Key);
var quotaController = storage.QuotaController;
storage.SetQuotaController(null);
try
{
var adjustedPath = file.Path;
var module = _moduleProvider.GetByStorageModule(file.Module, file.Domain);
if (module == null || module.TryAdjustFilePath(false, columnMapper, ref adjustedPath))
{
var key = file.GetZipKey();
using var stream = dataReader.GetEntry(key);
storage.SaveAsync(file.Domain, adjustedPath, module != null ? module.PrepareData(key, stream, columnMapper) : stream).Wait();
}
}
finally
{
if (quotaController != null)
{
storage.SetQuotaController(quotaController);
}
}
}
}
}
private IEnumerable<BackupFileInfo> GetFilesToProcess(IDataReadOperator dataReader)
{
using var stream = dataReader.GetEntry(KeyHelper.GetStorageRestoreInfoZipKey());
if (stream == null)
{
return Enumerable.Empty<BackupFileInfo>();
}
var restoreInfo = XElement.Load(new StreamReader(stream));
return restoreInfo.Elements("file").Select(BackupFileInfo.FromXElement).ToList();
}
private void SetTenantActive(int tenantId)
{
using var connection = _dbFactory.OpenConnection();
var commandText = string.Format(
"update tenants_tenants " +
"set " +
" status={0}, " +
" last_modified='{1}', " +
" statuschanged='{1}' " +
"where id = '{2}'",
(int)TenantStatus.Active,
DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),
tenantId);
var command = connection.CreateCommand();
command.CommandText = commandText;
command.ExecuteNonQuery();
}
}

View File

@ -0,0 +1,65 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Migration.PersonalToDocspace;
[Singletone]
public class MockEventBusRabbitMQ : IEventBus, IDisposable
{
public void Dispose()
{
}
public void Publish(IntegrationEvent @event)
{
}
public void Subscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{
}
public void SubscribeDynamic<TH>(string eventName) where TH : IDynamicIntegrationEventHandler
{
}
public void Unsubscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{
}
public void UnsubscribeDynamic<TH>(string eventName) where TH : IDynamicIntegrationEventHandler
{
}
}

View File

@ -24,18 +24,8 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using ASC.Api.Core.Extensions;
using ASC.Common;
using ASC.Common.Mapping;
using ASC.Core.Data;
using ASC.Data.Backup.Tasks;
using ASC.Data.Backup.Tasks.Modules;
using ASC.Data.Storage;
using ASC.Data.Storage.DiscStorage;
using ASC.Data.Storage.S3;
using ASC.Migration.PersonalToDocspace.Creator;
using Autofac.Extensions.DependencyInjection;
Thread.Sleep(4000);
var options = new WebApplicationOptions
{
Args = args,
@ -44,11 +34,19 @@ var options = new WebApplicationOptions
var builder = WebApplication.CreateBuilder(options);
builder.Host.ConfigureDefault(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.WebHost.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile($"appsettings.json", true)
.AddJsonFile($"storage.json", true)
.AddCommandLine(args);
});
var config = builder.Configuration;
builder.WebHost.ConfigureServices((hostContext, services) =>
{
var diHelper = new DIHelper();
services.AddScoped<EFLoggerFactory>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddHttpClient();
@ -66,7 +64,12 @@ builder.WebHost.ConfigureServices((hostContext, services) =>
services.AddBaseDbContextPool<FeedDbContext>();
services.AddBaseDbContextPool<MessagesContext>();
services.AddBaseDbContextPool<WebhooksDbContext>();
services.AddAutoMapper(typeof(MappingProfile));
services.AddAutoMapper(BaseStartup.GetAutoMapperProfileAssemblies());
services.AddMemoryCache();
services.AddSingleton<IEventBus, MockEventBusRabbitMQ>();
services.AddCacheNotify(config);
var diHelper = new DIHelper();
diHelper.Configure(services);
diHelper.TryAdd<TempStream>();
@ -80,7 +83,11 @@ builder.WebHost.ConfigureServices((hostContext, services) =>
});
var app = builder.Build();
var config = builder.Configuration;
var migrationCreator = new MigrationCreator(app.Services, string.IsNullOrEmpty(config["pathToSave"]) ? "" : config["pathToSave"], Int32.Parse(config["tenant"]));
migrationCreator.Create();
var migrationCreator = new MigrationCreator(app.Services, Int32.Parse(args[0]), args[1]);
migrationCreator.Create();
var migrationRunner = new MigrationRunner(app.Services, args[1] + ".tar.gz");
migrationRunner.Run();
Directory.GetFiles(AppContext.BaseDirectory).Where(f => f.Contains(".tar")).ToList().ForEach(File.Delete);

View File

@ -2,10 +2,7 @@
"profiles": {
"ASC.Migration.PersonalToDocspace.Creator": {
"commandName": "Project",
"launchBrowser": false,
"environmentVariables": {
"$STORAGE_ROOT": "../../../Data"
}
"launchBrowser": false
}
}
}

View File

@ -1,3 +1,28 @@
{
"pathToConf": "..\\..\\..\\config"
"ConnectionStrings": {
"default": {
"name": "default",
"connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false",
"providerName": "MySql.Data.MySqlClient"
},
"postgre": {
"name": "postgre",
"connectionString": "Host=localhost;Port=5432;Database=onlyoffice;Username=postgres;Password=dev;",
"providerName": "Npgsql"
},
"mysql": {
"name": "mysql",
"connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false",
"providerName": "MySql.Data.MySqlClient"
}
},
"DbProviderFactories": {
"mysql": {
"name": "MySQL Data Provider",
"invariant": "MySql.Data.MySqlClient",
"description": ".Net Framework Data Provider for MySQL",
"type": "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data"
}
},
"$STORAGE_ROOT": "../../../Data"
}

View File

@ -0,0 +1,290 @@
{
"storage": {
"appender": [
{
"name": "generic",
"append": "~/"
}
],
"handler": [
{
"name": "disc",
"type": "ASC.Data.Storage.DiscStorage.DiscDataStore, ASC.Data.Storage",
"property": [
{
"name": "$STORAGE_ROOT",
"value": "..\\Data\\"
}
]
}
],
"module": [
{
"name": "forum",
"data": "853B6EB9-73EE-438d-9B09-8FFEEDF36234",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Forum\\Data\\attachments",
"virtualpath": "~/products/community/modules/forum/data/attachments",
"expires": "0:10:0"
},
{
"name": "bookmarking",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Bookmarking\\Data\\images",
"virtualpath": "~/products/community/modules/bookmarking/data/images"
},
{
"name": "wiki",
"data": "742CF945-CBBC-4a57-82D6-1600A12CF8CA",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Wiki\\Data\\files",
"virtualpath": "~/products/community/modules/wiki/data/files",
"expires": "0:10:0",
"domain": [
{
"name": "temp",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Wiki\\Data\\filestemp",
"virtualpath": "~/products/community/modules/wiki/data/filestemp"
}
]
},
{
"name": "files",
"data": "e67be73d-f9ae-4ce1-8fec-1880cb518cb4",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Files",
"expires": "0:16:0",
"domain": [
{
"name": "files_temp",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Files\\{0}\\temp",
"virtualpath": "~/products/community/modules/wiki/data/filestemp",
"expires": "0:10:0"
}
]
},
{
"name": "room_logos",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Files\\logos\\{0}",
"domain": [
{
"name": "logos_temp",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\Files\\logos\\{0}\\temp",
"expires": "0:10:0"
}
]
},
{
"name": "files_template",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "DocStore",
"virtualpath": "~/products/files/docstore",
"appendTenantId": false,
"public": true,
"disableMigrate": true,
"disableEncryption": true
},
{
"name": "crm",
"data": "6743007C-6F95-4d20-8C88-A8601CE5E76D",
"type": "disc",
"path": "$STORAGE_ROOT\\Products\\CRM\\Data",
"virtualpath": "~/products/crm/data",
"domain": [
{
"name": "export",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\CRM\\Data\\{0}\\export",
"expires": "1.0:0:0"
},
{
"name": "temp",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\CRM\\Data\\{0}\\temp"
},
{
"name": "mail_messages",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\CRM\\Data\\{0}\\mail_messages"
},
{
"name": "voip",
"visible": true,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\CRM\\Data\\{0}\\voip",
"virtualpath": "~/products/crm/data/{0}/voip",
"public": true
}
]
},
{
"name": "crm_template",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "Products\\CRM\\DocStore",
"disableMigrate": true,
"disableEncryption": true
},
{
"name": "fckuploaders",
"count": false,
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\htmleditorfiles",
"virtualpath": "~/data/shared/htmleditorfiles",
"domain": [
{
"name": "mail",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\addons\\mail\\Data\\htmleditorfiles",
"virtualpath": "~/addons/mail/data/htmleditorfiles"
},
{
"name": "forum",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Forum\\Data\\htmleditorfiles",
"virtualpath": "~/products/community/modules/forum/data/htmleditorfiles"
},
{
"name": "news",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\News\\Data\\htmleditorfiles",
"virtualpath": "~/products/community/modules/news/data/htmleditorfiles"
},
{
"name": "news_comments",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\News\\Data\\fckcomments",
"virtualpath": "~/products/community/modules/news/data/fckcomments"
},
{
"name": "blogs",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Blogs\\Data\\htmleditorfiles",
"virtualpath": "~/products/community/modules/blogs/data/htmleditorfiles"
},
{
"name": "blogs_comments",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Blogs\\Data\\fckcomments",
"virtualpath": "~/products/community/modules/blogs/data/fckcomments"
},
{
"name": "bookmarking_comments",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Bookmarking\\data\\fckcomments",
"virtualpath": "~/products/community/modules/bookmarking/data/fckcomments"
},
{
"name": "wiki_comments",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Community\\Modules\\Wiki\\Data\\fckcomments",
"virtualpath": "~/products/community/modules/wiki/data/fckcomments"
},
{
"name": "projects_comments",
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Products\\Projects\\Data\\fckcomments",
"virtualpath": "~/products/projects/data/fckcomments"
}
]
},
{
"name": "talk",
"data": "BF88953E-3C43-4850-A3FB-B1E43AD53A3E",
"type": "disc",
"path": "$STORAGE_ROOT\\addons\\talk\\Data",
"virtualpath": "~/addons/talk/data"
},
{
"name": "certs",
"visible": "false",
"type": "disc",
"path": "$STORAGE_ROOT\\certs\\",
"appendTenantId": false,
"disableEncryption": true
},
{
"name": "mailaggregator",
"data": "666ceac1-4532-4f8c-9cba-8f510eca2fd1",
"type": "disc",
"path": "$STORAGE_ROOT\\addons\\mail\\Data\\aggregator",
"virtualpath": "~/addons/mail/data/aggregator"
},
{
"name": "logo",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\{0}\\logo",
"virtualpath": "~/studio/{0}/logo",
"public": true
},
{
"name": "whitelabel",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\{0}\\CoBranding",
"virtualpath": "~/studio/{0}/cobranding",
"public": true
},
{
"name": "backup",
"visible": false,
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\{0}\\backup",
"virtualpath": "~/studio/{0}/backup",
"expires": "0:10:0",
"disableEncryption": true
},
{
"name": "customnavigation",
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\{0}\\customnavigation",
"virtualpath": "~/studio/{0}/customnavigation"
},
{
"name": "userPhotos",
"count": false,
"data": "00000000-0000-0000-0000-000000000000",
"type": "disc",
"path": "$STORAGE_ROOT\\Studio\\{0}\\userphotos",
"virtualpath": "~/studio/{0}/userphotos",
"domain": [
{
"name": "temp",
"visible": false,
"data": "00000000-0000-0000-0000-000000000000",
"path": "$STORAGE_ROOT\\Studio\\{0}\\userphotos\\temp",
"virtualpath": "~/studio/{0}/userphotos/temp"
}
]
},
{
"name": "static_partnerdata",
"type": "disc",
"path": "App_Data\\static\\partnerdata",
"acl": "Read",
"virtualpath": "~/App_Data/static/partnerdata",
"appendTenantId": false,
"public": true,
"disableMigrate": true,
"disableEncryption": true
}
]
}
}