2020-02-09 18:08:34 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using CommandLine;
|
2018-05-01 12:00:02 +00:00
|
|
|
using CommandLine.Text;
|
|
|
|
using Jackett.Common.Models.Config;
|
2018-06-17 02:39:03 +00:00
|
|
|
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;
|
2018-05-01 11:13:20 +00:00
|
|
|
using Microsoft.AspNetCore;
|
|
|
|
using Microsoft.AspNetCore.Hosting;
|
|
|
|
using Microsoft.Extensions.Configuration;
|
2018-11-14 16:52:56 +00:00
|
|
|
using Microsoft.Extensions.Logging;
|
2018-05-20 11:21:08 +00:00
|
|
|
using NLog;
|
2018-06-18 12:01:25 +00:00
|
|
|
using NLog.Web;
|
2018-05-01 11:13:20 +00:00
|
|
|
|
|
|
|
namespace Jackett.Server
|
|
|
|
{
|
2018-06-03 11:11:18 +00:00
|
|
|
public static class Program
|
2018-05-01 11:13:20 +00:00
|
|
|
{
|
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
|
|
|
|
2018-05-01 11:13:20 +00:00
|
|
|
public static void Main(string[] args)
|
|
|
|
{
|
2018-06-03 11:11:18 +00:00
|
|
|
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
|
|
|
|
|
2018-06-17 04:12:52 +00:00
|
|
|
var commandLineParser = new Parser(settings => settings.CaseSensitive = false);
|
2018-06-10 02:33:16 +00:00
|
|
|
var optionsResult = commandLineParser.ParseArguments<ConsoleOptions>(args);
|
|
|
|
var runtimeDictionary = new Dictionary<string, string>();
|
2020-02-10 22:16:19 +00:00
|
|
|
var 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 = " ";
|
2020-12-06 23:14:23 +00:00
|
|
|
text.Heading = "Jackett " + EnvironmentUtil.JackettVersion();
|
2018-06-03 11:11:18 +00:00
|
|
|
Console.WriteLine(text);
|
2018-05-20 11:21:08 +00:00
|
|
|
Environment.Exit(1);
|
2018-05-01 12:00:02 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
optionsResult.WithParsed(options =>
|
|
|
|
{
|
2018-06-03 11:11:18 +00:00
|
|
|
if (string.IsNullOrEmpty(options.Client))
|
2020-09-19 17:16:13 +00:00
|
|
|
options.Client = DotNetCoreUtil.IsRunningOnDotNetCore ? "httpclient2" : "httpclient";
|
2018-06-03 11:11:18 +00:00
|
|
|
|
|
|
|
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-22 12:35:58 +00:00
|
|
|
LogManager.Configuration = LoggingSetup.GetLoggingConfiguration(Settings);
|
2020-02-10 22:16:19 +00:00
|
|
|
var logger = LogManager.GetCurrentClassLogger();
|
2020-12-06 23:14:23 +00:00
|
|
|
logger.Info("Starting Jackett " + EnvironmentUtil.JackettVersion());
|
2018-06-16 08:32:08 +00:00
|
|
|
|
2018-06-17 02:39:03 +00:00
|
|
|
// create PID file early
|
|
|
|
if (!string.IsNullOrWhiteSpace(Settings.PIDFile))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var proc = Process.GetCurrentProcess();
|
|
|
|
File.WriteAllText(Settings.PIDFile, proc.Id.ToString());
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
logger.Error($"Error while creating the PID file\n{e}");
|
2018-06-17 02:39:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-15 05:20:31 +00:00
|
|
|
Initialisation.CheckEnvironmentalVariables(logger);
|
2018-06-17 04:02:13 +00:00
|
|
|
Initialisation.ProcessSettings(Settings, logger);
|
|
|
|
|
2018-06-17 02:39:03 +00:00
|
|
|
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)
|
|
|
|
{
|
2020-02-10 22:16:19 +00:00
|
|
|
var isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
|
2018-06-17 02:39:03 +00:00
|
|
|
|
|
|
|
if (isWindows)
|
|
|
|
{
|
2020-02-10 22:16:19 +00:00
|
|
|
var serverConfig = configurationService.BuildServerConfig(Settings);
|
2018-06-17 02:39:03 +00:00
|
|
|
Initialisation.ProcessWindowsSpecificArgs(consoleOptions, processService, serverConfig, logger);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
logger.Error("ReserveUrls and service arguments only apply to Windows, please remove them from your start arguments");
|
2018-06-17 02:39:03 +00:00
|
|
|
Environment.Exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 12:00:02 +00:00
|
|
|
var builder = new ConfigurationBuilder();
|
|
|
|
builder.AddInMemoryCollection(runtimeDictionary);
|
2018-08-14 09:58:11 +00:00
|
|
|
builder.AddJsonFile(Path.Combine(configurationService.GetAppDataFolder(), "appsettings.json"), optional: true);
|
2018-05-01 12:00:02 +00:00
|
|
|
|
|
|
|
Configuration = builder.Build();
|
|
|
|
|
2018-06-16 08:06:14 +00:00
|
|
|
do
|
2018-05-20 11:21:08 +00:00
|
|
|
{
|
2018-06-16 08:06:14 +00:00
|
|
|
if (!isWebHostRestart)
|
2018-05-20 11:21:08 +00:00
|
|
|
{
|
2018-06-17 04:39:49 +00:00
|
|
|
if (consoleOptions.Port != 0 || consoleOptions.ListenPublic || consoleOptions.ListenPrivate)
|
2018-05-20 11:21:08 +00:00
|
|
|
{
|
2020-02-10 22:16:19 +00:00
|
|
|
var serverConfiguration = configurationService.BuildServerConfig(Settings);
|
2018-06-17 04:39:49 +00:00
|
|
|
Initialisation.ProcessConsoleOverrides(consoleOptions, processService, serverConfiguration, configurationService, logger);
|
2018-05-20 11:21:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-10 22:16:19 +00:00
|
|
|
var serverConfig = configurationService.BuildServerConfig(Settings);
|
|
|
|
int.TryParse(serverConfig.Port.ToString(), out var configPort);
|
|
|
|
var url = serverConfig.GetListenAddresses(serverConfig.AllowExternal);
|
2018-05-20 11:21:08 +00:00
|
|
|
|
2018-06-10 02:33:16 +00:00
|
|
|
isWebHostRestart = false;
|
2018-06-16 08:06:14 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2018-07-10 12:22:02 +00:00
|
|
|
logger.Debug("Creating web host...");
|
2020-02-10 22:16:19 +00:00
|
|
|
var applicationFolder = Path.Combine(configurationService.ApplicationFolder(), "Content");
|
2018-08-04 06:49:26 +00:00
|
|
|
logger.Debug($"Content root path is: {applicationFolder}");
|
|
|
|
|
|
|
|
CreateWebHostBuilder(args, url, applicationFolder).Build().Run();
|
2018-06-16 08:06:14 +00:00
|
|
|
}
|
2020-09-24 20:02:45 +00:00
|
|
|
catch (Exception e)
|
2018-06-16 08:06:14 +00:00
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
if (e.InnerException is Microsoft.AspNetCore.Connections.AddressInUseException)
|
2018-06-16 08:06:14 +00:00
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
logger.Error($"Address already in use: Most likely Jackett is already running. {e.Message}");
|
2018-06-16 08:06:14 +00:00
|
|
|
Environment.Exit(1);
|
|
|
|
}
|
2020-09-24 20:02:45 +00:00
|
|
|
logger.Error(e);
|
2018-06-16 08:06:14 +00:00
|
|
|
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-05-01 11:13:20 +00:00
|
|
|
}
|
|
|
|
|
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))
|
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
var pidFile = Settings.PIDFile;
|
|
|
|
if (File.Exists(pidFile))
|
2018-06-03 11:11:18 +00:00
|
|
|
{
|
2020-09-24 20:02:45 +00:00
|
|
|
Console.WriteLine("Deleting PID file " + pidFile);
|
|
|
|
File.Delete(pidFile);
|
2018-06-03 11:11:18 +00:00
|
|
|
}
|
2018-06-17 02:39:03 +00:00
|
|
|
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-08-04 06:49:26 +00:00
|
|
|
public static IWebHostBuilder CreateWebHostBuilder(string[] args, string[] urls, string contentRoot) =>
|
2018-05-12 03:16:56 +00:00
|
|
|
WebHost.CreateDefaultBuilder(args)
|
2018-08-04 06:49:26 +00:00
|
|
|
.UseContentRoot(contentRoot)
|
2018-08-05 05:31:54 +00:00
|
|
|
.UseWebRoot(contentRoot)
|
2018-06-10 02:33:16 +00:00
|
|
|
.UseUrls(urls)
|
|
|
|
.PreferHostingUrls(true)
|
2018-08-14 09:58:11 +00:00
|
|
|
.UseConfiguration(Configuration)
|
2018-06-18 12:01:25 +00:00
|
|
|
.UseStartup<Startup>()
|
2018-11-14 16:52:56 +00:00
|
|
|
.ConfigureLogging(logging =>
|
|
|
|
{
|
|
|
|
logging.ClearProviders();
|
|
|
|
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
|
|
|
})
|
2018-06-18 12:01:25 +00:00
|
|
|
.UseNLog();
|
2018-05-01 11:13:20 +00:00
|
|
|
}
|
|
|
|
}
|