Skip to content

Commit

Permalink
Removed config from Service
Browse files Browse the repository at this point in the history
  • Loading branch information
helto4real committed Dec 20, 2020
1 parent a47b078 commit 920a2c3
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 127 deletions.
2 changes: 1 addition & 1 deletion Docker/rootfs/etc/services.d/NetDaemonApp/finish
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/execlineb -S0
#!/usr/bin/execlineb -S1

if -n { s6-test $# -ne 0 }
if -n { s6-test ${1} -eq 256 }
Expand Down
48 changes: 31 additions & 17 deletions Docker/rootfs/etc/services.d/NetDaemonApp/run
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
#!/usr/bin/with-contenv bash
echo "Starting NetDaemon Runner"

declare runtype="Service.dll"
declare daemondir="/daemon"
declare is_custom_app_source=false
declare is_project=false
declare is_addon=false

if [ ! -d "/data" ]; then
echo -e "\\033[31mMissing mapping to apps, please map '/data' to your apps folder\\033[0m" >&2
exit 1
fi

if [ -f "/data/options.json" ]; then
echo -e "\\033[31m AddOn found!!.\\033[0m" >&2
export NETDAEMON__APPSOURCE=$( jq -r .app_source /data/options.json )
is_addon=true
fi


if [[ "${NETDAEMON__APPSOURCE}" == *.csproj ]] || [[ "${NETDAEMON__APPSOURCE}" == *.dll ]];
then
# make path relative /data if not hardcode
is_custom_app_source=true

if [ -z "${NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE}" ] || [[ "${NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE}" != true ]];
then
echo -e "\\033[33mWarning: you are using a custom daemon, this can potentially be unsecure. Please review your security." \
"To remove this warning, set NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE=false \033[0m" >&2
fi

# make path relative to data folder (/config/netdaemon if addon)
# if the path is a relative path
if [[ "${NETDAEMON__APPSOURCE}" != /* ]];
then
export NETDAEMON__APPSOURCE="/data/${NETDAEMON__APPSOURCE}"
if [[ $is_addon == true ]];
then
export NETDAEMON__APPSOURCE="/config/netdaemon/${NETDAEMON__APPSOURCE}"
else
export NETDAEMON__APPSOURCE="/data/${NETDAEMON__APPSOURCE}"
fi
fi

# The provided application source is ether a project or pre-compiled .Net application
Expand All @@ -31,29 +52,21 @@ then
then
is_project=true
fi

if [ -z "${NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE}" ] || [[ "${NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE}" != true ]];
then
echo -e "\\033[33mWarning: you are using a custom daemon, this can potentially be unsecure. Please review your security." \
"To remove this warning, set NETDAEMON__WARN_IF_CUSTOM_APP_SOURCE=false \033[0m" >&2
fi
is_custom_app_source=true
fi

if [[ $is_custom_app_source == false ]]; then
echo -e "\\033[32mRunning pre-compiled NetDaemon...\\033[0m" >&2
echo -e "\\033[32mRunning standard NetDaemon at ${daemondir}...\\033[0m" >&2
# This is a hack that makes the current behavor backwards compatible
# if there is a "apps" folder use that or any kind of project
# structure will mess it up
dir "/data"
if [ -d "/data/apps" ];
if [[ $is_addon == false ]] && [ -d "/data/apps" ];
then
export NETDAEMON__APPSOURCE="/data/apps"
echo -e "\\033[32mFound apps folder, using ${NETDAEMON__APPSOURCE}...\\033[0m" >&2
fi

cd "${daemondir}"
dotnet Service.dll
exec dotnet Service.dll
else
# We allow for custom projects and solutions to be used
echo -e "\\033[32mRun the custom daemon at ${NETDAEMON__APPSOURCE}..\\033[0m" >&2
Expand All @@ -67,11 +80,12 @@ else
if [[ $is_project == true ]];
then
echo -e "\\033[32mPlease wait while restore, compile and run custom project...\\033[0m" >&2
dotnet run -v m -c Release -p "$(basename "${NETDAEMON__APPSOURCE}")"
project="$(basename "${NETDAEMON__APPSOURCE}")"
exec dotnet run -v m -c Release -p $project
else
echo -e "\\033[32m Running custom pre-compiled daemon...\\033[0m" >&2

dotnet "$(basename "${NETDAEMON__APPSOURCE}")"
runme="$(basename "${NETDAEMON__APPSOURCE}")"
exec dotnet $runme
fi
fi

2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ FROM mcr.microsoft.com/dotnet/sdk:5.0.100
RUN apt update && apt install -y \
nodejs \
yarn \
jq \
make

COPY ./Docker/rootfs/etc /etc
Expand All @@ -49,6 +50,7 @@ COPY --from=netbuilder /daemon /daemon

# Set default values of NetDaemon env
ENV \
S6_KEEP_ENV=1 \
DOTNET_NOLOGO=true \
DOTNET_CLI_TELEMETRY_OPTOUT=true \
HASSCLIENT_MSGLOGLEVEL=Default \
Expand Down
2 changes: 2 additions & 0 deletions src/DaemonRunner/DaemonRunner/DaemonRunner.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0-dev-00839" />
<PackageReference Include="YamlDotNet" Version="9.1.0" />
</ItemGroup>

Expand Down
64 changes: 64 additions & 0 deletions src/DaemonRunner/DaemonRunner/NetDaemonExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NetDaemon.Common.Configuration;
using NetDaemon.Daemon.Config;
using NetDaemon.Service;
using NetDaemon.Service.App;
using NetDaemon.Service.Infrastructure;
using Serilog;
using Service.Infrastructure;

namespace NetDaemon
{
public static class NetDaemonExtensions
{
const string HassioConfigPath = "/data/options.json";
public static IHostBuilder UseNetDaemon(this IHostBuilder hostBuilder)
{
if (File.Exists(HassioConfigPath))
ReadHassioConfig();

return hostBuilder
.ConfigureServices((context, services) =>
{
Expand All @@ -30,6 +40,21 @@ public static IHostBuilder UseNetDaemon(this IHostBuilder hostBuilder)
});
}

public static IHostBuilder UseDefaultNetDaemonLogging(this IHostBuilder hostBuilder)
{
return hostBuilder
.ConfigureWebHostDefaults(webbuilder =>
{
Log.Logger = SerilogConfigurator.Configure().CreateLogger();
webbuilder.UseSerilog(Log.Logger);
});
}

public static void CleanupNetDaemon()
{
Log.CloseAndFlush();
}

private static void RegisterNetDaemonAssembly(IServiceCollection services)
{
if (!BypassLocalAssemblyLoading())
Expand All @@ -54,5 +79,44 @@ private static bool BypassLocalAssemblyLoading()
else
return true;
}

/// <summary>
/// Reads the Home Assistant (hassio) configuration file
/// </summary>
/// <returns></returns>
static void ReadHassioConfig()
{
try
{
var hassAddOnSettings = JsonSerializer.Deserialize<HassioConfig>(File.ReadAllBytes(HassioConfigPath));

if (hassAddOnSettings?.LogLevel is not null)
SerilogConfigurator.SetMinimumLogLevel(hassAddOnSettings.LogLevel);

if (hassAddOnSettings?.GenerateEntitiesOnStart is not null)
Environment.SetEnvironmentVariable("NETDAEMON__GENERATEENTITIES", hassAddOnSettings.GenerateEntitiesOnStart.ToString());

if (hassAddOnSettings?.LogMessages is not null && hassAddOnSettings.LogMessages == true)
Environment.SetEnvironmentVariable("HASSCLIENT_MSGLOGLEVEL", "Default");

_ = hassAddOnSettings?.AppSource ??
throw new NullReferenceException("AppSource cannot be null");

if (hassAddOnSettings.AppSource.StartsWith("/") || hassAddOnSettings.AppSource[1] == ':')
{
// Hard codede path
Environment.SetEnvironmentVariable("NETDAEMON__APPSOURCE", hassAddOnSettings.AppSource);
}
else
{
// We are in Hassio so hard code the path
Environment.SetEnvironmentVariable("NETDAEMON__APPSOURCE", Path.Combine("/config/netdaemon", hassAddOnSettings.AppSource));
}
}
catch (Exception e)
{
Log.Fatal(e, "Failed to read the Home Assistant Add-on config");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;

namespace Service
namespace Service.Infrastructure
{
public class HassioConfig
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System.IO;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;

namespace NetDaemon.Service.Infrastructure
{
internal class NetDaemonTheme : Serilog.Sinks.SystemConsole.Themes.ConsoleTheme
{
public override bool CanBuffer => false;

protected override int ResetCharCount => 0;

public override bool Equals(object? obj)
{
return base.Equals(obj);
}

public override int GetHashCode()
{
return base.GetHashCode();
}

public override void Reset(TextWriter output)
{
output.Write("\u001b[0m");
}

public override int Set(TextWriter output, ConsoleThemeStyle style)
{
string? x = style switch
{
ConsoleThemeStyle.LevelError => "\u001b[0;31m",
ConsoleThemeStyle.Name => "\u001b[1;34m",
ConsoleThemeStyle.LevelInformation => "\u001b[0;36m",
ConsoleThemeStyle.LevelWarning => "\u001b[1;33m",
ConsoleThemeStyle.LevelFatal => "\u001b[0;31m",
ConsoleThemeStyle.LevelDebug => "\u001b[0;37m",
ConsoleThemeStyle.Scalar => "\u001b[1;34m",
ConsoleThemeStyle.String => "\u001b[0;36m",
_ => null
};

if (x is not null)
{
output.Write(x);
return x.Length;
}
return 0;
}

public override string? ToString()
{
return base.ToString();
}
}

public static class SerilogConfigurator
{
private static readonly LoggingLevelSwitch LevelSwitch = new LoggingLevelSwitch();

public static LoggerConfiguration Configure()
{
var minimumLevel = GetMinimumLogLevel();

SetMinimumLogLevel(minimumLevel);

return new LoggerConfiguration()
.MinimumLevel.ControlledBy(LevelSwitch)
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.Enrich.FromLogContext()
.WriteTo.Console(theme: new NetDaemonTheme(), applyThemeToRedirectedOutput: true);
}

private static string GetMinimumLogLevel()
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();

var logValue = configuration.GetSection("Logging")["MinimumLevel"];

return string.IsNullOrEmpty(logValue) ? "info" : logValue;
}

public static void SetMinimumLogLevel(string level)
{
LevelSwitch.MinimumLevel = level.ToLower() switch
{
"info" => LogEventLevel.Information,
"debug" => LogEventLevel.Debug,
"error" => LogEventLevel.Error,
"warning" => LogEventLevel.Warning,
"trace" => LogEventLevel.Verbose,
_ => LogEventLevel.Information
};
}

}
}
Loading

0 comments on commit 920a2c3

Please sign in to comment.