Application: Allowing the app to be restarted

This commit is contained in:
Zoe Roux 2021-08-23 21:09:49 +02:00
parent d5e1d4f003
commit 4daa1eb28d
15 changed files with 322 additions and 239 deletions

View File

@ -107,25 +107,22 @@ jobs:
- name: Create the package structure
run: |
sudo mkdir -p pkg/usr/lib/
sudo mkdir -p pkg/DEBIAN
sudo cp -r --no-preserve ownership dist pkg/usr/lib/kyoo
sudo install -Dm 644 deployment/kyoo.service -t pkg/usr/lib/systemd/system/
sudo install -Dm 644 deployment/kyoo.sysusers pkg/usr/lib/sysusers.d/kyoo.conf
sudo install -Dm 644 deployment/kyoo.tmpfiles pkg/usr/lib/tmpfiles.d/kyoo.conf
sudo install -Dm 755 deployment/postinst -t pkg/DEBIAN/
- uses: jiro4989/build-deb-action@v2
with:
package: kyoo
package_root: pkg
maintainer: Zoe Roux <zoe.roux@sdg.moe>
version: ${{env.version}}
depends: "postgresql, libavutil-dev, libavcodec-dev, libavformat-dev"
depends: "libavutil-dev, libavcodec-dev, libavformat-dev"
arch: amd64
desc: ${{env.description}}
- name: Build rpm package
run: |
mkdir out
sudo rm -rf pkg/DEBIAN
rpmbuild -bb --buildroot $(pwd)/out --build-in-place --define "_rpmdir $(pwd)/rpm" deployment/kyoo.spec
- name: Prepare arch package
run: |

View File

@ -0,0 +1,24 @@
namespace Kyoo.Abstractions.Controllers
{
/// <summary>
/// An interface that allow one to interact with the host and shutdown or restart the app.
/// </summary>
public interface IApplication
{
/// <summary>
/// Shutdown the process and stop gracefully.
/// </summary>
void Shutdown();
/// <summary>
/// Restart Kyoo from scratch, reload plugins, configurations and restart the web server.
/// </summary>
void Restart();
/// <summary>
/// Get the data directory
/// </summary>
/// <returns>Retrieve the data directory where runtime data should be stored</returns>
string GetDataDirectory();
}
}

View File

@ -17,4 +17,5 @@
<Target Name="Clean" />
<Target Name="Pack" />
<Target Name="Restore" />
<Target Name="Publish" />
</Project>

View File

@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../Kyoo/Kyoo.csproj"/>
<ProjectReference Include="../Kyoo/Kyoo.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
using Autofac;
using Microsoft.Extensions.Hosting;
using Microsoft.Win32;
namespace Kyoo.WindowsHost
{
@ -13,22 +10,13 @@ namespace Kyoo.WindowsHost
/// It adds a system trait for windows and since the host is build as a windows executable instead of a console
/// app, the console is not showed.
/// </summary>
public static async Task Main(string[] args)
public static Task Main(string[] args)
{
object dataDir = Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\SDG\Kyoo\Settings", "DataDir", null)
?? Registry.GetValue(@"HKEY_CURRENT_USER\Software\SDG\Kyoo\Settings", "DataDir", null);
if (dataDir is string data)
Environment.SetEnvironmentVariable("KYOO_DATA_DIR", data);
Kyoo.Program.SetupDataDir(args);
IHost host = Kyoo.Program.CreateWebHostBuilder(args)
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterType<SystemTrait>().As<IStartable>().SingleInstance();
})
.Build();
await Kyoo.Program.StartWithHost(host);
Application application = new();
return application.Start(args, builder =>
{
builder.RegisterType<SystemTrait>().As<IStartable>().SingleInstance();
});
}
}
}

View File

@ -5,6 +5,7 @@ using System.IO;
using System.Threading;
using System.Windows.Forms;
using Autofac;
using Kyoo.Abstractions.Controllers;
using Kyoo.Models.Options;
using Microsoft.Extensions.Options;
@ -15,6 +16,11 @@ namespace Kyoo.WindowsHost
/// </summary>
public sealed class SystemTrait : IStartable, IDisposable
{
/// <summary>
/// The application running Kyoo.
/// </summary>
private readonly IApplication _application;
/// <summary>
/// The options containing the <see cref="BasicOptions.PublicUrl"/>.
/// </summary>
@ -29,16 +35,18 @@ namespace Kyoo.WindowsHost
/// <summary>
/// Create a new <see cref="SystemTrait"/>.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The options to use.</param>
public SystemTrait(IOptions<BasicOptions> options)
public SystemTrait(IApplication application, IOptions<BasicOptions> options)
{
_application = application;
_options = options;
}
/// <inheritdoc />
public void Start()
{
_thread = new Thread(() => InternalSystemTrait.Run(_options))
_thread = new Thread(() => InternalSystemTrait.Run(_application, _options))
{
IsBackground = true
};
@ -48,8 +56,7 @@ namespace Kyoo.WindowsHost
/// <inheritdoc />
public void Dispose()
{
// TODO not sure that the trait is ended and that it does shutdown but the only way to shutdown the
// app anyway is via the Trait's Exit or a Signal so it's fine.
System.Windows.Forms.Application.Exit();
_thread?.Join();
_thread = null;
}
@ -61,6 +68,11 @@ namespace Kyoo.WindowsHost
private class InternalSystemTrait : ApplicationContext
{
/// <summary>
/// The application running Kyoo.
/// </summary>
private readonly IApplication _application;
/// <summary>
/// The options containing the <see cref="BasicOptions.PublicUrl"/>.
/// </summary>
private readonly IOptions<BasicOptions> _options;
@ -73,13 +85,15 @@ namespace Kyoo.WindowsHost
/// <summary>
/// Create a new <see cref="InternalSystemTrait"/>. Used only by <see cref="Run"/>.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The option containing the public url.</param>
private InternalSystemTrait(IOptions<BasicOptions> options)
private InternalSystemTrait(IApplication application, IOptions<BasicOptions> options)
{
_application = application;
_options = options;
AppDomain.CurrentDomain.ProcessExit += (_, _) => Dispose();
Application.ApplicationExit += (_, _) => Dispose();
System.Windows.Forms.Application.ApplicationExit += (_, _) => Dispose();
_icon = new NotifyIcon();
_icon.Text = "Kyoo";
@ -96,20 +110,21 @@ namespace Kyoo.WindowsHost
_icon.ContextMenuStrip.Items.AddRange(new ToolStripItem[]
{
new ToolStripMenuItem("Open browser", null, (_, _) => { _StartBrowser(); }),
new ToolStripMenuItem("Open logs", null, (_, _) => { Process.Start("explorer.exe", Environment.CurrentDirectory); }),
new ToolStripMenuItem("Open logs", null, (_, _) => { _OpenLogs(); }),
new ToolStripSeparator(),
new ToolStripMenuItem("Exit", null, (_, _) => { Environment.Exit(0); })
new ToolStripMenuItem("Exit", null, (_, _) => { _application.Shutdown(); })
});
}
/// <summary>
/// Run the trait in the current thread, this method does not return while the trait is running.
/// </summary>
/// <param name="application">The application running Kyoo.</param>
/// <param name="options">The options to pass to <see cref="InternalSystemTrait"/>.</param>
public static void Run(IOptions<BasicOptions> options)
public static void Run(IApplication application, IOptions<BasicOptions> options)
{
using InternalSystemTrait trait = new(options);
Application.Run(trait);
using InternalSystemTrait trait = new(application, options);
System.Windows.Forms.Application.Run(trait);
}
/// <inheritdoc />
@ -134,6 +149,15 @@ namespace Kyoo.WindowsHost
};
browser.Start();
}
/// <summary>
/// Open the log directory in windows's explorer.
/// </summary>
private void _OpenLogs()
{
string logDir = Path.Combine(_application.GetDataDirectory(), "logs");
Process.Start("explorer.exe", logDir);
}
}
}
}

244
Kyoo/Application.cs Normal file
View File

@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using JetBrains.Annotations;
using Kyoo.Abstractions.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Win32;
using Serilog;
using Serilog.Templates;
using Serilog.Templates.Themes;
using ILogger = Serilog.ILogger;
namespace Kyoo
{
public class Application : IApplication
{
/// <summary>
/// The path to the data directory.
/// </summary>
private string _dataDir;
/// <summary>
/// Should the application restart after a shutdown?
/// </summary>
private bool _shouldRestart;
/// <summary>
/// The cancellation token source used to allow the app to be shutdown or restarted.
/// </summary>
private CancellationTokenSource _tokenSource;
/// <summary>
/// Start the application with the given console args.
/// This is generally called from the Main entrypoint of Kyoo.
/// </summary>
/// <param name="args">The console arguments to use for kyoo.</param>
/// <returns>A task representing the whole process</returns>
public Task Start(string[] args)
{
return Start(args, _ => { });
}
/// <summary>
/// Start the application with the given console args.
/// This is generally called from the Main entrypoint of Kyoo.
/// </summary>
/// <param name="args">The console arguments to use for kyoo.</param>
/// <param name="configure">A custom action to configure the container before the start</param>
/// <returns>A task representing the whole process</returns>
public async Task Start(string[] args, Action<ContainerBuilder> configure)
{
_dataDir = _SetupDataDir(args);
LoggerConfiguration config = new();
_ConfigureLogging(config, null);
Log.Logger = config.CreateBootstrapLogger()
.ForContext<Application>();
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
AppDomain.CurrentDomain.UnhandledException += (_, ex)
=> Log.Fatal(ex.ExceptionObject as Exception, "Unhandled exception");
do
{
IHost host = _CreateWebHostBuilder(args)
.ConfigureContainer(configure)
.Build();
Log.Logger = host.Services.GetRequiredService<ILogger>().ForContext<Application>();
_tokenSource = new CancellationTokenSource();
await _StartWithHost(host, _tokenSource.Token);
}
while (_shouldRestart);
}
/// <inheritdoc />
public void Shutdown()
{
_shouldRestart = false;
_tokenSource.Cancel();
}
/// <inheritdoc />
public void Restart()
{
_shouldRestart = true;
_tokenSource.Cancel();
}
/// <inheritdoc />
public string GetDataDirectory()
{
return _dataDir;
}
/// <summary>
/// Parse the data directory from environment variables and command line arguments, create it if necessary.
/// Set the current directory to said data folder and place a default configuration file if it does not already
/// exists.
/// </summary>
/// <param name="args">The command line arguments</param>
/// <returns>The current data directory.</returns>
private static string _SetupDataDir(string[] args)
{
Dictionary<string, string> registry = new();
if (OperatingSystem.IsWindows())
{
object dataDir = Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\SDG\Kyoo\Settings", "DataDir", null)
?? Registry.GetValue(@"HKEY_CURRENT_USER\Software\SDG\Kyoo\Settings", "DataDir", null);
if (dataDir is string data)
registry.Add("DataDir", data);
}
IConfiguration parsed = new ConfigurationBuilder()
.AddInMemoryCollection(registry)
.AddEnvironmentVariables()
.AddEnvironmentVariables("KYOO_")
.AddCommandLine(args)
.Build();
string path = parsed.GetValue<string>("datadir")
?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Kyoo");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Environment.CurrentDirectory = path;
if (!File.Exists(Program.JsonConfigPath))
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, Program.JsonConfigPath),
Program.JsonConfigPath);
return path;
}
/// <summary>
/// Start the given host and log failing exceptions.
/// </summary>
/// <param name="host">The host to start.</param>
/// <param name="cancellationToken">A token to allow one to stop the host.</param>
private async Task _StartWithHost(IHost host, CancellationToken cancellationToken)
{
try
{
Log.Information("Running as {Name}", Environment.UserName);
Log.Information("Data directory: {DataDirectory}", GetDataDirectory());
await host.RunAsync(cancellationToken);
}
catch (Exception ex)
{
Log.Fatal(ex, "Unhandled exception");
}
}
/// <summary>
/// Create a a web host
/// </summary>
/// <param name="args">Command line parameters that can be handled by kestrel</param>
/// <returns>A new web host instance</returns>
private IHostBuilder _CreateWebHostBuilder(string[] args)
{
IConfiguration configuration = _SetupConfig(new ConfigurationBuilder(), args).Build();
return new HostBuilder()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
.UseEnvironment(Program.Environment)
.ConfigureAppConfiguration(x => _SetupConfig(x, args))
.UseSerilog((host, builder) => _ConfigureLogging(builder, host.Configuration))
.ConfigureServices(x => x.AddRouting())
.ConfigureContainer<ContainerBuilder>(x =>
{
x.RegisterInstance(this).As<IApplication>().SingleInstance().ExternallyOwned();
})
.ConfigureWebHost(x => x
.UseKestrel(options => { options.AddServerHeader = false; })
.UseIIS()
.UseIISIntegration()
.UseUrls(configuration.GetValue<string>("basics:url"))
.UseStartup(host => PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog()))
);
}
/// <summary>
/// Register settings.json, environment variables and command lines arguments as configuration.
/// </summary>
/// <param name="builder">The configuration builder to use</param>
/// <param name="args">The command line arguments</param>
/// <returns>The modified configuration builder</returns>
private IConfigurationBuilder _SetupConfig(IConfigurationBuilder builder, string[] args)
{
return builder.SetBasePath(GetDataDirectory())
.AddJsonFile(Path.Join(AppDomain.CurrentDomain.BaseDirectory, Program.JsonConfigPath), false, true)
.AddJsonFile(Program.JsonConfigPath, false, true)
.AddEnvironmentVariables()
.AddEnvironmentVariables("KYOO_")
.AddCommandLine(args);
}
/// <summary>
/// Configure the logging.
/// </summary>
/// <param name="builder">The logger builder to configure.</param>
/// <param name="configuration">The configuration to read settings from.</param>
private void _ConfigureLogging(LoggerConfiguration builder, [CanBeNull] IConfiguration configuration)
{
if (configuration != null)
{
try
{
builder.ReadFrom.Configuration(configuration, "logging");
}
catch (Exception ex)
{
Log.Fatal(ex, "Could not read serilog configuration");
}
}
const string template =
"[{@t:HH:mm:ss} {@l:u3} {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), 15} "
+ "({@i:0000000000})] {@m}{#if not EndsWith(@m, '\n')}\n{#end}{@x}";
builder
.WriteTo.Console(new ExpressionTemplate(template, theme: TemplateTheme.Code))
.WriteTo.Debug()
.WriteTo.File(
path: Path.Combine(GetDataDirectory(), "logs", "log-.log"),
formatter: new ExpressionTemplate(template),
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true
)
.Enrich.WithThreadId()
.Enrich.FromLogContext();
}
}
}

View File

@ -21,10 +21,6 @@
<TranscoderBinary Condition="$(IsWindows) == true">transcoder.dll</TranscoderBinary>
<TranscoderBinary Condition="$(IsOSX) == true">libtranscoder.dylib</TranscoderBinary>
<TranscoderBinary Condition="$(IsLinux) == true">libtranscoder.so</TranscoderBinary>
<TranscoderBuild Condition="$(IsWindows) == true">$(TranscoderRoot)buildWin</TranscoderBuild>
<TranscoderBuild Condition="$(IsOSX) == true">$(TranscoderRoot)buildOSX</TranscoderBuild>
<TranscoderBuild Condition="$(IsLinux) == true">$(TranscoderRoot)build</TranscoderBuild>
</PropertyGroup>
<ItemGroup>
@ -52,7 +48,7 @@
<ProjectReference Include="../Kyoo.WebApp/Kyoo.WebApp.csproj" />
</ItemGroup>
<Target Name="BuildTranscoder" BeforeTargets="BeforeBuild" Condition="'$(SkipTranscoder)' != 'true' And !Exists('$(TranscoderBuild)/$(TranscoderBinary)')">
<Target Name="BuildTranscoder" BeforeTargets="BeforeBuild" Condition="'$(SkipTranscoder)' != 'true' And !Exists('$(TranscoderRoot)/build/$(TranscoderBinary)')">
<Exec Command="mkdir -p build %26%26 cd build %26%26 cmake .. %26%26 make -j" WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' != 'true'" />
<Exec Command="(if not exist build mkdir build) %26%26 cd build %26%26 cmake .. -G &quot;NMake Makefiles&quot; %26%26 nmake" WorkingDirectory="$(TranscoderRoot)" Condition="'$(IsWindows)' == 'true'" />
</Target>

View File

@ -1,17 +1,5 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Templates;
using Serilog.Templates.Themes;
using SEnvironment = System.Environment;
namespace Kyoo
{
@ -29,158 +17,19 @@ namespace Kyoo
/// The string representation of the environment used in <see cref="IWebHostEnvironment"/>.
/// </summary>
#if DEBUG
private const string Environment = "Development";
public const string Environment = "Development";
#else
private const string Environment = "Production";
public const string Environment = "Production";
#endif
/// <summary>
/// Initialize the bootstrap logger to use it anywhere. This is done here so it is called before any method,
/// even if the <see cref="Main"/> is not used and this binary is used as a dll.
/// </summary>
static Program()
{
LoggerConfiguration config = new();
_ConfigureLogging(null, config);
Log.Logger = config.CreateBootstrapLogger().ForContext<Application>();
AppDomain.CurrentDomain.ProcessExit += (_, _) => Log.CloseAndFlush();
}
/// <summary>
/// Main function of the program
/// </summary>
/// <param name="args">Command line arguments</param>
public static Task Main(string[] args)
{
SetupDataDir(args);
return StartWithHost(CreateWebHostBuilder(args).Build());
}
/// <summary>
/// Start the given host and log failing exceptions.
/// </summary>
/// <param name="host">The host to start.</param>
public static async Task StartWithHost(IHost host)
{
try
{
Log.Information("Running as {Name}", System.Environment.UserName);
Log.Information("Data directory: {DataDirectory}", System.Environment.CurrentDirectory);
await host.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Unhandled exception");
}
}
/// <summary>
/// Register settings.json, environment variables and command lines arguments as configuration.
/// </summary>
/// <param name="builder">The configuration builder to use</param>
/// <param name="args">The command line arguments</param>
/// <returns>The modified configuration builder</returns>
private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args)
{
return builder.SetBasePath(System.Environment.CurrentDirectory)
.AddJsonFile(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), false, true)
.AddJsonFile(JsonConfigPath, false, true)
.AddEnvironmentVariables()
.AddEnvironmentVariables("KYOO_")
.AddCommandLine(args);
}
/// <summary>
/// Configure the logging.
/// </summary>
/// <param name="context">The host context that contains the configuration</param>
/// <param name="builder">The logger builder to configure.</param>
private static void _ConfigureLogging([CanBeNull] HostBuilderContext context, LoggerConfiguration builder)
{
if (context != null)
{
try
{
builder.ReadFrom.Configuration(context.Configuration, "logging");
}
catch (Exception ex)
{
Log.Fatal(ex, "Could not read serilog configuration");
}
}
const string template =
"[{@t:HH:mm:ss} {@l:u3} {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), 15} "
+ "({@i:0000000000})] {@m}{#if not EndsWith(@m, '\n')}\n{#end}{@x}";
builder
.WriteTo.Console(new ExpressionTemplate(template, theme: TemplateTheme.Code))
.WriteTo.Debug()
.WriteTo.File(
path: "logs/log-.log",
formatter: new ExpressionTemplate(template),
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true
)
.Enrich.WithThreadId()
.Enrich.FromLogContext();
}
/// <summary>
/// Create a a web host
/// </summary>
/// <param name="args">Command line parameters that can be handled by kestrel</param>
/// <returns>A new web host instance</returns>
public static IHostBuilder CreateWebHostBuilder(string[] args)
{
IConfiguration configuration = SetupConfig(new ConfigurationBuilder(), args).Build();
return new HostBuilder()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
.UseEnvironment(Environment)
.ConfigureAppConfiguration(x => SetupConfig(x, args))
.UseSerilog(_ConfigureLogging)
.ConfigureServices(x => x.AddRouting())
.ConfigureWebHost(x => x
.UseKestrel(options => { options.AddServerHeader = false; })
.UseIIS()
.UseIISIntegration()
.UseUrls(configuration.GetValue<string>("basics:url"))
.UseStartup(host => PluginsStartup.FromWebHost(host, new LoggerFactory().AddSerilog()))
);
}
/// <summary>
/// Parse the data directory from environment variables and command line arguments, create it if necessary.
/// Set the current directory to said data folder and place a default configuration file if it does not already
/// exists.
/// </summary>
/// <param name="args">The command line arguments</param>
public static void SetupDataDir(string[] args)
{
IConfiguration parsed = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddEnvironmentVariables("KYOO_")
.AddCommandLine(args)
.Build();
string path = parsed.GetValue<string>("data_dir");
if (path == null)
path = Path.Combine(SEnvironment.GetFolderPath(SEnvironment.SpecialFolder.LocalApplicationData), "Kyoo");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
SEnvironment.CurrentDirectory = path;
if (!File.Exists(JsonConfigPath))
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath);
Application application = new();
return application.Start(args);
}
}
/// <summary>
/// An useless class only used to have a logger in the main.
/// </summary>
internal class Application {}
}

View File

@ -8,7 +8,7 @@ arch=("i686" "x86_64" "armv6h")
url="https://github.com/AnonymusRaccoon/Kyoo"
license=("GPLv3")
groups=()
depends=("dotnet-runtime>=5" "aspnet-runtime>=5" "postgresql" "ffmpeg")
depends=("dotnet-runtime>=5" "aspnet-runtime>=5" "ffmpeg")
makedepends=("dotnet-sdk>=5" "cmake" "gcc" "make" "npm" "git")
install="kyoo.install"
source=("git+https://github.com/AnonymusRaccoon/Kyoo" #tag=v${pkgver}
@ -30,7 +30,7 @@ build() {
# cd "Kyoo-$pkgver"
cd "Kyoo"
export DOTNET_CLI_TELEMETRY_OPTOUT=1
dotnet publish -c Release -o "$srcdir/output" Kyoo
dotnet publish -c Release -o "$srcdir/output" Kyoo
}
package() {

View File

@ -8,7 +8,7 @@ arch=("i686" "x86_64" "armv6h")
url="https://github.com/AnonymusRaccoon/Kyoo"
license=("GPLv3")
groups=()
depends=("postgresql" "ffmpeg")
depends=("ffmpeg")
makedepends=()
install="kyoo.install"
# The output folder is needed but we can't use directory in the source array.

View File

@ -1,11 +0,0 @@
post_install() {
sudo -u postgres psql <<- "EOF"
DO $$
BEGIN
CREATE ROLE kyoo WITH CREATEDB LOGIN PASSWORD 'kyooPassword';
EXCEPTION WHEN DUPLICATE_OBJECT THEN
RAISE NOTICE 'not creating role kyoo -- it already exists';
END
$$;
EOF
}

View File

@ -5,7 +5,7 @@ After=network.target
[Service]
User=kyoo
Environment=KYOO_DATA_DIR=/var/lib/kyoo
Environment=KYOO_DATADIR=/var/lib/kyoo
ExecStart=/usr/lib/kyoo/Kyoo
Restart=on-abort
TimeoutSec=20

View File

@ -7,7 +7,7 @@ Summary: A media browser
URL: https://github.com/AnonymusRaccoon/Kyoo
License: GPL-3.0
BuildArch: x86_64
Requires: postgresql-server ffmpeg-devel
Requires: ffmpeg-devel
AutoReqProv: no
%description
@ -24,17 +24,3 @@ rm -rf %{buildroot}
/usr/lib/systemd/system/*
/usr/lib/sysusers.d/kyoo.conf
/usr/lib/tmpfiles.d/kyoo.conf
%post
sudo postgresql-setup --initdb 2> /dev/null || true
sudo systemctl start postgresql
sudo -u postgres psql << "EOF"
DO $$
BEGIN
CREATE ROLE kyoo WITH CREATEDB LOGIN PASSWORD 'kyooPassword';
EXCEPTION WHEN DUPLICATE_OBJECT THEN
RAISE NOTICE 'not creating role kyoo -- it already exists';
END
$$;
EOF

View File

@ -1,15 +0,0 @@
#!/bin/sh
set -e
sudo -u postgres psql << "EOF"
DO $$
BEGIN
CREATE ROLE kyoo WITH CREATEDB LOGIN PASSWORD 'kyooPassword';
EXCEPTION WHEN DUPLICATE_OBJECT THEN
RAISE NOTICE 'not creating role kyoo -- it already exists';
END
$$;
EOF
systemd-sysusers
systemd-tmpfiles --create