Merge pull request #1383 from tgstation/V5-NetOnly

TGS5 (.NET 6 update)
This commit is contained in:
Jordan Dominion
2022-09-17 10:51:59 -04:00
committed by GitHub
67 changed files with 357 additions and 358 deletions
+2 -2
View File
@@ -34,7 +34,7 @@ You can of course, as always, ask for help at [#coderbus](irc://irc.rizon.net/co
### Development Environment
You need the Dotnet 3.1 SDK and npm>=v5.7 (in your PATH) to compile the server. In order to build the service version you also need a .NET 4.7.1 build chain
You need the Dotnet 6.0 SDK and npm>=v5.7 (in your PATH) to compile the server. In order to build the service version you also need a .NET 4.7.1 build chain
The recommended IDE is Visual Studio 2019 which has installation options for both of these.
@@ -174,7 +174,7 @@ Whenever you make a change to a model schema that must be reflected in the datab
We have a script to do this.
1. Run `build/GenerateMigrations.sh NameOfMigration` from the project root.
1. You should now have MY/MS migration files generated in `/src/Tgstation.Server.Host/Models/Migrations`. Fix compiler warnings in the generated files. Ensure all classes are in the Tgstation.Server.Host.Models.Migrations namespace.
1. You should now have MY/MS/SL/PG migration files generated in `/src/Tgstation.Server.Host/Models/Migrations`. Fix compiler warnings in the generated files. Ensure all classes are in the Tgstation.Server.Host.Database.Migrations namespace.
1. Manually review what each migration does.
1. Run the server in both configurations to ensure the migrations work.
+87 -68
View File
@@ -1,4 +1,4 @@
name: 'CI'
name: 'CI'
on:
push:
@@ -11,7 +11,7 @@ on:
- master
env:
TGS_DOTNET_VERSION: 3.1.x
TGS_DOTNET_VERSION: 6.0.x
TGS_TEST_DISCORD_CHANNEL: ${{ secrets.DISCORD_CHANNEL_ID }}
TGS_TEST_DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
TGS_TEST_IRC_CHANNEL: ${{ secrets.IRC_CHANNEL }}
@@ -20,6 +20,34 @@ env:
TGS_RELEASE_NOTES_TOKEN: ${{ secrets.DEV_PUSH_TOKEN }}
jobs:
analyze:
name: Code Scanning
runs-on: ubuntu-latest
steps:
- name: Install Node 12.X
uses: actions/setup-node@v3
with:
node-version: 12.x
- name: Upgrade NPM
run: npm install -g npm
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: csharp
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
dmapi-build:
name: Build DMAPI
env:
@@ -46,7 +74,7 @@ jobs:
exit 0
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Build DMAPI Test Project
run: |
@@ -73,7 +101,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Patch Doxyfile
run: |
@@ -114,7 +142,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Upgrade NPM
run: sudo npm install -g npm
@@ -125,17 +153,18 @@ jobs:
linux-unit-tests:
name: Linux Unit Tests
strategy:
fail-fast: false
matrix:
configuration: [ 'Debug', 'Release' ]
runs-on: ubuntu-latest
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Upgrade NPM
run: sudo npm install -g npm
@@ -147,7 +176,7 @@ jobs:
run: sudo dotnet test tgstation-server.sln --no-build --filter FullyQualifiedName!~IntegrationTest -l "console;verbosity=detailed;noprogress=true" -c ${{ matrix.configuration }}NoService --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings -r ./TestResults
- name: Store Code Coverage
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: linux-unit-test-coverage-${{ matrix.configuration }}
path: ./TestResults/
@@ -155,24 +184,22 @@ jobs:
windows-unit-tests:
name: Windows Unit Tests
strategy:
fail-fast: false
matrix:
configuration: [ 'Release' ]
configuration: [ 'Debug', 'Release' ]
runs-on: windows-latest
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Upgrade NPM
run: npm install -g npm
- name: Clean package cache as a temporary workaround for actions/setup-dotnet#155
run: dotnet clean && dotnet nuget locals all --clear
- name: Build
run: dotnet build -c ${{ matrix.configuration }}
@@ -180,7 +207,7 @@ jobs:
run: dotnet test tgstation-server.sln --no-build --filter FullyQualifiedName!~IntegrationTest -l "console;verbosity=detailed;noprogress=true" -c ${{ matrix.configuration }} --collect:"XPlat Code Coverage" --settings build/coverlet.runsettings -r ./TestResults
- name: Store Code Coverage
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: windows-unit-test-coverage-${{ matrix.configuration }}
path: ./TestResults/
@@ -192,13 +219,14 @@ jobs:
TGS_TEST_DATABASE_TYPE: SqlServer
TGS_TEST_DUMP_API_SPEC: yes
strategy:
fail-fast: false
matrix:
watchdog-type: [ 'Basic', 'System' ]
configuration: [ 'Debug', 'Release' ]
runs-on: windows-latest
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
@@ -216,7 +244,7 @@ jobs:
echo "TGS_TEST_CONNECTION_STRING=$(echo $TGS_CONNSTRING_VALUE)" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Set TGS_TEST_PULL_REQUEST_NUMBER
if: ${{ github.event_name == 'pull_request' }}
@@ -233,9 +261,6 @@ jobs:
TEMP_GITHUB_REF="${{ github.event.ref }}"
echo "TGS_GITHUB_REF=${TEMP_GITHUB_REF##*/}" >> $GITHUB_ENV
- name: Clean package cache as a temporary workaround for actions/setup-dotnet#155
run: dotnet clean && dotnet nuget locals all --clear
- name: Run Integration Test
run: |
cd tests/Tgstation.Server.Tests
@@ -243,14 +268,14 @@ jobs:
dotnet test -c ${{ matrix.configuration }} -l "console;verbosity=detailed;noprogress=true" --collect:"XPlat Code Coverage" --settings ../../build/coverlet.runsettings -r ./TestResults
- name: Store Code Coverage
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: windows-integration-test-coverage-${{ matrix.configuration }}-${{ matrix.watchdog-type }}
path: tests/Tgstation.Server.Tests/TestResults/
- name: Store OpenAPI Spec
if: ${{ matrix.configuration == 'Release' && matrix.watchdog-type == 'System' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: openapi-spec
path: C:/swagger.json
@@ -266,7 +291,7 @@ jobs:
- name: Store Server Service
if: ${{ matrix.configuration == 'Release' && matrix.watchdog-type == 'Basic' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ServerService
path: Artifacts/Service/
@@ -309,6 +334,7 @@ jobs:
--health-timeout=5s
--health-retries=3
strategy:
fail-fast: false
matrix:
database-type: [ 'Sqlite', 'PostgresSql', 'MariaDB', 'MySql' ]
watchdog-type: [ 'System' ]
@@ -325,7 +351,7 @@ jobs:
sudo apt-get install -y -o APT::Immediate-Configure=0 libc6-i386 libstdc++6:i386 gdb
- name: Install Node 12.X
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 12.x
@@ -333,7 +359,7 @@ jobs:
run: npm install -g npm
- name: Setup dotnet
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
@@ -367,7 +393,7 @@ jobs:
run: echo "General__UseBasicWatchdog=true" >> $GITHUB_ENV
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Set TGS_TEST_PULL_REQUEST_NUMBER
if: ${{ github.event_name == 'pull_request' }}
@@ -391,7 +417,7 @@ jobs:
dotnet test -c ${{ matrix.configuration }}NoService -l "console;verbosity=detailed;noprogress=true" --collect:"XPlat Code Coverage" --settings ../../build/coverlet.runsettings -r ./TestResults
- name: Store Code Coverage
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: linux-integration-test-coverage-${{ matrix.configuration }}-${{ matrix.watchdog-type }}-${{ matrix.database-type }}
path: tests/Tgstation.Server.Tests/TestResults/
@@ -414,14 +440,14 @@ jobs:
- name: Store Server Console
if: ${{ matrix.configuration == 'Release' && matrix.watchdog-type == 'System' && matrix.database-type == 'MariaDB' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ServerConsole
path: Artifacts/Console/
- name: Store Server Update Package
if: ${{ matrix.configuration == 'Release' && matrix.watchdog-type == 'System' && matrix.database-type == 'PostgresSql' }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: ServerUpdatePackage
path: Artifacts/ServerUpdate/
@@ -432,7 +458,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install Node 12.X
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 12.x
@@ -440,10 +466,10 @@ jobs:
run: npm i -g ibm-openapi-validator@0.51.3
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Retrieve OpenAPI Spec
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: openapi-spec
path: ./swagger
@@ -457,87 +483,80 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout for .codecov.yml
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Retrieve Linux Unit Test Coverage (Debug)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-unit-test-coverage-Debug
path: ./code_coverage/unit_tests/linux_unit_tests_debug
- name: Retrieve Linux Unit Test Coverage (Release)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-unit-test-coverage-Release
path: ./code_coverage/unit_tests/linux_unit_tests_release
- name: Retrieve Linux Integration Test Coverage (Release, System, Sqlite)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-integration-test-coverage-Release-System-Sqlite
path: ./code_coverage/integration_tests/linux_integration_tests_release_system_sqlite
- name: Retrieve Linux Integration Test Coverage (Release, System, PostgresSql)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-integration-test-coverage-Release-System-PostgresSql
path: ./code_coverage/integration_tests/linux_integration_tests_release_system_mariadb
- name: Retrieve Linux Integration Test Coverage (Release, System, MariaDB)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-integration-test-coverage-Release-System-MariaDB
path: ./code_coverage/integration_tests/linux_integration_tests_release_system_mysql
- name: Retrieve Linux Integration Test Coverage (Release, System, MySql)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: linux-integration-test-coverage-Release-System-MySql
path: ./code_coverage/integration_tests/linux_integration_tests_release_system_mysql
- name: Retrieve Windows Unit Test Coverage (Release)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-unit-test-coverage-Release
path: ./code_coverage/unit_tests/windows_unit_tests_release
- name: Retrieve Windows Integration Test Coverage (Debug, Basic)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-integration-test-coverage-Debug-Basic
path: ./code_coverage/integration_tests/windows_integration_tests_debug_basic
- name: Retrieve Windows Integration Test Coverage (Release, Basic)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-integration-test-coverage-Release-Basic
path: ./code_coverage/integration_tests/windows_integration_tests_release_basic
- name: Retrieve Windows Integration Test Coverage (Debug, System)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-integration-test-coverage-Debug-System
path: ./code_coverage/integration_tests/windows_integration_tests_debug_system
- name: Retrieve Windows Integration Test Coverage (Release, System)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: windows-integration-test-coverage-Release-System
path: ./code_coverage/integration_tests/windows_integration_tests_release_system
- name: Upload Unit Test Coverage to CodeCov
uses: codecov/codecov-action@v1
- name: Upload Coverage to CodeCov
uses: codecov/codecov-action@v3
with:
directory: ./code_coverage/unit_tests
flags: unittests
directory: ./code_coverage
fail_ci_if_error: true
- name: Upload Integration Test Coverage to CodeCov
uses: codecov/codecov-action@v1
with:
directory: ./code_coverage/integration_tests
flags: integration
fail_ci_if_error: true
deploy-http:
name: Deploy HTTP API
@@ -546,7 +565,7 @@ jobs:
if: github.event_name == 'push' && contains(github.event.head_commit.message, '[APIDeploy]')
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Parse API version
shell: powershell
@@ -556,7 +575,7 @@ jobs:
echo "TGS_API_VERSION=$apiVersion" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
- name: Retrieve OpenAPI Spec
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: openapi-spec
path: swagger
@@ -590,7 +609,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Parse DMAPI version
shell: powershell
@@ -632,15 +651,15 @@ jobs:
if: github.event_name == 'push' && contains(github.event.head_commit.message, '[NugetDeploy]')
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: ${{ env.TGS_DOTNET_VERSION }}
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Publish API to NuGet
uses: rohith/publish-nuget@v2
uses: brandedoutcast/publish-nuget@v2
with:
PROJECT_FILE_PATH: src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
TAG_COMMIT: false
@@ -648,7 +667,7 @@ jobs:
NUGET_KEY: ${{ secrets.NUGET_API_KEY }}
- name: Publish Client to NuGet
uses: rohith/publish-nuget@v2
uses: brandedoutcast/publish-nuget@v2
with:
PROJECT_FILE_PATH: src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
TAG_COMMIT: false
@@ -662,7 +681,7 @@ jobs:
if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' && contains(github.event.head_commit.message, '[TGSDeploy]')
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Parse TGS version
shell: powershell
@@ -672,25 +691,25 @@ jobs:
echo "TGS_VERSION=$tgsVersion" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
- name: Retrieve Server Service
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: ServerService
path: ServerService
- name: Retrieve Server Console
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: ServerConsole
path: ServerConsole
- name: Retrieve Server Update Package
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: ServerUpdatePackage
path: ServerUpdatePackage
- name: Retrieve OpenAPI Spec
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: openapi-spec
path: swagger
@@ -773,7 +792,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Parse TGS version
run: |
@@ -782,7 +801,7 @@ jobs:
echo "TGS_VERSION=$(xmlstarlet sel -N X="http://schemas.microsoft.com/developer/msbuild/2003" --template --value-of /X:Project/X:PropertyGroup/X:TgsCoreVersion build/Version.props)" >> $GITHUB_ENV
- name: Docker Build and Push
uses: elgohr/Publish-Docker-Github-Action@master
uses: elgohr/Publish-Docker-Github-Action@v4
with:
name: tgstation/server
username: ${{ secrets.DOCKER_USERNAME }}
-42
View File
@@ -1,42 +0,0 @@
name: "Code Scanning"
on:
push:
branches: [dev, master]
pull_request:
branches: [dev, master]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ['csharp']
steps:
- name: Install Node 12.X
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Upgrade NPM
run: npm install -g npm
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v3
- name: Merge master into dev
uses: robotology/gh-action-nightly-merge@v1.3.3
+1 -1
View File
@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/src/Tgstation.Server.Host/bin/Debug/netcoreapp3.1/Tgstation.Server.Host.dll",
"program": "${workspaceFolder}/src/Tgstation.Server.Host/bin/Debug/net6.0/Tgstation.Server.Host.dll",
"args": [],
"cwd": "${workspaceFolder}/src/Tgstation.Server.Host",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
+2 -2
View File
@@ -18,7 +18,7 @@ Older server versions can be found in the V# branches of this repository. Note t
### Pre-Requisites
- [ASP .NET Core Runtime (>= v3.1, < v5.0)](https://dotnet.microsoft.com/download/dotnet/3.1) (Choose the option to `Run Server Apps` for your system) If you plan to install tgstation-server as a Windows service, you should also ensure that your .NET Framework runtime version is >= v4.7.2 (Download can be found on same page). Ensure that the `dotnet` executable file is in your system's `PATH` variable (or that of the user's that will be running the server).
- [ASP .NET Core Runtime (>= v6.0)](https://dotnet.microsoft.com/download/dotnet/6.0) (Choose the option to `Run Server Apps` for your system) If you plan to install tgstation-server as a Windows service, you should also ensure that your .NET Framework runtime version is >= v4.7.2 (Download can be found on same page). Ensure that the `dotnet` executable file is in your system's `PATH` variable (or that of the user's that will be running the server).
- A [MariaDB](https://downloads.mariadb.org/), MySQL, [PostgresSQL](https://www.postgresql.org/download/), or [Microsoft SQL Server](https://www.microsoft.com/en-us/download/details.aspx?id=55994) database engine is required
### Installation
@@ -101,7 +101,7 @@ There are 3 primary supported ways to configure TGS:
- Set environment variables in the form `Section__Subsection=value` or `Section__ArraySubsection__0=value` for arrays.
- Set command line arguments in the form `--Section:Subsection=value` or `--Section:ArraySubsection:0=value` for arrays.
The latter two are not recommended as they cannot be dynamically changed at runtime. See more on ASP.NET core configuration [here](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1).
The latter two are not recommended as they cannot be dynamically changed at runtime. See more on ASP.NET core configuration [here](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-6.0).
#### Manual Configuration
+9 -6
View File
@@ -1,8 +1,8 @@
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim AS build
# install node and npm
# replace shell with bash so we can source files
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | sh
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/v0.39.1/install.sh | sh
ENV NODE_VERSION 14.18.1
@@ -60,18 +60,21 @@ RUN dotnet publish -c Release -o /app
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-buster-slim
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
#needed for byond
RUN apt-get update \
&& apt-get install -y \
gcc-multilib \
gdb \
multiarch-support \
&& rm -rf /var/lib/apt/lists/* \
curl \
&& curl http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/multiarch-support_2.27-3ubuntu1_amd64.deb --output multiarch-support_2.27.deb \
&& curl http://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u12_amd64.deb --output libssl1.0.0.deb \
&& dpkg -i multiarch-support_2.27.deb \
&& dpkg -i libssl1.0.0.deb \
&& rm libssl1.0.0.deb
&& rm multiarch-support_2.27.deb \
&& rm libssl1.0.0.deb \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 5000
+4 -4
View File
@@ -3,14 +3,14 @@
<!-- Integration tests will ensure they match across the board -->
<Import Project="ControlPanelVersion.props" />
<PropertyGroup>
<TgsCoreVersion>4.19.1</TgsCoreVersion>
<TgsCoreVersion>5.0.0</TgsCoreVersion>
<TgsConfigVersion>4.2.0</TgsConfigVersion>
<TgsApiVersion>9.6.0</TgsApiVersion>
<TgsApiLibraryVersion>9.6.0</TgsApiLibraryVersion>
<TgsClientVersion>10.7.0</TgsClientVersion>
<TgsApiLibraryVersion>9.6.1</TgsApiLibraryVersion>
<TgsClientVersion>10.7.1</TgsClientVersion>
<TgsDmapiVersion>6.0.5</TgsDmapiVersion>
<TgsInteropVersion>5.3.0</TgsInteropVersion>
<TgsHostWatchdogVersion>1.1.1</TgsHostWatchdogVersion>
<TgsHostWatchdogVersion>1.1.2</TgsHostWatchdogVersion>
<TgsContainerScriptVersion>1.2.0</TgsContainerScriptVersion>
</PropertyGroup>
</Project>
+2 -2
View File
@@ -2,9 +2,9 @@
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat code coverage">
<DataCollector friendlyName="XPlat Code Coverage">
<Configuration>
<Format>opencover</Format>
<Format>lcov</Format>
<IncludeTestAssembly>false</IncludeTestAssembly>
</Configuration>
</DataCollector>
@@ -47,10 +47,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
@@ -32,10 +32,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -3,11 +3,11 @@
"Tgstation.Server.Host.Console": {
"commandName": "Project",
"commandLineArgs": "--attach-host-debugger",
"workingDirectory": "bin\\Debug\\netcoreapp3.1",
"workingDirectory": "bin\\Debug\\net6.0",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}
@@ -3,7 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<DebugType>Full</DebugType>
<Version>$(TgsCoreVersion)</Version>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
@@ -15,19 +15,16 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
<DocumentationFile>bin\Release\netcoreapp3.1\Tgstation.Server.Host.Console.xml</DocumentationFile>
<DocumentationFile>bin\Release\net6.0\Tgstation.Server.Host.Console.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;SA1652</NoWarn>
<DocumentationFile>bin\Debug\netcoreapp3.1\Tgstation.Server.Host.Console.xml</DocumentationFile>
<DocumentationFile>bin\Debug\net6.0\Tgstation.Server.Host.Console.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- DO NOT UPDATE UNLESS YOU WANT TO DEAL WITH THE LOGGERFACTORY REFACTOR -->
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/Version.props" />
<PropertyGroup>
@@ -25,7 +25,7 @@
<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@@ -24,12 +24,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- DO NOT UPDATE UNLESS YOU WANT TO DEAL WITH THE LOGGERFACTORY REFACTOR -->
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -64,7 +64,7 @@ namespace Tgstation.Server.Host.Watchdog
Directory.Delete(assemblyStoragePath, true);
Directory.CreateDirectory(defaultAssemblyPath);
var sourcePath = "../../../../Tgstation.Server.Host/bin/Debug/netcoreapp3.1";
var sourcePath = "../../../../Tgstation.Server.Host/bin/Debug/net6.0";
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
Directory.CreateDirectory(dirPath.Replace(sourcePath, defaultAssemblyPath));
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.20",
"version": "6.0.8",
"commands": [
"dotnet-ef"
]
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -79,7 +80,7 @@ namespace Tgstation.Server.Host.Components.Byond
public abstract Task InstallByond(string path, Version version, CancellationToken cancellationToken);
/// <inheritdoc />
public Task<byte[]> DownloadVersion(Version version, CancellationToken cancellationToken)
public Task<MemoryStream> DownloadVersion(Version version, CancellationToken cancellationToken)
{
if (version == null)
throw new ArgumentNullException(nameof(version));
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -326,8 +326,7 @@ namespace Tgstation.Server.Host.Components.Byond
Stream downloadedStream = null;
if (customVersionStream == null)
{
var bytes = await byondInstaller.DownloadVersion(version, cancellationToken).ConfigureAwait(false);
downloadedStream = new MemoryStream(bytes);
downloadedStream = await byondInstaller.DownloadVersion(version, cancellationToken).ConfigureAwait(false);
versionZipStream = downloadedStream;
}
else
@@ -349,7 +348,7 @@ namespace Tgstation.Server.Host.Components.Byond
cancellationToken)
.ConfigureAwait(false);
}
catch (WebException e)
catch (HttpRequestException e)
{
// since the user can easily provide non-exitent version numbers, we'll turn this into a JobException
throw new JobException(ErrorCode.ByondDownloadFail, e);
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
@@ -29,8 +30,8 @@ namespace Tgstation.Server.Host.Components.Byond
/// </summary>
/// <param name="version">The <see cref="Version"/> of BYOND to download.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="byte"/>s of the zipfile.</returns>
Task<byte[]> DownloadVersion(Version version, CancellationToken cancellationToken);
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="MemoryStream"/> of the zipfile.</returns>
Task<MemoryStream> DownloadVersion(Version version, CancellationToken cancellationToken);
/// <summary>
/// Does actions necessary to get an extracted BYOND installation working.
@@ -11,9 +11,9 @@ using Remora.Discord.API.Abstractions.Gateway.Events;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.API.Abstractions.Rest;
using Remora.Discord.API.Objects;
using Remora.Discord.Core;
using Remora.Discord.Gateway;
using Remora.Discord.Gateway.Extensions;
using Remora.Rest.Core;
using Remora.Results;
using Tgstation.Server.Api.Models;
@@ -320,9 +320,17 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
return;
}
var unmappedTextChannels = currentGuildsResponse
.Entity
.SelectMany(x => x.Channels.Value);
var guildsClient = serviceProvider.GetRequiredService<IDiscordRestGuildAPI>();
var guildsChannelsTasks = currentGuildsResponse.Entity.Select(
guild => guildsClient.GetGuildChannelsAsync(guild.ID.Value, cancellationToken));
await Task.WhenAll(guildsChannelsTasks).ConfigureAwait(false);
var unmappedTextChannels = guildsChannelsTasks
.Select(task => task.Result)
.SelectMany(guildChannels => guildChannels.Entity)
.Where(guildChannel => guildChannel.Type == ChannelType.GuildText);
lock (mappedChannels)
unmappedTextChannels = unmappedTextChannels
@@ -188,6 +188,7 @@ namespace Tgstation.Server.Host.Components
{
using (LogContext.PushProperty("Instance", metadata.Id))
{
logger.LogDebug("Stopping instance...");
await SetAutoUpdateInterval(0).ConfigureAwait(false);
await Watchdog.StopAsync(cancellationToken).ConfigureAwait(false);
await Task.WhenAll(
@@ -459,6 +459,7 @@ namespace Tgstation.Server.Host.Components
{
try
{
logger.LogDebug("Stopping instance manager...");
var instanceFactoryStopTask = instanceFactory.StopAsync(cancellationToken);
await jobManager.StopAsync(cancellationToken).ConfigureAwait(false);
await Task.WhenAll(instances.Select(x => x.Value.Instance.StopAsync(cancellationToken))).ConfigureAwait(false);
@@ -20,6 +20,6 @@ While the database represents stored instance data, in component code an instanc
`IInstance`s are created via the [IInstanceFactory](./IInstanceFactory.cs) ([implementation](./InstanceFactory.cs)) and are generally controlled via the [IInstanceManager](./IInstanceManager.cs) ([implementation](./InstanceManager.cs)).
Many classes in here implement [IHostedService](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio), `InstanceManager` being the only one that is called by the ASP.NET runtime. In the case of instances `StartAsync()` is called when an `Instance` is being brought online (from server startup or user request). The `Instance` handles calling `StartAsync()` on its various subcomponents that need it. When an `Instance` is being brought offline (from server shutdown/restart/update or user request) the same pattern is followed calling `StopAsync()`.
Many classes in here implement [IHostedService](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio), `InstanceManager` being the only one that is called by the ASP.NET runtime. In the case of instances `StartAsync()` is called when an `Instance` is being brought online (from server startup or user request). The `Instance` handles calling `StartAsync()` on its various subcomponents that need it. When an `Instance` is being brought offline (from server shutdown/restart/update or user request) the same pattern is followed calling `StopAsync()`.
`IInstanceManager` is the sole point where the controllers talk to component code. It also dispatches bridge requests to their relevant instances.
@@ -46,7 +46,7 @@ namespace Tgstation.Server.Host.Components.Repository
var repo = await Task.Factory.StartNew<LibGit2Sharp.IRepository>(
() =>
{
logger.LogTrace("Creating libgit2 repostory at {0}...", path);
logger.LogTrace("Creating libgit2 repostory at {repoPath}...", path);
return new LibGit2Sharp.Repository(path);
},
cancellationToken,
@@ -63,7 +63,7 @@ namespace Tgstation.Server.Host.Components.Repository
{
try
{
logger.LogTrace("Cloning {0} into {1}...", url, path);
logger.LogTrace("Cloning {repoUrl} into {repoPath}...", url, path);
LibGit2Sharp.Repository.Clone(url.ToString(), path, cloneOptions);
}
catch (UserCancelledException ex)
@@ -88,7 +88,11 @@ namespace Tgstation.Server.Host.Components.Repository
var supportsUserPass = supportedCredentialTypes.HasFlag(SupportedCredentialTypes.UsernamePassword);
var supportsAnonymous = supportedCredentialTypes.HasFlag(SupportedCredentialTypes.Default);
logger.LogTrace("Credentials requested. Present: {0}. Supports anonymous: {1}. Supports user/pass: {2}", hasCreds, supportsAnonymous, supportsUserPass);
logger.LogTrace(
"Credentials requested. Present: {credentialsPresent}. Supports anonymous: {credentialsSupportAnon}. Supports user/pass: {credentialsSupportUserPass}",
hasCreds,
supportsAnonymous,
supportsUserPass);
if (supportsUserPass && hasCreds)
return new UsernamePasswordCredentials
{
@@ -261,9 +261,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
string GetFileSha()
{
var content = synchronousIOManager.ReadFile(path);
#pragma warning disable CA5350 // Do not use insecure cryptographic algorithm SHA1.
using var sha1 = new SHA1Managed();
#pragma warning restore CA5350 // Do not use insecure cryptographic algorithm SHA1.
using var sha1 = SHA1.Create();
return String.Join(String.Empty, sha1.ComputeHash(content).Select(b => b.ToString("x2", CultureInfo.InvariantCulture)));
}
@@ -245,6 +245,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
restartRegistration.Dispose();
// DCT: None available, Operation must always run
releaseServers = false; // Server release should have been handled in StopAsync, this causes a DB access that can create ObjectDisposedExceptions
await DisposeAndNullControllers(default).ConfigureAwait(false);
controllerDisposeSemaphore.Dispose();
monitorCts?.Dispose();
@@ -11,7 +11,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using Octokit;
@@ -149,7 +149,7 @@ namespace Tgstation.Server.Host.Controllers
if (!uploadingZip && byondManager.InstalledVersions.Any(x => x == model.Version))
{
Logger.LogInformation(
"User ID {0} changing instance ID {1} BYOND version to {2}",
"User ID {userId} changing instance ID {instanceId} BYOND version to {newByondVersion}",
AuthenticationContext.User.Id,
Instance.Id,
model.Version);
@@ -164,7 +164,7 @@ namespace Tgstation.Server.Host.Controllers
: model.Version;
Logger.LogInformation(
"User ID {0} installing BYOND version to {1} on instance ID {2}",
"User ID {userId} installing BYOND version to {newByondVersion} on instance ID {instanceId}",
AuthenticationContext.User.Id,
installingVersion,
Instance.Id);
@@ -21,6 +21,8 @@ using Tgstation.Server.Host.Jobs;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
#pragma warning disable API1001 // Action method returns a success result without a corresponding ProducesResponseType. Somehow this happens ONLY IN THIS CONTROLLER???
namespace Tgstation.Server.Host.Controllers
{
/// <summary>
@@ -24,7 +24,6 @@ using Serilog.Events;
using Serilog.Formatting.Display;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
@@ -296,6 +295,7 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton<IPasswordHasher<Models.User>, PasswordHasher<Models.User>>();
// configure platform specific services
#pragma warning disable CA1416 // Validate platform compatibility
if (postSetupServices.PlatformIdentifier.IsWindows)
{
AddWatchdog<WindowsWatchdogFactory>(services, postSetupServices);
@@ -325,6 +325,7 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton<IHostedService, PosixSignalHandler>();
}
#pragma warning restore CA1416 // Validate platform compatibility
// configure component/misc services
services.AddScoped<IPortAllocator, PortAllocator>();
@@ -392,8 +393,8 @@ namespace Tgstation.Server.Host.Core
if (logger == null)
throw new ArgumentNullException(nameof(logger));
logger.LogDebug("Content Root: {0}", hostingEnvironment.ContentRootPath);
logger.LogTrace("Web Root: {0}", hostingEnvironment.WebRootPath);
logger.LogDebug("Content Root: {contentRoot}", hostingEnvironment.ContentRootPath);
logger.LogTrace("Web Root: {webRoot}", hostingEnvironment.WebRootPath);
// attempt to restart the server if the configuration changes
if (serverControl.WatchdogPresent)
@@ -437,7 +438,7 @@ namespace Tgstation.Server.Host.Core
}
else if (controlPanelConfiguration.AllowedOrigins?.Count > 0)
{
logger.LogTrace("Access-Control-Allow-Origin: {0}", String.Join(',', controlPanelConfiguration.AllowedOrigins));
logger.LogTrace("Access-Control-Allow-Origin: {allowedOrigins}", String.Join(',', controlPanelConfiguration.AllowedOrigins));
corsBuilder = builder => builder.WithOrigins(controlPanelConfiguration.AllowedOrigins.ToArray());
}
@@ -478,11 +479,11 @@ namespace Tgstation.Server.Host.Core
// 404 anything that gets this far
// End of request pipeline setup
var masterVersionsAttribute = MasterVersionsAttribute.Instance;
logger.LogTrace("Configuration version: {0}", masterVersionsAttribute.RawConfigurationVersion);
logger.LogTrace("DMAPI Interop version: {0}", masterVersionsAttribute.RawInteropVersion);
logger.LogTrace("Web control panel version: {0}", masterVersionsAttribute.RawControlPanelVersion);
logger.LogTrace("Configuration version: {configVersion}", masterVersionsAttribute.RawConfigurationVersion);
logger.LogTrace("DMAPI Interop version: {interopVersion}", masterVersionsAttribute.RawInteropVersion);
logger.LogTrace("Web control panel version: {webCPVersion}", masterVersionsAttribute.RawControlPanelVersion);
logger.LogDebug("Starting hosting on port {0}...", serverPortProvider.HttpApiPort);
logger.LogDebug("Starting hosting on port {httpApiPort}...", serverPortProvider.HttpApiPort);
}
/// <inheritdoc />
+2 -2
View File
@@ -9,5 +9,5 @@ This is a bag of classes used throughout TGS that don't quite belong anywhere el
- [IServerControl](./IServerControl.cs) is an interface used to initiate a restart or update the server.
- [IServerPortProvider](./IServerPortProvider.cs) and [implementation](./ServerPortProvider.cs) is used by services to determine the local TGS API port. Used mainly for telling DreamDaemon where to make bridge requests.
- [OpenApiEnumVarNamesExtension](./OpenApiEnumVarNamesExtension) implements the [x-var-names OpenAPI 3.0 extension](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md#enum) in our generated API json.
- [SemaphoreSlimContext](./SemaphoreSlimContext.cs) is a helper class for working with [.NET asynchronous sempahores](https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-3.1).
- [SwaggerConfiguration](./SwaggerConfiguration.cs) configures [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) to generate our OpenAPI specification.
- [SemaphoreSlimContext](./SemaphoreSlimContext.cs) is a helper class for working with [.NET asynchronous sempahores](https://docs.microsoft.com/en-us/dotnet/api/system.threading.semaphoreslim?view=netcore-6.0).
- [SwaggerConfiguration](./SwaggerConfiguration.cs) configures [Swashbuckle](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) to generate our OpenAPI specification.
@@ -3,7 +3,9 @@ using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.Data.Sqlite;
using MySql.Data.MySqlClient;
using MySqlConnector;
using Npgsql;
using Tgstation.Server.Host.Configuration;
@@ -1,6 +1,7 @@
using System;
using Microsoft.EntityFrameworkCore;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
using Tgstation.Server.Host.Configuration;
@@ -38,19 +39,22 @@ namespace Tgstation.Server.Host.Database
if (databaseConfiguration.DatabaseType != DatabaseType.MariaDB && databaseConfiguration.DatabaseType != DatabaseType.MySql)
throw new InvalidOperationException($"Invalid DatabaseType for {nameof(MySqlDatabaseContext)}!");
ServerVersion serverVersion;
if (!String.IsNullOrEmpty(databaseConfiguration.ServerVersion))
{
serverVersion = ServerVersion.Parse(
databaseConfiguration.ServerVersion,
databaseConfiguration.DatabaseType == DatabaseType.MariaDB
? ServerType.MariaDb
: ServerType.MySql);
}
else
serverVersion = ServerVersion.AutoDetect(databaseConfiguration.ConnectionString);
options.UseMySql(
databaseConfiguration.ConnectionString,
mySqlOptions =>
{
mySqlOptions.EnableRetryOnFailure();
if (!String.IsNullOrEmpty(databaseConfiguration.ServerVersion))
mySqlOptions.ServerVersion(
Version.Parse(databaseConfiguration.ServerVersion),
databaseConfiguration.DatabaseType == DatabaseType.MariaDB
? ServerType.MariaDb
: ServerType.MySql);
});
serverVersion,
mySqlOptions => mySqlOptions.EnableRetryOnFailure());
}
}
}
@@ -39,6 +39,8 @@ namespace Tgstation.Server.Host.Database
if (databaseConfiguration.DatabaseType != DatabaseType.PostgresSql)
throw new InvalidOperationException($"Invalid DatabaseType for {nameof(PostgresSqlDatabaseContext)}!");
// Why the fuck is this an AppContext switch
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
options.UseNpgsql(databaseConfiguration.ConnectionString, options =>
{
options.EnableRetryOnFailure();
-24
View File
@@ -1,24 +0,0 @@
#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"]
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Host.IO
{
/// <summary>
@@ -29,6 +31,11 @@ namespace Tgstation.Server.Host.IO
/// </summary>
public const TaskCreationOptions BlockingTaskCreationOptions = TaskCreationOptions.None;
/// <summary>
/// The <see cref="IAssemblyInformationProvider"/> for the <see cref="DefaultIOManager"/>.
/// </summary>
readonly IAssemblyInformationProvider assemblyInformationProvider;
/// <summary>
/// Recursively empty a directory.
/// </summary>
@@ -64,6 +71,22 @@ namespace Tgstation.Server.Host.IO
dir.Delete(true);
}
/// <summary>
/// Initializes a new instance of the <see cref="DefaultIOManager"/> class.
/// </summary>
/// <param name="assemblyInformationProvider">The value of <see cref="assemblyInformationProvider"/>.</param>
public DefaultIOManager(IAssemblyInformationProvider assemblyInformationProvider)
{
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
}
/// <summary>
/// Initializes a new instance of the <see cref="DefaultIOManager"/> class.
/// </summary>
protected DefaultIOManager()
{
}
/// <inheritdoc />
public async Task CopyDirectory(string src, string dest, IEnumerable<string> ignore, CancellationToken cancellationToken)
{
@@ -270,27 +293,26 @@ namespace Tgstation.Server.Host.IO
TaskScheduler.Current);
/// <inheritdoc />
public async Task<byte[]> DownloadFile(Uri url, CancellationToken cancellationToken)
public async Task<MemoryStream> DownloadFile(Uri url, CancellationToken cancellationToken)
{
// DownloadDataTaskAsync can't be cancelled and is shittily written, don't use it
using var wc = new WebClient();
var tcs = new TaskCompletionSource<byte[]>();
wc.DownloadDataCompleted += (a, b) =>
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.UserAgent.Add(assemblyInformationProvider.ProductInfoHeaderValue);
var webRequestTask = httpClient.GetAsync(url, cancellationToken);
using var response = await webRequestTask.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var memoryStream = new MemoryStream();
try
{
if (b.Error != null)
tcs.TrySetException(b.Error);
else if (b.Cancelled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(b.Result);
};
wc.DownloadDataAsync(url);
using (cancellationToken.Register(() =>
await responseStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
catch
{
wc.CancelAsync();
tcs.TrySetCanceled();
}))
return await tcs.Task.ConfigureAwait(false);
memoryStream.Dispose();
throw;
}
}
/// <inheritdoc />
@@ -332,7 +354,7 @@ namespace Tgstation.Server.Host.IO
TaskScheduler.Current);
/// <inheritdoc />
public FileStream GetFileStream(string path, bool shareWrite) => new FileStream(
public FileStream GetFileStream(string path, bool shareWrite) => new (
ResolvePath(path),
FileMode.Open,
FileAccess.Read,
+2 -2
View File
@@ -184,8 +184,8 @@ namespace Tgstation.Server.Host.IO
/// </summary>
/// <param name="url">The URL to download.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="byte"/>s of the downloaded file.</returns>
Task<byte[]> DownloadFile(Uri url, CancellationToken cancellationToken);
/// <returns>A <see cref="Task{TResult}"/> resulting in a <see cref="MemoryStream"/> of the downloaded file.</returns>
Task<MemoryStream> DownloadFile(Uri url, CancellationToken cancellationToken);
/// <summary>
/// Extract a set of <paramref name="zipFile"/> to a given <paramref name="path"/>.
@@ -95,9 +95,7 @@ namespace Tgstation.Server.Host.IO
return false;
// suppressed due to only using for consistency checks
#pragma warning disable CA5350 // Do not use insecure cryptographic algorithm SHA1.
using (var sha1 = new SHA1Managed())
#pragma warning restore CA5350 // Do not use insecure cryptographic algorithm SHA1.
using (var sha1 = SHA1.Create())
{
string GetSha1(Stream dataToHash) => dataToHash != null && dataToHash.Length != 0 ? String.Join(String.Empty, sha1.ComputeHash(dataToHash).Select(b => b.ToString("x2", CultureInfo.InvariantCulture))) : null;
var originalSha1 = GetSha1(file);
+2 -2
View File
@@ -12,8 +12,8 @@ Server startup can be a bit complicated so here's a walkthrough
1. `CreateServer()` is called on the `IServerFactory` to get the `IServer` instance.
- The factory pattern is used throughout TGS to construct implementations where the composition root is not sufficient. `ServerFactory` is somewhat of an exception to this because it exists outside of the dependency injection umbrella.
1. Inside `CreateServer()` we run the [setup code](./Setup) if need be.
- This is implemented as a separate [dotnet host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1) to the main server.
1. Still inside `CreateServer()` we configure the main [dotnet host (IHostBuilder)](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1) using the application [Application](./Core/Application.cs) class as the [Startup class](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-3.1#the-startup-class).
- This is implemented as a separate [dotnet host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-6.0) to the main server.
1. Still inside `CreateServer()` we configure the main [dotnet host (IHostBuilder)](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-6.0) using the application [Application](./Core/Application.cs) class as the [Startup class](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-6.0#the-startup-class).
1. The `IHostBuilder` is used to construct the return `Server` implementation.
1. `Run()` is called on the `IServer` instance.
1. The DI container is built using the [Application](./Core/Application.cs) class.
@@ -33,7 +33,7 @@ namespace Tgstation.Server.Host.Security
/// <inheritdoc />
public byte[] GetSecureBytes(uint amount)
{
using var rng = new RNGCryptoServiceProvider();
using var rng = RandomNumberGenerator.Create(); // uses RNGCryptoServiceProvider under the hood https://khalidabuhakmeh.com/creating-random-numbers-with-dotnet-core
var byt = new byte[amount];
rng.GetBytes(byt);
return byt;
@@ -1,5 +1,6 @@
using System;
using System.DirectoryServices.AccountManagement;
using System.Runtime.Versioning;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
@@ -11,6 +12,7 @@ namespace Tgstation.Server.Host.Security
/// <summary>
/// <see cref="ISystemIdentity"/> for windows systems.
/// </summary>
[SupportedOSPlatform("windows")]
sealed class WindowsSystemIdentity : ISystemIdentity
{
/// <inheritdoc />
@@ -1,5 +1,6 @@
using System;
using System.DirectoryServices.AccountManagement;
using System.Runtime.Versioning;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
@@ -15,6 +16,7 @@ namespace Tgstation.Server.Host.Security
/// <summary>
/// <see cref="ISystemIdentityFactory"/> for windows systems. Uses long running tasks due to potential networked domains.
/// </summary>
[SupportedOSPlatform("windows")]
sealed class WindowsSystemIdentityFactory : ISystemIdentityFactory
{
/// <summary>
+10 -9
View File
@@ -132,6 +132,11 @@ namespace Tgstation.Server.Host
await host.RunAsync(cancellationTokenSource.Token).ConfigureAwait(false);
}
}
catch (OperationCanceledException ex)
{
if (logger != null)
logger.LogDebug(ex, "Server run cancelled!");
}
catch (Exception ex)
{
CheckExceptionPropagation(ex);
@@ -171,7 +176,7 @@ namespace Tgstation.Server.Host
{
try
{
logger.LogInformation("Updating server to version {0} ({1})...", version, updateZipUrl);
logger.LogInformation("Updating server to version {version} ({zipUrl})...", version, updateZipUrl);
if (cancellationTokenSource == null)
throw new InvalidOperationException("Tried to update a non-running Server!");
@@ -185,11 +190,7 @@ namespace Tgstation.Server.Host
try
{
logger.LogTrace("Downloading zip package...");
updateZipData = new MemoryStream(
await ioManager.DownloadFile(
updateZipUrl,
cancellationToken)
.ConfigureAwait(false));
updateZipData = await ioManager.DownloadFile(updateZipUrl, cancellationToken).ConfigureAwait(false);
}
catch (Exception e1)
{
@@ -216,7 +217,7 @@ namespace Tgstation.Server.Host
try
{
logger.LogTrace("Extracting zip package to {0}...", updatePath);
logger.LogTrace("Extracting zip package to {extractPath}...", updatePath);
await ioManager.ZipToDirectory(updatePath, updateZipData, cancellationToken).ConfigureAwait(false);
}
catch (Exception e)
@@ -267,7 +268,7 @@ namespace Tgstation.Server.Host
lock (restartLock)
if (!shutdownInProgress)
{
logger.LogTrace("Registering restart handler {0}...", handler);
logger.LogTrace("Registering restart handler {handlerImplementationName}...", handler);
restartHandlers.Add(handler);
return new RestartRegistration(() =>
{
@@ -331,7 +332,7 @@ namespace Tgstation.Server.Host
// if the watchdog isn't required and there's no issue, this is just a graceful shutdown
bool isGracefulShutdown = !requireWatchdog && exception == null;
logger.LogTrace(
"Begin {0}...",
"Begin {restartType}...",
isGracefulShutdown
? "graceful shutdown"
: "restart");
@@ -19,16 +19,16 @@ namespace Tgstation.Server.Host.Setup
/// </summary>
class SetupApplication
{
/// <summary>
/// The <see cref="IIOManager"/> for the <see cref="SetupApplication"/>.
/// </summary>
protected static readonly IIOManager IOManager = new DefaultIOManager();
/// <summary>
/// The <see cref="IAssemblyInformationProvider"/> for the <see cref="SetupApplication"/>.
/// </summary>
protected static readonly IAssemblyInformationProvider AssemblyInformationProvider = new AssemblyInformationProvider();
/// <summary>
/// The <see cref="IIOManager"/> for the <see cref="SetupApplication"/>.
/// </summary>
protected static readonly IIOManager IOManager = new DefaultIOManager(AssemblyInformationProvider);
/// <summary>
/// The <see cref="IConfiguration"/> for the <see cref="SetupApplication"/>.
/// </summary>
@@ -15,7 +15,9 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MySql.Data.MySqlClient;
using MySqlConnector;
using Npgsql;
using Tgstation.Server.Host.Configuration;
@@ -25,7 +25,7 @@ namespace Tgstation.Server.Host.System
public string VersionString { get; }
/// <inheritdoc />
public ProductInfoHeaderValue ProductInfoHeaderValue => new ProductInfoHeaderValue(
public ProductInfoHeaderValue ProductInfoHeaderValue => new (
VersionPrefix,
Version.ToString());
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
@@ -16,6 +17,7 @@ using Tgstation.Server.Host.Jobs;
namespace Tgstation.Server.Host.System
{
/// <inheritdoc />
[SupportedOSPlatform("windows")]
sealed class WindowsProcessFeatures : IProcessFeatures
{
/// <summary>
@@ -2,16 +2,16 @@
<Import Project="../../build/Version.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<DebugType>Full</DebugType>
<Version>$(TgsCoreVersion)</Version>
<LangVersion>latest</LangVersion>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
<IsPackable>false</IsPackable>
<IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
<DocumentationFile>bin\$(Configuration)\netcoreapp3.1\Tgstation.Server.Host.xml</DocumentationFile>
<DocumentationFile>bin\$(Configuration)\net6.0\Tgstation.Server.Host.xml</DocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<NoWarn>API1000,IDE0004</NoWarn>
<NoWarn>API1000</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
@@ -35,7 +35,7 @@
<Touch Files="$(NpmInstallStampFile)" AlwaysCreate="true" />
</Target>
<Target Name="NpmBuild" BeforeTargets="BeforeBuild" DependsOnTargets="ClientInstall" Inputs="@(ClientApp)" Outputs="wwwroot\index.html">
<Target Name="NpmBuild" BeforeTargets="BeforeBuild" DependsOnTargets="ClientInstall" Inputs="../../build/ControlPanelVersion.props" Outputs="wwwroot\index.html">
<Message Text="Building web control panel..." Importance="high" />
<Exec WorkingDirectory="ClientApp" Command="yarn run msbuild" />
</Target>
@@ -69,41 +69,37 @@
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="1.5.3" />
<PackageReference Include="GitLabApiClient" Version="1.8.0" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0034" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.20" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.20" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.20">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.18" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.1.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.18" />
<PackageReference Include="Octokit" Version="0.50.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.7" />
<PackageReference Include="Remora.Discord" Version="3.0.72" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="2.2.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.6" />
<PackageReference Include="Octokit" Version="3.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" />
<PackageReference Include="Remora.Discord" Version="2022.48.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.4.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.4.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.3" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="5.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.13.1" />
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.2.16" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="6.0.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" />
<PackageReference Include="System.Management" Version="6.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="6.15.0" />
</ItemGroup>
<ItemGroup>
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -14,13 +14,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mono.Unix.Native;
using Moq;
using Tgstation.Server.Host.Core;
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
@@ -9,8 +9,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -1,7 +1,8 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.IO;
using System.Threading.Tasks;
using Tgstation.Server.Host.IO;
@@ -21,7 +22,7 @@ namespace Tgstation.Server.Host.Components.Byond.Tests
Assert.ThrowsException<ArgumentNullException>(() => new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, null));
var mockLogger = new Mock<ILogger<PosixByondInstaller>>();
new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockLogger.Object);
_ = new PosixByondInstaller(mockPostWriteHandler.Object, mockIOManager.Object, mockLogger.Object);
}
[TestMethod]
@@ -46,11 +47,11 @@ namespace Tgstation.Server.Host.Components.Byond.Tests
await Assert.ThrowsExceptionAsync<ArgumentNullException>(() => installer.DownloadVersion(null, default)).ConfigureAwait(false);
var ourArray = Array.Empty<byte>();
mockIOManager.Setup(x => x.DownloadFile(It.Is<Uri>(uri => uri == new Uri("https://secure.byond.com/download/build/511/511.1385_byond_linux.zip")), default)).Returns(Task.FromResult(ourArray)).Verifiable();
mockIOManager.Setup(x => x.DownloadFile(It.Is<Uri>(uri => uri == new Uri("https://secure.byond.com/download/build/511/511.1385_byond_linux.zip")), default)).Returns(Task.FromResult(new MemoryStream(ourArray))).Verifiable();
var result = await installer.DownloadVersion(new Version(511, 1385), default).ConfigureAwait(false);
Assert.AreSame(ourArray, result);
Assert.AreSame(ourArray, result.ToArray());
mockIOManager.Verify();
}
@@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MySql.Data.MySqlClient;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MySqlConnector;
using System;
using System.Data.SqlClient;
@@ -57,7 +57,7 @@ namespace Tgstation.Server.Host.System.Tests
processExecutor = new ProcessExecutor(
new PosixProcessFeatures(
new Lazy<IProcessExecutor>(() => processExecutor),
new DefaultIOManager(),
new DefaultIOManager(new AssemblyInformationProvider()),
loggerFactory.CreateLogger<PosixProcessFeatures>()),
loggerFactory.CreateLogger<ProcessExecutor>(),
loggerFactory);
@@ -1,8 +1,8 @@
using Castle.Core.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Tgstation.Server.Host.IO;
@@ -20,9 +20,9 @@ namespace Tgstation.Server.Host.System.Tests
[TestInitialize]
public void Init()
{
features = new PlatformIdentifier().IsWindows
features = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of<ILogger<WindowsProcessFeatures>>())
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => null), new DefaultIOManager(), Mock.Of<ILogger<PosixProcessFeatures>>());
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => null), new DefaultIOManager(new AssemblyInformationProvider()), Mock.Of<ILogger<PosixProcessFeatures>>());
}
[TestMethod]
@@ -1,4 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.IO;
@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.System;
namespace Tgstation.Server.Host.Tests
{
@@ -70,7 +71,7 @@ namespace Tgstation.Server.Host.Tests
mockServer.Setup(x => x.Run(It.IsAny<CancellationToken>())).Throws(exception);
mockServer.SetupGet(x => x.RestartRequested).Returns(true);
var mockServerFactory = new Mock<IServerFactory>();
mockServerFactory.SetupGet(x => x.IOManager).Returns(new DefaultIOManager());
mockServerFactory.SetupGet(x => x.IOManager).Returns(new DefaultIOManager(new AssemblyInformationProvider()));
mockServerFactory.Setup(x => x.CreateServer(It.IsNotNull<string[]>(), It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(mockServer.Object);
Program.ServerFactory = mockServerFactory.Object;
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
@@ -14,14 +14,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Tests.Instance
{
sealed class ByondTest : JobsRequiredTest
{
public static readonly Version TestVersion = new Version(513, 1536);
public static readonly Version TestVersion = new (513, 1536);
readonly IByondClient byondClient;
@@ -90,16 +90,15 @@ namespace Tgstation.Server.Tests.Instance
var byondInstaller = new PlatformIdentifier().IsWindows
? (IByondInstaller)new WindowsByondInstaller(
Mock.Of<IProcessExecutor>(),
new DefaultIOManager(),
new DefaultIOManager(new AssemblyInformationProvider()),
Mock.Of<ILogger<WindowsByondInstaller>>())
: new PosixByondInstaller(
Mock.Of<IPostWriteHandler>(),
new DefaultIOManager(),
new DefaultIOManager(new AssemblyInformationProvider()),
Mock.Of<ILogger<PosixByondInstaller>>());
// get the bytes for stable
using var stableBytesMs = new MemoryStream(
await byondInstaller.DownloadVersion(TestVersion, cancellationToken));
using var stableBytesMs = await byondInstaller.DownloadVersion(TestVersion, cancellationToken);
var test = await byondClient.SetActiveVersion(
new ByondVersionRequest
@@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -228,7 +229,7 @@ namespace Tgstation.Server.Tests.Instance
using var ddProc = ddProcs.Single();
IProcessExecutor executor = null;
executor = new ProcessExecutor(
new PlatformIdentifier().IsWindows
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of<ILogger<WindowsProcessFeatures>>())
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => executor), Mock.Of<IIOManager>(), Mock.Of<ILogger<PosixProcessFeatures>>()),
Mock.Of<ILogger<ProcessExecutor>>(),
@@ -826,9 +826,10 @@ namespace Tgstation.Server.Tests
{
// Dump swagger to disk
// This is purely for CI
var webRequest = WebRequest.Create(server.Url.ToString() + "swagger/v1/swagger.json");
using var response = webRequest.GetResponse();
using var content = response.GetResponseStream();
using var httpClient = new HttpClient();
var webRequestTask = httpClient.GetAsync(server.Url.ToString() + "swagger/v1/swagger.json");
using var response = await webRequestTask;
using var content = await response.Content.ReadAsStreamAsync();
using var output = new FileStream(@"C:\swagger.json", FileMode.Create);
await content.CopyToAsync(output);
}
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.5" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
</ItemGroup>
<ItemGroup>
+2 -2
View File
@@ -2,12 +2,12 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="octokit" Version="0.50.0" />
<PackageReference Include="octokit" Version="3.0.0" />
</ItemGroup>
</Project>