Exemple #1
0
        private static async Task StartApp(StartupOptions options)
        {
            ServerApplicationPaths appPaths = CreateApplicationPaths(options);

            // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
            Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
            await CreateLogger(appPaths);

            _logger = _loggerFactory.CreateLogger("Main");

            AppDomain.CurrentDomain.UnhandledException += (sender, e)
                                                          => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");

            // Intercept Ctrl+C and Ctrl+Break
            Console.CancelKeyPress += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }
                e.Cancel = true;
                _logger.LogInformation("Ctrl+C, shutting down");
                Environment.ExitCode = 128 + 2;
                Shutdown();
            };

            // Register a SIGTERM handler
            AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }
                _logger.LogInformation("Received a SIGTERM signal, shutting down");
                Environment.ExitCode = 128 + 15;
                Shutdown();
            };

            _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version);

            EnvironmentInfo environmentInfo = new EnvironmentInfo(GetOperatingSystem());

            ApplicationHost.LogEnvironmentInfo(_logger, appPaths, environmentInfo);

            SQLitePCL.Batteries_V2.Init();

            // Allow all https requests
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); });

            var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, null, appPaths.TempDirectory, true);

            using (var appHost = new CoreAppHost(
                       appPaths,
                       _loggerFactory,
                       options,
                       fileSystem,
                       environmentInfo,
                       new NullImageEncoder(),
                       new NetworkManager(_loggerFactory, environmentInfo)))
            {
                await appHost.Init();

                appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);

                await appHost.RunStartupTasks();

                // TODO: read input for a stop command

                try
                {
                    // Block main thread until shutdown
                    await Task.Delay(-1, _tokenSource.Token);
                }
                catch (TaskCanceledException)
                {
                    // Don't throw on cancellation
                }
            }

            if (_restartOnShutdown)
            {
                StartNewInstance(options);
            }
        }
Exemple #2
0
        private static async Task StartApp(StartupOptions options)
        {
            ServerApplicationPaths appPaths = CreateApplicationPaths(options);

            // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
            Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);

            IConfiguration appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false);

            CreateLogger(appConfig, appPaths);

            _logger = _loggerFactory.CreateLogger("Main");

            AppDomain.CurrentDomain.UnhandledException += (sender, e)
                                                          => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");

            // Intercept Ctrl+C and Ctrl+Break
            Console.CancelKeyPress += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }

                e.Cancel = true;
                _logger.LogInformation("Ctrl+C, shutting down");
                Environment.ExitCode = 128 + 2;
                Shutdown();
            };

            // Register a SIGTERM handler
            AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }

                _logger.LogInformation("Received a SIGTERM signal, shutting down");
                Environment.ExitCode = 128 + 15;
                Shutdown();
            };

            _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version);

            ApplicationHost.LogEnvironmentInfo(_logger, appPaths);

            // Increase the max http request limit
            // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others.
            ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit);

            // Disable the "Expect: 100-Continue" header by default
            // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c
            ServicePointManager.Expect100Continue = false;

// CA5359: Do Not Disable Certificate Validation
#pragma warning disable CA5359

            // Allow all https requests
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); });
#pragma warning restore CA5359

            Batteries_V2.Init();
            if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK)
            {
                _logger.LogWarning("Failed to enable shared cache for SQLite");
            }

            var appHost = new CoreAppHost(
                appPaths,
                _loggerFactory,
                options,
                new ManagedFileSystem(_loggerFactory.CreateLogger <ManagedFileSystem>(), appPaths),
                new NullImageEncoder(),
                new NetworkManager(_loggerFactory.CreateLogger <NetworkManager>()),
                appConfig);
            try
            {
                await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false);

                appHost.ImageProcessor.ImageEncoder = GetImageEncoder(appPaths, appHost.LocalizationManager);

                await appHost.RunStartupTasksAsync().ConfigureAwait(false);

                // Block main thread until shutdown
                await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false);
            }
            catch (TaskCanceledException)
            {
                // Don't throw on cancellation
            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex, "Error while starting server.");
            }
            finally
            {
                appHost?.Dispose();
            }

            if (_restartOnShutdown)
            {
                StartNewInstance(options);
            }
        }
Exemple #3
0
        private static async Task StartApp(StartupOptions options)
        {
            ServerApplicationPaths appPaths = CreateApplicationPaths(options);

            // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
            Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);

            appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false);

            CreateLogger(appConfig, appPaths);

            _logger = _loggerFactory.CreateLogger("Main");

            AppDomain.CurrentDomain.UnhandledException += (sender, e)
                                                          => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");

            // Intercept Ctrl+C and Ctrl+Break
            Console.CancelKeyPress += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }

                e.Cancel = true;
                _logger.LogInformation("Ctrl+C, shutting down");
                Environment.ExitCode = 128 + 2;
                Shutdown();
            };

            // Register a SIGTERM handler
            AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
            {
                if (_tokenSource.IsCancellationRequested)
                {
                    return; // Already shutting down
                }

                _logger.LogInformation("Received a SIGTERM signal, shutting down");
                Environment.ExitCode = 128 + 15;
                Shutdown();
            };

            _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version);

            ApplicationHost.LogEnvironmentInfo(_logger, appPaths);

            SQLitePCL.Batteries_V2.Init();

            // Increase the max http request limit
            // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others.
            ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit);

// CA5359: Do Not Disable Certificate Validation
#pragma warning disable CA5359

            // Allow all https requests
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); });
#pragma warning restore CA5359

            var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths);

            using (var appHost = new CoreAppHost(
                       appPaths,
                       _loggerFactory,
                       options,
                       fileSystem,
                       new NullImageEncoder(),
                       new NetworkManager(_loggerFactory),
                       appConfig))
            {
                await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false);

                appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);

                await appHost.RunStartupTasksAsync().ConfigureAwait(false);

                try
                {
                    // Block main thread until shutdown
                    await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false);
                }
                catch (TaskCanceledException)
                {
                    // Don't throw on cancellation
                }
            }

            if (_restartOnShutdown)
            {
                StartNewInstance(options);
            }
        }
Exemple #4
0
        static void Main()
        {
            ApplicationPath = Assembly.GetEntryAssembly().Location;

            var environmentInfo = GetEnvironmentInfo();

            var appPaths = new ApplicationPaths(GetProgramDataPath(ApplicationPath), ApplicationPath);

            _appPaths = appPaths;

            using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "theater"))
            {
                _logManager = logManager;
                logManager.ReloadLogger(LogSeverity.Debug);
                logManager.AddConsoleOutput();

                var logger = _logger = logManager.GetLogger("Main");

                logger.Info("Application path: {0}", ApplicationPath);

                ApplicationHost.LogEnvironmentInfo(logger, appPaths, true);

                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

                // Mutex credit: https://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567

                // unique id for global mutex - Global prefix means it is global to the machine
                string mutexId = string.Format("Global\\{{{0}}}", "EmbyTheater");

                // Need a place to store a return value in Mutex() constructor call
                bool createdNew;

                // edited by MasonGZhwiti to prevent race condition on security settings via VanNguyen
                using (var mutex = new Mutex(false, mutexId, out createdNew))
                {
                    // edited by acidzombie24
                    var hasHandle = false;
                    try
                    {
                        // note, you may want to time out here instead of waiting forever
                        // edited by acidzombie24
                        hasHandle = mutex.WaitOne(5000, false);
                        if (hasHandle == false)
                        {
                            logger.Info("Exiting because another instance is already running.");
                            return;
                        }
                    }
                    catch (AbandonedMutexException)
                    {
                        // Log the fact that the mutex was abandoned in another process,
                        // it will still get acquired
                        hasHandle = true;
                        logger.Info("Mutex was abandoned in another process.");
                    }

                    using (new MutexHandle(mutex, hasHandle, _logger))
                    {
                        if (PerformUpdateIfNeeded(appPaths, environmentInfo, logger))
                        {
                            logger.Info("Exiting to perform application update.");
                            return;
                        }

                        RunApplication(appPaths, logManager, environmentInfo, new StartupOptions(Environment.GetCommandLineArgs()));
                    }
                }

                logger.Info("Shutdown complete");

                if (_restartOnShutdown)
                {
                    // This is artificial, but add some delay to ensure sockets are released.
                    var delay = environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows
                        ? 5000
                        : 60000;

                    var task = Task.Delay(delay);
                    Task.WaitAll(task);

                    logger.Info("Starting new server process");
                    var restartCommandLine = GetRestartCommandLine();

                    Process.Start(restartCommandLine.Item1, restartCommandLine.Item2);
                }
            }
        }
Exemple #5
0
        public static async Task <int> Main(string[] args)
        {
            StartupOptions options = new StartupOptions(args);
            Version        version = Assembly.GetEntryAssembly().GetName().Version;

            if (options.ContainsOption("-v") || options.ContainsOption("--version"))
            {
                Console.WriteLine(version.ToString());
                return(0);
            }

            ServerApplicationPaths appPaths = createApplicationPaths(options);

            // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
            Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
            await createLogger(appPaths);

            _loggerFactory = new SerilogLoggerFactory();
            _logger        = _loggerFactory.CreateLogger("Main");

            AppDomain.CurrentDomain.UnhandledException += (sender, e)
                                                          => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");

            _logger.LogInformation("Jellyfin version: {Version}", version);

            EnvironmentInfo environmentInfo = new EnvironmentInfo(getOperatingSystem());

            ApplicationHost.LogEnvironmentInfo(_logger, appPaths, environmentInfo);

            SQLitePCL.Batteries_V2.Init();

            // Allow all https requests
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); });

            var fileSystem = new ManagedFileSystem(_loggerFactory.CreateLogger("FileSystem"), environmentInfo, null, appPaths.TempDirectory, true);

            using (var appHost = new CoreAppHost(
                       appPaths,
                       _loggerFactory,
                       options,
                       fileSystem,
                       environmentInfo,
                       new NullImageEncoder(),
                       new SystemEvents(_loggerFactory.CreateLogger("SystemEvents")),
                       new NetworkManager(_loggerFactory.CreateLogger("NetworkManager"), environmentInfo)))
            {
                appHost.Init();

                appHost.ImageProcessor.ImageEncoder = getImageEncoder(_logger, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo, appHost.LocalizationManager);

                _logger.LogInformation("Running startup tasks");

                await appHost.RunStartupTasks();

                // TODO: read input for a stop command
                // Block main thread until shutdown
                await ApplicationTaskCompletionSource.Task;

                _logger.LogInformation("Disposing app host");
            }

            if (_restartOnShutdown)
            {
                StartNewInstance(options);
            }

            return(0);
        }
Exemple #6
0
 /// <summary>
 /// Begins the log.
 /// </summary>
 /// <param name="logger">The logger.</param>
 private static void BeginLog(ILogger logger, IApplicationPaths appPaths)
 {
     logger.Info("Media Browser Server started");
     ApplicationHost.LogEnvironmentInfo(logger, appPaths);
 }