Update to .NET Core 3.0 (#6151)

* Update to .NET Core 3.0

Updated Jackett so that it runs on .NET Core 3.0 now

.NET Core 3.0 brings the following benefits https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0/
One of the benefits is the ability to create single file executables. I haven't enabled this yet, but its only a one line change to turn it on (would likely also require some changes to the updater).

This means that builds for LinuxAMDx64, LinuxARM32, LinuxARM64 and macOS will now run on .NET Core 3.0 instead of 2.2. Windows and Mono remain on full framework. Once .NET Core 3.1 is released (November) I'll look to moving Windows over to .NET Core as well

Tested on
-Windows 10 x64
-Debian running Jackett with Mono
-Debian running Jackett standalone (.NET Core)
This commit is contained in:
junglebus 2019-10-15 04:51:33 +11:00 committed by garfield69
parent 6151cc6e8b
commit 64abc61893
12 changed files with 189 additions and 80 deletions

View File

@ -610,7 +610,7 @@ All contributions are welcome just send a pull request.
* Install the .NET Core [SDK](https://www.microsoft.com/net/download/windows)
* Clone Jackett
* Open Powershell and from the `src` directory, run `dotnet restore`
* Open the Jackett solution in Visual Studio 2017 (version 15.9 or above)
* Open the Jackett solution in Visual Studio 2019 (version 16.3 or above)
* Right click on the Jackett solution and click 'Rebuild Solution' to restore nuget packages
* Select Jackett.Server as startup project
* In the drop down menu of the run button select "Jackett.Server" instead of "IIS Express"
@ -627,21 +627,21 @@ git clone https://github.com/Jackett/Jackett.git
cd Jackett/src
# dotnet core version
dotnet publish Jackett.Server -f netcoreapp2.2 --self-contained -r osx-x64 -c Debug # takes care of everything
./Jackett.Server/bin/Debug/netcoreapp2.2/osx-x64/jackett # run jackett
dotnet publish Jackett.Server -f netcoreapp3.0 --self-contained -r osx-x64 -c Debug # takes care of everything
./Jackett.Server/bin/Debug/netcoreapp3.0/osx-x64/jackett # run jackett
```
### Linux
```bash
sudo apt install mono-complete nuget msbuild dotnet-sdk-2.2 # install build tools (debian/ubuntu)
sudo apt install mono-complete nuget msbuild dotnet-sdk-3.0 # install build tools (debian/ubuntu)
git clone https://github.com/Jackett/Jackett.git
cd Jackett/src
# dotnet core version
dotnet publish Jackett.Server -f netcoreapp2.2 --self-contained -r linux-x64 -c Debug # takes care of everything
./Jackett.Server/bin/Debug/netcoreapp2.2/linux-x64/jackett # run jackett
dotnet publish Jackett.Server -f netcoreapp3.0 --self-contained -r linux-x64 -c Debug # takes care of everything
./Jackett.Server/bin/Debug/netcoreapp3.0/linux-x64/jackett # run jackett
```
## Screenshots

View File

@ -1,15 +1,11 @@
version: 0.11.{build}
version: 0.12.{build}
skip_tags: true
image:
- Ubuntu
- Visual Studio 2017
- Visual Studio 2019
environment:
APPVEYOR_YML_DISABLE_PS_LINUX: true
configuration: Release
install:
#Remove once .NET Core 2.2.5 is deployed to Appveyor
- sh: sudo apt-get update
- sh: sudo apt-get -y install dotnet-sdk-2.2
assembly_info:
patch: true
file: '**\AssemblyInfo.*'

View File

@ -16,7 +16,7 @@ var configuration = Argument("configuration", "Debug");
var workingDir = MakeAbsolute(Directory("./"));
string artifactsDirName = "Artifacts";
string testResultsDirName = "TestResults";
string netCoreFramework = "netcoreapp2.2";
string netCoreFramework = "netcoreapp3.0";
string serverProjectPath = "./src/Jackett.Server/Jackett.Server.csproj";
string updaterProjectPath = "./src/Jackett.Updater/Jackett.Updater.csproj";
@ -28,7 +28,7 @@ Task("Info")
.Does(() =>
{
Information(@"Jackett Cake build script starting...");
Information(@"Requires InnoSetup and C:\cygwin to be present for packaging (Pre-installed on AppVeyor) on Windows");
Information(@"Requires InnoSetup and C:\msys64 to be present for packaging (Pre-installed on AppVeyor) on Windows");
Information(@"Working directory is: " + workingDir);
if (IsRunningOnWindows())
@ -64,7 +64,7 @@ Task("Build-Full-Framework")
var buildSettings = new MSBuildSettings()
.SetConfiguration(configuration)
.UseToolVersion(MSBuildToolVersion.VS2017);
.UseToolVersion(MSBuildToolVersion.VS2019);
MSBuild("./src/Jackett.sln", buildSettings);
});
@ -106,6 +106,8 @@ Task("Package-Windows-Full-Framework")
InnoSetupSettings settings = new InnoSetupSettings();
settings.OutputDirectory = workingDir + "/" + artifactsDirName;
//Can remove below line once Cake is updated for InnoSetup 6 - https://github.com/cake-build/cake/pull/2565
settings.ToolPath = @"C:\Program Files (x86)\Inno Setup 6\ISCC.exe";
settings.Defines = new Dictionary<string, string>
{
{ "MyFileForVersion", sourceFolder + "/Jackett.Common.dll" },
@ -145,6 +147,7 @@ Task("Package-Mono-Full-Framework")
DeleteFile(buildOutputPath + "/System.Runtime.InteropServices.RuntimeInformation.dll");
InstallMsysTar();
Gzip("./BuildOutput/net461/linux-x64", $"./{artifactsDirName}", "Jackett", "Jackett.Binaries.Mono.tar.gz");
});
@ -326,13 +329,13 @@ Task("Linux-Environment")
});
private void RunCygwinCommand(string utility, string utilityArguments)
private void RunMsysCommand(string utility, string utilityArguments)
{
var cygwinDir = @"C:\cygwin\bin\";
var utilityProcess = cygwinDir + utility + ".exe";
var msysDir = @"C:\msys64\usr\bin\";
var utilityProcess = msysDir + utility + ".exe";
Information("CygWin Utility: " + utility);
Information("CygWin Directory: " + cygwinDir);
Information("MSYS2 Utility: " + utility);
Information("MSYS2 Directory: " + msysDir);
Information("Utility Location: " + utilityProcess);
Information("Utility Arguments: " + utilityArguments);
@ -343,7 +346,7 @@ private void RunCygwinCommand(string utility, string utilityArguments)
utilityProcess,
new ProcessSettings {
Arguments = utilityArguments,
WorkingDirectory = cygwinDir,
WorkingDirectory = msysDir,
RedirectStandardOutput = true
},
out redirectedStandardOutput,
@ -364,11 +367,9 @@ private void RunCygwinCommand(string utility, string utilityArguments)
Information(utility + " Exit code: {0}", exitCodeWithArgument);
}
private string RelativeWinPathToCygPath(string relativePath)
private string RelativeWinPathToFullPath(string relativePath)
{
var cygdriveBase = "/cygdrive/" + workingDir.ToString().Replace(":", "").Replace("\\", "/");
var cygPath = cygdriveBase + relativePath.TrimStart('.');
return cygPath;
return (workingDir + relativePath.TrimStart('.'));
}
private void RunLinuxCommand(string file, string arg)
@ -390,12 +391,12 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect
if (IsRunningOnWindows())
{
var cygSourcePath = RelativeWinPathToCygPath(sourceFolder);
var tarArguments = @"-cvf " + cygSourcePath + "/" + tarFileName + " -C " + cygSourcePath + $" {tarCdirectoryOption} --mode ='755'";
var gzipArguments = @"-k " + cygSourcePath + "/" + tarFileName;
var fullSourcePath = RelativeWinPathToFullPath(sourceFolder);
var tarArguments = @"--force-local -cvf " + fullSourcePath + "/" + tarFileName + " -C " + fullSourcePath + $" {tarCdirectoryOption} --mode ='755'";
var gzipArguments = @"-k " + fullSourcePath + "/" + tarFileName;
RunCygwinCommand("Tar", tarArguments);
RunCygwinCommand("Gzip", gzipArguments);
RunMsysCommand("tar", tarArguments);
RunMsysCommand("gzip", gzipArguments);
MoveFile($"{sourceFolder}/{tarFileName}.gz", $"{outputDirectory}/{tarFileName}.gz");
}
else
@ -421,16 +422,57 @@ private void Gzip(string sourceFolder, string outputDirectory, string tarCdirect
}
}
private void DotNetCorePublish(string projectPath, string framework, string runtime, string outputPath)
private void InstallMsysTar()
{
var settings = new DotNetCorePublishSettings
//Gzip is included by default with MSYS2, but not tar. Use the package manager to install tar
var startInfo = new System.Diagnostics.ProcessStartInfo()
{
Framework = framework,
Runtime = runtime,
OutputDirectory = outputPath
Arguments = "-S --noconfirm tar",
FileName = @"C:\msys64\usr\bin\pacman.exe",
UseShellExecute = false
};
DotNetCorePublish(projectPath, settings);
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
if (FileExists(@"C:\msys64\usr\bin\tar.exe") && FileExists(@"C:\msys64\usr\bin\gzip.exe"))
{
Information("tar.exe and gzip.exe were found");
}
else
{
throw new Exception("tar.exe and gzip.exe were NOT found");
}
}
private void DotNetCorePublish(string projectPath, string framework, string runtime, string outputPath)
{
bool publishSingleFile = false;
if (publishSingleFile && framework != "net461")
{
var settings = new DotNetCorePublishSettings
{
Framework = framework,
Runtime = runtime,
OutputDirectory = outputPath,
ArgumentCustomization = args=>args.Append("/p:PublishSingleFile=true")
};
DotNetCorePublish(projectPath, settings);
}
else
{
var settings = new DotNetCorePublishSettings
{
Framework = framework,
Runtime = runtime,
OutputDirectory = outputPath
};
DotNetCorePublish(projectPath, settings);
}
}
//////////////////////////////////////////////////////////////////////

View File

@ -7,23 +7,23 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AngleSharp" Version="0.12.0" />
<PackageReference Include="Autofac" Version="4.9.2" />
<PackageReference Include="AngleSharp" Version="0.13.0" />
<PackageReference Include="Autofac" Version="4.9.4" />
<PackageReference Include="AutoMapper" Version="8.1.0" />
<PackageReference Include="BencodeNET" Version="2.3.0" />
<PackageReference Include="CloudflareSolverRe" Version="1.0.5" />
<PackageReference Include="CommandLineParser" Version="2.5.0" />
<PackageReference Include="CommandLineParser" Version="2.6.0" />
<PackageReference Include="CsQuery.NETStandard" Version="1.3.6.1" />
<PackageReference Include="DotNet4.SocksProxy" Version="1.4.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="MimeMapping" Version="1.0.1.12" />
<PackageReference Include="Microsoft.CSharp" Version="4.6.0" />
<PackageReference Include="MimeMapping" Version="1.0.1.17" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="NLog" Version="4.6.3" />
<PackageReference Include="SharpZipLib" Version="1.1.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.5.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
<PackageReference Include="NLog" Version="4.6.7" />
<PackageReference Include="SharpZipLib" Version="1.2.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.6.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.6.0" />
<PackageReference Include="YamlDotNet" Version="6.0.0" />
</ItemGroup>

View File

@ -8,15 +8,23 @@ using Microsoft.AspNetCore.Hosting;
using NLog;
using System.Linq;
using System.Text;
#if !NET461
using Microsoft.Extensions.Hosting;
#endif
namespace Jackett.Server
{
public static class Helper
{
public static IContainer ApplicationContainer { get; set; }
public static IApplicationLifetime applicationLifetime;
private static bool _automapperInitialised = false;
#if NET461
public static IApplicationLifetime applicationLifetime;
#else
public static IHostApplicationLifetime applicationLifetime;
#endif
public static void Initialize()
{
if (_automapperInitialised == false)

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<ApplicationIcon>jackett.ico</ApplicationIcon>
<AssemblyName>JackettConsole</AssemblyName>
<OutputType>Exe</OutputType>
@ -13,25 +13,15 @@
<AssemblyName>jackett</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.2'">
<RuntimeIdentifiers>win-x86;osx-x64;linux-x64;linux-arm;linux-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net461'">
<RuntimeIdentifiers>win7-x86;linux-x64</RuntimeIdentifiers>
</PropertyGroup>
<!-- Conditionally obtain references for the .NET Core App 2.2 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">
<!-- Conditionally obtain references for the .NET Core App 3.0 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0' ">
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.2" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
<PackageReference Include="AutoMapper" Version="8.1.0" />
<PackageReference Include="CommandLineParser" Version="2.5.0" />
<!-- Conditionally obtain references for the .NET461 target -->
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
@ -39,11 +29,18 @@
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Rewrite" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.4" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.4.0" />
<PackageReference Include="AutoMapper" Version="8.1.0" />
<PackageReference Include="CommandLineParser" Version="2.6.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="NLog" Version="4.6.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.8.1" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.1" />
<PackageReference Include="NLog" Version="4.6.7" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.6.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.6.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
using Jackett.Common.Services.Interfaces;
using NLog;
using System;
#if NETCOREAPP2_2
#if !NET461
using Mono.Unix;
#endif
@ -18,7 +18,7 @@ namespace Jackett.Server.Services
public void MakeFileExecutable(string path)
{
#if NETCOREAPP2_2
#if !NET461
//Calling the file permission service to limit usage to netcoreapp. The Mono.Posix.NETStandard library causes issues outside of .NET Core
//https://github.com/xamarin/XamarinComponents/issues/282

View File

@ -21,6 +21,9 @@ using Newtonsoft.Json.Serialization;
using System;
using System.IO;
using System.Text;
#if !NET461
using Microsoft.Extensions.Hosting;
#endif
namespace Jackett.Server
{
@ -49,6 +52,9 @@ namespace Jackett.Server
options.Cookie.SameSite = SameSiteMode.None;
});
#if NET461
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
@ -59,8 +65,20 @@ namespace Jackett.Server
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //Web app uses Pascal Case JSON
});
#else
services.AddControllers(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver(); //Web app uses Pascal Case JSON
});
#endif
RuntimeSettings runtimeSettings = new RuntimeSettings();
Configuration.GetSection("RuntimeSettings").Bind(runtimeSettings);
@ -96,6 +114,7 @@ namespace Jackett.Server
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
#if NET461
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationLifetime)
{
applicationLifetime.ApplicationStopping.Register(OnShutdown);
@ -134,6 +153,53 @@ namespace Jackett.Server
app.UseMvc();
}
#else
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime)
{
applicationLifetime.ApplicationStopping.Register(OnShutdown);
Helper.applicationLifetime = applicationLifetime;
app.UseResponseCompression();
app.UseDeveloperExceptionPage();
app.UseCustomExceptionHandler();
string serverBasePath = Helper.ServerService.BasePath() ?? string.Empty;
if (!string.IsNullOrEmpty(serverBasePath))
{
app.UsePathBase(serverBasePath);
}
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
// When adjusting these pareamters make sure it's well tested with various environments
// See https://github.com/Jackett/Jackett/issues/3517
ForwardLimit = 10,
ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost
});
var rewriteOptions = new RewriteOptions()
.AddRewrite(@"^torznab\/([\w-]*)", "api/v2.0/indexers/$1/results/torznab", skipRemainingRules: true) //legacy torznab route
.AddRewrite(@"^potato\/([\w-]*)", "api/v2.0/indexers/$1/results/potato", skipRemainingRules: true) //legacy potato route
.Add(RedirectRules.RedirectToDashboard);
app.UseRewriter(rewriteOptions);
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
#endif
private void OnShutdown()
{

View File

@ -21,15 +21,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.2" />
<PackageReference Include="FluentAssertions" Version="5.6.0" />
<PackageReference Include="Autofac" Version="4.9.4" />
<PackageReference Include="FluentAssertions" Version="5.9.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.10.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
</ItemGroup>
<ItemGroup>

View File

@ -30,7 +30,7 @@ namespace Jackett.Test
};
//https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider?view=netcore-2.0
#if NETCOREAPP2_0
#if !NET461
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

View File

@ -110,7 +110,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser">
<Version>2.5.0</Version>
<Version>2.6.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netcoreapp2.2</TargetFrameworks>
<TargetFrameworks>net461;netcoreapp3.0</TargetFrameworks>
<ApplicationIcon>jackett.ico</ApplicationIcon>
<AssemblyName>JackettUpdater</AssemblyName>
<OutputType>Exe</OutputType>