setup
This commit is contained in:
parent
cedec0d4cc
commit
65da61823a
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>4d58719c-20df-4407-bfb4-0f65a324a118</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Framework\FileUtils\FileUtils.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ActiveDebugProfile>Container (Dockerfile)</ActiveDebugProfile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
@BittorrentDriver_HostAddress = http://localhost:5160
|
||||
|
||||
GET {{BittorrentDriver_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
|
@ -0,0 +1,50 @@
|
|||
using Logging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BittorrentDriver.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class TorrentController : ControllerBase
|
||||
{
|
||||
private readonly ILog log = new ConsoleLog();
|
||||
private readonly TorrentTracker tracker = new TorrentTracker();
|
||||
private readonly Transmission transmission;
|
||||
|
||||
public TorrentController()
|
||||
{
|
||||
transmission = new Transmission(log);
|
||||
}
|
||||
|
||||
[HttpPut("tracker")]
|
||||
public string StartTracker([FromBody] int port)
|
||||
{
|
||||
Log("Starting tracker...");
|
||||
return tracker.Start(port);
|
||||
}
|
||||
|
||||
[HttpPost("create")]
|
||||
public string CreateTorrent([FromBody] CreateTorrentInput input)
|
||||
{
|
||||
return transmission.CreateNew(input.Size, input.TrackerUrl);
|
||||
}
|
||||
|
||||
[HttpPost("download")]
|
||||
public string DownloadTorrent([FromBody] string torrentBase64)
|
||||
{
|
||||
return transmission.Download(torrentBase64);
|
||||
}
|
||||
|
||||
private void Log(string v)
|
||||
{
|
||||
log.Log(v);
|
||||
}
|
||||
}
|
||||
|
||||
public class CreateTorrentInput
|
||||
{
|
||||
public int Size { get; set; }
|
||||
public string TrackerUrl { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
USER app
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["BittorrentDriver/BittorrentDriver.csproj", "BittorrentDriver/"]
|
||||
RUN dotnet restore "./BittorrentDriver/BittorrentDriver.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/BittorrentDriver"
|
||||
RUN dotnet build "./BittorrentDriver.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "./BittorrentDriver.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
USER root
|
||||
# Set up npm and bittorrent-tracker
|
||||
RUN apt-get update
|
||||
RUN apt-get install npm software-properties-common -y
|
||||
RUN npm install -g bittorrent-tracker
|
||||
# Set up transmission
|
||||
RUN apt-get install transmission-cli transmission-common transmission-daemon -y
|
||||
|
||||
USER app
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "BittorrentDriver.dll"]
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
namespace BittorrentDriver
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
var listenPort = Environment.GetEnvironmentVariable("APIPORT");
|
||||
if (string.IsNullOrEmpty(listenPort)) listenPort = "31100";
|
||||
|
||||
builder.WebHost.ConfigureKestrel((context, options) =>
|
||||
{
|
||||
options.ListenAnyIP(Convert.ToInt32(listenPort));
|
||||
});
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
Console.WriteLine("TorrentController BittorrentDriver listening on port " + listenPort);
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5160"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7134;http://localhost:5160"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:32045",
|
||||
"sslPort": 44353
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# Run from Tools folder:
|
||||
|
||||
docker build -t thatbenbierens/bittorrentdriver:init -f .\BittorrentDriver\Dockerfile .
|
||||
docker push thatbenbierens/bittorrentdriver:init
|
|
@ -0,0 +1,36 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
namespace BittorrentDriver
|
||||
{
|
||||
public class TorrentTracker
|
||||
{
|
||||
private Process? process;
|
||||
|
||||
public string Start(int port)
|
||||
{
|
||||
if (process != null) throw new Exception("Already started");
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = "bittorrent-tracker",
|
||||
Arguments = $"--port {port} &",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
};
|
||||
|
||||
process = Process.Start(info);
|
||||
if (process == null) return "Failed to start";
|
||||
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (process.HasExited)
|
||||
{
|
||||
return
|
||||
$"STDOUT: {process.StandardOutput.ReadToEnd()} " +
|
||||
$"STDERR: {process.StandardError.ReadToEnd()}";
|
||||
}
|
||||
return "OK";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
using FileUtils;
|
||||
using Logging;
|
||||
using System.Buffers.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Utils;
|
||||
|
||||
namespace BittorrentDriver
|
||||
{
|
||||
public class Transmission
|
||||
{
|
||||
private readonly string dataDir;
|
||||
private readonly ILog log;
|
||||
|
||||
public Transmission(ILog log)
|
||||
{
|
||||
dataDir = Path.Combine(Directory.GetCurrentDirectory(), "files");
|
||||
Directory.CreateDirectory(dataDir);
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public string CreateNew(int size, string trackerUrl)
|
||||
{
|
||||
var file = CreateFile(size);
|
||||
|
||||
var outFile = Path.Combine(Directory.GetCurrentDirectory(), Guid.NewGuid().ToString());
|
||||
|
||||
var base64 = CreateTorrentFile(file, outFile, trackerUrl);
|
||||
|
||||
if (File.Exists(outFile)) File.Delete(outFile);
|
||||
|
||||
return base64;
|
||||
}
|
||||
|
||||
public string Download(string torrentBase64)
|
||||
{
|
||||
var torrentFile = Path.Combine(Directory.GetCurrentDirectory(), Guid.NewGuid().ToString() + ".torrent");
|
||||
File.WriteAllBytes(torrentFile, Convert.FromBase64String(torrentBase64));
|
||||
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = "transmission-cli",
|
||||
Arguments = torrentFile
|
||||
};
|
||||
RunToComplete(info);
|
||||
|
||||
return "OK";
|
||||
}
|
||||
|
||||
private string CreateTorrentFile(TrackedFile file, string outFile, string trackerUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = "transmission-create",
|
||||
Arguments = $"-o {outFile} -t {trackerUrl} {file.Filename}",
|
||||
};
|
||||
|
||||
var process = RunToComplete(info);
|
||||
|
||||
log.Log(nameof(CreateTorrentFile) + " exited with: " + process.ExitCode);
|
||||
|
||||
if (!File.Exists(outFile)) throw new Exception("Outfile not created.");
|
||||
|
||||
return Convert.ToBase64String(File.ReadAllBytes(outFile));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error("Failed to create torrent file: " + ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private Process RunToComplete(ProcessStartInfo info)
|
||||
{
|
||||
var process = Process.Start(info);
|
||||
if (process == null) throw new Exception("Failed to start");
|
||||
process.WaitForExit(TimeSpan.FromMinutes(3));
|
||||
return process;
|
||||
}
|
||||
|
||||
private TrackedFile CreateFile(int size)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileManager = new FileManager(log, dataDir);
|
||||
return fileManager.GenerateFile(size.Bytes());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error("Failed to create file: " + ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using Core;
|
||||
using KubernetesWorkflow;
|
||||
using KubernetesWorkflow.Recipe;
|
||||
|
||||
namespace BittorrentPlugin
|
||||
{
|
||||
public class BittorrentPlugin : IProjectPlugin
|
||||
{
|
||||
private readonly IPluginTools tools;
|
||||
|
||||
public BittorrentPlugin(IPluginTools tools)
|
||||
{
|
||||
this.tools = tools;
|
||||
}
|
||||
|
||||
public void Announce()
|
||||
{
|
||||
tools.GetLog().Log("Loaded Bittorrent plugin");
|
||||
}
|
||||
|
||||
public void Decommission()
|
||||
{
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
var flow = tools.CreateWorkflow();
|
||||
var trackerPod = flow.Start(1, new TrackerContainerRecipe(), new StartupConfig()).WaitForOnline();
|
||||
var trackerContainer = trackerPod.Containers.Single();
|
||||
|
||||
//var msg = flow.ExecuteCommand(trackerContainer, "apt-get", "update");
|
||||
//msg = flow.ExecuteCommand(trackerContainer, "apt-get", "install", "npm", "-y");
|
||||
//var msg = flow.ExecuteCommand(trackerContainer, "npm", "install", "-g", "bittorrent-tracker");
|
||||
//msg = flow.ExecuteCommand(trackerContainer, "bittorrent-tracker", "--port", "30800", "&");
|
||||
|
||||
var clientPod = flow.Start(1, new BittorrentContainerRecipe(), new StartupConfig()).WaitForOnline();
|
||||
var clientContainer = clientPod.Containers.Single();
|
||||
|
||||
var msg = flow.ExecuteCommand(clientContainer, "echo", "1234567890987654321",
|
||||
">", "/root/datafile.txt");
|
||||
|
||||
var trackerAddress = trackerContainer.GetAddress(tools.GetLog(), TrackerContainerRecipe.HttpPort);
|
||||
if (trackerAddress == null) throw new Exception();
|
||||
var trackerAddressStr = trackerAddress.ToString();
|
||||
|
||||
msg = flow.ExecuteCommand(clientContainer, "transmission-create",
|
||||
"-o", "/root/outfile.torrent",
|
||||
"-t", trackerAddressStr,
|
||||
"/root/datafile.txt");
|
||||
|
||||
msg = flow.ExecuteCommand(clientContainer, "cat", "/root/outfile.torrent");
|
||||
|
||||
var a = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class TrackerContainerRecipe : ContainerRecipeFactory
|
||||
{
|
||||
public override string AppName => "bittorrenttracker";
|
||||
public override string Image => "thatbenbierens/bittorrent-tracker:init";
|
||||
|
||||
public static string HttpPort = "http";
|
||||
|
||||
protected override void Initialize(StartupConfig config)
|
||||
{
|
||||
AddExposedPort(30800, HttpPort);
|
||||
}
|
||||
}
|
||||
|
||||
public class BittorrentContainerRecipe : ContainerRecipeFactory
|
||||
{
|
||||
public override string AppName => "bittorrentclient";
|
||||
public override string Image => "thatbenbierens/bittorrent-client:init";
|
||||
|
||||
protected override void Initialize(StartupConfig config)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Framework\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,17 @@
|
|||
using Core;
|
||||
|
||||
namespace BittorrentPlugin
|
||||
{
|
||||
public static class CoreInterfaceExtensions
|
||||
{
|
||||
public static void RunThing(this CoreInterface ci)
|
||||
{
|
||||
Plugin(ci).Run();
|
||||
}
|
||||
|
||||
private static BittorrentPlugin Plugin(CoreInterface ci)
|
||||
{
|
||||
return ci.GetPlugin<BittorrentPlugin>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using DistTestCore;
|
||||
using GethPlugin;
|
||||
using MetricsPlugin;
|
||||
using BittorrentPlugin;
|
||||
using NUnit.Framework;
|
||||
using Utils;
|
||||
|
||||
|
@ -66,5 +67,11 @@ namespace CodexTests.BasicTests
|
|||
Assert.That(bootN, Is.EqualTo(followN));
|
||||
Assert.That(discN, Is.LessThan(bootN));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BittorrentPluginTest()
|
||||
{
|
||||
Ci.RunThing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BittorrentPlugin\BittorrentPlugin.csproj" />
|
||||
<ProjectReference Include="..\..\Framework\DiscordRewards\DiscordRewards.csproj" />
|
||||
<ProjectReference Include="..\..\ProjectPlugins\CodexContractsPlugin\CodexContractsPlugin.csproj" />
|
||||
<ProjectReference Include="..\..\ProjectPlugins\CodexDiscordBotPlugin\CodexDiscordBotPlugin.csproj" />
|
||||
|
|
|
@ -76,6 +76,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TranscriptAnalysis", "Tools
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarketInsights", "Tools\MarketInsights\MarketInsights.csproj", "{004614DF-1C65-45E3-882D-59AE44282573}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BittorrentPlugin", "BittorrentPlugin\BittorrentPlugin.csproj", "{0E2C6152-951D-433A-A150-96CFBCD1472A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BittorrentDriver", "BittorrentDriver\BittorrentDriver.csproj", "{59B53781-9E5E-4A38-89F3-52996556B593}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -202,6 +206,14 @@ Global
|
|||
{004614DF-1C65-45E3-882D-59AE44282573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{004614DF-1C65-45E3-882D-59AE44282573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{004614DF-1C65-45E3-882D-59AE44282573}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0E2C6152-951D-433A-A150-96CFBCD1472A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0E2C6152-951D-433A-A150-96CFBCD1472A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0E2C6152-951D-433A-A150-96CFBCD1472A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0E2C6152-951D-433A-A150-96CFBCD1472A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{59B53781-9E5E-4A38-89F3-52996556B593}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{59B53781-9E5E-4A38-89F3-52996556B593}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{59B53781-9E5E-4A38-89F3-52996556B593}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{59B53781-9E5E-4A38-89F3-52996556B593}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -237,6 +249,8 @@ Global
|
|||
{870DDFBE-D7ED-4196-9681-13CA947BDEA6} = {81AE04BC-CBFA-4E6F-B039-8208E9AFAAE7}
|
||||
{C0EEBD32-23CB-45EC-A863-79FB948508C8} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
{004614DF-1C65-45E3-882D-59AE44282573} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
{0E2C6152-951D-433A-A150-96CFBCD1472A} = {8F1F1C2A-E313-4E0C-BE40-58FB0BA91124}
|
||||
{59B53781-9E5E-4A38-89F3-52996556B593} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}
|
||||
|
|
Loading…
Reference in New Issue