Remove DB and Directory settings out of the BTCPayServerOptions (#2168)

This commit is contained in:
Nicolas Dorier
2020-12-27 22:06:00 +09:00
committed by GitHub
parent 0dcd834535
commit a6ee64ea63
11 changed files with 126 additions and 123 deletions

View File

@@ -1,11 +1,41 @@
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Extensions.Configuration;
namespace BTCPayServer.Abstractions.Models
{
public class DatabaseOptions
{
public DatabaseOptions(DatabaseType type, string connString)
public DatabaseOptions(IConfiguration conf, string dataDir)
{
DatabaseType = type;
ConnectionString = connString;
var postgresConnectionString = conf["postgres"];
var mySQLConnectionString = conf["mysql"];
var sqliteFileName = conf["sqlitefile"];
if (!string.IsNullOrEmpty(postgresConnectionString))
{
DatabaseType = DatabaseType.Postgres;
ConnectionString = postgresConnectionString;
}
else if (!string.IsNullOrEmpty(mySQLConnectionString))
{
DatabaseType = DatabaseType.MySQL;
ConnectionString = mySQLConnectionString;
}
else if (!string.IsNullOrEmpty(sqliteFileName))
{
var connStr = "Data Source=" + (Path.IsPathRooted(sqliteFileName)
? sqliteFileName
: Path.Combine(dataDir, sqliteFileName));
DatabaseType = DatabaseType.Sqlite;
ConnectionString = sqliteFileName;
}
else
{
throw new InvalidOperationException("No database option was configured.");
}
}
public DatabaseType DatabaseType { get; set; }

View File

@@ -38,11 +38,6 @@ namespace BTCPayServer.Configuration
get;
private set;
}
public string DataDir
{
get;
private set;
}
public EndPoint SocksEndpoint { get; set; }
public List<NBXplorerConnectionSetting> NBXplorerConnectionSettings
@@ -64,8 +59,7 @@ namespace BTCPayServer.Configuration
{
if (!Path.IsPathRooted(logfile))
{
var networkType = DefaultConfiguration.GetNetworkType(configuration);
logfile = Path.Combine(configuration.GetDataDir(networkType), logfile);
logfile = Path.Combine(new DataDirectories(configuration).DataDir, logfile);
}
}
return logfile;
@@ -79,8 +73,7 @@ namespace BTCPayServer.Configuration
public void LoadArgs(IConfiguration conf)
{
NetworkType = DefaultConfiguration.GetNetworkType(conf);
DataDir = conf.GetDataDir(NetworkType);
PluginDir = conf.GetPluginDir(NetworkType);
Logs.Configuration.LogInformation("Network: " + NetworkType.ToString());
if (conf.GetOrDefault<bool>("launchsettings", false) && NetworkType != NetworkType.Regtest)
@@ -164,10 +157,6 @@ namespace BTCPayServer.Configuration
}
}
PostgresConnectionString = conf.GetOrDefault<string>("postgres", null);
MySQLConnectionString = conf.GetOrDefault<string>("mysql", null);
SQLiteFileName = conf.GetOrDefault<string>("sqlitefile", null);
BundleJsCss = conf.GetOrDefault<bool>("bundlejscss", true);
DockerDeployment = conf.GetOrDefault<bool>("dockerdeployment", true);
AllowAdminRegistration = conf.GetOrDefault<bool>("allow-admin-registration", false);
@@ -245,7 +234,6 @@ namespace BTCPayServer.Configuration
RecommendedPlugins = conf.GetOrDefault("recommended-plugins", "").ToLowerInvariant().Split('\r','\n','\t',' ').Where(s => !string.IsNullOrEmpty(s)).Distinct().ToArray();
}
public string PluginDir { get; set; }
public string PluginRemote { get; set; }
public string[] RecommendedPlugins { get; set; }
@@ -292,21 +280,6 @@ namespace BTCPayServer.Configuration
public BTCPayNetworkProvider NetworkProvider { get; set; }
public bool DockerDeployment { get; set; }
public string PostgresConnectionString
{
get;
set;
}
public string MySQLConnectionString
{
get;
set;
}
public string SQLiteFileName
{
get;
set;
}
public bool BundleJsCss
{
get;

View File

@@ -55,23 +55,5 @@ namespace BTCPayServer.Configuration
throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name);
}
}
public static string GetDataDir(this IConfiguration configuration)
{
var networkType = DefaultConfiguration.GetNetworkType(configuration);
return GetDataDir(configuration, networkType);
}
public static string GetDataDir(this IConfiguration configuration, NetworkType networkType)
{
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(networkType);
return configuration.GetOrDefault("datadir", defaultSettings.DefaultDataDirectory);
}
public static string GetPluginDir(this IConfiguration configuration, NetworkType networkType)
{
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(networkType);
return configuration.GetOrDefault("plugindir", defaultSettings.DefaultPluginDirectory);
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace BTCPayServer.Configuration
{
public class DataDirectories
{
public DataDirectories(IConfiguration conf)
{
var networkType = DefaultConfiguration.GetNetworkType(conf);
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(networkType);
DataDir = conf["datadir"] ?? defaultSettings.DefaultDataDirectory;
PluginDir = conf["plugindir"] ?? defaultSettings.DefaultPluginDirectory;
StorageDir = Path.Combine(DataDir, Storage.Services.Providers.FileSystemStorage.FileSystemFileProviderService.LocalStorageDirectoryName);
TempStorageDir = Path.Combine(StorageDir, "tmp");
}
public string DataDir { get; }
public string PluginDir { get; }
public string TempStorageDir { get; }
public string StorageDir { get; set; }
}
}

View File

@@ -12,10 +12,10 @@ namespace BTCPayServer.Storage
private readonly FileService _FileService;
private readonly string _dir;
public StorageController(FileService fileService, BTCPayServerOptions serverOptions)
public StorageController(FileService fileService, DataDirectories datadirs)
{
_FileService = fileService;
_dir = FileSystemFileProviderService.GetTempStorageDir(serverOptions);
_dir = datadirs.TempStorageDir;
}
[HttpGet("{fileId}")]

View File

@@ -1,5 +1,7 @@
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using System.Security.Cryptography;
using System.Threading;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Extensions;
@@ -65,6 +67,7 @@ namespace BTCPayServer.Hosting
}
public static IServiceCollection AddBTCPayServer(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<DataDirectories>();
services.AddSingleton<MvcNewtonsoftJsonOptions>(o => o.GetRequiredService<IOptions<MvcNewtonsoftJsonOptions>>().Value);
services.AddDbContext<ApplicationDbContext>((provider, o) =>
{
@@ -98,9 +101,9 @@ namespace BTCPayServer.Hosting
services.AddStartupTask<BlockExplorerLinkStartupTask>();
services.TryAddSingleton<InvoiceRepository>(o =>
{
var opts = o.GetRequiredService<BTCPayServerOptions>();
var datadirs = o.GetRequiredService<DataDirectories>();
var dbContext = o.GetRequiredService<ApplicationDbContextFactory>();
var dbpath = Path.Combine(opts.DataDir, "InvoiceDB");
var dbpath = Path.Combine(datadirs.DataDir, "InvoiceDB");
if (!Directory.Exists(dbpath))
Directory.CreateDirectory(dbpath);
return new InvoiceRepository(dbContext, dbpath, o.GetRequiredService<BTCPayNetworkProvider>(), o.GetService<EventAggregator>());
@@ -111,32 +114,33 @@ namespace BTCPayServer.Hosting
services.TryAddSingleton<EventAggregator>();
services.TryAddSingleton<PaymentRequestService>();
services.TryAddSingleton<U2FService>();
services.TryAddSingleton<DataDirectories>();
services.TryAddSingleton<DatabaseOptions>(o =>
{
var opts = o.GetRequiredService<BTCPayServerOptions>();
if (!string.IsNullOrEmpty(opts.PostgresConnectionString))
try
{
var dbOptions = new DatabaseOptions(o.GetRequiredService<IConfiguration>(),
o.GetRequiredService<DataDirectories>().DataDir);
if (dbOptions.DatabaseType == DatabaseType.Postgres)
{
Logs.Configuration.LogInformation($"Postgres DB used");
return new DatabaseOptions(DatabaseType.Postgres, opts.PostgresConnectionString);
}
else if (!string.IsNullOrEmpty(opts.MySQLConnectionString))
else if (dbOptions.DatabaseType == DatabaseType.MySQL)
{
Logs.Configuration.LogInformation($"MySQL DB used");
Logs.Configuration.LogWarning("MySQL is not widely tested and should be considered experimental, we advise you to use postgres instead.");
return new DatabaseOptions(DatabaseType.MySQL, opts.MySQLConnectionString);
}
else if (!string.IsNullOrEmpty(opts.SQLiteFileName))
else if (dbOptions.DatabaseType == DatabaseType.Sqlite)
{
var connStr = "Data Source=" +(Path.IsPathRooted(opts.SQLiteFileName)
? opts.SQLiteFileName
: Path.Combine(opts.DataDir, opts.SQLiteFileName));
Logs.Configuration.LogInformation($"SQLite DB used");
Logs.Configuration.LogWarning("SQLite is not widely tested and should be considered experimental, we advise you to use postgres instead.");
return new DatabaseOptions(DatabaseType.Sqlite, connStr);
}
else
return dbOptions;
}
catch (Exception ex)
{
throw new ConfigException("No database option was configured.");
throw new ConfigException($"No database option was configured. ({ex.Message})");
}
});
services.AddSingleton<ApplicationDbContextFactory>();

View File

@@ -48,7 +48,7 @@ namespace BTCPayServer.Hosting
services.AddMemoryCache();
services.AddDataProtection()
.SetApplicationName("BTCPay Server")
.PersistKeysToFileSystem(GetDataDir());
.PersistKeysToFileSystem(new DirectoryInfo(new DataDirectories(Configuration).DataDir));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
@@ -156,27 +156,23 @@ namespace BTCPayServer.Hosting
IWebHostEnvironment env,
IServiceProvider prov,
BTCPayServerOptions options,
DataDirectories dataDirectories,
ILoggerFactory loggerFactory)
{
Logs.Configuration.LogInformation($"Root Path: {options.RootPath}");
if (options.RootPath.Equals("/", StringComparison.OrdinalIgnoreCase))
{
ConfigureCore(app, env, prov, loggerFactory, options);
ConfigureCore(app, env, prov, loggerFactory, dataDirectories);
}
else
{
app.Map(options.RootPath, appChild =>
{
ConfigureCore(appChild, env, prov, loggerFactory, options);
ConfigureCore(appChild, env, prov, loggerFactory, dataDirectories);
});
}
}
private DirectoryInfo GetDataDir()
{
return new DirectoryInfo(Configuration.GetDataDir(DefaultConfiguration.GetNetworkType(Configuration)));
}
private static void ConfigureCore(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider prov, ILoggerFactory loggerFactory, BTCPayServerOptions options)
private static void ConfigureCore(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider prov, ILoggerFactory loggerFactory, DataDirectories dataDirectories)
{
Logs.Configure(loggerFactory);
app.UsePlugins();
@@ -212,7 +208,7 @@ namespace BTCPayServer.Hosting
}
});
app.UseProviderStorage(options);
app.UseProviderStorage(dataDirectories);
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();

View File

@@ -5,6 +5,7 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Configuration;
using McMaster.NETCore.Plugins;
@@ -27,7 +28,7 @@ namespace BTCPayServer.Plugins
IConfiguration config, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger(typeof(PluginManager));
var pluginsFolder = config.GetPluginDir(DefaultConfiguration.GetNetworkType(config));
var pluginsFolder = new DataDirectories(config).PluginDir;
var plugins = new List<IBTCPayServerPlugin>();

View File

@@ -17,17 +17,19 @@ namespace BTCPayServer.Plugins
{
public class PluginService: IPluginHookService
{
private readonly BTCPayServerOptions _btcPayServerOptions;
private readonly DataDirectories _datadirs;
private readonly BTCPayServerOptions _options;
private readonly HttpClient _githubClient;
private readonly IEnumerable<IPluginHookAction> _actions;
private readonly IEnumerable<IPluginHookFilter> _filters;
public PluginService(IEnumerable<IBTCPayServerPlugin> btcPayServerPlugins,
IHttpClientFactory httpClientFactory, BTCPayServerOptions btcPayServerOptions,IEnumerable<IPluginHookAction> actions, IEnumerable<IPluginHookFilter> filters)
IHttpClientFactory httpClientFactory, DataDirectories datadirs, BTCPayServerOptions options, IEnumerable<IPluginHookAction> actions, IEnumerable<IPluginHookFilter> filters)
{
LoadedPlugins = btcPayServerPlugins;
_githubClient = httpClientFactory.CreateClient();
_githubClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("btcpayserver", "1"));
_btcPayServerOptions = btcPayServerOptions;
_datadirs = datadirs;
_options = options;
_actions = actions;
_filters = filters;
}
@@ -37,7 +39,7 @@ namespace BTCPayServer.Plugins
public async Task<IEnumerable<AvailablePlugin>> GetRemotePlugins()
{
var resp = await _githubClient
.GetStringAsync(new Uri($"https://api.github.com/repos/{_btcPayServerOptions.PluginRemote}/contents"));
.GetStringAsync(new Uri($"https://api.github.com/repos/{_options.PluginRemote}/contents"));
var files = JsonConvert.DeserializeObject<GithubFile[]>(resp);
return await Task.WhenAll(files.Where(file => file.Name.EndsWith($"{PluginManager.BTCPayPluginSuffix}.json", StringComparison.InvariantCulture)).Select(async file =>
{
@@ -48,9 +50,9 @@ namespace BTCPayServer.Plugins
public async Task DownloadRemotePlugin(string plugin)
{
var dest = _btcPayServerOptions.PluginDir;
var dest = _datadirs.PluginDir;
var resp = await _githubClient
.GetStringAsync(new Uri($"https://api.github.com/repos/{_btcPayServerOptions.PluginRemote}/contents"));
.GetStringAsync(new Uri($"https://api.github.com/repos/{_options.PluginRemote}/contents"));
var files = JsonConvert.DeserializeObject<GithubFile[]>(resp);
var ext = files.SingleOrDefault(file => file.Name == $"{plugin}{PluginManager.BTCPayPluginSuffix}");
if (ext is null)
@@ -65,19 +67,19 @@ namespace BTCPayServer.Plugins
public void InstallPlugin(string plugin)
{
var dest = _btcPayServerOptions.PluginDir;
var dest = _datadirs.PluginDir;
UninstallPlugin(plugin);
PluginManager.QueueCommands(dest, ("install", plugin));
}
public void UpdatePlugin(string plugin)
{
var dest = _btcPayServerOptions.PluginDir;
var dest = _datadirs.PluginDir;
PluginManager.QueueCommands(dest, ("update", plugin));
}
public async Task UploadPlugin(IFormFile plugin)
{
var dest = _btcPayServerOptions.PluginDir;
var dest = _datadirs.PluginDir;
var filedest = Path.Combine(dest, plugin.FileName);
Directory.CreateDirectory(Path.GetDirectoryName(filedest));
if (Path.GetExtension(filedest) == PluginManager.BTCPayPluginSuffix)
@@ -89,7 +91,7 @@ namespace BTCPayServer.Plugins
public void UninstallPlugin(string plugin)
{
var dest = _btcPayServerOptions.PluginDir;
var dest = _datadirs.PluginDir;
PluginManager.QueueCommands(dest, ("delete", plugin));
}
@@ -124,12 +126,12 @@ namespace BTCPayServer.Plugins
public (string command, string plugin)[] GetPendingCommands()
{
return PluginManager.GetPendingCommands(_btcPayServerOptions.PluginDir);
return PluginManager.GetPendingCommands(_datadirs.PluginDir);
}
public void CancelCommands(string plugin)
{
PluginManager.CancelCommands(_btcPayServerOptions.PluginDir, plugin);
PluginManager.CancelCommands(_datadirs.PluginDir, plugin);
}
public async Task ApplyAction(string hook, object args)

View File

@@ -14,24 +14,14 @@ namespace BTCPayServer.Storage.Services.Providers.FileSystemStorage
public class
FileSystemFileProviderService : BaseTwentyTwentyStorageFileProviderServiceBase<FileSystemStorageConfiguration>
{
private readonly BTCPayServerOptions _options;
private readonly DataDirectories _datadirs;
public FileSystemFileProviderService(BTCPayServerOptions options)
public FileSystemFileProviderService(DataDirectories datadirs)
{
_options = options;
_datadirs = datadirs;
}
public const string LocalStorageDirectoryName = "LocalStorage";
public static string GetStorageDir(BTCPayServerOptions options)
{
return Path.Combine(options.DataDir, LocalStorageDirectoryName);
}
public static string GetTempStorageDir(BTCPayServerOptions options)
{
return Path.Combine(GetStorageDir(options), "tmp");
}
public override StorageProvider StorageProvider()
{
return Storage.Models.StorageProvider.FileSystem;
@@ -40,14 +30,14 @@ namespace BTCPayServer.Storage.Services.Providers.FileSystemStorage
protected override Task<IStorageProvider> GetStorageProvider(FileSystemStorageConfiguration configuration)
{
return Task.FromResult<IStorageProvider>(
new LocalStorageProvider(new DirectoryInfo(GetStorageDir(_options)).FullName));
new LocalStorageProvider(new DirectoryInfo(_datadirs.StorageDir).FullName));
}
public override async Task<string> GetFileUrl(Uri baseUri, StoredFile storedFile, StorageSettings configuration)
{
var baseResult = await base.GetFileUrl(baseUri, storedFile, configuration);
var url = new Uri(baseUri, LocalStorageDirectoryName);
return baseResult.Replace(new DirectoryInfo(GetStorageDir(_options)).FullName, url.AbsoluteUri,
return baseResult.Replace(new DirectoryInfo(_datadirs.StorageDir).FullName, url.AbsoluteUri,
StringComparison.InvariantCultureIgnoreCase);
}
@@ -63,13 +53,13 @@ namespace BTCPayServer.Storage.Services.Providers.FileSystemStorage
IsDownload = isDownload
};
var name = Guid.NewGuid().ToString();
var fullPath = Path.Combine(GetTempStorageDir(_options), name);
var fullPath = Path.Combine(_datadirs.TempStorageDir, name);
if (!File.Exists(fullPath))
{
File.Create(fullPath).Dispose();
}
await File.WriteAllTextAsync(Path.Combine(GetTempStorageDir(_options), name), JsonConvert.SerializeObject(localFileDescriptor));
await File.WriteAllTextAsync(Path.Combine(_datadirs.TempStorageDir, name), JsonConvert.SerializeObject(localFileDescriptor));
return new Uri(baseUri, $"{LocalStorageDirectoryName}tmp/{name}{(isDownload ? "?download" : string.Empty)}").AbsoluteUri;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Runtime.InteropServices.ComTypes;
using BTCPayServer.Configuration;
using BTCPayServer.Storage.Services;
using BTCPayServer.Storage.Services.Providers;
@@ -27,30 +28,28 @@ namespace BTCPayServer.Storage
// serviceCollection.AddSingleton<IStorageProviderService, GoogleCloudStorageFileProviderService>();
}
public static void UseProviderStorage(this IApplicationBuilder builder, BTCPayServerOptions options)
public static void UseProviderStorage(this IApplicationBuilder builder, DataDirectories datadirs)
{
try
{
var dir = FileSystemFileProviderService.GetStorageDir(options);
var tmpdir = FileSystemFileProviderService.GetTempStorageDir(options);
DirectoryInfo dirInfo;
if (!Directory.Exists(dir))
if (!Directory.Exists(datadirs.StorageDir))
{
dirInfo = Directory.CreateDirectory(dir);
dirInfo = Directory.CreateDirectory(datadirs.StorageDir);
}
else
{
dirInfo = new DirectoryInfo(dir);
dirInfo = new DirectoryInfo(datadirs.StorageDir);
}
DirectoryInfo tmpdirInfo;
if (!Directory.Exists(tmpdir))
if (!Directory.Exists(datadirs.TempStorageDir))
{
tmpdirInfo = Directory.CreateDirectory(tmpdir);
tmpdirInfo = Directory.CreateDirectory(datadirs.TempStorageDir);
}
else
{
tmpdirInfo = new DirectoryInfo(tmpdir);
tmpdirInfo = new DirectoryInfo(datadirs.TempStorageDir);
}
builder.UseStaticFiles(new StaticFileOptions()