Jackett/src/Jackett.Server/Program.cs

194 lines
7.4 KiB
C#
Raw Normal View History

using CommandLine;
2018-05-01 12:00:02 +00:00
using CommandLine.Text;
using Jackett.Common.Models.Config;
using Jackett.Common.Services;
2018-05-20 11:21:08 +00:00
using Jackett.Common.Services.Interfaces;
2018-05-01 12:00:02 +00:00
using Jackett.Common.Utils;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
2018-05-20 11:21:08 +00:00
using NLog;
2018-05-01 12:00:02 +00:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
2018-05-01 12:00:02 +00:00
using System.Linq;
2018-05-20 11:21:08 +00:00
using System.Runtime.InteropServices;
namespace Jackett.Server
{
2018-06-03 11:11:18 +00:00
public static class Program
{
2018-05-01 12:00:02 +00:00
public static IConfiguration Configuration { get; set; }
2018-06-03 11:11:18 +00:00
private static RuntimeSettings Settings { get; set; }
2018-06-10 02:33:16 +00:00
public static bool isWebHostRestart = false;
2018-06-03 11:11:18 +00:00
public static void Main(string[] args)
{
2018-06-03 11:11:18 +00:00
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
2018-06-10 02:33:16 +00:00
var commandLineParser = new Parser();
var optionsResult = commandLineParser.ParseArguments<ConsoleOptions>(args);
var runtimeDictionary = new Dictionary<string, string>();
ConsoleOptions consoleOptions = new ConsoleOptions();
2018-06-03 11:11:18 +00:00
2018-05-01 12:00:02 +00:00
optionsResult.WithNotParsed(errors =>
{
var text = HelpText.AutoBuild(optionsResult);
text.Copyright = " ";
2018-06-03 11:11:18 +00:00
text.Heading = "Jackett v" + EnvironmentUtil.JackettVersion;
Console.WriteLine(text);
2018-05-20 11:21:08 +00:00
Environment.Exit(1);
2018-05-01 12:00:02 +00:00
return;
});
optionsResult.WithParsed(options =>
{
2018-06-03 11:11:18 +00:00
if (string.IsNullOrEmpty(options.Client))
{
//TODO: Remove libcurl once off owin
options.Client = "httpclient";
}
Settings = options.ToRunTimeSettings();
2018-05-20 11:21:08 +00:00
consoleOptions = options;
2018-06-10 02:33:16 +00:00
runtimeDictionary = GetValues(Settings);
2018-05-01 12:00:02 +00:00
});
2018-06-10 02:33:16 +00:00
Helper.ConsoleOptions = consoleOptions;
2018-06-16 08:32:08 +00:00
LogManager.Configuration = Initialisation.SetupLogging(Settings);
Logger logger = LogManager.GetCurrentClassLogger();
logger.Info("Starting Jackett v" + EnvironmentUtil.JackettVersion);
// create PID file early
if (!string.IsNullOrWhiteSpace(Settings.PIDFile))
{
try
{
var proc = Process.GetCurrentProcess();
File.WriteAllText(Settings.PIDFile, proc.Id.ToString());
}
catch (Exception e)
{
logger.Error(e, "Error while creating the PID file");
}
}
ISerializeService serializeService = new SerializeService();
IProcessService processService = new ProcessService(logger);
IConfigurationService configurationService = new ConfigurationService(serializeService, processService, logger, Settings);
if (consoleOptions.Install || consoleOptions.Uninstall || consoleOptions.StartService || consoleOptions.StopService || consoleOptions.ReserveUrls)
{
bool isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
if (isWindows)
{
ServerConfig serverConfig = configurationService.BuildServerConfig(Settings);
Initialisation.ProcessWindowsSpecificArgs(consoleOptions, processService, serverConfig, logger);
}
else
{
logger.Error($"ReserveUrls and service arguments only apply to Windows, please remove them from your start arguments");
Environment.Exit(1);
}
}
2018-05-01 12:00:02 +00:00
var builder = new ConfigurationBuilder();
builder.AddInMemoryCollection(runtimeDictionary);
Configuration = builder.Build();
do
2018-05-20 11:21:08 +00:00
{
ServerConfig serverConfig = configurationService.BuildServerConfig(Settings);
Int32.TryParse(serverConfig.Port.ToString(), out Int32 configPort);
if (!isWebHostRestart)
2018-05-20 11:21:08 +00:00
{
// Override port
if (consoleOptions.Port != 0)
2018-05-20 11:21:08 +00:00
{
if (configPort != consoleOptions.Port)
2018-05-20 11:21:08 +00:00
{
logger.Info("Overriding port to " + consoleOptions.Port);
serverConfig.Port = consoleOptions.Port;
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
if (isWindows)
{
if (ServerUtil.IsUserAdministrator())
{
Initialisation.ReserveUrls(processService, serverConfig, logger, doInstall: true);
}
else
{
logger.Error("Unable to switch ports when not running as administrator");
Environment.Exit(1);
}
}
configurationService.SaveConfig(serverConfig);
2018-05-20 11:21:08 +00:00
}
}
}
string[] url = serverConfig.GetListenAddresses(serverConfig.AllowExternal).Take(1).ToArray(); //Kestrel doesn't need 127.0.0.1 and localhost to be registered, remove once off OWIN
2018-05-20 11:21:08 +00:00
2018-06-10 02:33:16 +00:00
isWebHostRestart = false;
try
{
CreateWebHostBuilder(args, url).Build().Run();
}
catch (Exception ex)
{
if (ex.InnerException is Microsoft.AspNetCore.Connections.AddressInUseException)
{
logger.Error("Address already in use: Most likely Jackett is already running. " + ex.Message);
Environment.Exit(1);
}
logger.Error(ex);
throw;
}
2018-06-10 02:33:16 +00:00
} while (isWebHostRestart);
2018-05-01 12:00:02 +00:00
}
public static Dictionary<string, string> GetValues(object obj)
{
return obj
.GetType()
.GetProperties()
.ToDictionary(p => "RuntimeSettings:" + p.Name, p => p.GetValue(obj) == null ? null : p.GetValue(obj).ToString());
}
2018-06-03 11:11:18 +00:00
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
try
{
if (Settings != null && !string.IsNullOrWhiteSpace(Settings.PIDFile))
{
var PIDFile = Settings.PIDFile;
if (File.Exists(PIDFile))
{
Console.WriteLine("Deleting PID file " + PIDFile);
File.Delete(PIDFile);
}
LogManager.Shutdown();
2018-06-03 11:11:18 +00:00
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString(), "Error while deleting the PID file");
}
}
2018-05-20 11:21:08 +00:00
public static IWebHostBuilder CreateWebHostBuilder(string[] args, string[] urls) =>
WebHost.CreateDefaultBuilder(args)
.UseConfiguration(Configuration)
2018-06-10 02:33:16 +00:00
.UseUrls(urls)
.PreferHostingUrls(true)
.UseStartup<Startup>();
}
}