mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 16:39:21 +01:00
+11
-8
@@ -1,13 +1,18 @@
|
||||
.dockerignore
|
||||
*/bin
|
||||
*/obj
|
||||
|
||||
.git
|
||||
.github
|
||||
.gitignore
|
||||
.vs
|
||||
.vscode
|
||||
.travis.yml
|
||||
.codecov.yml
|
||||
.dockerignore
|
||||
.gitignore
|
||||
.travis.yml
|
||||
appveyor.yml
|
||||
README
|
||||
omnisharp.json
|
||||
README.md
|
||||
|
||||
build/**
|
||||
!build/analyzers.ruleset
|
||||
!build/tgs.docker.sh
|
||||
@@ -15,11 +20,7 @@ build/**
|
||||
!build/tgs.png
|
||||
!build/stylecop.json
|
||||
!build/Version.props
|
||||
*/bin
|
||||
*/obj
|
||||
tests
|
||||
docs
|
||||
tools
|
||||
src/DMAPI
|
||||
src/Tgstation.Server.Host/ClientApp/build
|
||||
src/Tgstation.Server.Host/ClientApp/node_modules
|
||||
@@ -29,3 +30,5 @@ src/Tgstation.Server.Host/tgs.bat
|
||||
src/Tgstation.Server.Host/tgs.sh
|
||||
src/Tgstation.Server.Host.Client
|
||||
src/Tgstation.Server.Host.Service
|
||||
tests
|
||||
tools
|
||||
|
||||
@@ -361,15 +361,17 @@ Contact project maintainers to get your client added to this list
|
||||
|
||||
Note that tgstation-server is NOT a backup solution, the onus is on the server runners.
|
||||
|
||||
The `Repository` folder should, by the nature of git, not need to be backed up or should be done so on the remote server if necessary.
|
||||
The `Repository` folder should be backed up on the remote server, do not rely on the instance copy to store changes.
|
||||
|
||||
The `BYOND` and `Game` folders should never be backed up due.
|
||||
The `BYOND` and `Game` folders should never be backed up due to being intertwined with instance data.
|
||||
|
||||
The `Configuration` folder should and database be fully backed up
|
||||
The `Configuration` folder should be fully backed up.
|
||||
|
||||
To restore an installation from backups, first restore the instance `Configuration` folders in their new homes. Then restore the database, modifying the `Path` column in the `Instances` table where necessary to point to the new instances. Then start the server pointed at the new database.
|
||||
The database should be fully backed up.
|
||||
|
||||
Should you end up with a lost database for some reason or want to reattach a detached instance you can reattach an existing folder by creating an empty file named `TGS4_ALLOW_INSTANCE_ATTACH` inside it (This is automatically created when detaching instances). Then create a new instance with that path, this will bypass the empty folder check. Note that this will not restore things such as user permissions, server config options, or deployment metadata. Those must be reconfigured manually
|
||||
To restore an installation from backups, first restore the instance `Configuration` folder in its new home. Then restore the database, modifying the `Path` column in the `Instances` table where necessary to point to the new instances. Then start the server pointed at the new database.
|
||||
|
||||
Should you end up with a lost database for some reason or want to reattach a detached instance you can reattach an existing folder by creating an empty file named `TGS4_ALLOW_INSTANCE_ATTACH` inside it (This is automatically created when detaching instances). Then create a new instance with that path, this will bypass the empty folder check. Note that this will not restore things such as user permissions, server config options, or deployment metadata. Those must be reconfigured manually.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
+2
-3
@@ -11,11 +11,10 @@ if($publish_dox){
|
||||
echo "Cloning https://git@$github_url..."
|
||||
git clone -b gh-pages --single-branch "https://git@$github_url" "$doxdir" 2>$null
|
||||
rm -r "$doxdir\*"
|
||||
Add-Content "$bf\docs\Doxyfile" "`nPROJECT_NUMBER = $version`nINPUT = $bf`nOUTPUT_DIRECTORY = $doxdir`nPROJECT_LOGO = $bf/build/tgs.ico"
|
||||
}else{
|
||||
Add-Content "$bf\docs\Doxyfile" "`nPROJECT_NUMBER = $version`nINPUT = $bf`nOUTPUT_DIRECTORY = $doxdir`nPROJECT_LOGO = $bf/build/tgs.ico`nHAVE_DOT=YES"
|
||||
}
|
||||
|
||||
Add-Content "$bf\docs\Doxyfile" "`nPROJECT_NUMBER = $version`nINPUT = $bf`nOUTPUT_DIRECTORY = $doxdir`nPROJECT_LOGO = $bf/build/tgs.ico`nHAVE_DOT=YES"
|
||||
|
||||
&"C:\Program Files\doxygen\bin\doxygen.exe" "$bf\docs\Doxyfile"
|
||||
|
||||
if($publish_dox){
|
||||
|
||||
+20
-7
@@ -1,4 +1,4 @@
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build
|
||||
|
||||
# install node and npm
|
||||
# replace shell with bash so we can source files
|
||||
@@ -18,29 +18,42 @@ RUN . $NVM_DIR/nvm.sh \
|
||||
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
|
||||
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
|
||||
|
||||
WORKDIR /src
|
||||
# Build web control panel
|
||||
WORKDIR /repo/build
|
||||
|
||||
COPY build/Version.props Version.props
|
||||
|
||||
WORKDIR /repo/src/Tgstation.Server.Host
|
||||
|
||||
COPY src/Tgstation.Server.Host/ClientApp ClientApp
|
||||
COPY src/Tgstation.Server.Host/Tgstation.Server.Host.csproj ./
|
||||
|
||||
RUN dotnet msbuild -target:NpmBuild
|
||||
|
||||
WORKDIR /repo
|
||||
|
||||
# Restore nuget packages
|
||||
COPY tgstation-server.sln ./
|
||||
|
||||
COPY src/Tgstation.Server.Host.Console/Tgstation.Server.Host.Console.csproj src/Tgstation.Server.Host.Console/
|
||||
COPY src/Tgstation.Server.Host.Watchdog/Tgstation.Server.Host.Watchdog.csproj src/Tgstation.Server.Host.Watchdog/
|
||||
COPY src/Tgstation.Server.Host/Tgstation.Server.Host.csproj src/Tgstation.Server.Host/
|
||||
COPY src/Tgstation.Server.Api/Tgstation.Server.Api.csproj src/Tgstation.Server.Api/
|
||||
|
||||
RUN dotnet restore -nowarn:MSB3202,nu1503 -p:RestoreUseSkipNonexistentTargets=false
|
||||
|
||||
# Final copy for building
|
||||
COPY . .
|
||||
|
||||
#run dos2unix on tgs.docker.sh so we can build without issue on windows
|
||||
RUN dos2unix build/tgs.docker.sh
|
||||
|
||||
WORKDIR /src/src/Tgstation.Server.Host.Console
|
||||
WORKDIR /repo/src/Tgstation.Server.Host.Console
|
||||
RUN dotnet publish -c Release -o /app
|
||||
|
||||
WORKDIR /src/src/Tgstation.Server.Host
|
||||
WORKDIR /repo/src/Tgstation.Server.Host
|
||||
RUN dotnet publish -c Release -o /app/lib/Default && mv /app/lib/Default/appsettings* /app
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic
|
||||
EXPOSE 80
|
||||
|
||||
#needed for byond
|
||||
@@ -52,7 +65,7 @@ RUN apt-get update \
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=build /app .
|
||||
COPY --from=build /src/build/tgs.docker.sh tgs.sh
|
||||
COPY --from=build /repo/build/tgs.docker.sh tgs.sh
|
||||
|
||||
VOLUME ["/config_data", "/tgs_logs", "/app/lib"]
|
||||
|
||||
|
||||
+16
-1
@@ -1,9 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT_VERSION="1.1.0"
|
||||
|
||||
echo "tgstation-server 4 container startup script v$SCRIPT_VERSION"
|
||||
echo "PWD: $PWD"
|
||||
|
||||
PROD_CONFIG=/config_data/appsettings.Production.json
|
||||
HOST_CONFIG=/app/appsettings.Production.json
|
||||
|
||||
if [ ! -f $PROD_CONFIG ]; then
|
||||
echo "$PROD_CONFIG not detected! Creating empty..."
|
||||
echo "{}" > $PROD_CONFIG
|
||||
fi
|
||||
ln -s $PROD_CONFIG /app/appsettings.Production.json
|
||||
|
||||
ln -v -s $PROD_CONFIG $HOST_CONFIG
|
||||
|
||||
if [ ! -f "$HOST_CONFIG" ]; then
|
||||
echo "ln failed to create symlink!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Executing console runner..."
|
||||
exec dotnet Tgstation.Server.Host.Console.dll
|
||||
|
||||
@@ -108,9 +108,14 @@ namespace Tgstation.Server.Host.Components
|
||||
readonly IPlatformIdentifier platformIdentifier;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IRepositoryFactory"/> for the <see cref="InstanceFactory"/>.
|
||||
/// The <see cref="ILibGit2RepositoryFactory"/> for the <see cref="InstanceFactory"/>.
|
||||
/// </summary>
|
||||
readonly IRepositoryFactory repositoryFactory;
|
||||
readonly ILibGit2RepositoryFactory repositoryFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILibGit2Commands"/> for the <see cref="InstanceFactory"/>.
|
||||
/// </summary>
|
||||
readonly ILibGit2Commands repositoryCommands;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerPortProvider"/> for the <see cref="InstanceFactory"/>.
|
||||
@@ -138,6 +143,7 @@ namespace Tgstation.Server.Host.Components
|
||||
/// <param name="gitHubClientFactory">The value of <see cref="gitHubClientFactory"/></param>
|
||||
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/></param>
|
||||
/// <param name="repositoryFactory">The value of <see cref="repositoryFactory"/>.</param>
|
||||
/// <param name="repositoryCommands">The value of <see cref="repositoryCommands"/>.</param>
|
||||
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
|
||||
public InstanceFactory(
|
||||
IIOManager ioManager,
|
||||
@@ -157,7 +163,8 @@ namespace Tgstation.Server.Host.Components
|
||||
INetworkPromptReaper networkPromptReaper,
|
||||
IGitHubClientFactory gitHubClientFactory,
|
||||
IPlatformIdentifier platformIdentifier,
|
||||
IRepositoryFactory repositoryFactory,
|
||||
ILibGit2RepositoryFactory repositoryFactory,
|
||||
ILibGit2Commands repositoryCommands,
|
||||
IServerPortProvider serverPortProvider)
|
||||
{
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
@@ -178,6 +185,7 @@ namespace Tgstation.Server.Host.Components
|
||||
this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
|
||||
this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
|
||||
this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory));
|
||||
this.repositoryCommands = repositoryCommands ?? throw new ArgumentNullException(nameof(repositoryCommands));
|
||||
this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
|
||||
}
|
||||
|
||||
@@ -198,6 +206,7 @@ namespace Tgstation.Server.Host.Components
|
||||
var eventConsumer = new EventConsumer(configuration);
|
||||
var repoManager = new RepositoryManager(
|
||||
repositoryFactory,
|
||||
repositoryCommands,
|
||||
repoIoManager,
|
||||
eventConsumer,
|
||||
loggerFactory.CreateLogger<Repository.Repository>(),
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using LibGit2Sharp;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// For low level interactions with a <see cref="LibGit2Sharp.IRepository"/>.
|
||||
/// </summary>
|
||||
interface ILibGit2Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs a blocking fetch operation on a given <paramref name="repository"/>.
|
||||
/// </summary>
|
||||
/// <param name="repository">The <see cref="IRepository"/> to fetch with.</param>
|
||||
/// <param name="refSpecs">The refspecs to fetch.</param>
|
||||
/// <param name="remote">The <see cref="Remote"/> to fetch.</param>
|
||||
/// <param name="fetchOptions">The <see cref="FetchOptions"/>.</param>
|
||||
/// <param name="logMessage">The message to write in the git log.</param>
|
||||
void Fetch(LibGit2Sharp.IRepository repository, IEnumerable<string> refSpecs, Remote remote, FetchOptions fetchOptions, string logMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Runs a blocking checkout operation on a given <paramref name="repository"/>.
|
||||
/// </summary>
|
||||
/// <param name="repository">The <see cref="IRepository"/> to checkout with.</param>
|
||||
/// <param name="checkoutOptions">The <see cref="CheckoutOptions"/>.</param>
|
||||
/// <param name="commitish">The git object to checkout.</param>
|
||||
void Checkout(LibGit2Sharp.IRepository repository, CheckoutOptions checkoutOptions, string commitish);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <summary>
|
||||
/// Factory for creating <see cref="LibGit2Sharp.IRepository"/>s.
|
||||
/// </summary>
|
||||
interface IRepositoryFactory : ICredentialsProvider
|
||||
interface ILibGit2RepositoryFactory : ICredentialsProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an in-memeory <see cref="LibGit2Sharp.IRepository"/>.
|
||||
@@ -0,0 +1,34 @@
|
||||
using LibGit2Sharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class LibGit2Commands : ILibGit2Commands
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Checkout(LibGit2Sharp.IRepository libGit2Repo, CheckoutOptions checkoutOptions, string commitish)
|
||||
=> Commands.Checkout(libGit2Repo, commitish, checkoutOptions);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Fetch(
|
||||
LibGit2Sharp.IRepository libGit2Repo,
|
||||
IEnumerable<string> refSpecs,
|
||||
Remote remote,
|
||||
FetchOptions fetchOptions,
|
||||
string logMessage)
|
||||
{
|
||||
if (libGit2Repo == null)
|
||||
throw new ArgumentNullException(nameof(libGit2Repo));
|
||||
|
||||
if (!(libGit2Repo is LibGit2Sharp.Repository concreteRepo))
|
||||
throw new ArgumentException("libGit2Repo must be an instance of LibGit2Sharp.Repository!", nameof(libGit2Repo));
|
||||
|
||||
if (remote == null)
|
||||
throw new ArgumentNullException(nameof(remote));
|
||||
|
||||
Commands.Fetch(concreteRepo, remote.Name, refSpecs, fetchOptions, logMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
-11
@@ -9,18 +9,18 @@ using Tgstation.Server.Host.Jobs;
|
||||
namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class RepositoryFactory : IRepositoryFactory
|
||||
sealed class LibGit2RepositoryFactory : ILibGit2RepositoryFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="RepositoryFactory"/>.
|
||||
/// The <see cref="ILogger"/> for the <see cref="LibGit2RepositoryFactory"/>.
|
||||
/// </summary>
|
||||
readonly ILogger<RepositoryFactory> logger;
|
||||
readonly ILogger<LibGit2RepositoryFactory> logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepositoryFactory"/> <see langword="class"/>.
|
||||
/// Initializes a new instance of the <see cref="LibGit2RepositoryFactory"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
/// <param name="logger">The value of <see cref="logger"/>.</param>
|
||||
public RepositoryFactory(ILogger<RepositoryFactory> logger)
|
||||
public LibGit2RepositoryFactory(ILogger<LibGit2RepositoryFactory> logger)
|
||||
{
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
@@ -28,8 +28,18 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <inheritdoc />
|
||||
public LibGit2Sharp.IRepository CreateInMemory()
|
||||
{
|
||||
logger.LogTrace("Creating in-memory repository...");
|
||||
return new LibGit2Sharp.Repository();
|
||||
logger.LogTrace("Creating in-memory libgit2 repository...");
|
||||
var repo = new LibGit2Sharp.Repository();
|
||||
try
|
||||
{
|
||||
logger.LogTrace("Successfully created in-memory libgit2 repository.");
|
||||
return repo;
|
||||
}
|
||||
catch
|
||||
{
|
||||
repo.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -37,9 +47,13 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
logger.LogTrace("Creating repostory at {0}...", path);
|
||||
return Task.Factory.StartNew(
|
||||
() => (LibGit2Sharp.IRepository)new LibGit2Sharp.Repository(path),
|
||||
|
||||
return Task.Factory.StartNew<LibGit2Sharp.IRepository>(
|
||||
() =>
|
||||
{
|
||||
logger.LogTrace("Creating libgit2 repostory at {0}...", path);
|
||||
return new LibGit2Sharp.Repository(path);
|
||||
},
|
||||
cancellationToken,
|
||||
TaskCreationOptions.LongRunning,
|
||||
TaskScheduler.Current);
|
||||
@@ -78,7 +92,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (supportsAnonymous)
|
||||
return new DefaultCredentials();
|
||||
|
||||
if (!hasCreds)
|
||||
if (supportsUserPass)
|
||||
throw new JobException("Remote does not support anonymous authentication!");
|
||||
|
||||
throw new JobException("Server does not support anonymous or username/password authentication!");
|
||||
@@ -43,21 +43,26 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
public string GitHubRepoName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Tracking => Reference != null && repository.Head.IsTracking;
|
||||
public bool Tracking => Reference != null && libGitRepo.Head.IsTracking;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Head => repository.Head.Tip.Sha;
|
||||
public string Head => libGitRepo.Head.Tip.Sha;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Reference => repository.Head.FriendlyName;
|
||||
public string Reference => libGitRepo.Head.FriendlyName;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Origin => repository.Network.Remotes.First().Url;
|
||||
public string Origin => libGitRepo.Network.Remotes.First().Url;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="LibGit2Sharp.IRepository"/> for the <see cref="Repository"/>
|
||||
/// </summary>
|
||||
readonly LibGit2Sharp.IRepository repository;
|
||||
readonly LibGit2Sharp.IRepository libGitRepo;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILibGit2Commands"/> for the <see cref="Repository"/>.
|
||||
/// </summary>
|
||||
readonly ILibGit2Commands commands;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="Repository"/>
|
||||
@@ -99,21 +104,32 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <summary>
|
||||
/// Construct a <see cref="Repository"/>
|
||||
/// </summary>
|
||||
/// <param name="repository">The value of <see cref="repository"/></param>
|
||||
/// <param name="libGitRepo">The value of <see cref="libGitRepo"/></param>
|
||||
/// <param name="commands">The value of <see cref="commands"/>.</param>
|
||||
/// <param name="ioMananger">The value of <see cref="ioMananger"/></param>
|
||||
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
|
||||
/// <param name="credentialsProvider">The value of <see cref="credentialsProvider"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
/// <param name="onDispose">The value if <see cref="onDispose"/></param>
|
||||
public Repository(LibGit2Sharp.IRepository repository, IIOManager ioMananger, IEventConsumer eventConsumer, ICredentialsProvider credentialsProvider, ILogger<Repository> logger, Action onDispose)
|
||||
public Repository(
|
||||
LibGit2Sharp.IRepository libGitRepo,
|
||||
ILibGit2Commands commands,
|
||||
IIOManager ioMananger,
|
||||
IEventConsumer eventConsumer,
|
||||
ICredentialsProvider credentialsProvider,
|
||||
ILogger<Repository> logger,
|
||||
Action onDispose)
|
||||
{
|
||||
this.repository = repository ?? throw new ArgumentNullException(nameof(repository));
|
||||
this.libGitRepo = libGitRepo ?? throw new ArgumentNullException(nameof(libGitRepo));
|
||||
this.commands = commands ?? throw new ArgumentNullException(nameof(commands));
|
||||
this.ioMananger = ioMananger ?? throw new ArgumentNullException(nameof(ioMananger));
|
||||
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
|
||||
this.credentialsProvider = credentialsProvider ?? throw new ArgumentNullException(nameof(credentialsProvider));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
this.onDispose = onDispose ?? throw new ArgumentNullException(nameof(onDispose));
|
||||
|
||||
IsGitHubRepository = Origin.Contains(GitHubUrl, StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
if (IsGitHubRepository)
|
||||
{
|
||||
GetRepositoryOwnerName(Origin, out var owner, out var name);
|
||||
@@ -134,7 +150,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
}
|
||||
|
||||
logger.LogTrace("Disposing...");
|
||||
repository.Dispose();
|
||||
libGitRepo.Dispose();
|
||||
onDispose();
|
||||
}
|
||||
|
||||
@@ -191,15 +207,18 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
progressReporter(0);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
Commands.Checkout(repository, committish, new CheckoutOptions
|
||||
{
|
||||
CheckoutModifiers = CheckoutModifiers.Force,
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progressReporter)
|
||||
});
|
||||
commands.Checkout(
|
||||
libGitRepo,
|
||||
new CheckoutOptions
|
||||
{
|
||||
CheckoutModifiers = CheckoutModifiers.Force,
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progressReporter)
|
||||
},
|
||||
committish);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -248,7 +267,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
var refSpecList = new List<string> { refSpec };
|
||||
var logMessage = String.Format(CultureInfo.InvariantCulture, "Merge remote pull request #{0}", testMergeParameters.Number);
|
||||
|
||||
var originalCommit = repository.Head;
|
||||
var originalCommit = libGitRepo.Head;
|
||||
|
||||
MergeResult result = null;
|
||||
|
||||
@@ -261,37 +280,42 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
logger.LogTrace("Fetching refspec {0}...", refSpec);
|
||||
|
||||
var remote = repository.Network.Remotes.First();
|
||||
var remote = libGitRepo.Network.Remotes.First();
|
||||
progressReporter(0);
|
||||
Commands.Fetch((LibGit2Sharp.Repository)repository, remote.Name, refSpecList, new FetchOptions
|
||||
{
|
||||
Prune = true,
|
||||
OnProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
OnTransferProgress = (a) =>
|
||||
commands.Fetch(
|
||||
libGitRepo,
|
||||
refSpecList,
|
||||
remote,
|
||||
new FetchOptions
|
||||
{
|
||||
var percentage = 50 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2));
|
||||
progressReporter((int)percentage);
|
||||
return !cancellationToken.IsCancellationRequested;
|
||||
Prune = true,
|
||||
OnProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
OnTransferProgress = (a) =>
|
||||
{
|
||||
var percentage = 50 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2));
|
||||
progressReporter((int)percentage);
|
||||
return !cancellationToken.IsCancellationRequested;
|
||||
},
|
||||
OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested,
|
||||
CredentialsProvider = credentialsProvider.GenerateCredentialsHandler(username, password)
|
||||
},
|
||||
OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested,
|
||||
CredentialsProvider = credentialsProvider.GenerateCredentialsHandler(username, password)
|
||||
}, logMessage);
|
||||
logMessage);
|
||||
}
|
||||
catch (UserCancelledException) { }
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
testMergeParameters.PullRequestRevision = repository.Lookup(testMergeParameters.PullRequestRevision ?? localBranchName).Sha;
|
||||
testMergeParameters.PullRequestRevision = libGitRepo.Lookup(testMergeParameters.PullRequestRevision ?? localBranchName).Sha;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
logger.LogTrace("Merging {0} into {1}...", testMergeParameters.PullRequestRevision.Substring(0, 7), Reference);
|
||||
|
||||
result = repository.Merge(testMergeParameters.PullRequestRevision, sig, new MergeOptions
|
||||
result = libGitRepo.Merge(testMergeParameters.PullRequestRevision, sig, new MergeOptions
|
||||
{
|
||||
CommitOnSuccess = commitMessage == null,
|
||||
FailOnConflict = true,
|
||||
@@ -302,7 +326,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
}
|
||||
finally
|
||||
{
|
||||
repository.Branches.Remove(localBranchName);
|
||||
libGitRepo.Branches.Remove(localBranchName);
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -315,7 +339,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
|
||||
if (result.Status == MergeStatus.Conflicts)
|
||||
@@ -327,7 +351,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (commitMessage != null && result.Status != MergeStatus.UpToDate)
|
||||
{
|
||||
logger.LogTrace("Committing merge: \"{0}\"...", commitMessage);
|
||||
await Task.Factory.StartNew(() => repository.Commit(commitMessage, sig, sig, new CommitOptions
|
||||
await Task.Factory.StartNew(() => libGitRepo.Commit(commitMessage, sig, sig, new CommitOptions
|
||||
{
|
||||
PrettifyMessage = true
|
||||
}), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
@@ -359,7 +383,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
await eventConsumer.HandleEvent(EventType.RepoCheckout, new List<string> { committish }, cancellationToken).ConfigureAwait(false);
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
RawCheckout(committish, progressReporter, cancellationToken);
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
}
|
||||
@@ -373,10 +397,10 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
await eventConsumer.HandleEvent(EventType.RepoFetch, Array.Empty<string>(), cancellationToken).ConfigureAwait(false);
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
var remote = repository.Network.Remotes.First();
|
||||
var remote = libGitRepo.Network.Remotes.First();
|
||||
try
|
||||
{
|
||||
Commands.Fetch((LibGit2Sharp.Repository)repository, remote.Name, remote.FetchRefSpecs.Select(x => x.Specification), new FetchOptions
|
||||
Commands.Fetch((LibGit2Sharp.Repository)libGitRepo, remote.Name, remote.FetchRefSpecs.Select(x => x.Specification), new FetchOptions
|
||||
{
|
||||
Prune = true,
|
||||
OnProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
@@ -408,17 +432,17 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
Task PushHeadToTemporaryBranch(string username, string password, Action<int> progressReporter, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
|
||||
{
|
||||
logger.LogInformation("Pushing changes to temporary remote branch...");
|
||||
var branch = repository.CreateBranch(RemoteTemporaryBranchName);
|
||||
var branch = libGitRepo.CreateBranch(RemoteTemporaryBranchName);
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var remote = repository.Network.Remotes.First();
|
||||
var remote = libGitRepo.Network.Remotes.First();
|
||||
try
|
||||
{
|
||||
var forcePushString = String.Format(CultureInfo.InvariantCulture, "+{0}:{0}", branch.CanonicalName);
|
||||
repository.Network.Push(remote, forcePushString, GeneratePushOptions(progress => progressReporter((int)(0.9f * progress)), username, password, cancellationToken));
|
||||
libGitRepo.Network.Push(remote, forcePushString, GeneratePushOptions(progress => progressReporter((int)(0.9f * progress)), username, password, cancellationToken));
|
||||
var removalString = String.Format(CultureInfo.InvariantCulture, ":{0}", branch.CanonicalName);
|
||||
repository.Network.Push(remote, removalString, GeneratePushOptions(progress => progressReporter(90 + (int)(0.1f * progress)), username, password, cancellationToken));
|
||||
libGitRepo.Network.Push(remote, removalString, GeneratePushOptions(progress => progressReporter(90 + (int)(0.1f * progress)), username, password, cancellationToken));
|
||||
}
|
||||
catch (UserCancelledException)
|
||||
{
|
||||
@@ -431,7 +455,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
}
|
||||
finally
|
||||
{
|
||||
repository.Branches.Remove(branch);
|
||||
libGitRepo.Branches.Remove(branch);
|
||||
}
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
|
||||
|
||||
@@ -443,7 +467,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (!Tracking)
|
||||
throw new JobException("Cannot reset to origin while not on a tracked reference!");
|
||||
logger.LogTrace("Reset to origin...");
|
||||
var trackedBranch = repository.Head.TrackedBranch;
|
||||
var trackedBranch = libGitRepo.Head.TrackedBranch;
|
||||
await eventConsumer.HandleEvent(EventType.RepoResetOrigin, new List<string> { trackedBranch.FriendlyName, trackedBranch.Tip.Sha }, cancellationToken).ConfigureAwait(false);
|
||||
await ResetToSha(trackedBranch.Tip.Sha, progressReporter, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
@@ -458,16 +482,16 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
|
||||
logger.LogDebug("Reset to sha: {0}", sha.Substring(0, 7));
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var gitObject = repository.Lookup(sha, ObjectType.Commit);
|
||||
var gitObject = libGitRepo.Lookup(sha, ObjectType.Commit);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (gitObject == null)
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot reset to non-existent SHA: {0}", sha));
|
||||
|
||||
repository.Reset(ResetMode.Hard, gitObject.Peel<Commit>(), new CheckoutOptions
|
||||
libGitRepo.Reset(ResetMode.Hard, gitObject.Peel<Commit>(), new CheckoutOptions
|
||||
{
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progressReporter)
|
||||
});
|
||||
@@ -491,7 +515,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
MergeResult result = null;
|
||||
Branch trackedBranch = null;
|
||||
|
||||
var oldHead = repository.Head;
|
||||
var oldHead = libGitRepo.Head;
|
||||
var oldTip = oldHead.Tip;
|
||||
|
||||
await Task.Factory.StartNew(() =>
|
||||
@@ -499,13 +523,13 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (!Tracking)
|
||||
throw new JobException("Cannot reset to origin while not on a tracked reference!");
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
trackedBranch = repository.Head.TrackedBranch;
|
||||
trackedBranch = libGitRepo.Head.TrackedBranch;
|
||||
logger.LogDebug("Merge origin/{2}: <{0} ({1})>", committerName, committerEmail, trackedBranch.FriendlyName);
|
||||
result = repository.Merge(trackedBranch, new Signature(new Identity(committerName, committerEmail), DateTimeOffset.Now), new MergeOptions
|
||||
result = libGitRepo.Merge(trackedBranch, new Signature(new Identity(committerName, committerEmail), DateTimeOffset.Now), new MergeOptions
|
||||
{
|
||||
CommitOnSuccess = true,
|
||||
FailOnConflict = true,
|
||||
@@ -519,14 +543,14 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (result.Status == MergeStatus.Conflicts)
|
||||
{
|
||||
logger.LogDebug("Merge conflict, aborting and reverting to {0}", oldHead.FriendlyName);
|
||||
repository.Reset(ResetMode.Hard, oldTip, new CheckoutOptions
|
||||
libGitRepo.Reset(ResetMode.Hard, oldTip, new CheckoutOptions
|
||||
{
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progressReporter)
|
||||
});
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
|
||||
if (result.Status == MergeStatus.Conflicts)
|
||||
@@ -566,9 +590,9 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
logger.LogTrace("Configuring <{0} ({1})> as author/committer", committerName, committerEmail);
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
repository.Config.Set("user.name", committerName);
|
||||
libGitRepo.Config.Set("user.name", committerName);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
repository.Config.Set("user.email", committerEmail);
|
||||
libGitRepo.Config.Set("user.email", committerEmail);
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -592,9 +616,9 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
logger.LogTrace("Resetting and cleaning untracked files...");
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
repository.RemoveUntrackedFiles();
|
||||
libGitRepo.RemoveUntrackedFiles();
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
repository.Reset(ResetMode.Hard, repository.Head.Tip, new CheckoutOptions
|
||||
libGitRepo.Reset(ResetMode.Hard, libGitRepo.Head.Tip, new CheckoutOptions
|
||||
{
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progress => progressReporter(progress / 10))
|
||||
});
|
||||
@@ -620,10 +644,10 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
|
||||
return await Task.Factory.StartNew(() =>
|
||||
{
|
||||
var remote = repository.Network.Remotes.First();
|
||||
var remote = libGitRepo.Network.Remotes.First();
|
||||
try
|
||||
{
|
||||
repository.Network.Push(repository.Head, GeneratePushOptions(FinalReporter, username, password, cancellationToken));
|
||||
libGitRepo.Network.Push(libGitRepo.Head, GeneratePushOptions(FinalReporter, username, password, cancellationToken));
|
||||
return true;
|
||||
}
|
||||
catch (NonFastForwardException)
|
||||
@@ -648,18 +672,18 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
public Task<bool> IsSha(string committish, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
|
||||
{
|
||||
// check if it's a tag
|
||||
var gitObject = repository.Lookup(committish, ObjectType.Tag);
|
||||
var gitObject = libGitRepo.Lookup(committish, ObjectType.Tag);
|
||||
if (gitObject != null)
|
||||
return false;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// check if it's a branch
|
||||
if (repository.Branches[committish] != null)
|
||||
if (libGitRepo.Branches[committish] != null)
|
||||
return false;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// err on the side of references, if we can't look it up, assume its a reference
|
||||
if (repository.Lookup<Commit>(committish) != null)
|
||||
if (libGitRepo.Lookup<Commit>(committish) != null)
|
||||
return true;
|
||||
return false;
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
|
||||
|
||||
@@ -19,9 +19,14 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
public bool CloneInProgress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IRepositoryFactory"/> for the <see cref="RepositoryManager"/>
|
||||
/// The <see cref="ILibGit2RepositoryFactory"/> for the <see cref="RepositoryManager"/>
|
||||
/// </summary>
|
||||
readonly IRepositoryFactory repositoryFactory;
|
||||
readonly ILibGit2RepositoryFactory repositoryFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILibGit2Commands"/> for the <see cref="RepositoryManager"/>.
|
||||
/// </summary>
|
||||
readonly ILibGit2Commands commands;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="RepositoryManager"/>
|
||||
@@ -57,13 +62,15 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// Construct a <see cref="RepositoryManager"/>
|
||||
/// </summary>
|
||||
/// <param name="repositoryFactory">The value of <see cref="repositoryFactory"/>.</param>
|
||||
/// <param name="commands">The value of <see cref="commands"/>.</param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/></param>
|
||||
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
|
||||
/// <param name="repositoryLogger">The value of <see cref="repositoryLogger"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
/// <param name="repositorySettings">The value of <see cref="repositorySettings"/></param>
|
||||
public RepositoryManager(
|
||||
IRepositoryFactory repositoryFactory,
|
||||
ILibGit2RepositoryFactory repositoryFactory,
|
||||
ILibGit2Commands commands,
|
||||
IIOManager ioManager,
|
||||
IEventConsumer eventConsumer,
|
||||
ILogger<Repository> repositoryLogger,
|
||||
@@ -71,6 +78,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
RepositorySettings repositorySettings)
|
||||
{
|
||||
this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory));
|
||||
this.commands = commands ?? throw new ArgumentNullException(nameof(commands));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
|
||||
this.repositoryLogger = repositoryLogger ?? throw new ArgumentNullException(nameof(repositoryLogger));
|
||||
@@ -175,12 +183,18 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
using (var context = await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
|
||||
try
|
||||
{
|
||||
var repo = await repositoryFactory.CreateFromPath(ioManager.ResolvePath(), cancellationToken).ConfigureAwait(false);
|
||||
var libGitRepo = await repositoryFactory.CreateFromPath(ioManager.ResolvePath(), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (repo == null)
|
||||
if (libGitRepo == null)
|
||||
return null;
|
||||
|
||||
return new Repository(repo, ioManager, eventConsumer, repositoryFactory, repositoryLogger, () =>
|
||||
return new Repository(
|
||||
libGitRepo,
|
||||
commands,
|
||||
ioManager,
|
||||
eventConsumer,
|
||||
repositoryFactory,
|
||||
repositoryLogger, () =>
|
||||
{
|
||||
logger.LogTrace("Releasing semaphore due to Repository disposal...");
|
||||
semaphore.Release();
|
||||
|
||||
@@ -289,7 +289,8 @@ namespace Tgstation.Server.Host.Core
|
||||
});
|
||||
|
||||
// configure component services
|
||||
services.AddSingleton<IRepositoryFactory, RepositoryFactory>();
|
||||
services.AddSingleton<ILibGit2RepositoryFactory, LibGit2RepositoryFactory>();
|
||||
services.AddSingleton<ILibGit2Commands, LibGit2Commands>();
|
||||
services.AddSingleton<IProviderFactory, ProviderFactory>();
|
||||
services.AddSingleton<IChatManagerFactory, ChatManagerFactory>();
|
||||
services.AddSingleton<IInstanceFactory, InstanceFactory>();
|
||||
|
||||
@@ -21,27 +21,22 @@ namespace Tgstation.Server.Host.Core
|
||||
|
||||
var httpEndpoint = configuration
|
||||
.GetSection("Kestrel")
|
||||
.GetSection("Endpoints")
|
||||
.GetSection("EndPoints")
|
||||
.GetSection("Http")
|
||||
.GetSection("Url")
|
||||
.Value;
|
||||
|
||||
HttpApiPort = GetPortFromAddress(httpEndpoint);
|
||||
}
|
||||
if (httpEndpoint == null)
|
||||
throw new InvalidOperationException("Missing required configuration option Kestrel:EndPoints:Http:Url!");
|
||||
|
||||
/// <summary>
|
||||
/// Convert a given <paramref name="address"/> to its port.
|
||||
/// </summary>
|
||||
/// <param name="address">The address <see cref="string"/>.</param>
|
||||
/// <returns>The parsed port.</returns>
|
||||
static ushort GetPortFromAddress(string address)
|
||||
{
|
||||
var splits = address.Split(":", StringSplitOptions.RemoveEmptyEntries);
|
||||
var splits = httpEndpoint.Split(":", StringSplitOptions.RemoveEmptyEntries);
|
||||
var portString = splits.Last();
|
||||
portString = portString.TrimEnd('/');
|
||||
|
||||
if (!UInt16.TryParse(portString, out var result))
|
||||
throw new InvalidOperationException("Failed to parse HTTP API port!");
|
||||
return result;
|
||||
throw new InvalidOperationException($"Failed to parse HTTP EndPoint port: {httpEndpoint}");
|
||||
|
||||
HttpApiPort = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
# THIS SHOULD NOT BE USED TO CREATE THE PRODUCTION BUILD IT'S FOR DEBUGGING ONLY
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
|
||||
WORKDIR /src
|
||||
COPY ["src/Tgstation.Server.Host/Tgstation.Server.Host.csproj", "src/Tgstation.Server.Host/"]
|
||||
COPY ["src/Tgstation.Server.Api/Tgstation.Server.Api.csproj", "src/Tgstation.Server.Api/"]
|
||||
RUN dotnet restore "src/Tgstation.Server.Host/Tgstation.Server.Host.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/src/Tgstation.Server.Host"
|
||||
RUN dotnet build "Tgstation.Server.Host.csproj" -c Debug -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "Tgstation.Server.Host.csproj" -c Debug -o /app/publish
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "Tgstation.Server.Host.dll"]
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.System;
|
||||
|
||||
namespace Tgstation.Server.Host
|
||||
{
|
||||
@@ -29,7 +30,7 @@ namespace Tgstation.Server.Host
|
||||
/// Entrypoint for the <see cref="Program"/>
|
||||
/// </summary>
|
||||
/// <param name="args">The command line arguments</param>
|
||||
/// <returns>The <see cref="Process.ExitCode"/></returns>
|
||||
/// <returns>The <see cref="global::System.Diagnostics.Process.ExitCode"/>.</returns>
|
||||
public static async Task<int> Main(string[] args)
|
||||
{
|
||||
// first arg is 100% always the update path, starting it otherwise is solely for debugging purposes
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Tgstation.Server.Host": {
|
||||
"Local": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"DOTNET_ENVIRONMENT": "Development"
|
||||
"DOTNET_ENVIRONMENT": "Development",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Docker": {
|
||||
"commandName": "Docker",
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"publishAllPorts": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,9 @@ namespace Tgstation.Server.Host
|
||||
throw new ArgumentNullException(nameof(args));
|
||||
|
||||
IHostBuilder CreateDefaultBuilder() => Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
|
||||
.ConfigureAppConfiguration((context, configurationBuilder) => configurationBuilder.SetBasePath(IOManager.ResolvePath()))
|
||||
.ConfigureAppConfiguration((context, configuration) => configuration
|
||||
.SetBasePath(
|
||||
IOManager.ResolvePath()))
|
||||
.ConfigureServices(services => services.RemoveEventLogging());
|
||||
|
||||
var setupWizardHostBuilder = CreateDefaultBuilder()
|
||||
@@ -56,7 +58,7 @@ namespace Tgstation.Server.Host
|
||||
await setupHost.RunAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var hostBuilder = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
|
||||
var hostBuilder = CreateDefaultBuilder()
|
||||
.ConfigureWebHostDefaults(webHostBuilder =>
|
||||
webHostBuilder
|
||||
.UseApplication(postSetupServices)
|
||||
|
||||
@@ -58,6 +58,8 @@ namespace Tgstation.Server.Host.Setup
|
||||
if (services == null)
|
||||
throw new ArgumentNullException(nameof(services));
|
||||
|
||||
services.RemoveEventLogging();
|
||||
|
||||
services.AddSingleton(IOManager);
|
||||
services.AddSingleton(AssemblyInformationProvider);
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Tgstation.Server.Host
|
||||
namespace Tgstation.Server.Host.System
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a <see cref="CancellationToken"/> that triggers when the operating system requests the program shuts down.
|
||||
@@ -26,6 +26,8 @@
|
||||
<PropertyGroup>
|
||||
<NodeModulesFolder>ClientApp/node_modules</NodeModulesFolder>
|
||||
<NpmInstallStampFile>ClientApp/node_modules/.install-stamp</NpmInstallStampFile>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DockerfileContext>..\..</DockerfileContext>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="NpmInstall" Inputs="ClientApp/package-lock.json" Outputs="$(NpmInstallStampFile)">
|
||||
@@ -68,6 +70,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Octokit" Version="0.47.0" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.1" />
|
||||
|
||||
@@ -9,26 +9,26 @@ using System.Threading.Tasks;
|
||||
namespace Tgstation.Server.Host.Components.Repository.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for <see cref="RepositoryFactory"/>.
|
||||
/// Tests for <see cref="LibGit2RepositoryFactory"/>.
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public sealed class TestRepositoryFactory
|
||||
{
|
||||
static IRepositoryFactory CreateFactory() => new RepositoryFactory(Mock.Of<ILogger<RepositoryFactory>>());
|
||||
static ILibGit2RepositoryFactory CreateFactory() => new LibGit2RepositoryFactory(Mock.Of<ILogger<LibGit2RepositoryFactory>>());
|
||||
|
||||
static Task<LibGit2Sharp.IRepository> TestRepoLoading(
|
||||
string path,
|
||||
IRepositoryFactory repositoryFactory = null) =>
|
||||
ILibGit2RepositoryFactory repositoryFactory = null) =>
|
||||
(repositoryFactory ?? CreateFactory())
|
||||
.CreateFromPath(path, default);
|
||||
|
||||
[TestMethod]
|
||||
public void TestConstructionThrows() => Assert.ThrowsException<ArgumentNullException>(() => new RepositoryFactory(null));
|
||||
public void TestConstructionThrows() => Assert.ThrowsException<ArgumentNullException>(() => new LibGit2RepositoryFactory(null));
|
||||
|
||||
[TestMethod]
|
||||
public void TestInMemoryRepoCreation()
|
||||
{
|
||||
new RepositoryFactory(Mock.Of<ILogger<RepositoryFactory>>()).CreateInMemory().Dispose();
|
||||
new LibGit2RepositoryFactory(Mock.Of<ILogger<LibGit2RepositoryFactory>>()).CreateInMemory().Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
Reference in New Issue
Block a user