public void Default_database_path_settings() { var config = new RavenConfiguration("foo", ResourceType.Database, _emptySettingFile); config.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); config.Initialize(); Assert.Equal(new PathSetting("Databases/foo").FullPath, config.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting("Databases/foo/Indexes").FullPath, config.Indexing.StoragePath.FullPath); Assert.Null(config.Indexing.TempPath); Assert.Null(config.Storage.TempPath); // actual configuration is created in the following manner config = RavenConfiguration.CreateFrom(new RavenConfiguration(null, ResourceType.Server, _emptySettingFile), "foo", ResourceType.Database); config.Initialize(); Assert.Equal(new PathSetting("Databases/foo").FullPath, config.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting("Databases/foo/Indexes").FullPath, config.Indexing.StoragePath.FullPath); Assert.Null(config.Indexing.TempPath); Assert.Null(config.Storage.TempPath); }
protected DocumentDatabase CreateDocumentDatabase([CallerMemberName] string caller = null, bool runInMemory = true, string dataDirectory = null, Action <RavenConfiguration> modifyConfiguration = null) { var name = caller != null ? $"{caller}_{Interlocked.Increment(ref _counter)}" : Guid.NewGuid().ToString("N"); if (string.IsNullOrEmpty(dataDirectory)) { dataDirectory = NewDataPath(name); } _pathsToDelete.Add(dataDirectory); var configuration = new RavenConfiguration(); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.MinNumberOfMapAttemptsAfterWhichBatchWillBeCanceledIfRunningLowOnMemory), int.MaxValue.ToString()); configuration.Initialize(); configuration.Core.ThrowIfAnyIndexOrTransformerCouldNotBeOpened = true; configuration.Core.RunInMemory = runInMemory; configuration.Core.DataDirectory = dataDirectory; modifyConfiguration?.Invoke(configuration); var documentDatabase = new DocumentDatabase(name, configuration, null); documentDatabase.Initialize(); return(documentDatabase); }
public void Inherits_server_settings_and_appends_resource_specific_suffix_paths() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}Deployment"); server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}temp"); server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.JournalsStoragePath), $@"{_rootPathString}Journals"); server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.StoragePath), $@"{_rootPathString}Indexes"); server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}indexes-temp"); server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.JournalsStoragePath), $@"{_rootPathString}Indexes-Journals"); server.Initialize(); var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database); database.Initialize(); Assert.Equal(new PathSetting($@"{_rootPathString}Deployment\Databases\Foo").FullPath, database.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}temp\Databases\Foo").FullPath, database.Storage.TempPath.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}Journals\Databases\Foo").FullPath, database.Storage.JournalsStoragePath.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}Indexes\Databases\Foo").FullPath, database.Indexing.StoragePath.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}indexes-temp\Databases\Foo").FullPath, database.Indexing.TempPath.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}Indexes-Journals\Databases\Foo").FullPath, database.Indexing.JournalsStoragePath.FullPath); }
public void Resource_specific_paths_do_not_require_any_suffixes() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}Deployment"); server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}temp"); server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}indexes-temp"); server.Initialize(); var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database); database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}MyDatabase"); database.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}my-temp-path"); database.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}my-indexes-temp"); database.Initialize(); Assert.Equal(new PathSetting($@"{_rootPathString}MyDatabase").FullPath, database.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}my-temp-path").FullPath, database.Storage.TempPath.FullPath); Assert.Equal(new PathSetting($@"{_rootPathString}my-indexes-temp").FullPath, database.Indexing.TempPath.FullPath); }
private static RavenServer CreateServer(int port, int tcpPort) { var configuration = new RavenConfiguration(); configuration.Initialize(); configuration.DebugLog.LogMode = LogMode.None; configuration.Core.ServerUrl = $"http://localhost:{port}"; configuration.Core.TcpServerUrl = $"tcp://localhost:{tcpPort}"; configuration.Server.Name = ServerName; configuration.Core.RunInMemory = true; string postfix = port == 8080 ? "" : "_" + port; configuration.Core.DataDirectory = Path.Combine(configuration.Core.DataDirectory, $"Tests{postfix}"); configuration.Server.MaxTimeForTaskToWaitForDatabaseToLoad = new TimeSetting(10, TimeUnit.Seconds); configuration.Storage.AllowOn32Bits = true; IOExtensions.DeleteDirectory(configuration.Core.DataDirectory); var server = new RavenServer(configuration); server.Initialize(); // TODO: Make sure to properly handle this when this is resolved: // TODO: https://github.com/dotnet/corefx/issues/5205 // TODO: AssemblyLoadContext.GetLoadContext(typeof(RavenTestBase).GetTypeInfo().Assembly).Unloading += return(server); }
public DocumentsCrud() { _configuration = new RavenConfiguration(); _configuration.Initialize(); _configuration.Core.RunInMemory = true; _configuration.Core.DataDirectory = Path.GetTempPath() + @"\crud"; _documentDatabase = new DocumentDatabase("foo", _configuration, null); _documentDatabase.Initialize(); }
public void Restart() { if (Logger.IsInfoEnabled) { Logger.Info($"Restarting RavenDB Windows Service: {ServiceName}."); } _ravenServer.Dispose(); var configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath); if (_args != null) { configuration.AddCommandLine(_args); } configuration.Initialize(); _ravenServer = new RavenServer(configuration); Start(_args, _serviceStoppedCallback); configuration.Initialize(); }
public void IfConfigurationKeyIsStringArrayThenItShouldSupportValuesWithSemicolonPropely() { var configuration = new RavenConfiguration("Foo", ResourceType.Server); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Core.ServerUrls), "http://123.123.123.123:10105;http://123.123.123.124:10105"); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Core.PublicServerUrl), "http://public.url.com"); configuration.Initialize(); Assert.NotNull(configuration.Core.ServerUrls); Assert.Equal(2, configuration.Core.ServerUrls.Length); Assert.Contains("http://123.123.123.123:10105", configuration.Core.ServerUrls); Assert.Contains("http://123.123.123.124:10105", configuration.Core.ServerUrls); }
public RavenConfiguration GetConfiguration(string serverUrl = null, string tcpServerUrl = null, string certPath = null) { var configuration = new RavenConfiguration(null, ResourceType.Server); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Core.ServerUrl), serverUrl); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Core.TcpServerUrl), tcpServerUrl); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Security.CertificatePath), certPath); configuration.Initialize(); return(configuration); }
protected RachisConsensus <CountingStateMachine> SetupServer(bool bootstrap = false, int port = 0, int electionTimeout = 300, [CallerMemberName] string caller = null) { var tcpListener = new TcpListener(IPAddress.Loopback, port); tcpListener.Start(); var ch = (char)(66 + _count++); if (bootstrap) { ch = (char)65; _count--; } var url = "tcp://localhost:" + ((IPEndPoint)tcpListener.LocalEndpoint).Port + "/?" + caller + "#" + ch; var server = StorageEnvironmentOptions.CreateMemoryOnly(); int seed = PredictableSeeds ? _random.Next(int.MaxValue) : _count; var configuration = new RavenConfiguration(caller, ResourceType.Server); configuration.Initialize(); configuration.Core.RunInMemory = true; configuration.Core.PublicServerUrl = new UriSetting($"http://localhost:{((IPEndPoint)tcpListener.LocalEndpoint).Port}"); configuration.Cluster.ElectionTimeout = new TimeSetting(electionTimeout, TimeUnit.Milliseconds); var serverStore = new RavenServer(configuration).ServerStore; serverStore.Initialize(); var rachis = new RachisConsensus <CountingStateMachine>(serverStore, seed); var storageEnvironment = new StorageEnvironment(server); rachis.Initialize(storageEnvironment, configuration, configuration.Core.ServerUrls[0]); rachis.OnDispose += (sender, args) => { serverStore.Dispose(); storageEnvironment.Dispose(); }; if (bootstrap) { rachis.Bootstrap(url, "A"); } rachis.Url = url; _listeners.Add(tcpListener); RachisConsensuses.Add(rachis); var task = AcceptConnection(tcpListener, rachis); return(rachis); }
private void Restart() { var options = _documentDatabase.DocumentsStorage.Environment.Options; options.OwnsPagers = false; _documentDatabase.Dispose(); options.OwnsPagers = true; _configuration = new RavenConfiguration(); _configuration.Core.DataDirectory = Path.GetTempPath() + @"\crud"; _configuration.Initialize(); _configuration.Core.RunInMemory = true; _documentDatabase = new DocumentDatabase("test", _configuration, null); _documentDatabase.Initialize(options); }
private static void Validate(string key) { Environment.SetEnvironmentVariable(key, LogMode.Information.ToString()); try { var configuration = new RavenConfiguration("test", ResourceType.Server); configuration.Initialize(); Assert.Equal(LogMode.Information, configuration.Logs.Mode); } finally { Environment.SetEnvironmentVariable(key, null); } }
public void ShouldWork() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager), "true"); server.Initialize(); // should not throw Assert.True(server.Storage.ForceUsing32BitsPager); var database = RavenConfiguration.CreateFrom(server, "dbName", ResourceType.Database); database.SetSetting(RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager), "true"); var e = Assert.Throws <InvalidOperationException>(() => database.Initialize()); Assert.Equal($"Configuration '{RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager)}' can only be set at server level.", e.Message); }
protected virtual RavenServer GetNewServer(IDictionary <string, string> customSettings = null, bool deletePrevious = true, bool runInMemory = true, string partialPath = null, string customConfigPath = null) { lock (_getNewServerSync) { var configuration = new RavenConfiguration(Guid.NewGuid().ToString(), ResourceType.Server, customConfigPath); if (customSettings != null) { foreach (var setting in customSettings) { configuration.SetSetting(setting.Key, setting.Value); } } configuration.Initialize(); configuration.Logs.Mode = LogMode.None; if (customSettings == null || customSettings.ContainsKey(RavenConfiguration.GetKey(x => x.Core.ServerUrls)) == false) { configuration.Core.ServerUrls = new[] { "http://127.0.0.1:0" }; } configuration.Server.Name = ServerName; configuration.Core.RunInMemory = runInMemory; configuration.Core.DataDirectory = configuration.Core.DataDirectory.Combine(partialPath ?? $"Tests{Interlocked.Increment(ref _serverCounter)}"); configuration.Server.MaxTimeForTaskToWaitForDatabaseToLoad = new TimeSetting(60, TimeUnit.Seconds); configuration.Replication.ReplicationMinimalHeartbeat = new TimeSetting(100, TimeUnit.Milliseconds); configuration.Replication.RetryReplicateAfter = new TimeSetting(3, TimeUnit.Seconds); configuration.Cluster.AddReplicaTimeout = new TimeSetting(10, TimeUnit.Seconds); configuration.Licensing.EulaAccepted = true; if (customSettings == null || customSettings.ContainsKey(RavenConfiguration.GetKey(x => x.Core.FeaturesAvailability)) == false) { configuration.Core.FeaturesAvailability = FeaturesAvailability.Experimental; } if (deletePrevious) { IOExtensions.DeleteDirectory(configuration.Core.DataDirectory.FullPath); } var server = new RavenServer(configuration); server.Initialize(); return(server); } }
public void Should_create_data_in_directory_specified_at_server_level() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}RavenData"); server.Initialize(); var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database); database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"Items"); database.Initialize(); Assert.Equal(new PathSetting($@"{_rootPathString}RavenData\Items").FullPath, database.Core.DataDirectory.FullPath); }
public void Database_creation_using_relative_path_creates_directories_incorrectly() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), "RavenData"); server.Initialize(); var database = RavenConfiguration.CreateFrom(server, "foo", ResourceType.Database); database.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"MyWork\MyDatabaseFolder"); database.Initialize(); Assert.Equal(new PathSetting("RavenData/MyWork/MyDatabaseFolder").FullPath, database.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting("RavenData/MyWork/MyDatabaseFolder/Indexes").FullPath, database.Indexing.StoragePath.FullPath); }
public RavenConfiguration GetConfiguration( string certPath = null, UnsecuredAccessAddressRange unsecuredAccessAddressRange = UnsecuredAccessAddressRange.Local, string publicServerUrl = null, string serverUrl = null) { var configuration = new RavenConfiguration(null, ResourceType.Server); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Core.ServerUrls), serverUrl); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Core.PublicServerUrl), publicServerUrl); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Security.CertificatePath), certPath); configuration.SetSetting( RavenConfiguration.GetKey(x => x.Security.UnsecuredAccessAllowed), Enum.GetName(typeof(UnsecuredAccessAddressRange), unsecuredAccessAddressRange)); configuration.Initialize(); return(configuration); }
public void Should_handle_APPDRIVE_properly_if_specified() { var server = new RavenConfiguration(null, ResourceType.Server); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true"); server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"APPDRIVE:\RavenData"); server.Initialize(); var rootPath = Path.GetPathRoot(AppContext.BaseDirectory); Assert.Equal(new PathSetting($@"{rootPath}RavenData").FullPath, server.Core.DataDirectory.FullPath); var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database); database.Initialize(); Assert.Equal(new PathSetting($@"{rootPath}RavenData\Databases\Foo").FullPath, database.Core.DataDirectory.FullPath); Assert.Equal(new PathSetting($@"{rootPath}RavenData\Databases\Foo\Indexes").FullPath, database.Indexing.StoragePath.FullPath); }
public void CanDefineMoreThanOneAdditionalStoragePath() { var configuration = new RavenConfiguration(); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.IndexStoragePath), "C:\\temp\\0"); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.AdditionalIndexStoragePaths), "C:\\temp\\1;C:\\temp\\2"); configuration.Initialize(); Assert.Equal("C:\\temp\\0", configuration.Indexing.IndexStoragePath); Assert.Equal(2, configuration.Indexing.AdditionalIndexStoragePaths.Length); Assert.Equal("C:\\temp\\1", configuration.Indexing.AdditionalIndexStoragePaths[0]); Assert.Equal("C:\\temp\\2", configuration.Indexing.AdditionalIndexStoragePaths[1]); configuration = new RavenConfiguration(); configuration.DatabaseName = "DB"; configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.IndexStoragePath), "C:\\temp\\0"); configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.AdditionalIndexStoragePaths), "C:\\temp\\1;C:\\temp\\2"); configuration.Initialize(); Assert.Equal("C:\\temp\\0\\DB", configuration.Indexing.IndexStoragePath); Assert.Equal(2, configuration.Indexing.AdditionalIndexStoragePaths.Length); Assert.Equal("C:\\temp\\1\\DB", configuration.Indexing.AdditionalIndexStoragePaths[0]); Assert.Equal("C:\\temp\\2\\DB", configuration.Indexing.AdditionalIndexStoragePaths[1]); }
private static void InteractiveRun(string[] args) { string backupLocation = null; string restoreLocation = null; bool defrag = false; string theUser = null; Action actionToTake = null; bool launchBrowser = false; bool noLog = false; var ravenConfiguration = new RavenConfiguration(); OptionSet optionSet = null; optionSet = new OptionSet { { "set={==}", "The configuration {0:option} to set to the specified {1:value}", (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); } }, { "nolog", "Don't use the default log", s => noLog = true }, { "config=", "The config {0:file} to use", ravenConfiguration.LoadFrom }, { "install", "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart) }, { "user="******"Which user will be used", user => theUser = user }, { "setup-perf-counters", "Setup the performance counters and the related permissions", key => actionToTake = () => AdminRequired(() => SetupPerfCounters(theUser)) }, { "allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0)) }, { "deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1)) }, { "service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name }, { "uninstall", "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall) }, { "start", "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService) }, { "restart", "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService) }, { "stop", "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService) }, { "ram", "Run RavenDB in RAM only", key => { ravenConfiguration.Settings["Raven/RunInMemory"] = "true"; ravenConfiguration.RunInMemory = true; actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog); } }, { "debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog) }, { "browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true }, { "help", "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); } }, { "config-help", "Help about configuration options", key => { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); } }, { "restore", "Restores a RavenDB database from backup", key => actionToTake = () => { if (backupLocation == null || restoreLocation == null) { throw new OptionException("when using restore, source and destination must be specified", "restore"); } RunRestoreOperation(backupLocation, restoreLocation, defrag); } }, { "defrag", "Applicable only during restore, execute defrag after the restore is completed", key => { defrag = true; } }, { "dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value }, { "src=|source=", "The {0:path} of the backup", value => backupLocation = value }, { "encrypt-self-config", "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); } }, { "encrypt-config=", "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); } }, { "decrypt-self-config", "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); } }, { "decrypt-config=", "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); } }, { "installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); } }, { "uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); } } }; try { if (args.Length == 0) // we default to executing in debug mode { args = new[] { "--debug" } } ; optionSet.Parse(args); } catch (Exception e) { Console.WriteLine(e.Message); PrintUsage(optionSet); return; } if (actionToTake == null) { actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog); } actionToTake(); }
public static int Main(string[] args) { SetCurrentDirectoryToServerPath(); string[] configurationArgs; try { configurationArgs = CommandLineSwitches.Process(args); } catch (CommandParsingException commandParsingException) { Console.WriteLine(commandParsingException.Message); CommandLineSwitches.ShowHelp(); return(1); } if (CommandLineSwitches.ShouldShowHelp) { CommandLineSwitches.ShowHelp(); return(0); } if (CommandLineSwitches.PrintVersionAndExit) { Console.WriteLine(ServerVersion.FullVersion); return(0); } new WelcomeMessage(Console.Out).Print(); var targetSettingsFile = new PathSetting(string.IsNullOrEmpty(CommandLineSwitches.CustomConfigPath) ? "settings.json" : CommandLineSwitches.CustomConfigPath); var destinationSettingsFile = new PathSetting("settings.default.json"); if (File.Exists(targetSettingsFile.FullPath) == false && File.Exists(destinationSettingsFile.FullPath)) //just in case { File.Copy(destinationSettingsFile.FullPath, targetSettingsFile.FullPath); } var configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath); if (configurationArgs != null) { configuration.AddCommandLine(configurationArgs); } configuration.Initialize(); LoggingSource.Instance.SetupLogMode(configuration.Logs.Mode, configuration.Logs.Path.FullPath); if (Logger.IsInfoEnabled) { Logger.Info($"Logging to {configuration.Logs.Path} set to {configuration.Logs.Mode} level."); } if (Logger.IsOperationsEnabled) { Logger.Operations(RavenCli.GetInfoText()); } if (WindowsServiceRunner.ShouldRunAsWindowsService()) { try { WindowsServiceRunner.Run(CommandLineSwitches.ServiceName, configuration, configurationArgs); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Error running Windows Service", e); } return(1); } return(0); } RestartServer = () => { ResetServerMre.Set(); ShutdownServerMre.Set(); }; var rerun = false; RavenConfiguration configBeforeRestart = configuration; do { if (rerun) { Console.WriteLine("\nRestarting Server..."); rerun = false; configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath); if (configurationArgs != null) { var argsAfterRestart = PostSetupCliArgumentsUpdater.Process( configurationArgs, configBeforeRestart, configuration); configuration.AddCommandLine(argsAfterRestart); configBeforeRestart = configuration; } configuration.Initialize(); } try { using (var server = new RavenServer(configuration)) { try { try { server.OpenPipes(); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Unable to OpenPipe. Admin Channel will not be available to the user", e); } Console.WriteLine("Warning: Admin Channel is not available:" + e); } server.Initialize(); if (CommandLineSwitches.PrintServerId) { Console.WriteLine($"Server ID is {server.ServerStore.GetServerId()}."); } new RuntimeSettings(Console.Out).Print(); if (CommandLineSwitches.LaunchBrowser) { BrowserHelper.OpenStudioInBrowser(server.ServerStore.GetNodeHttpServerUrl()); } new ClusterMessage(Console.Out, server.ServerStore).Print(); var prevColor = Console.ForegroundColor; Console.Write("Server available on: "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{server.ServerStore.GetNodeHttpServerUrl()}"); Console.ForegroundColor = prevColor; var tcpServerStatus = server.GetTcpServerStatus(); prevColor = Console.ForegroundColor; Console.Write("Tcp listening on "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{string.Join(", ", tcpServerStatus.Listeners.Select(l => l.LocalEndpoint))}"); Console.ForegroundColor = prevColor; Console.WriteLine("Server started, listening to requests..."); prevColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine("TIP: type 'help' to list the available commands."); Console.ForegroundColor = prevColor; IsRunningNonInteractive = false; rerun = CommandLineSwitches.NonInteractive || configuration.Core.SetupMode == SetupMode.Initial ? RunAsNonInteractive() : RunInteractive(server); Console.WriteLine("Starting shut down..."); if (Logger.IsInfoEnabled) { Logger.Info("Server is shutting down"); } } catch (Exception e) { if (Logger.IsOperationsEnabled) { Logger.Operations("Failed to initialize the server", e); } Console.WriteLine(e); return(-1); } } Console.WriteLine("Shutdown completed"); } catch (Exception e) { Console.WriteLine("Error during shutdown"); Console.WriteLine(e); return(-2); } finally { if (Logger.IsOperationsEnabled) { Logger.OperationsAsync("Server has shut down").Wait(TimeSpan.FromSeconds(15)); } } } while (rerun); return(0); }
public async Task <HttpResponseMessage> Restore() { if (EnsureSystemDatabase() == false) { return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest)); } var restoreStatus = new RestoreStatus { Messages = new List <string>() }; var restoreRequest = await ReadJsonObjectAsync <DatabaseRestoreRequest>(); DatabaseDocument databaseDocument = null; var databaseDocumentPath = MaintenanceActions.FindDatabaseDocument(restoreRequest.BackupLocation); if (File.Exists(databaseDocumentPath)) { var databaseDocumentText = File.ReadAllText(databaseDocumentPath); databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>(); } var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName : databaseDocument == null ? null : databaseDocument.Id; if (string.IsNullOrWhiteSpace(databaseName)) { var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id)) ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen." : "A database name must be supplied if the restore location does not contain a valid Database.Document file"; restoreStatus.Messages.Add(errorMessage); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest)); } if (databaseName == Constants.SystemDatabase) { return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest)); } var existingDatabase = Database.Documents.GetDocumentMetadata("Raven/Databases/" + databaseName, null); if (existingDatabase != null) { return(GetMessageWithString("Cannot do an online restore for an existing database, delete the database " + databaseName + " and restore again.", HttpStatusCode.BadRequest)); } var ravenConfiguration = new RavenConfiguration { DatabaseName = databaseName, IsTenantDatabase = true }; if (databaseDocument != null) { foreach (var setting in databaseDocument.Settings) { ravenConfiguration.Settings[setting.Key] = setting.Value; } } if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName; } else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName; } ravenConfiguration.CustomizeValuesForTenant(databaseName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir); restoreRequest.DatabaseLocation = ravenConfiguration.DataDirectory; DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null); bool defrag; if (bool.TryParse(GetQueryStringValue("defrag"), out defrag)) { restoreRequest.Defrag = defrag; } var task = Task.Factory.StartNew(() => { MaintenanceActions.Restore(ravenConfiguration, restoreRequest, msg => { restoreStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }); if (databaseDocument == null) { return; } databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir; if (restoreRequest.IndexesLocation != null) { databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation; } if (restoreRequest.JournalsLocation != null) { databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation; } databaseDocument.Id = databaseName; DatabasesLandlord.Protect(databaseDocument); DatabasesLandlord.SystemDatabase.Documents.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null); restoreStatus.Messages.Add("The new database was created"); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }, TaskCreationOptions.LongRunning); long id; Database.Tasks.AddTask(task, new object(), new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.RestoreDatabase, Payload = "Restoring database " + databaseName + " from " + restoreRequest.BackupLocation }, out id); return(GetMessageWithObject(new { OperationId = id })); }
private static void InteractiveRun(string[] args) { string backupLocation = null; string restoreLocation = null; bool defrag = false; string theUser = null; Action actionToTake = null; bool launchBrowser = false; bool noLog = false; var ravenConfiguration = new RavenConfiguration(); OptionSet optionSet = null; optionSet = new OptionSet { {"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); }}, {"nolog", "Don't use the default log", s => noLog=true}, {"config=", "The config {0:file} to use", ravenConfiguration.LoadFrom}, {"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart)}, {"user="******"Which user will be used", user=> theUser = user}, {"setup-perf-counters", "Setup the performance counters and the related permissions", key => actionToTake = ()=> AdminRequired(()=>SetupPerfCounters(theUser))}, {"allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))}, {"deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))}, {"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name}, {"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall)}, {"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService)}, {"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService)}, {"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService)}, {"ram", "Run RavenDB in RAM only", key => { ravenConfiguration.Settings["Raven/RunInMemory"] = "true"; ravenConfiguration.RunInMemory = true; actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog); }}, {"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)}, {"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true}, {"help", "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); }}, {"config-help", "Help about configuration options", key=> { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); }}, {"restore", "Restores a RavenDB database from backup", key => actionToTake = () => { if(backupLocation == null || restoreLocation == null) { throw new OptionException("when using restore, source and destination must be specified", "restore"); } RunRestoreOperation(backupLocation, restoreLocation, defrag); }}, {"defrag", "Applicable only during restore, execute defrag after the restore is completed", key => { defrag = true; }}, {"dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value}, {"src=|source=", "The {0:path} of the backup", value => backupLocation = value}, {"encrypt-self-config", "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"encrypt-config=", "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); }}, {"decrypt-self-config", "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"decrypt-config=", "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); }}, {"installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }}, {"uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }} }; try { if (args.Length == 0) // we default to executing in debug mode args = new[] { "--debug" }; optionSet.Parse(args); } catch (Exception e) { Console.WriteLine(e.Message); PrintUsage(optionSet); return; } if (actionToTake == null) actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog); actionToTake(); }
private static void InteractiveRun(string[] args) { string backupLocation = null; string restoreLocation = null; Action actionToTake = null; bool launchBrowser = false; var ravenConfiguration = new RavenConfiguration(); OptionSet optionSet = null; optionSet = new OptionSet { { "set={==}", "The configuration {0:option} to set to the specified {1:value}", (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); } }, { "config=", "The config {0:file} to use", path => ravenConfiguration.LoadFrom(path) }, { "install", "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart, key) }, { "service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name }, { "uninstall", "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall, key) }, { "start", "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService, key) }, { "restart", "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService, key) }, { "stop", "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService, key) }, { "ram", "Run RavenDB in RAM only", key => { ravenConfiguration.Settings["Raven/RunInMemory"] = "true"; ravenConfiguration.RunInMemory = true; actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.All, ravenConfiguration, launchBrowser); } }, { "debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser) }, { "browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true }, { "help", "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); } }, { "config-help", "Help about configuration options", key => { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); } }, { "restore", "Restores a RavenDB database from backup", key => actionToTake = () => { if (backupLocation == null || restoreLocation == null) { throw new OptionException("when using restore, source and destination must be specified", "restore"); } RunRestoreOperation(backupLocation, restoreLocation); } }, { "dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value }, { "src=|source=", "The {0:path} of the backup", value => backupLocation = value }, { "encrypt-self-config", "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); } }, { "encrypt-config=", "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); } }, { "decrypt-self-config", "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); } }, { "decrypt-config=", "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); } } }; try { if (args.Length == 0) // we default to executing in debug mode { args = new[] { "--debug" } } ; optionSet.Parse(args); } catch (Exception e) { Console.WriteLine(e.Message); PrintUsage(optionSet); return; } if (actionToTake == null) { actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser); } actionToTake(); }
private static void InteractiveRun(string[] args) { var ioTestRequest = new GenericPerformanceTestRequest(); string backupLocation = null; string restoreLocation = null; string restoreDatabaseName = null; string restoreFilesystemName = null; bool restoreDisableReplication = false; bool defrag = false; var requiresRestoreAction = new HashSet <string>(); bool isRestoreAction = false; var requiresIoTestAction = new HashSet <string>(); bool isIoTestAction = false; Action actionToTake = null; bool launchBrowser = false; bool noLog = false; var ravenConfiguration = new RavenConfiguration(); bool waitForRestore = true; int? restoreStartTimeout = 15; var optionSet = new OptionSet(); optionSet.Add("set={==}", OptionCategory.None, "The configuration {0:option} to set to the specified {1:value}", (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); }); optionSet.Add("nolog", OptionCategory.General, "Don't use the default log", s => noLog = true); optionSet.Add("config=", OptionCategory.General, "The config {0:file} to use", ravenConfiguration.LoadFrom); optionSet.Add("install", OptionCategory.Service, "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart)); optionSet.Add("allow-blank-password-use", OptionCategory.Other, "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))); optionSet.Add("deny-blank-password-use", OptionCategory.Other, "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))); optionSet.Add("service-name=", OptionCategory.Service, "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name); optionSet.Add("uninstall", OptionCategory.Service, "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall)); optionSet.Add("start", OptionCategory.Service, "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService)); optionSet.Add("restart", OptionCategory.Service, "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService)); optionSet.Add("stop", OptionCategory.Service, "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService)); optionSet.Add("ram", OptionCategory.General, "Run RavenDB in RAM only", key => { ravenConfiguration.Settings[Constants.RunInMemory] = "true"; ravenConfiguration.RunInMemory = true; ravenConfiguration.Initialize(); actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog); }); optionSet.Add("debug", OptionCategory.General, "Run RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)); optionSet.Add("browser|launchbrowser", OptionCategory.General, "After the server starts, launches the browser", key => launchBrowser = true); optionSet.Add("help", OptionCategory.Help, "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); }); optionSet.Add("config-help", OptionCategory.Help, "Help about configuration databaseOptions", key => { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); }); optionSet.Add("restore", OptionCategory.RestoreDatabase, "[Obsolete] Use --restore-system-database or --restore-database", key => { actionToTake = () => { throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore"); }; isRestoreAction = true; }); optionSet.Add("restore-system-database", OptionCategory.RestoreDatabase, "Restores a SYSTEM database from backup.", key => { actionToTake = () => { if (backupLocation == null || restoreLocation == null) { throw new OptionException("When using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database"); } RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag); }; isRestoreAction = true; }); optionSet.Add("restore-database=", OptionCategory.RestoreDatabase, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("When using --restore-database, --restore-source must be specified", "restore-database"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("Specified destination server url is not valid", "restore-database"); } RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, restoreDisableReplication, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; }); optionSet.Add("restore-filesystem=", OptionCategory.RestoreFileSystem, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("When using --restore-filesystem, --restore-source must be specified", "restore-filesystem"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("Specified destination server url is not valid", "restore-database"); } RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; }); optionSet.Add("restore-disable-replication", OptionCategory.RestoreDatabase, "Disables replication destinations in newly restored database", value => { restoreDisableReplication = true; requiresRestoreAction.Add("restore-disable-replication"); }); optionSet.Add("restore-no-wait", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Return immediately without waiting for a restore to complete", value => { waitForRestore = false; requiresRestoreAction.Add("restore-no-wait"); }); optionSet.Add("restore-start-timeout=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value => { int timeout; if (int.TryParse(value, out timeout) == false) { throw new OptionException("Specified restore start timeout is not valid", "restore-start-timeout"); } restoreStartTimeout = timeout; requiresRestoreAction.Add("restore-start-timeout"); }); optionSet.Add("restore-defrag", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Applicable only during restore, execute defrag after the restore is completed", key => { defrag = true; requiresRestoreAction.Add("restore-defrag"); }); optionSet.Add("restore-destination=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the new database. If not specified it will be located in default data directory", value => { restoreLocation = value; requiresRestoreAction.Add("restore-destination"); }); optionSet.Add("restore-source=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the backup", value => { backupLocation = value; requiresRestoreAction.Add("restore-source"); }); optionSet.Add("restore-database-name=", OptionCategory.RestoreDatabase, "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value => { restoreDatabaseName = value; requiresRestoreAction.Add("restore-database-name"); }); optionSet.Add("restore-filesystem-name", OptionCategory.RestoreFileSystem, "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value => { restoreFilesystemName = value; requiresRestoreAction.Add("restore-filesystem-name"); }); optionSet.Add("io-test=", OptionCategory.IOTest, "Performs disk io test using {0:dir} as temporary dir path", path => { ioTestRequest.Path = path; actionToTake = () => IoTest(ioTestRequest); isIoTestAction = true; }); optionSet.Add("io-test-file-size=", OptionCategory.IOTest, "The {0:size} of test file for io test in MB (default: 1024MB)", value => { int fileSize; if (int.TryParse(value, out fileSize) == false) { throw new OptionException("Specified test file size is not valid", "io-test-file-size"); } ioTestRequest.FileSize = fileSize * 1024 * 1024; requiresIoTestAction.Add("io-test-file-size"); }); optionSet.Add("io-test-threads=", OptionCategory.IOTest, "The {0:number} of threads to use during test", value => { int threads; if (int.TryParse(value, out threads) == false) { throw new OptionException("Specified amount of threads is not valid", "io-test-threads"); } ioTestRequest.ThreadCount = threads; requiresIoTestAction.Add("io-test-threads"); }); optionSet.Add("io-test-time=", OptionCategory.IOTest, "The {0:number} of seconds to run the test (default: 30)", value => { int testTime; if (int.TryParse(value, out testTime) == false) { throw new OptionException("Specified test time is not valid", "io-test-time"); } ioTestRequest.TimeToRunInSeconds = testTime; requiresIoTestAction.Add("io-test-time"); }); optionSet.Add("io-test-seed=", OptionCategory.IOTest, "The {0:seed} for random generator", value => { int seed; if (int.TryParse(value, out seed) == false) { throw new OptionException("Specified random seed is not valid", "io-test-seed"); } ioTestRequest.RandomSeed = seed; requiresIoTestAction.Add("io-test-seed"); }); optionSet.Add("io-test-mode=", OptionCategory.IOTest, "The operation {0:mode} (read,write,mix) (default: write)", value => { OperationType opType; if (Enum.TryParse(value, true, out opType) == false) { throw new OptionException("Specified test mode is not valid", "io-test-mode"); } ioTestRequest.OperationType = opType; requiresIoTestAction.Add("io-test-mode"); }); optionSet.Add("io-test-chunk-size=", OptionCategory.IOTest, "The {0:value} for chunk size in KB (default: 4 KB)", value => { int chunkSize; if (int.TryParse(value, out chunkSize) == false) { throw new OptionException("Specified test chunk size is not valid", "io-test-chunk-size"); } ioTestRequest.ChunkSize = chunkSize * 1024; requiresIoTestAction.Add("io-test-chunk-size"); }); optionSet.Add("io-test-sequential", OptionCategory.IOTest, "Perform sequential read/write (default: random)", value => { ioTestRequest.Sequential = true; requiresIoTestAction.Add("io-test-sequential"); }); optionSet.Add("io-test-buffering-type", OptionCategory.IOTest, "Buffering type (None,Read, ReadAndWrite) (default: None)", value => { BufferingType bufferingType; if (Enum.TryParse(value, true, out bufferingType) == false) { throw new OptionException("Specified buffering type is not valid", "io-test-buffering-type"); } ioTestRequest.BufferingType = bufferingType; requiresIoTestAction.Add("io-test-buffering-type"); }); optionSet.Add("encrypt-self-config", OptionCategory.Encryption, "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }); optionSet.Add("encrypt-config=", OptionCategory.Encryption, "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); }); optionSet.Add("decrypt-self-config", OptionCategory.Encryption, "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }); optionSet.Add("decrypt-config=", OptionCategory.Encryption, "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); }); optionSet.Add("installSSL={==}", OptionCategory.SSL, "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }); optionSet.Add("uninstallSSL={==}", OptionCategory.SSL, "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }); optionSet.Add("update-version=", OptionCategory.Update, "Updates the specified {0:databaseName} to newest version", dbName => { actionToTake = () => UpdateVersion(dbName); }); try { if (args.Length == 0) // we default to executing in debug mode { args = new[] { "--debug" } } ; optionSet.Parse(args); } catch (Exception e) { ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message); PrintUsage(optionSet); ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message); Environment.Exit(-1); return; } if (!isRestoreAction && requiresRestoreAction.Any()) { var joinedActions = string.Join(", ", requiresRestoreAction); throw new OptionException(string.Format("When using {0}, --restore-source must be specified", joinedActions), joinedActions); } if (!isIoTestAction && requiresIoTestAction.Any()) { var joinedActions = string.Join(", ", requiresRestoreAction); throw new OptionException(string.Format("When using {0}, --io-test must be specified", joinedActions), joinedActions); } if (actionToTake == null) { actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog); } actionToTake(); }
private static void InteractiveRun(string[] args) { string backupLocation = null; string restoreLocation = null; string restoreDatabaseName = null; string restoreFilesystemName = null; bool defrag = false; var requiresRestoreAction = new HashSet<string>(); bool isRestoreAction = false; Action actionToTake = null; bool launchBrowser = false; bool noLog = false; var ravenConfiguration = new RavenConfiguration(); bool waitForRestore = true; int? restoreStartTimeout = 15; OptionSet optionSet = null; optionSet = new OptionSet { {"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); }}, {"nolog", "Don't use the default log", s => noLog=true}, {"config=", "The config {0:file} to use", ravenConfiguration.LoadFrom}, {"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart)}, {"allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))}, {"deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))}, {"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name}, {"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall)}, {"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService)}, {"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService)}, {"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService)}, {"ram", "Run RavenDB in RAM only", key => { ravenConfiguration.Settings["Raven/RunInMemory"] = "true"; ravenConfiguration.RunInMemory = true; ravenConfiguration.Initialize(); actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog); }}, {"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)}, {"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true}, {"help", "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); }}, {"config-help", "Help about configuration options", key=> { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); }}, {"restore", "[Obsolete] Use --restore-system-database or --restore-database", key => { actionToTake = () => { throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore"); }; isRestoreAction = true; } }, {"restore-system-database", "Restores a SYSTEM database from backup.", key => { actionToTake = () => { if (backupLocation == null || restoreLocation == null) { throw new OptionException("when using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database"); } RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag); }; isRestoreAction = true; } }, {"restore-database=", "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("when using --restore-database, --restore-source must be specified", "restore-database"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("specified destination server url is not valid", "restore-database"); } RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; } }, {"restore-filesystem=", "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("when using --restore-filesystem, --restore-source must be specified", "restore-filesystem"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("specified destination server url is not valid", "restore-database"); } RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; } }, { "restore-no-wait", "Return immediately without waiting for a restore to complete", value => { waitForRestore = false; requiresRestoreAction.Add("restore-no-wait"); } }, { "restore-start-timeout=", "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value => { int timeout; if (int.TryParse(value, out timeout) == false) { throw new OptionException("specified restore start timeout is not valid", "restore-start-timeout"); } restoreStartTimeout = timeout; requiresRestoreAction.Add("restore-start-timeout"); }}, {"restore-defrag", "Applicable only during restore, execute defrag after the restore is completed", key => { defrag = true; requiresRestoreAction.Add("restore-defrag"); }}, {"restore-destination=", "The {0:path} of the new database. If not specified it will be located in default data directory", value => { restoreLocation = value; requiresRestoreAction.Add("restore-destination"); }}, {"restore-source=", "The {0:path} of the backup", value => { backupLocation = value; requiresRestoreAction.Add("restore-source"); }}, {"restore-database-name=", "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value => { restoreDatabaseName = value; requiresRestoreAction.Add("restore-database-name"); }}, {"restore-filesystem-name", "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value => { restoreFilesystemName = value; requiresRestoreAction.Add("restore-filesystem-name"); }}, {"encrypt-self-config", "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"encrypt-config=", "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); }}, {"decrypt-self-config", "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"decrypt-config=", "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); }}, {"installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }}, {"uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }}, {"update-version=", "Updates the specified {0:databaseName} to newest version", dbName => { actionToTake = () => UpdateVersion(dbName); }} }; try { if (args.Length == 0) // we default to executing in debug mode args = new[] { "--debug" }; optionSet.Parse(args); } catch (Exception e) { Console.WriteLine(e.Message); PrintUsage(optionSet); return; } if (!isRestoreAction && requiresRestoreAction.Any()) { var joinedActions = string.Join(", ", requiresRestoreAction); throw new OptionException(string.Format("when using {0}, --restore-source must be specified", joinedActions), joinedActions); } if (actionToTake == null) actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog); actionToTake(); }
public async Task <HttpResponseMessage> Restore() { if (EnsureSystemDatabase() == false) { return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest)); } var restoreStatus = new RestoreStatus { State = RestoreStatusState.Running, Messages = new List <string>() }; var restoreRequest = await ReadJsonObjectAsync <DatabaseRestoreRequest>(); DatabaseDocument databaseDocument = null; var databaseDocumentPath = MaintenanceActions.FindDatabaseDocument(restoreRequest.BackupLocation); if (File.Exists(databaseDocumentPath)) { var databaseDocumentText = File.ReadAllText(databaseDocumentPath); databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>(); } var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName : databaseDocument == null ? null : databaseDocument.Id; if (string.IsNullOrWhiteSpace(databaseName)) { var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id)) ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen." : "A database name must be supplied if the restore location does not contain a valid Database.Document file"; restoreStatus.Messages.Add(errorMessage); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest)); } if (databaseName == Constants.SystemDatabase) { return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest)); } var existingDatabase = Database.Documents.GetDocumentMetadata("Raven/Databases/" + databaseName, null); if (existingDatabase != null) { return(GetMessageWithString("Cannot do an online restore for an existing database, delete the database " + databaseName + " and restore again.", HttpStatusCode.BadRequest)); } var ravenConfiguration = new RavenConfiguration { DatabaseName = databaseName, IsTenantDatabase = true }; if (databaseDocument != null) { foreach (var setting in databaseDocument.Settings) { ravenConfiguration.Settings[setting.Key] = setting.Value; } } if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName; } else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName; } ravenConfiguration.CustomizeValuesForDatabaseTenant(databaseName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir); restoreRequest.DatabaseLocation = ravenConfiguration.DataDirectory; string anotherRestoreResourceName; if (IsAnotherRestoreInProgress(out anotherRestoreResourceName)) { if (restoreRequest.RestoreStartTimeout.HasValue) { try { using (var cts = new CancellationTokenSource()) { cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value)); var token = cts.Token; do { await Task.Delay(500, token); }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName)); } } catch (OperationCanceledException) { return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable)); } } else { return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable)); } } Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress { Resource = databaseName }), new RavenJObject(), null); DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null); bool defrag; if (bool.TryParse(GetQueryStringValue("defrag"), out defrag)) { restoreRequest.Defrag = defrag; } var task = Task.Factory.StartNew(() => { try { MaintenanceActions.Restore(ravenConfiguration, restoreRequest, msg => { restoreStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }); if (databaseDocument == null) { return; } databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir; if (restoreRequest.IndexesLocation != null) { databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation; } if (restoreRequest.JournalsLocation != null) { databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation; } bool replicationBundleRemoved = false; if (restoreRequest.DisableReplicationDestinations) { replicationBundleRemoved = TryRemoveReplicationBundle(databaseDocument); } databaseDocument.Id = databaseName; DatabasesLandlord.Protect(databaseDocument); DatabasesLandlord .SystemDatabase .Documents .Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null); restoreStatus.Messages.Add("The new database was created"); restoreStatus.State = RestoreStatusState.Completed; DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); if (restoreRequest.GenerateNewDatabaseId) { GenerateNewDatabaseId(databaseName); } if (replicationBundleRemoved) { AddReplicationBundleAndDisableReplicationDestinations(databaseName); } } catch (Exception e) { restoreStatus.State = RestoreStatusState.Faulted; restoreStatus.Messages.Add("Unable to restore database " + e.Message); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); throw; } finally { Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null); } }, TaskCreationOptions.LongRunning); long id; Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.RestoreDatabase, Payload = "Restoring database " + databaseName + " from " + restoreRequest.BackupLocation }, out id); return(GetMessageWithObject(new { OperationId = id })); }
public static void Main(string[] args) { string path = string.Concat(Environment.CurrentDirectory, "\\settings.json"); var configuration = new RavenConfiguration(null, ResourceType.Server, path); configuration.Initialize(); LoggingSource.Instance.SetupLogMode(configuration.Logs.Mode, configuration.Logs.Path.FullPath); if (Logger.IsInfoEnabled) { Logger.Info($"Logging to {configuration.Logs.Path} set to {configuration.Logs.Mode} level."); } if (Logger.IsOperationsEnabled) { Logger.Operations(RavenCli.GetInfoText()); } RestartServer = () => { ResetServerMre.Set(); ShutdownServerMre.Set(); }; var rerun = false; RavenConfiguration configBeforeRestart = configuration; do { try { using (var server = new RavenServer(configuration)) { try { try { server.OpenPipes(); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Unable to OpenPipe. Admin Channel will not be available to the user", e); } Console.WriteLine("Warning: Admin Channel is not available"); } server.Initialize(); var prevColor = Console.ForegroundColor; Console.Write("Server available on: "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{server.ServerStore.GetNodeHttpServerUrl()}"); Console.ForegroundColor = prevColor; var tcpServerStatus = server.GetTcpServerStatus(); prevColor = Console.ForegroundColor; Console.Write("Tcp listening on "); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"{string.Join(", ", tcpServerStatus.Listeners.Select(l => l.LocalEndpoint))}"); Console.ForegroundColor = prevColor; IsRunningNonInteractive = false; Console.WriteLine("Server start completed"); Console.ReadLine(); Console.WriteLine("Starting shut down..."); if (Logger.IsInfoEnabled) { Logger.Info("Server is shutting down"); } } catch (Exception e) { if (Logger.IsOperationsEnabled) { Logger.Operations("Failed to initialize the server", e); } Console.WriteLine(e); } } Console.WriteLine("Shutdown completed"); } catch (Exception e) { Console.WriteLine("Error during shutdown"); Console.WriteLine(e); } finally { if (Logger.IsOperationsEnabled) { Logger.OperationsAsync("Server has shut down").Wait(TimeSpan.FromSeconds(15)); } } } while (rerun); }
private static void InteractiveRun(string[] args) { var ioTestRequest = new GenericPerformanceTestRequest(); string backupLocation = null; string restoreLocation = null; string restoreDatabaseName = null; string restoreFilesystemName = null; bool restoreDisableReplication = false; bool defrag = false; var requiresRestoreAction = new HashSet<string>(); bool isRestoreAction = false; var requiresIoTestAction = new HashSet<string>(); bool isIoTestAction = false; Action actionToTake = null; bool launchBrowser = false; bool noLog = false; var ravenConfiguration = new RavenConfiguration(); bool waitForRestore = true; int? restoreStartTimeout = 15; var optionSet = new OptionSet(); optionSet.Add("set={==}", OptionCategory.None, "The configuration {0:option} to set to the specified {1:value}", (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); }); optionSet.Add("nolog", OptionCategory.General, "Don't use the default log", s => noLog = true); optionSet.Add("config=", OptionCategory.General, "The config {0:file} to use", ravenConfiguration.LoadFrom); optionSet.Add("install", OptionCategory.Service, "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart)); optionSet.Add("allow-blank-password-use", OptionCategory.Other, "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))); optionSet.Add("deny-blank-password-use", OptionCategory.Other, "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))); optionSet.Add("service-name=", OptionCategory.Service, "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name); optionSet.Add("uninstall", OptionCategory.Service, "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall)); optionSet.Add("start", OptionCategory.Service, "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService)); optionSet.Add("restart", OptionCategory.Service, "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService)); optionSet.Add("stop", OptionCategory.Service, "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService)); optionSet.Add("ram", OptionCategory.General, "Run RavenDB in RAM only", key => { ravenConfiguration.Settings[Constants.RunInMemory] = "true"; ravenConfiguration.RunInMemory = true; ravenConfiguration.Initialize(); actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog); }); optionSet.Add("debug", OptionCategory.General, "Run RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)); optionSet.Add("browser|launchbrowser", OptionCategory.General, "After the server starts, launches the browser", key => launchBrowser = true); optionSet.Add("help", OptionCategory.Help, "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); }); optionSet.Add("config-help", OptionCategory.Help, "Help about configuration databaseOptions", key => { actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs()); }); optionSet.Add("restore", OptionCategory.RestoreDatabase, "[Obsolete] Use --restore-system-database or --restore-database", key => { actionToTake = () => { throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore"); }; isRestoreAction = true; }); optionSet.Add("restore-system-database", OptionCategory.RestoreDatabase, "Restores a SYSTEM database from backup.", key => { actionToTake = () => { if (backupLocation == null || restoreLocation == null) { throw new OptionException("When using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database"); } RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag); }; isRestoreAction = true; }); optionSet.Add("restore-database=", OptionCategory.RestoreDatabase, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("When using --restore-database, --restore-source must be specified", "restore-database"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("Specified destination server url is not valid", "restore-database"); } RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, restoreDisableReplication, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; }); optionSet.Add("restore-filesystem=", OptionCategory.RestoreFileSystem, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url => { actionToTake = () => { if (backupLocation == null) { throw new OptionException("When using --restore-filesystem, --restore-source must be specified", "restore-filesystem"); } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false) { throw new OptionException("Specified destination server url is not valid", "restore-database"); } RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout); Environment.Exit(0); }; isRestoreAction = true; }); optionSet.Add("restore-disable-replication", OptionCategory.RestoreDatabase, "Disables replication destinations in newly restored database", value => { restoreDisableReplication = true; requiresRestoreAction.Add("restore-disable-replication"); }); optionSet.Add("restore-no-wait", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Return immediately without waiting for a restore to complete", value => { waitForRestore = false; requiresRestoreAction.Add("restore-no-wait"); }); optionSet.Add("restore-start-timeout=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value => { int timeout; if (int.TryParse(value, out timeout) == false) { throw new OptionException("Specified restore start timeout is not valid", "restore-start-timeout"); } restoreStartTimeout = timeout; requiresRestoreAction.Add("restore-start-timeout"); }); optionSet.Add("restore-defrag", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Applicable only during restore, execute defrag after the restore is completed", key => { defrag = true; requiresRestoreAction.Add("restore-defrag"); }); optionSet.Add("restore-destination=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the new database. If not specified it will be located in default data directory", value => { restoreLocation = value; requiresRestoreAction.Add("restore-destination"); }); optionSet.Add("restore-source=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the backup", value => { backupLocation = value; requiresRestoreAction.Add("restore-source"); }); optionSet.Add("restore-database-name=", OptionCategory.RestoreDatabase, "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value => { restoreDatabaseName = value; requiresRestoreAction.Add("restore-database-name"); }); optionSet.Add("restore-filesystem-name", OptionCategory.RestoreFileSystem, "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value => { restoreFilesystemName = value; requiresRestoreAction.Add("restore-filesystem-name"); }); optionSet.Add("io-test=", OptionCategory.IOTest, "Performs disk io test using {0:dir} as temporary dir path", path => { ioTestRequest.Path = path; actionToTake = () => IoTest(ioTestRequest); isIoTestAction = true; }); optionSet.Add("io-test-file-size=", OptionCategory.IOTest, "The {0:size} of test file for io test in MB (default: 1024MB)", value => { int fileSize; if (int.TryParse(value, out fileSize) == false) { throw new OptionException("Specified test file size is not valid", "io-test-file-size"); } ioTestRequest.FileSize = fileSize * 1024 * 1024; requiresIoTestAction.Add("io-test-file-size"); }); optionSet.Add("io-test-threads=", OptionCategory.IOTest, "The {0:number} of threads to use during test", value => { int threads; if (int.TryParse(value, out threads) == false) { throw new OptionException("Specified amount of threads is not valid", "io-test-threads"); } ioTestRequest.ThreadCount = threads; requiresIoTestAction.Add("io-test-threads"); }); optionSet.Add("io-test-time=", OptionCategory.IOTest, "The {0:number} of seconds to run the test (default: 30)", value => { int testTime; if (int.TryParse(value, out testTime) == false) { throw new OptionException("Specified test time is not valid", "io-test-time"); } ioTestRequest.TimeToRunInSeconds = testTime; requiresIoTestAction.Add("io-test-time"); }); optionSet.Add("io-test-seed=", OptionCategory.IOTest, "The {0:seed} for random generator", value => { int seed; if (int.TryParse(value, out seed) == false) { throw new OptionException("Specified random seed is not valid", "io-test-seed"); } ioTestRequest.RandomSeed = seed; requiresIoTestAction.Add("io-test-seed"); }); optionSet.Add("io-test-mode=", OptionCategory.IOTest, "The operation {0:mode} (read,write,mix) (default: write)", value => { OperationType opType; if (Enum.TryParse(value, true, out opType) == false) { throw new OptionException("Specified test mode is not valid", "io-test-mode"); } ioTestRequest.OperationType = opType; requiresIoTestAction.Add("io-test-mode"); }); optionSet.Add("io-test-chunk-size=", OptionCategory.IOTest, "The {0:value} for chunk size in KB (default: 4 KB)", value => { int chunkSize; if (int.TryParse(value, out chunkSize) == false) { throw new OptionException("Specified test chunk size is not valid", "io-test-chunk-size"); } ioTestRequest.ChunkSize = chunkSize * 1024; requiresIoTestAction.Add("io-test-chunk-size"); }); optionSet.Add("io-test-sequential", OptionCategory.IOTest, "Perform sequential read/write (default: random)", value => { ioTestRequest.Sequential = true; requiresIoTestAction.Add("io-test-sequential"); }); optionSet.Add("io-test-buffering-type", OptionCategory.IOTest, "Buffering type (None,Read, ReadAndWrite) (default: None)", value => { BufferingType bufferingType; if (Enum.TryParse(value, true, out bufferingType) == false) { throw new OptionException("Specified buffering type is not valid", "io-test-buffering-type"); } ioTestRequest.BufferingType = bufferingType; requiresIoTestAction.Add("io-test-buffering-type"); }); optionSet.Add("encrypt-self-config", OptionCategory.Encryption, "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }); optionSet.Add("encrypt-config=", OptionCategory.Encryption, "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); }); optionSet.Add("decrypt-self-config", OptionCategory.Encryption, "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }); optionSet.Add("decrypt-config=", OptionCategory.Encryption, "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); }); optionSet.Add("installSSL={==}", OptionCategory.SSL, "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }); optionSet.Add("uninstallSSL={==}", OptionCategory.SSL, "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) => { actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration); }); optionSet.Add("update-version=", OptionCategory.Update, "Updates the specified {0:databaseName} to newest version", dbName => { actionToTake = () => UpdateVersion(dbName); }); try { if (args.Length == 0) // we default to executing in debug mode args = new[] { "--debug" }; optionSet.Parse(args); } catch (Exception e) { ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message); PrintUsage(optionSet); ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message); Environment.Exit(-1); return; } if (!isRestoreAction && requiresRestoreAction.Any()) { var joinedActions = string.Join(", ", requiresRestoreAction); throw new OptionException(string.Format("When using {0}, --restore-source must be specified", joinedActions), joinedActions); } if (!isIoTestAction && requiresIoTestAction.Any()) { var joinedActions = string.Join(", ", requiresRestoreAction); throw new OptionException(string.Format("When using {0}, --io-test must be specified", joinedActions), joinedActions); } if (actionToTake == null) actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog); actionToTake(); }
public async Task <HttpResponseMessage> Restore() { if (EnsureSystemDatabase() == false) { return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest)); } var restoreStatus = new RestoreStatus { Messages = new List <string>() }; var restoreRequest = await ReadJsonObjectAsync <FilesystemRestoreRequest>(); FileSystemDocument filesystemDocument = null; var fileSystemDocumentPath = FindFilesystemDocument(restoreRequest.BackupLocation); if (!File.Exists(fileSystemDocumentPath)) { throw new InvalidOperationException("Cannot restore when the Filesystem.Document file is missing in the backup folder: " + restoreRequest.BackupLocation); } var filesystemDocumentText = File.ReadAllText(fileSystemDocumentPath); filesystemDocument = RavenJObject.Parse(filesystemDocumentText).JsonDeserialization <FileSystemDocument>(); var filesystemName = !string.IsNullOrWhiteSpace(restoreRequest.FilesystemName) ? restoreRequest.FilesystemName : filesystemDocument == null ? null : filesystemDocument.Id; if (string.IsNullOrWhiteSpace(filesystemName)) { var errorMessage = (filesystemDocument == null || String.IsNullOrWhiteSpace(filesystemDocument.Id)) ? BackupMethods.FilesystemDocumentFilename + " file is invalid - filesystem name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen." : "A filesystem name must be supplied if the restore location does not contain a valid " + BackupMethods.FilesystemDocumentFilename + " file"; restoreStatus.Messages.Add(errorMessage); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest)); } var ravenConfiguration = new RavenConfiguration { DatabaseName = filesystemName, IsTenantDatabase = true }; if (filesystemDocument != null) { foreach (var setting in filesystemDocument.Settings) { ravenConfiguration.Settings[setting.Key] = setting.Value; } } if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename))) { ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.VoronTypeName; } else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new"))) { ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.EsentTypeName; } ravenConfiguration.CustomizeValuesForTenant(filesystemName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.FileSystem.DataDirectory = ResolveTenantDataDirectory(restoreRequest.FilesystemLocation, filesystemName, out documentDataDir); restoreRequest.FilesystemLocation = ravenConfiguration.FileSystem.DataDirectory; DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, null); bool defrag; if (bool.TryParse(GetQueryStringValue("defrag"), out defrag)) { restoreRequest.Defrag = defrag; } //TODO: add task to pending task list like in ImportDatabase Task.Factory.StartNew(() => { if (!string.IsNullOrWhiteSpace(restoreRequest.FilesystemLocation)) { ravenConfiguration.FileSystem.DataDirectory = restoreRequest.FilesystemLocation; } using (var transactionalStorage = RavenFileSystem.CreateTransactionalStorage(ravenConfiguration)) { transactionalStorage.Restore(restoreRequest, msg => { restoreStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }); } if (filesystemDocument == null) { return; } filesystemDocument.Settings["Raven/FileSystem/DataDir"] = documentDataDir; if (restoreRequest.IndexesLocation != null) { filesystemDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation; } if (restoreRequest.JournalsLocation != null) { filesystemDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation; } filesystemDocument.Id = filesystemName; DatabasesLandlord.SystemDatabase.Documents.Put("Raven/FileSystems/" + filesystemName, null, RavenJObject.FromObject(filesystemDocument), new RavenJObject(), null); restoreStatus.Messages.Add("The new filesystem was created"); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }, TaskCreationOptions.LongRunning); return(GetEmptyMessage()); }
public async Task <HttpResponseMessage> Restore() { if (EnsureSystemDatabase() == false) { return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest)); } var restoreStatus = new RestoreStatus { State = RestoreStatusState.Running, Messages = new List <string>() }; var restoreRequest = await ReadJsonObjectAsync <FilesystemRestoreRequest>(); var fileSystemDocumentPath = FindFilesystemDocument(restoreRequest.BackupLocation); if (!File.Exists(fileSystemDocumentPath)) { throw new InvalidOperationException("Cannot restore when the Filesystem.Document file is missing in the backup folder: " + restoreRequest.BackupLocation); } var filesystemDocumentText = File.ReadAllText(fileSystemDocumentPath); var filesystemDocument = RavenJObject.Parse(filesystemDocumentText).JsonDeserialization <FileSystemDocument>(); var filesystemName = !string.IsNullOrWhiteSpace(restoreRequest.FilesystemName) ? restoreRequest.FilesystemName : filesystemDocument == null ? null : filesystemDocument.Id; if (string.IsNullOrWhiteSpace(filesystemName)) { var errorMessage = (filesystemDocument == null || String.IsNullOrWhiteSpace(filesystemDocument.Id)) ? Constants.FilesystemDocumentFilename + " file is invalid - filesystem name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen." : "A filesystem name must be supplied if the restore location does not contain a valid " + Constants.FilesystemDocumentFilename + " file"; restoreStatus.Messages.Add(errorMessage); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest)); } var ravenConfiguration = new RavenConfiguration { FileSystemName = filesystemName, }; if (filesystemDocument != null) { foreach (var setting in filesystemDocument.Settings) { ravenConfiguration.Settings[setting.Key] = setting.Value; } } if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new"))) { ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.EsentTypeName; } else { ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.VoronTypeName; } ravenConfiguration.CustomizeValuesForFileSystemTenant(filesystemName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.FileSystem.DataDirectory = ResolveTenantDataDirectory(restoreRequest.FilesystemLocation, filesystemName, out documentDataDir); restoreRequest.FilesystemLocation = ravenConfiguration.FileSystem.DataDirectory; string anotherRestoreResourceName; if (IsAnotherRestoreInProgress(out anotherRestoreResourceName)) { if (restoreRequest.RestoreStartTimeout.HasValue) { try { using (var cts = new CancellationTokenSource()) { cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value)); var token = cts.Token; do { await Task.Delay(500, token); }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName)); } } catch (OperationCanceledException) { return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable)); } } else { return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable)); } } Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress { Resource = filesystemName }), new RavenJObject(), null); DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, null); bool defrag; if (bool.TryParse(GetQueryStringValue("defrag"), out defrag)) { restoreRequest.Defrag = defrag; } var task = Task.Factory.StartNew(() => { try { if (!string.IsNullOrWhiteSpace(restoreRequest.FilesystemLocation)) { ravenConfiguration.FileSystem.DataDirectory = restoreRequest.FilesystemLocation; } using (var transactionalStorage = RavenFileSystem.CreateTransactionalStorage(ravenConfiguration)) { transactionalStorage.Restore(restoreRequest, msg => { restoreStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); }); } if (filesystemDocument == null) { return; } filesystemDocument.Settings[Constants.FileSystem.DataDirectory] = documentDataDir; if (restoreRequest.IndexesLocation != null) { filesystemDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation; } if (restoreRequest.JournalsLocation != null) { filesystemDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation; } filesystemDocument.Id = filesystemName; FileSystemsLandlord.Protect(filesystemDocument); DatabasesLandlord.SystemDatabase.Documents.Put(Constants.FileSystem.Prefix + filesystemName, null, RavenJObject.FromObject(filesystemDocument), new RavenJObject(), null); restoreStatus.State = RestoreStatusState.Completed; restoreStatus.Messages.Add("The new filesystem was created"); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); } catch (Exception e) { restoreStatus.State = RestoreStatusState.Faulted; restoreStatus.Messages.Add("Unable to restore filesystem " + e.Message); DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null); throw; } finally { Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null); } }, TaskCreationOptions.LongRunning); long id; Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.RestoreFilesystem, Payload = "Restoring filesystem " + filesystemName + " from " + restoreRequest.BackupLocation }, out id); return(GetMessageWithObject(new { OperationId = id })); }
private static void InteractiveRun(string[] args) { string backupLocation = null; string restoreLocation = null; Action actionToTake = null; bool launchBrowser = false; var ravenConfiguration = new RavenConfiguration(); OptionSet optionSet = null; optionSet = new OptionSet { {"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) => { ravenConfiguration.Settings[key] = value; ravenConfiguration.Initialize(); }}, {"config=", "The config {0:file} to use", path => ravenConfiguration.LoadFrom(path)}, {"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart, key)}, {"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name}, {"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall, key)}, {"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService, key)}, {"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService, key)}, {"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService, key)}, {"ram", "Run RavenDB in RAM only", key => { ravenConfiguration.Settings["Raven/RunInMemory"] = "true"; ravenConfiguration.RunInMemory = true; actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.All, ravenConfiguration, launchBrowser); }}, {"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser)}, {"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true}, {"help", "Help about the command line interface", key => { actionToTake = () => PrintUsage(optionSet); }}, {"config-help", "Help about configuration options", key=> { actionToTake = PrintConfig; }}, {"restore", "Restores a RavenDB database from backup", key => actionToTake = () => { if(backupLocation == null || restoreLocation == null) { throw new OptionException("when using restore, source and destination must be specified", "restore"); } RunRestoreOperation(backupLocation, restoreLocation); }}, {"dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value}, {"src=|source=", "The {0:path} of the backup", value => backupLocation = value}, {"encrypt-self-config", "Encrypt the RavenDB configuration file", file => { actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"encrypt-config=", "Encrypt the specified {0:configuration file}", file => { actionToTake = () => ProtectConfiguration(file); }}, {"decrypt-self-config", "Decrypt the RavenDB configuration file", file => { actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); }}, {"decrypt-config=", "Decrypt the specified {0:configuration file}", file => { actionToTake = () => UnprotectConfiguration(file); }} }; try { if (args.Length == 0) // we default to executing in debug mode args = new[] { "--debug" }; optionSet.Parse(args); } catch (Exception e) { Console.WriteLine(e.Message); PrintUsage(optionSet); return; } if (actionToTake == null) actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser); actionToTake(); }
public override void RespondToAdmin(IHttpContext context) { if (EnsureSystemDatabase(context) == false) { return; } var restoreRequest = context.ReadJsonObject <RestoreRequest>(); DatabaseDocument databaseDocument = null; if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Database.Document"))) { var databaseDocumentText = File.ReadAllText(Path.Combine(restoreRequest.RestoreLocation, "Database.Document")); databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>(); } var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName : databaseDocument == null ? null : databaseDocument.Id; if (string.IsNullOrWhiteSpace(databaseName)) { context.SetStatusToBadRequest(); context.WriteJson(new { Error = "A database name must be supplied if the restore location does not contain a valid Database.Document file" }); return; } var ravenConfiguration = new RavenConfiguration() { DatabaseName = databaseName, IsTenantDatabase = true }; if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Raven.ravendb"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Managed.TransactionalStorage).AssemblyQualifiedName; } else if (Directory.Exists(Path.Combine(restoreRequest.RestoreLocation, "new"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName; } ravenConfiguration.CustomizeValuesForTenant(databaseName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir); var restoreStatus = new List <string>(); SystemDatabase.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, new TransactionInformation()); DocumentDatabase.Restore(ravenConfiguration, restoreRequest.RestoreLocation, null, msg => { restoreStatus.Add(msg); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); }); if (databaseDocument == null) { return; } databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir; databaseDocument.Id = databaseName; SystemDatabase.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null); restoreStatus.Add("The new database was created"); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); }
public override void RespondToAdmin(IHttpContext context) { if (EnsureSystemDatabase(context) == false) { return; } var restoreRequest = context.ReadJsonObject <RestoreRequest>(); var restoreStatus = new List <string>(); SystemDatabase.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null); DatabaseDocument databaseDocument = null; if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Database.Document"))) { var databaseDocumentText = File.ReadAllText(Path.Combine(restoreRequest.RestoreLocation, "Database.Document")); databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>(); } var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName : databaseDocument == null ? null : databaseDocument.Id; if (string.IsNullOrWhiteSpace(databaseName)) { context.SetStatusToBadRequest(); var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id)) ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen." : "A database name must be supplied if the restore location does not contain a valid Database.Document file"; context.WriteJson(new { Error = errorMessage }); restoreStatus.Add(errorMessage); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return; } if (databaseName == Constants.SystemDatabase) { context.SetStatusToBadRequest(); context.WriteJson(new { Error = "Cannot do an online restore for the <system> database" }); restoreStatus.Add("Cannot do an online restore for the <system> database"); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return; } var ravenConfiguration = new RavenConfiguration { DatabaseName = databaseName, IsTenantDatabase = true }; if (databaseDocument != null) { foreach (var setting in databaseDocument.Settings) { ravenConfiguration.Settings[setting.Key] = setting.Value; } } if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Raven.ravendb"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Managed.TransactionalStorage).AssemblyQualifiedName; } else if (Directory.Exists(Path.Combine(restoreRequest.RestoreLocation, "new"))) { ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName; } ravenConfiguration.CustomizeValuesForTenant(databaseName); ravenConfiguration.Initialize(); string documentDataDir; ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir); var defrag = "true".Equals(context.Request.QueryString["defrag"], StringComparison.InvariantCultureIgnoreCase); Task.Factory.StartNew(() => { DocumentDatabase.Restore(ravenConfiguration, restoreRequest.RestoreLocation, null, msg => { restoreStatus.Add(msg); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); }, defrag); if (databaseDocument == null) { restoreStatus.Add("Restore ended but could not create the datebase document, in order to access the data create a database with the appropriate name"); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); return; } databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir; databaseDocument.Id = databaseName; server.Protect(databaseDocument); SystemDatabase.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null); restoreStatus.Add("The new database was created"); SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null); }, TaskCreationOptions.LongRunning); }