mirror of
https://github.com/Smaug123/PulumiConfig
synced 2025-10-25 09:28:39 +00:00
Compare commits
26 Commits
3eec70b88d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a33e60324b | ||
|
|
17bfb62adc | ||
|
|
7a2f9017d0 | ||
|
|
d3793f9b40 | ||
|
|
f188ede756 | ||
|
|
0986cfee52 | ||
|
|
d42652dc43 | ||
|
|
3706de1a14 | ||
|
|
8587f48d28 | ||
|
|
43766bad42 | ||
|
|
3d095e25ae | ||
|
|
fcd5cb82a8 | ||
|
|
656b93b248 | ||
|
|
58b958ae86 | ||
|
|
2df318d570 | ||
|
|
233e8f5c96 | ||
|
|
0e44c0219f | ||
|
|
585b7b9fbc | ||
|
|
2c238bff62 | ||
|
|
a4e1417e2a | ||
|
|
6f4bc26313 | ||
|
|
e879dbcd60 | ||
|
|
24d3d8c00a | ||
|
|
078dc8e416 | ||
|
|
6d6c107f67 | ||
|
|
a2c79d0df0 |
@@ -3,7 +3,7 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"fantomas": {
|
||||
"version": "5.2.0-alpha-010",
|
||||
"version": "6.3.16",
|
||||
"commands": [
|
||||
"fantomas"
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ fsharp_space_before_class_constructor=true
|
||||
fsharp_space_before_member=true
|
||||
fsharp_space_before_colon=true
|
||||
fsharp_space_before_semicolon=true
|
||||
fsharp_multiline_block_brackets_on_same_column=true
|
||||
fsharp_multiline_bracket_style=aligned
|
||||
fsharp_newline_between_type_definition_and_members=true
|
||||
fsharp_align_function_signature_to_indentation=true
|
||||
fsharp_alternative_long_member_definitions=true
|
||||
|
||||
23
.envrc
Normal file
23
.envrc
Normal file
@@ -0,0 +1,23 @@
|
||||
use flake
|
||||
DOTNET_PATH=$(readlink "$(which dotnet)")
|
||||
SETTINGS_FILE=$(find . -maxdepth 1 -type f -name '*.sln.DotSettings.user')
|
||||
MSBUILD=$(realpath "$(find "$(dirname "$DOTNET_PATH")/../share/dotnet/sdk" -maxdepth 2 -type f -name MSBuild.dll)")
|
||||
if [ -f "$SETTINGS_FILE" ] ; then
|
||||
xmlstarlet ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:shemas-jetbrains-com:settings-storage-xaml" \
|
||||
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue']" \
|
||||
--value "$(realpath "$(dirname "$DOTNET_PATH")/../share/dotnet/dotnet")" \
|
||||
"$SETTINGS_FILE"
|
||||
|
||||
xmlstarlet ed --inplace \
|
||||
-N wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" \
|
||||
-N x="http://schemas.microsoft.com/winfx/2006/xaml" \
|
||||
-N s="clr-namespace:System;assembly=mscorlib" \
|
||||
-N ss="urn:shemas-jetbrains-com:settings-storage-xaml" \
|
||||
--update "//s:String[@x:Key='/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue']" \
|
||||
--value "$MSBUILD" \
|
||||
"$SETTINGS_FILE"
|
||||
fi
|
||||
1
.fantomasignore
Normal file
1
.fantomasignore
Normal file
@@ -0,0 +1 @@
|
||||
.direnv/
|
||||
13
.github/workflows/dotnetcore.yml
vendored
13
.github/workflows/dotnetcore.yml
vendored
@@ -23,16 +23,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v17
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
run: nix develop --command dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration ${{matrix.config}}
|
||||
run: nix develop --command dotnet build --no-restore --configuration ${{matrix.config}}
|
||||
- name: Test
|
||||
run: dotnet test --no-build --verbosity normal --configuration ${{matrix.config}}
|
||||
run: nix develop --command dotnet test --no-build --verbosity normal --configuration ${{matrix.config}}
|
||||
|
||||
check-dotnet-format:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -359,3 +359,5 @@ MigrationBackup/
|
||||
|
||||
/.profile
|
||||
/.profile-*-link
|
||||
|
||||
.direnv/
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="TestConfiguration.fs" />
|
||||
<Compile Include="TestJsonSchema.fs" />
|
||||
<EmbeddedResource Include="..\PulumiWebServer\Nix\config.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsCheck" Version="2.16.5" />
|
||||
<PackageReference Include="FsUnit" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="NJsonSchema" Version="10.8.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PulumiWebServer\PulumiWebServer.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="TestConfiguration.fs" />
|
||||
<Compile Include="TestJsonSchema.fs" />
|
||||
<EmbeddedResource Include="..\PulumiWebServer\Nix\config.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FsCheck" Version="3.3.1" />
|
||||
<PackageReference Include="FsUnit" Version="7.1.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
|
||||
<PackageReference Include="NJsonSchema" Version="11.5.1" />
|
||||
<PackageReference Include="NJsonSchema.NewtonsoftJson" Version="11.5.1" />
|
||||
<PackageReference Include="NUnit" Version="4.4.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="5.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PulumiWebServer\PulumiWebServer.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -4,6 +4,7 @@ open System
|
||||
open System.IO
|
||||
open NUnit.Framework
|
||||
open FsCheck
|
||||
open FsCheck.FSharp
|
||||
open FsUnitTyped
|
||||
open PulumiWebServer
|
||||
|
||||
@@ -18,7 +19,7 @@ module TestConfiguration =
|
||||
|
||||
let bashStringGenerator =
|
||||
gen {
|
||||
let! s = Arb.generate<string>
|
||||
let! s = ArbMap.defaults |> ArbMap.generate<string>
|
||||
return BashString.make s
|
||||
}
|
||||
|
||||
@@ -37,14 +38,25 @@ module TestConfiguration =
|
||||
|
||||
[<Test>]
|
||||
let ``Serialisation round-trip`` () =
|
||||
Arb.register<MyGenerators> () |> ignore
|
||||
let arbMap =
|
||||
ArbMap.defaults
|
||||
|> ArbMap.mergeArb
|
||||
{ new Arbitrary<FileInfo>() with
|
||||
override x.Generator = fileInfoGenerator
|
||||
override x.Shrinker t = Seq.empty
|
||||
}
|
||||
|> ArbMap.mergeArb
|
||||
{ new Arbitrary<BashString>() with
|
||||
override x.Generator = bashStringGenerator
|
||||
override x.Shrinker t = Seq.empty
|
||||
}
|
||||
|
||||
let property (c : Configuration) : bool =
|
||||
let serialised = SerialisedConfig.Make c
|
||||
let roundTripped = SerialisedConfig.Deserialise serialised
|
||||
c = roundTripped
|
||||
|
||||
property |> Check.QuickThrowOnFailure
|
||||
Check.One (Config.QuickThrowOnFailure, Prop.forAll (arbMap.ArbFor<_> ()) property)
|
||||
|
||||
[<Test>]
|
||||
let ``Specific example`` () =
|
||||
@@ -58,6 +70,8 @@ module TestConfiguration =
|
||||
Subdomains = Set.empty
|
||||
AcmeEmail = EmailAddress "test@example.com"
|
||||
RemoteUsername = Username "non-root"
|
||||
RadicaleConfig = None
|
||||
GiteaConfig = None
|
||||
}
|
||||
|
||||
let serialised = SerialisedConfig.Make publicConfig
|
||||
|
||||
@@ -3,7 +3,6 @@ namespace PulumiWebServer.Test
|
||||
open System.IO
|
||||
open System.Reflection
|
||||
open PulumiWebServer
|
||||
open NJsonSchema.Generation
|
||||
open NJsonSchema.Validation
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
@@ -16,19 +15,21 @@ module TestSchema =
|
||||
|
||||
[<Test>]
|
||||
let ``Example conforms to schema`` () =
|
||||
let executing = Assembly.GetExecutingAssembly().Location |> FileInfo
|
||||
task {
|
||||
let executing = Assembly.GetExecutingAssembly().Location |> FileInfo
|
||||
|
||||
let schemaFile =
|
||||
Utils.findFileAbove "PulumiWebServer/config.schema.json" executing.Directory
|
||||
let schemaFile =
|
||||
Utils.findFileAbove "PulumiWebServer/config.schema.json" executing.Directory
|
||||
|
||||
let schema = JsonSchema.FromJsonAsync(File.ReadAllText schemaFile.FullName).Result
|
||||
let! schema = JsonSchema.FromJsonAsync (File.ReadAllText schemaFile.FullName)
|
||||
|
||||
let json = Utils.getEmbeddedResource typeof<Utils.Dummy>.Assembly "config.json"
|
||||
let json = Utils.getEmbeddedResource typeof<Utils.Dummy>.Assembly "config.json"
|
||||
|
||||
let validator = JsonSchemaValidator ()
|
||||
let errors = validator.Validate (json, schema)
|
||||
let validator = JsonSchemaValidator ()
|
||||
let errors = validator.Validate (json, schema)
|
||||
|
||||
errors |> shouldBeEmpty
|
||||
errors |> shouldBeEmpty
|
||||
}
|
||||
|
||||
[<Test>]
|
||||
let ``Example can be loaded`` () =
|
||||
@@ -41,8 +42,8 @@ module TestSchema =
|
||||
writer.WriteLine config
|
||||
writer.Flush ()
|
||||
|
||||
stream.Seek (0L, SeekOrigin.Begin) |> ignore
|
||||
Configuration.get stream |> ignore
|
||||
stream.Seek (0L, SeekOrigin.Begin) |> ignore<int64>
|
||||
Configuration.get stream |> ignore<Configuration>
|
||||
|
||||
[<Test>]
|
||||
[<Explicit "Run this to regenerate the schema file">]
|
||||
@@ -53,7 +54,8 @@ module TestSchema =
|
||||
|> fun fi -> fi.Directory
|
||||
|> Utils.findFileAbove "PulumiWebServer/config.schema.json"
|
||||
|
||||
let settings = JsonSchemaGeneratorSettings ()
|
||||
let settings =
|
||||
NJsonSchema.NewtonsoftJson.Generation.NewtonsoftJsonSchemaGeneratorSettings ()
|
||||
|
||||
settings.SerializerSettings <-
|
||||
JsonSerializerSettings (ContractResolver = CamelCasePropertyNamesContractResolver ())
|
||||
|
||||
@@ -5,9 +5,7 @@ open System.IO
|
||||
[<RequireQualifiedAccess>]
|
||||
module Utils =
|
||||
|
||||
type Dummy =
|
||||
class
|
||||
end
|
||||
type Dummy = class end
|
||||
|
||||
let rec findFileAbove (fileName : string) (di : DirectoryInfo) =
|
||||
if isNull di then
|
||||
|
||||
1
PulumiWebServer/.gitignore
vendored
Normal file
1
PulumiWebServer/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
venv/
|
||||
@@ -3,19 +3,20 @@ namespace PulumiWebServer
|
||||
open Nager.PublicSuffix
|
||||
open Pulumi
|
||||
open Pulumi.Cloudflare
|
||||
open Pulumi.Cloudflare.Inputs
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type ARecord =
|
||||
{
|
||||
IPv4 : Record option
|
||||
IPv6 : Record option
|
||||
IPv4 : DnsRecord option
|
||||
IPv6 : DnsRecord option
|
||||
}
|
||||
|
||||
type Cname =
|
||||
{
|
||||
Source : string
|
||||
Target : string
|
||||
Record : Record
|
||||
Record : DnsRecord
|
||||
}
|
||||
|
||||
type DnsRecord =
|
||||
@@ -27,7 +28,7 @@ module Cloudflare =
|
||||
|
||||
let getZone (DomainName domain) : Output<ZoneId> =
|
||||
let args = GetZoneInvokeArgs ()
|
||||
args.Name <- domain
|
||||
args.Filter <- GetZoneFilterInputArgs (Name = domain, Match = "any")
|
||||
|
||||
output {
|
||||
let! zone = GetZone.Invoke args
|
||||
@@ -40,26 +41,26 @@ module Cloudflare =
|
||||
| None -> None
|
||||
| Some ipv6Addr ->
|
||||
|
||||
let args = RecordArgs ()
|
||||
let args = DnsRecordArgs ()
|
||||
args.ZoneId <- Input.lift zone
|
||||
args.Name <- Input.lift name
|
||||
args.Ttl <- Input.lift 60
|
||||
args.Type <- Input.lift "AAAA"
|
||||
args.Value <- Input.lift ipv6Addr
|
||||
Record ($"{name}-ipv6", args) |> Some
|
||||
args.Content <- Input.lift ipv6Addr
|
||||
DnsRecord ($"{name}-ipv6", args) |> Some
|
||||
|
||||
let v4 =
|
||||
match ipAddress.IPv4 with
|
||||
| None -> None
|
||||
| Some ipv4Addr ->
|
||||
|
||||
let args = RecordArgs ()
|
||||
let args = DnsRecordArgs ()
|
||||
args.ZoneId <- Input.lift zone
|
||||
args.Name <- Input.lift name
|
||||
args.Ttl <- Input.lift 60
|
||||
args.Type <- Input.lift "A"
|
||||
args.Value <- Input.lift ipv4Addr
|
||||
Record ($"{name}-ipv4", args) |> Some
|
||||
args.Content <- Input.lift ipv4Addr
|
||||
DnsRecord ($"{name}-ipv4", args) |> Some
|
||||
|
||||
{
|
||||
ARecord.IPv4 = v4
|
||||
@@ -67,6 +68,7 @@ module Cloudflare =
|
||||
}
|
||||
|
||||
let addDns
|
||||
(parser : IDomainParser)
|
||||
(domain : DomainName)
|
||||
(cnames : Map<WellKnownCname, WellKnownCnameTarget>)
|
||||
(subdomains : Set<WellKnownSubdomain>)
|
||||
@@ -76,9 +78,8 @@ module Cloudflare =
|
||||
=
|
||||
let globalSubdomain =
|
||||
let (DomainName domain) = domain
|
||||
let parser = DomainParser (WebTldRuleProvider ())
|
||||
let info = parser.Parse domain
|
||||
info.SubDomain |> Option.ofObj
|
||||
info.Subdomain |> Option.ofObj
|
||||
|
||||
let subdomainMarker =
|
||||
match globalSubdomain with
|
||||
@@ -91,16 +92,16 @@ module Cloudflare =
|
||||
|> Seq.map (fun (cname, target) ->
|
||||
let source = $"{cname.ToString ()}{subdomainMarker}"
|
||||
let target = WellKnownCnameTarget.Reify domain target
|
||||
let args = RecordArgs ()
|
||||
let args = DnsRecordArgs ()
|
||||
args.ZoneId <- Input.lift zone
|
||||
args.Name <- Input.lift source
|
||||
args.Ttl <- Input.lift 60
|
||||
args.Type <- Input.lift "CNAME"
|
||||
args.Value <- Input.lift target
|
||||
args.Content <- Input.lift target
|
||||
|
||||
source,
|
||||
{
|
||||
Record = Record ($"{cname}{subdomainMarker}-cname", args)
|
||||
Record = DnsRecord ($"{cname}{subdomainMarker}-cname", args)
|
||||
Source = source
|
||||
Target = target
|
||||
}
|
||||
|
||||
@@ -5,6 +5,23 @@ open System.Collections.Generic
|
||||
open System.IO
|
||||
open Newtonsoft.Json
|
||||
|
||||
[<NoComparison>]
|
||||
type RadicaleConfig =
|
||||
{
|
||||
User : string
|
||||
Password : string
|
||||
GitEmail : string
|
||||
}
|
||||
|
||||
[<NoComparison>]
|
||||
type GiteaConfig =
|
||||
{
|
||||
ServerPassword : string
|
||||
AdminPassword : string
|
||||
AdminEmailAddress : string
|
||||
AdminUsername : string
|
||||
}
|
||||
|
||||
[<NoComparison>]
|
||||
type Configuration =
|
||||
{
|
||||
@@ -30,6 +47,8 @@ type Configuration =
|
||||
AcmeEmail : EmailAddress
|
||||
/// Username for the user account to be created on the server
|
||||
RemoteUsername : Username
|
||||
RadicaleConfig : RadicaleConfig option
|
||||
GiteaConfig : GiteaConfig option
|
||||
}
|
||||
|
||||
member this.PublicKey =
|
||||
@@ -39,6 +58,61 @@ type Configuration =
|
||||
let (PrivateKey k) = this.PrivateKey
|
||||
Path.Combine (k.Directory.FullName, k.Name + ".pub") |> FileInfo |> PublicKey
|
||||
|
||||
[<NoComparison>]
|
||||
type SerialisedRadicaleConfig =
|
||||
{
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
User : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
Password : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
GitEmail : string
|
||||
}
|
||||
|
||||
static member Make (config : RadicaleConfig) : SerialisedRadicaleConfig =
|
||||
{
|
||||
User = config.User
|
||||
Password = config.Password
|
||||
GitEmail = config.GitEmail
|
||||
}
|
||||
|
||||
static member Deserialise (config : SerialisedRadicaleConfig) : RadicaleConfig =
|
||||
{
|
||||
User = config.User
|
||||
Password = config.Password
|
||||
GitEmail = config.GitEmail
|
||||
}
|
||||
|
||||
[<NoComparison>]
|
||||
type SerialisedGiteaConfig =
|
||||
{
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
ServerPassword : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
AdminPassword : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
AdminEmailAddress : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
AdminUsername : string
|
||||
}
|
||||
|
||||
static member Make (config : GiteaConfig) : SerialisedGiteaConfig =
|
||||
{
|
||||
ServerPassword = config.ServerPassword
|
||||
AdminPassword = config.AdminPassword
|
||||
AdminEmailAddress = config.AdminEmailAddress
|
||||
AdminUsername = config.AdminUsername
|
||||
}
|
||||
|
||||
static member Deserialise (config : SerialisedGiteaConfig) : GiteaConfig =
|
||||
{
|
||||
ServerPassword = config.ServerPassword
|
||||
AdminPassword = config.AdminPassword
|
||||
AdminEmailAddress = config.AdminEmailAddress
|
||||
AdminUsername = config.AdminUsername
|
||||
}
|
||||
|
||||
|
||||
[<NoComparison>]
|
||||
[<RequireQualifiedAccess>]
|
||||
type SerialisedConfig =
|
||||
@@ -61,6 +135,10 @@ type SerialisedConfig =
|
||||
AcmeEmail : string
|
||||
[<JsonProperty(Required = Required.Always)>]
|
||||
RemoteUsername : string
|
||||
[<JsonProperty(Required = Required.Default)>]
|
||||
RadicaleConfig : SerialisedRadicaleConfig
|
||||
[<JsonProperty(Required = Required.Default)>]
|
||||
GiteaConfig : SerialisedGiteaConfig
|
||||
}
|
||||
|
||||
static member Make (config : Configuration) =
|
||||
@@ -82,6 +160,11 @@ type SerialisedConfig =
|
||||
Subdomains = config.Subdomains |> Seq.map (fun sub -> sub.ToString ()) |> Seq.toArray
|
||||
AcmeEmail = config.AcmeEmail.ToString ()
|
||||
RemoteUsername = config.RemoteUsername.ToString ()
|
||||
RadicaleConfig =
|
||||
config.RadicaleConfig
|
||||
|> Option.map SerialisedRadicaleConfig.Make
|
||||
|> Option.toObj
|
||||
GiteaConfig = config.GiteaConfig |> Option.map SerialisedGiteaConfig.Make |> Option.toObj
|
||||
}
|
||||
|
||||
static member Deserialise (config : SerialisedConfig) : Configuration =
|
||||
@@ -105,6 +188,14 @@ type SerialisedConfig =
|
||||
| subdomains -> subdomains |> Seq.map WellKnownSubdomain.Parse |> Set.ofSeq
|
||||
AcmeEmail = config.AcmeEmail |> EmailAddress
|
||||
RemoteUsername = config.RemoteUsername |> Username
|
||||
RadicaleConfig =
|
||||
config.RadicaleConfig
|
||||
|> Option.ofObj
|
||||
|> Option.map SerialisedRadicaleConfig.Deserialise
|
||||
GiteaConfig =
|
||||
config.GiteaConfig
|
||||
|> Option.ofObj
|
||||
|> Option.map SerialisedGiteaConfig.Deserialise
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
|
||||
@@ -15,7 +15,7 @@ module DigitalOcean =
|
||||
let makeNixosServer (name : string) (region : Region) (sshKeys : Input<SshFingerprint>[]) : Output<Droplet> =
|
||||
output {
|
||||
let args =
|
||||
DropletArgs (Name = Input.lift name, Size = InputUnion.liftRight DropletSlug.DropletS1VCPU1GB)
|
||||
DropletArgs (Name = Input.lift name, Size = InputUnion.liftRight DropletSlug.DropletS1VCPU2GB)
|
||||
|
||||
args.Tags.Add (Input.lift "nixos")
|
||||
args.Image <- "ubuntu-22-04-x64" |> Input.lift
|
||||
|
||||
@@ -95,6 +95,7 @@ type Address =
|
||||
|
||||
type WellKnownSubdomain =
|
||||
| Nextcloud
|
||||
| Apps
|
||||
| Gitea
|
||||
| Radicale
|
||||
| Rss
|
||||
@@ -102,20 +103,28 @@ type WellKnownSubdomain =
|
||||
| WoodpeckerAgent
|
||||
| Grafana
|
||||
| PureGym
|
||||
| Whisper
|
||||
| Robocop
|
||||
| Syncthing
|
||||
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| Nextcloud -> "nextcloud"
|
||||
| Gitea -> "gitea"
|
||||
| Radicale -> "calendar"
|
||||
| Rss -> "rss"
|
||||
| Grafana -> "grafana"
|
||||
| Woodpecker -> "woodpecker"
|
||||
| WoodpeckerAgent -> "woodpecker-agent"
|
||||
| PureGym -> "puregym"
|
||||
| WellKnownSubdomain.Nextcloud -> "nextcloud"
|
||||
| WellKnownSubdomain.Apps -> "apps"
|
||||
| WellKnownSubdomain.Gitea -> "gitea"
|
||||
| WellKnownSubdomain.Radicale -> "calendar"
|
||||
| WellKnownSubdomain.Rss -> "rss"
|
||||
| WellKnownSubdomain.Grafana -> "grafana"
|
||||
| WellKnownSubdomain.Woodpecker -> "woodpecker"
|
||||
| WellKnownSubdomain.WoodpeckerAgent -> "woodpecker-agent"
|
||||
| WellKnownSubdomain.PureGym -> "puregym"
|
||||
| WellKnownSubdomain.Whisper -> "whisper"
|
||||
| WellKnownSubdomain.Robocop -> "robocop"
|
||||
| WellKnownSubdomain.Syncthing -> "syncthing"
|
||||
|
||||
static member Parse (s : string) =
|
||||
match s with
|
||||
| "apps" -> WellKnownSubdomain.Apps
|
||||
| "nextcloud" -> WellKnownSubdomain.Nextcloud
|
||||
| "gitea" -> WellKnownSubdomain.Gitea
|
||||
| "calendar" -> WellKnownSubdomain.Radicale
|
||||
@@ -124,6 +133,9 @@ type WellKnownSubdomain =
|
||||
| "woodpecker-agent" -> WellKnownSubdomain.WoodpeckerAgent
|
||||
| "grafana" -> WellKnownSubdomain.Grafana
|
||||
| "puregym" -> WellKnownSubdomain.PureGym
|
||||
| "whisper" -> WellKnownSubdomain.Whisper
|
||||
| "robocop" -> WellKnownSubdomain.Robocop
|
||||
| "syncthing" -> WellKnownSubdomain.Syncthing
|
||||
| _ -> failwith $"Failed to deserialise: {s}"
|
||||
|
||||
|
||||
|
||||
32
PulumiWebServer/Nix/apps/apps.nix
Normal file
32
PulumiWebServer/Nix/apps/apps.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
services.apps-config = {
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "example.com";
|
||||
description = lib.mdDoc "Top-level domain to configure";
|
||||
};
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "apps";
|
||||
description = lib.mdDoc "Subdomain in which to put apps";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = lib.mdDoc "App server localhost port";
|
||||
default = 9521;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
services.nginx.virtualHosts."${config.services.apps-config.subdomain}.${config.services.apps-config.domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
root = ./static;
|
||||
};
|
||||
};
|
||||
}
|
||||
12
PulumiWebServer/Nix/apps/static/index.html
Normal file
12
PulumiWebServer/Nix/apps/static/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Apps</h1>
|
||||
<p>This is a collection of single-page applications, mostly vomited out by Claude to solve small tasks.</p>
|
||||
<ul>
|
||||
<li><a href="/middle_word.html">Compute the number of words in a string and the middle word.</a></li>
|
||||
<li><a href="/sha256sum.html">Compute SHA256sums, as one might wish to do to verify someone's precommitment to a piece of text.</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
25
PulumiWebServer/Nix/apps/static/middle_word.html
Normal file
25
PulumiWebServer/Nix/apps/static/middle_word.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<textarea id="input" rows="10" cols="50"></textarea><br>
|
||||
<button onclick="analyzeText()">Ok</button>
|
||||
<div id="result"></div>
|
||||
|
||||
<script>
|
||||
function analyzeText() {
|
||||
const text = document.getElementById('input').value;
|
||||
const words = text.trim().split(' ').filter(word => word.length > 0);
|
||||
const count = words.length;
|
||||
const result = `Word count: ${count}`;
|
||||
|
||||
if (count % 2 === 1) {
|
||||
const middleWord = words[Math.floor(count/2)];
|
||||
document.getElementById('result').textContent =
|
||||
`${result}\nMiddle word: ${middleWord}`;
|
||||
} else {
|
||||
document.getElementById('result').textContent = result;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
95
PulumiWebServer/Nix/apps/static/sha256sum.html
Normal file
95
PulumiWebServer/Nix/apps/static/sha256sum.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Base64 Decoder and SHA256 Calculator</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
.input-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
button {
|
||||
padding: 8px 16px;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
#hashOutput {
|
||||
font-family: monospace;
|
||||
padding: 8px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="input-group">
|
||||
<label for="base64Input">Base64 Input:</label>
|
||||
<textarea id="base64Input" placeholder="Enter base64 encoded text here"></textarea>
|
||||
<button onclick="decodeBase64()">Decode Base64</button>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="textInput">Text Input:</label>
|
||||
<textarea id="textInput" placeholder="Enter text or see decoded base64 here"></textarea>
|
||||
<button onclick="calculateSHA256()">Calculate SHA256</button>
|
||||
</div>
|
||||
|
||||
<div class="input-group">
|
||||
<label for="hashOutput">SHA256 Hash:</label>
|
||||
<div id="hashOutput"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function decodeBase64() {
|
||||
try {
|
||||
const base64Input = document.getElementById('base64Input').value;
|
||||
const decoded = atob(base64Input);
|
||||
document.getElementById('textInput').value = decoded;
|
||||
} catch (error) {
|
||||
alert('Invalid base64 input: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function calculateSHA256() {
|
||||
try {
|
||||
const text = document.getElementById('textInput').value;
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(text);
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
document.getElementById('hashOutput').textContent = hashHex;
|
||||
} catch (error) {
|
||||
alert('Error calculating hash: ' + error.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +1,4 @@
|
||||
{
|
||||
nixpkgs,
|
||||
website,
|
||||
puregym-client,
|
||||
...
|
||||
}: let
|
||||
{nixpkgs, ...}: let
|
||||
lib = nixpkgs.lib;
|
||||
# TODO: how can I get this passed in?
|
||||
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
||||
@@ -12,7 +7,9 @@
|
||||
in {
|
||||
imports = [
|
||||
./sops.nix
|
||||
./apps/apps.nix
|
||||
./radicale/radicale-config.nix
|
||||
./syncthing/syncthing-config.nix
|
||||
./gitea/gitea-config.nix
|
||||
./miniflux/miniflux.nix
|
||||
./userconfig.nix
|
||||
@@ -24,6 +21,7 @@ in {
|
||||
# generated at runtime by nixos-infect and copied here
|
||||
./hardware-configuration.nix
|
||||
./networking.nix
|
||||
# ./whisper/whisper.nix
|
||||
];
|
||||
|
||||
services.radicale-config.domain = userConfig.domain;
|
||||
@@ -47,6 +45,12 @@ in {
|
||||
services.prometheus-config.domain-exporter-domains = [userConfig.domain];
|
||||
services.puregym-config.domain = userConfig.domain;
|
||||
services.puregym-config.subdomain = "puregym";
|
||||
services.apps-config.subdomain = "apps";
|
||||
services.apps-config.domain = userConfig.domain;
|
||||
# services.whisper-config.domain = userConfig.domain;
|
||||
# services.whisper-config.subdomain = "whisper";
|
||||
services.syncthing-config.subdomain = "syncthing";
|
||||
services.syncthing-config.domain = userConfig.domain;
|
||||
|
||||
services.journald.extraConfig = "SystemMaxUse=100M";
|
||||
|
||||
@@ -57,9 +61,9 @@ in {
|
||||
auto-optimise-store = true;
|
||||
experimental-features = ["nix-command" "flakes"];
|
||||
};
|
||||
package = pkgs.nixUnstable;
|
||||
package = pkgs.nixVersions.latest;
|
||||
extraOptions = ''
|
||||
experimental-features = ca-derivations
|
||||
experimental-features = ca-derivations flakes
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
241
PulumiWebServer/Nix/flake.lock
generated
241
PulumiWebServer/Nix/flake.lock
generated
@@ -3,7 +3,7 @@
|
||||
"anki-compiler": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694219801,
|
||||
@@ -64,11 +64,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -99,6 +99,24 @@
|
||||
"inputs": {
|
||||
"systems": "systems_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_4": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694529238,
|
||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||
@@ -113,6 +131,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_5": {
|
||||
"inputs": {
|
||||
"systems": "systems_5"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -120,11 +156,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703795120,
|
||||
"narHash": "sha256-Scr4fwfGn03zwFgM7IltT8hqbFDkHvymnF5AaR4eDAg=",
|
||||
"lastModified": 1757256385,
|
||||
"narHash": "sha256-WK7tOhWwr15mipcckhDg2no/eSpM1nIh4C9le8HgHhk=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "ba6b75011b44e85b1b755b6c423f85d0817645f7",
|
||||
"rev": "f35703b412c67b48e97beb6e27a6ab96a084cd37",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -146,10 +182,11 @@
|
||||
"scripts": "scripts_2"
|
||||
},
|
||||
"locked": {
|
||||
"dirtyRev": "9e2f5603f1e4e263e73ae0d0ca7c86ae14427c73-dirty",
|
||||
"dirtyShortRev": "9e2f560-dirty",
|
||||
"lastModified": 1701513782,
|
||||
"narHash": "sha256-dDym75Eq6TIw9IrokBWwSoto0/l3nxFGpH4/VZkeqrQ=",
|
||||
"lastModified": 1721842442,
|
||||
"narHash": "sha256-bjvLR/KwHToz0/kRcZ8/MHXs3y4YCTtz3UUQ/D/AliA=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "cab3ccc58ec12af893c9ea6b87aac0dfeefa3752",
|
||||
"revCount": 24,
|
||||
"type": "git",
|
||||
"url": "file:/Users/patrick/Desktop/website/static-site-images"
|
||||
},
|
||||
@@ -160,21 +197,15 @@
|
||||
},
|
||||
"katex": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"website",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"website",
|
||||
"nixpkgs"
|
||||
]
|
||||
"flake-utils": "flake-utils_4",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1696151934,
|
||||
"narHash": "sha256-8kihcqdgYjoVuGozfgfcWh81yqMUvns4+C/fgkn+RNQ=",
|
||||
"lastModified": 1704150937,
|
||||
"narHash": "sha256-G6uJKkY5VErgobe51IIbp/ugHDIhVx5e0xNjJ90JEOk=",
|
||||
"owner": "Smaug123",
|
||||
"repo": "KaTeX",
|
||||
"rev": "ac1f9b30441f63ea20216a36ffa7148dc0e9a9b3",
|
||||
"rev": "b74ed701beec2bebd161a0b5ea30c496c5206b96",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -184,70 +215,35 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"model": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1703467016,
|
||||
"narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d02d818f22c777aa4e854efc3242ec451e5d462a",
|
||||
"type": "github"
|
||||
"narHash": "sha256-CSrDFPoQgkvBW36keGkYpjxz740TBrCKVSxwSnfYvV8=",
|
||||
"type": "file",
|
||||
"url": "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin?download=true"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-23.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
"type": "file",
|
||||
"url": "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin?download=true"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703351344,
|
||||
"narHash": "sha256-9FEelzftkE9UaJ5nqxidaJJPEhe9TPhbypLHmc2Mysc=",
|
||||
"lastModified": 1757068644,
|
||||
"narHash": "sha256-NOrUtIhTkIIumj1E/Rsv1J37Yi3xGStISEo8tZm3KW4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7790e078f8979a9fcd543f9a47427eeaba38f268",
|
||||
"rev": "8eb28adfa3dc4de28e792e3bf49fcf9007ca8ac9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-23.05",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1703792911,
|
||||
"narHash": "sha256-BzCq3IiOlTghYtgPngIUnJDeGlRdz4RJGyS9faONrOE=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1d17e304ac93dde75178d7ad47abbecc0357c937",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1703134684,
|
||||
"narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d6863cbcbbb80e71cecfc03356db1cda38919523",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1694021185,
|
||||
"narHash": "sha256-v5Ie83yfsiQgp4GDRZFIsbkctEynfOdNOi67vBH12XM=",
|
||||
@@ -262,6 +258,22 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1688392541,
|
||||
"narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-22.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pdfs": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
@@ -275,11 +287,11 @@
|
||||
"scripts": "scripts_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1696190787,
|
||||
"narHash": "sha256-bO/NInpwVefs5Iey8WVwPFnXPt/3WN7WvYXTxzLKmGQ=",
|
||||
"lastModified": 1725713640,
|
||||
"narHash": "sha256-JBTpmQn3Gg3scVUUyLuks1gX+EzkctD+ZN3CBsxXuwQ=",
|
||||
"owner": "Smaug123",
|
||||
"repo": "static-site-pdfs",
|
||||
"rev": "a36d3025b9625cc50fc5bd2eca867eacd8a5bcb9",
|
||||
"rev": "e7133d72e6fab800aa3fd91cab47b6bc6824a0ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -291,14 +303,16 @@
|
||||
"puregym-client": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703797686,
|
||||
"narHash": "sha256-4HZ+uz7LFK+44IzKuLe9lL34Oau/J1Tppmxpe+x5FCw=",
|
||||
"lastModified": 1757366940,
|
||||
"narHash": "sha256-GFxGO40Tu65a1VZQ6z7RTMEHf9jr6TD4nuLplv17fKM=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "8ece87ff57b0ae66f38120d8a26b33661625fa61",
|
||||
"revCount": 5,
|
||||
"rev": "2ca8c5e43b7b77c1e6208e2ae996192e0c820e74",
|
||||
"revCount": 21,
|
||||
"type": "git",
|
||||
"url": "https://gitea.patrickstevens.co.uk/patrick/puregym-unofficial-dotnet"
|
||||
},
|
||||
@@ -313,7 +327,8 @@
|
||||
"nixpkgs": "nixpkgs",
|
||||
"puregym-client": "puregym-client",
|
||||
"sops": "sops",
|
||||
"website": "website"
|
||||
"website": "website",
|
||||
"whisper-packages": "whisper-packages"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
@@ -378,15 +393,16 @@
|
||||
},
|
||||
"sops": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703387502,
|
||||
"narHash": "sha256-JnWuQmyanPtF8c5yAEFXVWzaIlMxA3EAZCh8XNvnVqE=",
|
||||
"lastModified": 1754988908,
|
||||
"narHash": "sha256-t+voe2961vCgrzPFtZxha0/kmFSHFobzF00sT8p9h0U=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "e523e89763ff45f0a6cf15bcb1092636b1da9ed3",
|
||||
"rev": "3223c7a92724b5d804e9988c6b447a0d09017d48",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -440,6 +456,36 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_4": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_5": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"website": {
|
||||
"inputs": {
|
||||
"anki-decks": "anki-decks",
|
||||
@@ -454,11 +500,11 @@
|
||||
"scripts": "scripts_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701514896,
|
||||
"narHash": "sha256-XDhco86dHsoHzezarG1UQBpsCyZ+AqRY+w+l3g4hL1o=",
|
||||
"lastModified": 1756748330,
|
||||
"narHash": "sha256-6Z/wDFdESbTwgiTnV1oBfQZ661MIgfAhD1rDKipFHbc=",
|
||||
"owner": "Smaug123",
|
||||
"repo": "static-site-pipeline",
|
||||
"rev": "b35c219d0e3e93b5bbd52befa486b54fa4e8b710",
|
||||
"rev": "9901b1dfc4274dc4d8792fcbde27861b47173dfa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -466,6 +512,29 @@
|
||||
"repo": "static-site-pipeline",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"whisper-packages": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_5",
|
||||
"model": "model",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1706487294,
|
||||
"narHash": "sha256-h5Ptbc6Kks4zZllR2nHnbVPJAJyYOAHEqGyEBFNMvzE=",
|
||||
"owner": "Smaug123",
|
||||
"repo": "whisper.cpp",
|
||||
"rev": "96214a91134021ad6416f06cb7d35419a73b302c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Smaug123",
|
||||
"ref": "nix-small",
|
||||
"repo": "whisper.cpp",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
website = {
|
||||
url = "github:Smaug123/static-site-pipeline";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
puregym-client = {
|
||||
url = "git+https://gitea.patrickstevens.co.uk/patrick/puregym-unofficial-dotnet";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
sops.url = "github:Mic92/sops-nix";
|
||||
sops = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
whisper-packages = {
|
||||
url = "github:Smaug123/whisper.cpp/nix-small";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
@@ -22,6 +30,7 @@
|
||||
home-manager,
|
||||
website,
|
||||
puregym-client,
|
||||
whisper-packages,
|
||||
} @ inputs: let
|
||||
system = "x86_64-linux";
|
||||
in {
|
||||
@@ -31,6 +40,7 @@
|
||||
inherit system;
|
||||
website = website.packages.${system}.default;
|
||||
puregym-client = puregym-client.packages.${system}.default;
|
||||
whisper-packages = whisper-packages.packages.${system};
|
||||
};
|
||||
modules = [
|
||||
(import ./configuration.nix (inputs // {inherit inputs;}))
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
RENDER_COMMAND = ''${docutils}/bin/rst2html.py'';
|
||||
IS_INPUT_FILE = false;
|
||||
};
|
||||
repository = {
|
||||
DISABLE_DOWNLOAD_SOURCE_ARCHIVES = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -87,6 +90,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
system.activationScripts = {
|
||||
gitea-robots-txt = ''
|
||||
mkdir -p /preserve/gitea/data/custom/public
|
||||
cp ${./robots.txt} /preserve/gitea/data/custom/public/robots.txt
|
||||
chown gitea:gitea /preserve/gitea/data/custom/public/robots.txt
|
||||
chmod 644 /preserve/gitea/data/custom/public/robots.txt
|
||||
'';
|
||||
};
|
||||
|
||||
# The Gitea module does not allow adding users declaratively
|
||||
systemd.services.gitea-add-user = {
|
||||
description = "gitea-add-user";
|
||||
|
||||
2
PulumiWebServer/Nix/gitea/robots.txt
Normal file
2
PulumiWebServer/Nix/gitea/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: GPTBot
|
||||
Disallow: /
|
||||
@@ -41,6 +41,13 @@
|
||||
mode = "0440";
|
||||
};
|
||||
|
||||
environment.etc."grafana-dashboards/puregym.json" = {
|
||||
source = ./puregym.json;
|
||||
group = "grafana";
|
||||
user = "grafana";
|
||||
mode = "0440";
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
||||
144
PulumiWebServer/Nix/grafana/puregym.json
Normal file
144
PulumiWebServer/Nix/grafana/puregym.json
Normal file
@@ -0,0 +1,144 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "P40645DF18AF953B4"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"axisSoftMin": 0,
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 1,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"timezone": [
|
||||
"Europe/London"
|
||||
],
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "P40645DF18AF953B4"
|
||||
},
|
||||
"disableTextWrap": false,
|
||||
"editorMode": "builder",
|
||||
"expr": "fullness",
|
||||
"fullMetaSearch": false,
|
||||
"includeNullMetadata": true,
|
||||
"instant": false,
|
||||
"legendFormat": "{{label}}",
|
||||
"range": true,
|
||||
"refId": "A",
|
||||
"useBackend": false
|
||||
}
|
||||
],
|
||||
"title": "Gym occupancy",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"schemaVersion": 38,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "PureGym",
|
||||
"uid": "f1399663-bebe-42d8-9162-b046af9fb0c2",
|
||||
"version": 3,
|
||||
"weekStart": ""
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
website,
|
||||
@@ -45,6 +44,9 @@
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80 # required for the ACME challenge
|
||||
443
|
||||
# syncthing
|
||||
21027
|
||||
22000
|
||||
];
|
||||
|
||||
users.users."nginx".extraGroups = [config.users.groups.keys.name];
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = config.services.prometheus-config.port;
|
||||
retentionTime = "60d";
|
||||
exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
@@ -52,6 +53,18 @@
|
||||
};
|
||||
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "gym-fullness";
|
||||
static_configs = [
|
||||
{
|
||||
# Gym 19 is London Oval
|
||||
targets = ["localhost:${toString config.services.puregym-config.port}"];
|
||||
}
|
||||
];
|
||||
params = {gym_id = ["19"];};
|
||||
metrics_path = "/fullness-prometheus";
|
||||
scrape_interval = "5m";
|
||||
}
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = [
|
||||
|
||||
@@ -13,12 +13,49 @@ class MyHandler(BaseHTTPRequestHandler):
|
||||
_last_accessed_by_id = defaultdict(lambda: datetime.min)
|
||||
_last_accessed_by_name = defaultdict(lambda: datetime.min)
|
||||
|
||||
_all_gyms = {}
|
||||
_last_refreshed_gyms = datetime.min
|
||||
|
||||
def _bad_request(self, text: str, code: int = 400) -> None:
|
||||
self.send_response(code)
|
||||
self.send_header('Content-type', 'text/plain; charset=utf-8')
|
||||
self.end_headers()
|
||||
self.wfile.write(text.encode('utf-8'))
|
||||
|
||||
def _get_fullness(self, gym_id: int) -> bytes:
|
||||
if abs(datetime.now() - self._last_accessed_by_id[gym_id]) > timedelta(seconds=30):
|
||||
token = subprocess.check_output(['cat', '/tmp/puregym_token']).strip()
|
||||
output = subprocess.check_output(
|
||||
[puregym, 'fullness', '--bearer-token', token, '--gym-id', str(gym_id)], text=True,
|
||||
encoding='utf-8')
|
||||
output = output.encode('utf-8')
|
||||
self._cache_result_by_id[gym_id] = output
|
||||
self._last_accessed_by_id[gym_id] = datetime.now()
|
||||
else:
|
||||
output = self._cache_result_by_id[gym_id]
|
||||
return output
|
||||
|
||||
def _refresh_gyms(self) -> None:
|
||||
if self._last_refreshed_gyms < datetime.now() - timedelta(days=1):
|
||||
token = subprocess.check_output(['cat', '/tmp/puregym_token']).strip()
|
||||
output = subprocess.check_output(
|
||||
[puregym, 'all-gyms', '--bearer-token', token, '--terse', 'true'], text=True,
|
||||
encoding='utf-8')
|
||||
new_gyms = {}
|
||||
for line in output.splitlines():
|
||||
gym_id, gym_name = line.split(',')
|
||||
new_gyms[int(gym_id)] = gym_name
|
||||
self._all_gyms = new_gyms
|
||||
self._last_refreshed_gyms = datetime.now()
|
||||
|
||||
def get_all_gyms(self, _query: dict[AnyStr, list[AnyStr]]) -> None:
|
||||
self._refresh_gyms()
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
for gym_id, gym_name in self._all_gyms.items():
|
||||
self.wfile.write(f'{gym_id}: {gym_name}\n'.encode())
|
||||
|
||||
def get_fullness(self, query: dict[AnyStr, list[AnyStr]]) -> None:
|
||||
desired_gym_name = None
|
||||
query_gym = query.get("gym_name", None)
|
||||
@@ -48,16 +85,7 @@ class MyHandler(BaseHTTPRequestHandler):
|
||||
desired_gym_id = None
|
||||
|
||||
if desired_gym_id is not None:
|
||||
if abs(datetime.now() - self._last_accessed_by_id[desired_gym_id]) > timedelta(seconds=30):
|
||||
token = subprocess.check_output(['cat', '/tmp/puregym_token']).strip()
|
||||
output = subprocess.check_output(
|
||||
[puregym, 'fullness', '--bearer-token', token, '--gym-id', str(desired_gym_id)], text=True,
|
||||
encoding='utf-8')
|
||||
output = output.encode('utf-8')
|
||||
self._cache_result_by_id[desired_gym_id] = output
|
||||
self._last_accessed_by_id[desired_gym_id] = datetime.now()
|
||||
else:
|
||||
output = self._cache_result_by_id[desired_gym_id]
|
||||
output = self._get_fullness(desired_gym_id)
|
||||
elif desired_gym_name is not None:
|
||||
if abs(datetime.now() - self._last_accessed_by_name[desired_gym_name]) > timedelta(seconds=30):
|
||||
token = subprocess.check_output(['cat', '/tmp/puregym_token']).strip()
|
||||
@@ -79,8 +107,39 @@ class MyHandler(BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
self.wfile.write(output)
|
||||
|
||||
def get_prometheus(self, query: dict[AnyStr, list[AnyStr]]) -> None:
|
||||
query_gym = query.get("gym_id", None)
|
||||
if query_gym is None:
|
||||
self._bad_request('Must supply gym_id')
|
||||
return
|
||||
try:
|
||||
gym_id = [int(i) for i in query_gym]
|
||||
except ValueError:
|
||||
self._bad_request('at least one gym_id did not parse as an int')
|
||||
return
|
||||
|
||||
if not gym_id:
|
||||
self._bad_request('supply at least one gym_id')
|
||||
return
|
||||
|
||||
try:
|
||||
fullness = [(i, int(self._get_fullness(i).split(b' ')[0])) for i in gym_id]
|
||||
except ValueError:
|
||||
self._bad_request('at least one fullness did not yield an int', 500)
|
||||
return
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
self._refresh_gyms()
|
||||
for gym_id, fullness in fullness:
|
||||
gym_name = ''.join(c for c in self._all_gyms[gym_id] if c == ' ' or str.isalnum(c))
|
||||
self.wfile.write(f'fullness{{label="{gym_name}"}} {fullness}\n'.encode())
|
||||
|
||||
_handlers: dict[str, Callable[["MyHandler", dict[AnyStr, list[AnyStr]]], None]] = {
|
||||
"/fullness": get_fullness
|
||||
"/fullness": get_fullness,
|
||||
"/fullness-prometheus": get_prometheus,
|
||||
"/gym-mapping": get_all_gyms,
|
||||
}
|
||||
|
||||
def do_GET(self):
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
if config.services.radicale-config.enableGit
|
||||
then {
|
||||
filesystem_folder = filesystem_folder;
|
||||
hook = "GIT=${pkgs.git}/bin/git GITIGNORE=${./.gitignore} /bin/sh ${./githook.sh}";
|
||||
hook = "GIT=${pkgs.git}/bin/git GITIGNORE=${./gitignore} /bin/sh ${./githook.sh}";
|
||||
}
|
||||
else {};
|
||||
};
|
||||
|
||||
41
PulumiWebServer/Nix/syncthing/syncthing-config.nix
Normal file
41
PulumiWebServer/Nix/syncthing/syncthing-config.nix
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
services.syncthing-config = {
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "example.com";
|
||||
description = lib.mdDoc "Top-level domain to configure";
|
||||
};
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "syncthing";
|
||||
description = lib.mdDoc "Subdomain in which to put Syncthing";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = lib.mdDoc "Syncthing localhost port";
|
||||
default = 8384;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = let
|
||||
filesystem_folder = "/preserve/syncthing/";
|
||||
in {
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
user = "syncthing";
|
||||
dataDir = "${filesystem_folder}/data"; # Default folder for new synced folders
|
||||
configDir = "${filesystem_folder}/config"; # Folder for Syncthing's settings and keys
|
||||
openDefaultPorts = true;
|
||||
};
|
||||
|
||||
systemd.services.syncthing.serviceConfig.ReadWritePaths = [filesystem_folder];
|
||||
|
||||
systemd.tmpfiles.rules = ["d ${filesystem_folder} 0750 syncthing syncthing -"];
|
||||
};
|
||||
}
|
||||
2
PulumiWebServer/Nix/whisper/requirements.txt
Normal file
2
PulumiWebServer/Nix/whisper/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
flask
|
||||
waitress
|
||||
107
PulumiWebServer/Nix/whisper/transcribe.html
Normal file
107
PulumiWebServer/Nix/whisper/transcribe.html
Normal file
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Whisper Transcription</title>
|
||||
<style>
|
||||
#output {
|
||||
white-space: pre-wrap;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
width: 95%;
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Whisper Transcription</h1>
|
||||
<p>Submit file for transcription</p>
|
||||
<form action="/upload" method="POST" enctype="multipart/form-data">
|
||||
<input type="file" name="file">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<label for="file-to-analyze">File to analyze:</label>
|
||||
<div contenteditable="true" id="file-to-analyze">{no file set}</div>
|
||||
</div>
|
||||
<button id="start">Start analysing</button>
|
||||
|
||||
<button id="displayWav" hidden="hidden">Listen to file being transcribed</button>
|
||||
<div id="wavContainer"></div>
|
||||
|
||||
<div id="status"></div>
|
||||
<div id="output"></div>
|
||||
|
||||
<script>
|
||||
const uploadForm = document.querySelector('form');
|
||||
const uploadResultDiv = document.getElementById('file-to-analyze');
|
||||
uploadForm.addEventListener('submit', e => {
|
||||
e.preventDefault();
|
||||
|
||||
const files = document.querySelector('[type=file]').files;
|
||||
const formData = new FormData();
|
||||
formData.append('file', files[0]);
|
||||
|
||||
fetch('/upload', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(response => {
|
||||
uploadResultDiv.innerText = response;
|
||||
})
|
||||
.catch(error => console.error(error))
|
||||
});
|
||||
|
||||
const outputDiv = document.getElementById('output');
|
||||
const statusDiv = document.getElementById('status');
|
||||
const displayButton = document.getElementById('displayWav');
|
||||
const wavContainer = document.getElementById('wavContainer');
|
||||
const startButton = document.getElementById('start');
|
||||
|
||||
startButton.onclick = function() {
|
||||
// Create a new EventSource instance pointing to the SSE route
|
||||
// const eventSource = new EventSource('/transcribe-youtube?url=https://www.youtube.com/watch?v=-xZQ0YZ7ls4');
|
||||
const eventSource = new EventSource('/transcribe-file?file=' + uploadResultDiv.innerText);
|
||||
|
||||
let file = '';
|
||||
|
||||
displayButton.onclick = function () {
|
||||
const audioElt = document.createElement('audio');
|
||||
audioElt.controls = true;
|
||||
audioElt.src = '/download?file=' + file;
|
||||
|
||||
wavContainer.innerHTML = '';
|
||||
wavContainer.appendChild(audioElt);
|
||||
};
|
||||
|
||||
eventSource.addEventListener('started', function (e) {
|
||||
statusDiv.innerText = 'Transcription has begun. Please hold the line; my server is only very small and weedy.';
|
||||
displayButton.hidden = false;
|
||||
file = e.data;
|
||||
});
|
||||
|
||||
eventSource.addEventListener('quit', function (e) {
|
||||
statusDiv.innerText = 'Transcription finished';
|
||||
eventSource.close()
|
||||
});
|
||||
|
||||
eventSource.onmessage = function (e) {
|
||||
outputDiv.innerText += e.data + '\n';
|
||||
};
|
||||
|
||||
// Handle any errors
|
||||
eventSource.onerror = function (e) {
|
||||
if (eventSource.readyState === EventSource.CLOSED) {
|
||||
console.log('Connection was closed');
|
||||
} else {
|
||||
outputDiv.innerText += 'Error! Connection was lost. Refresh the page to retry.\n';
|
||||
eventSource.close()
|
||||
}
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
65
PulumiWebServer/Nix/whisper/whisper.nix
Normal file
65
PulumiWebServer/Nix/whisper/whisper.nix
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
whisper-packages,
|
||||
...
|
||||
}: {
|
||||
options = {
|
||||
services.whisper-config = {
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "example.com";
|
||||
description = lib.mdDoc "Top-level domain to configure";
|
||||
};
|
||||
subdomain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "whisper";
|
||||
description = lib.mdDoc "Subdomain in which to put the Whisper server";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = lib.mdDoc "Whisper localhost port to be forwarded";
|
||||
default = 1739;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
users.users."whisper".extraGroups = [config.users.groups.keys.name];
|
||||
users.users."whisper".group = "whisper";
|
||||
users.groups.whisper = {};
|
||||
users.users."whisper".isSystemUser = true;
|
||||
|
||||
systemd.services.whisper-server = {
|
||||
description = "whisper-server";
|
||||
wantedBy = ["multi-user.target"];
|
||||
serviceConfig = let
|
||||
python = pkgs.python3.withPackages (p: with p; [flask waitress]);
|
||||
in {
|
||||
Restart = "always";
|
||||
Type = "exec";
|
||||
User = "whisper";
|
||||
Group = "whisper";
|
||||
ExecStart = "${python}/bin/python ${./whisper.py}";
|
||||
};
|
||||
environment = {
|
||||
WHISPER_NORMALIZE = "${whisper-packages.normalize}/bin/normalize.sh";
|
||||
WHISPER_CLIENT = "${whisper-packages.default}/bin/whisper-cpp";
|
||||
WHISPER_PORT = toString config.services.whisper-config.port;
|
||||
INDEX_PAGE_PATH = ./transcribe.html;
|
||||
YT_DLP = "${pkgs.yt-dlp}/bin/yt-dlp";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.proxyTimeout = "300s";
|
||||
services.nginx.clientMaxBodySize = "50M";
|
||||
services.nginx.virtualHosts."${config.services.whisper-config.subdomain}.${config.services.whisper-config.domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString config.services.whisper-config.port}/";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
134
PulumiWebServer/Nix/whisper/whisper.py
Normal file
134
PulumiWebServer/Nix/whisper/whisper.py
Normal file
@@ -0,0 +1,134 @@
|
||||
import subprocess
|
||||
import os
|
||||
from typing import AnyStr
|
||||
import re
|
||||
from flask import Flask, Response, request, render_template_string
|
||||
import waitress
|
||||
import tempfile
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
youtube_regex = re.compile(
|
||||
r"^(?:https?://)?(?:www\.)?(?:youtu\.be/|youtube\.com/(?:embed/|v/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$")
|
||||
|
||||
acceptable_regex = re.compile(r"^[a-zA-Z0-9_]+$")
|
||||
|
||||
|
||||
def generate_output(wav_file):
|
||||
process = subprocess.Popen([whisper, "--file", f"/tmp/whisper/{wav_file}.wav", "--output-txt"],
|
||||
stdout=subprocess.PIPE, bufsize=1,
|
||||
text=True)
|
||||
|
||||
yield f'event: started\ndata: {wav_file}\n\n'
|
||||
|
||||
for line in iter(process.stdout.readline, ''):
|
||||
yield f"data: {line}\n\n"
|
||||
|
||||
yield 'event: quit\ndata: \n\n'
|
||||
|
||||
os.remove(f"/tmp/whisper/{wav_file}.wav")
|
||||
|
||||
|
||||
def obtain_youtube(url: AnyStr) -> str:
|
||||
# handle, temp_file = tempfile.mkstemp(".wav", text=False)
|
||||
# os.close(handle)
|
||||
# os.remove(temp_file)
|
||||
|
||||
# output = subprocess.run(
|
||||
# [ytdlp, '--extract-audio', '--audio-format', 'wav', '--cookies', '/tmp/cookies.txt', '--audio-quality', '16k', '--force-ipv6', '--output', temp_file,
|
||||
# url], check=True, capture_output=True, text=True)
|
||||
# if "429 Too Many Requests" in output.stdout:
|
||||
# raise subprocess.CalledProcessError(1, whisper, "YouTube replied saying Too Many Requests")
|
||||
# return temp_file
|
||||
|
||||
raise Exception("DigitalOcean is rate limited to YouTube")
|
||||
|
||||
|
||||
def normalize(path: str, output: str):
|
||||
try:
|
||||
subprocess.run([normalize_binary, path, output], check=True)
|
||||
except subprocess.CalledProcessError:
|
||||
os.remove(path)
|
||||
return Response("failed to normalize", status=500)
|
||||
|
||||
|
||||
@app.route('/transcribe-youtube')
|
||||
def transcribe_youtube():
|
||||
try:
|
||||
url = request.args.get('url')
|
||||
except KeyError:
|
||||
return Response("must have a URL in the format ?url=https://www.youtube.com/watch?v=...", status=400)
|
||||
if youtube_regex.match(url) is None:
|
||||
return Response(f"url '{url}' did not appear to be a YouTube video", status=400)
|
||||
wav_file = obtain_youtube(url)
|
||||
return Response(generate_output(wav_file), mimetype="text/event-stream")
|
||||
|
||||
|
||||
@app.route('/transcribe-file')
|
||||
def transcribe_file():
|
||||
try:
|
||||
file = request.args.get('file')
|
||||
except KeyError:
|
||||
return Response("must have a file as obtained from /upload, in the format ?file=...", status=400)
|
||||
if acceptable_regex.match(file) is None:
|
||||
return Response(f"filename '{file}' did not match acceptable regex", status=400)
|
||||
return Response(generate_output(file), mimetype="text/event-stream")
|
||||
|
||||
|
||||
@app.route('/transcribe-ui')
|
||||
def index():
|
||||
return render_template_string(open(index_page_path).read()) # Assuming 'index.html' is in the same directory
|
||||
|
||||
|
||||
@app.route('/upload', methods=["POST"])
|
||||
def upload():
|
||||
if 'file' not in request.files:
|
||||
return 'No "file" part in request', 400
|
||||
file = request.files['file']
|
||||
|
||||
try:
|
||||
os.mkdir("/tmp/whisper")
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
# Create temp file for this upload
|
||||
handle, temp_file = tempfile.mkstemp(text=False)
|
||||
try:
|
||||
os.close(handle)
|
||||
file.save(temp_file)
|
||||
# get filename from absolute path
|
||||
temp_file_frag = os.path.basename(temp_file)
|
||||
|
||||
normalize(temp_file, f"/tmp/whisper/{temp_file_frag}")
|
||||
finally:
|
||||
try:
|
||||
os.remove(temp_file)
|
||||
finally:
|
||||
pass
|
||||
|
||||
return Response(temp_file_frag, mimetype="text/plain")
|
||||
|
||||
|
||||
@app.route('/download')
|
||||
def download():
|
||||
try:
|
||||
file = request.args.get('file')
|
||||
except KeyError:
|
||||
return Response("must have a file parameter", status=400)
|
||||
|
||||
if acceptable_regex.match(file) is None:
|
||||
return Response(f"file '{file}' did not match acceptable regex, bad format", status=400)
|
||||
|
||||
return Response(open(f"/tmp/whisper/{file}.wav", 'rb').read(), mimetype="audio/wav")
|
||||
|
||||
|
||||
def run(port: int):
|
||||
waitress.serve(app, host="0.0.0.0", port=port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
normalize_binary = os.environ["WHISPER_NORMALIZE"]
|
||||
whisper = os.environ["WHISPER_CLIENT"]
|
||||
index_page_path = os.environ["INDEX_PAGE_PATH"]
|
||||
ytdlp = os.environ["YT_DLP"]
|
||||
run(int(os.environ["WHISPER_PORT"]))
|
||||
@@ -87,6 +87,14 @@
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString config.services.woodpecker-config.port}/";
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = ''
|
||||
proxy_redirect off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_buffering off;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace PulumiWebServer
|
||||
namespace PulumiWebServer
|
||||
|
||||
open System
|
||||
open System.Net.Http
|
||||
open Nager.PublicSuffix
|
||||
open Nager.PublicSuffix.RuleProviders
|
||||
open Newtonsoft.Json
|
||||
open Pulumi
|
||||
open Pulumi.DigitalOcean
|
||||
@@ -9,10 +10,9 @@ open System.IO
|
||||
|
||||
module Program =
|
||||
|
||||
let stripSubdomain (DomainName str) =
|
||||
let parser = DomainParser (WebTldRuleProvider ())
|
||||
let stripSubdomain (parser : IDomainParser) (DomainName str) =
|
||||
let info = parser.Parse str
|
||||
$"{info.Domain}.{info.TLD}" |> DomainName
|
||||
$"{info.Domain}.{info.TopLevelDomain}" |> DomainName
|
||||
|
||||
let config =
|
||||
use file =
|
||||
@@ -23,6 +23,15 @@ module Program =
|
||||
|
||||
[<EntryPoint>]
|
||||
let main _argv =
|
||||
use httpClient = new HttpClient ()
|
||||
let cacheProvider = RuleProviders.CacheProviders.LocalFileSystemCacheProvider ()
|
||||
let ruleProvider = CachedHttpRuleProvider (cacheProvider, httpClient)
|
||||
|
||||
if not (ruleProvider.BuildAsync().Result) then
|
||||
failwith "did not build rules"
|
||||
|
||||
let parser = DomainParser ruleProvider
|
||||
|
||||
fun () ->
|
||||
output {
|
||||
let! existingKeys = DigitalOcean.storedSshKeys (Output.Create "")
|
||||
@@ -68,10 +77,10 @@ module Program =
|
||||
IPv6 = Option.ofObj ipv6
|
||||
}
|
||||
|
||||
let! zone = Cloudflare.getZone (stripSubdomain config.Domain)
|
||||
let! zone = Cloudflare.getZone (stripSubdomain parser config.Domain)
|
||||
|
||||
let dns =
|
||||
Cloudflare.addDns config.Domain config.Cnames config.Subdomains zone address
|
||||
Cloudflare.addDns parser config.Domain config.Cnames config.Subdomains zone address
|
||||
|
||||
let readyCommand = Server.waitForReady 1 config.PrivateKey address
|
||||
let! _ = readyCommand.Stdout
|
||||
@@ -106,6 +115,15 @@ module Program =
|
||||
(BashString.make "/tmp/networking.nix")
|
||||
|> fun c -> c.Stdout
|
||||
|
||||
// TODO: do this properly via Command
|
||||
keys
|
||||
|> Array.map (fun k -> k.PublicKeyContents)
|
||||
|> Array.collect (fun s -> s.Split "\n")
|
||||
|> JsonConvert.SerializeObject
|
||||
|> fun s -> File.WriteAllText ("/tmp/ssh-keys.json", s)
|
||||
|
||||
Log.Info "Stored SSH keys at /tmp/ssh-keys.json"
|
||||
|
||||
let pullHardware =
|
||||
Command.pullFile
|
||||
config.PrivateKey
|
||||
@@ -121,15 +139,6 @@ module Program =
|
||||
let! _ = pullHardware
|
||||
Log.Info "Hardware configuration at /tmp/hardware.nix"
|
||||
|
||||
// TODO: do this properly via Command
|
||||
keys
|
||||
|> Array.map (fun k -> k.PublicKeyContents)
|
||||
|> Array.collect (fun s -> s.Split "\n")
|
||||
|> JsonConvert.SerializeObject
|
||||
|> fun s -> File.WriteAllText ("/tmp/ssh-keys.json", s)
|
||||
|
||||
Log.Info "Stored SSH keys at /tmp/ssh-keys.json"
|
||||
|
||||
// The nixos rebuild has blatted the known public key.
|
||||
let! _ = (Local.forgetKey (address.Get ())).Stdout
|
||||
let! _ = (Local.forgetKey (string<DomainName> config.Domain)).Stderr
|
||||
|
||||
@@ -1,63 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nager.PublicSuffix" Version="2.4.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Pulumi" Version="3.54.1" />
|
||||
<PackageReference Include="Pulumi.Cloudflare" Version="5.2.0" />
|
||||
<PackageReference Include="Pulumi.Command" Version="0.5.2" />
|
||||
<PackageReference Include="Pulumi.DigitalOcean" Version="4.19.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Domain.fs" />
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="BashString.fsi" />
|
||||
<Compile Include="BashString.fs" />
|
||||
<Compile Include="Pulumi.fs" />
|
||||
<Compile Include="Command.fs" />
|
||||
<Compile Include="Cloudflare.fs" />
|
||||
<Compile Include="DigitalOcean.fs" />
|
||||
<Compile Include="Nginx.fs" />
|
||||
<Compile Include="Server.fs" />
|
||||
<Compile Include="Local.fs" />
|
||||
<Compile Include="Configuration.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
<None Include="Nix\userconfig.nix" />
|
||||
<None Include="Nix\sops.nix" />
|
||||
<None Include="Nix\flake.nix" />
|
||||
<None Include="Nix\flake.lock" />
|
||||
<None Include="Nix\configuration.nix" />
|
||||
<None Include="Nix\hardware-configuration.nix" />
|
||||
<None Include="Nix\networking.nix" />
|
||||
<None Include="Nix\radicale\githook.sh" />
|
||||
<None Include="Nix\radicale\.gitignore" />
|
||||
<None Include="Nix\radicale\radicale-config.nix" />
|
||||
<Content Include="Nix\gitea\add-user.sh" />
|
||||
<None Include="Nix\gitea\gitea-config.nix" />
|
||||
<Content Include="Nix\config.json" />
|
||||
<Content Include="Nix\ssh-keys.json" />
|
||||
<Content Include="Nix\woodpecker\secrets.sh" />
|
||||
<Content Include="Nix\woodpecker\woodpecker.nix" />
|
||||
<Content Include="Nix\grafana\grafana.nix" />
|
||||
<Content Include="Nix\grafana\node.json" />
|
||||
<Content Include="Nix\prometheus\prometheus.nix" />
|
||||
<Content Include="Nix\prometheus\domains.yaml" />
|
||||
<Content Include="Nix\miniflux\miniflux.nix" />
|
||||
<None Include="Nix\nginx\nginx.nix" />
|
||||
<Content Include="Nix\puregym\puregym.nix" />
|
||||
<Content Include="Nix\puregym\refresh-auth.sh" />
|
||||
<Content Include="Nix\puregym\puregym.py" />
|
||||
<Content Include="config.schema.json" />
|
||||
<Content Include="waitforready.sh">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Nager.PublicSuffix" Version="3.6.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="Pulumi" Version="3.90.0" />
|
||||
<PackageReference Include="Pulumi.Cloudflare" Version="6.10.0" />
|
||||
<PackageReference Include="Pulumi.Command" Version="1.1.3" />
|
||||
<PackageReference Include="Pulumi.DigitalOcean" Version="4.53.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Domain.fs" />
|
||||
<Compile Include="Utils.fs" />
|
||||
<Compile Include="BashString.fsi" />
|
||||
<Compile Include="BashString.fs" />
|
||||
<Compile Include="Pulumi.fs" />
|
||||
<Compile Include="Command.fs" />
|
||||
<Compile Include="Cloudflare.fs" />
|
||||
<Compile Include="DigitalOcean.fs" />
|
||||
<Compile Include="Nginx.fs" />
|
||||
<Compile Include="Server.fs" />
|
||||
<Compile Include="Local.fs" />
|
||||
<Compile Include="Configuration.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
<None Include="Nix\**" />
|
||||
<Content Include="config.schema.json" />
|
||||
<Content Include="waitforready.sh">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -41,6 +41,72 @@
|
||||
},
|
||||
"remoteUsername": {
|
||||
"type": "string"
|
||||
},
|
||||
"radicaleConfig": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SerialisedRadicaleConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"giteaConfig": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SerialisedGiteaConfig"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"SerialisedRadicaleConfig": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"user",
|
||||
"password",
|
||||
"gitEmail"
|
||||
],
|
||||
"properties": {
|
||||
"user": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"gitEmail": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SerialisedGiteaConfig": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"serverPassword",
|
||||
"adminPassword",
|
||||
"adminEmailAddress",
|
||||
"adminUsername"
|
||||
],
|
||||
"properties": {
|
||||
"serverPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminEmailAddress": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,4 +37,4 @@ sops updatekeys "$NIX_FLAKE/secrets/staging.json" || exit 3
|
||||
|
||||
cd "$NIX_FLAKE" || exit 4
|
||||
|
||||
nixos-rebuild switch --fast --flake .#default --target-host "root@$DOMAIN" --build-host "root@$DOMAIN" || exit
|
||||
nixos-rebuild switch --keep-going --show-trace --fast --flake .#default --target-host "root@$DOMAIN" --build-host "root@$DOMAIN" || exit
|
||||
|
||||
12
flake.lock
generated
12
flake.lock
generated
@@ -5,11 +5,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1703438236,
|
||||
"narHash": "sha256-aqVBq1u09yFhL7bj1/xyUeJjzr92fXVvQSSEx6AdB1M=",
|
||||
"lastModified": 1734649271,
|
||||
"narHash": "sha256-4EVBRhOjMDuGtMaofAIqzJbg4Ql7Ai0PSeuVZTHjyKQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5f64a12a728902226210bf01d25ec6cbb9d9265b",
|
||||
"rev": "d70bd19e0a38ad4790d3913bf08fcbfc9eeca507",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
42
flake.nix
42
flake.nix
@@ -5,7 +5,6 @@
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
...
|
||||
@@ -16,8 +15,8 @@
|
||||
projectFile = "./PulumiWebServer/PulumiWebServer.fsproj";
|
||||
testProjectFile = "./PulumiWebServer.Test/PulumiWebServer.Test.fsproj";
|
||||
pname = "PulumiWebServer";
|
||||
dotnet-sdk = pkgs.dotnet-sdk_7;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.runtime_7_0;
|
||||
dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
|
||||
dotnet-runtime = pkgs.dotnetCorePackages.runtime_9_0;
|
||||
version = "0.0.1";
|
||||
dotnetTool = toolName: toolVersion: sha256:
|
||||
pkgs.stdenvNoCC.mkDerivation rec {
|
||||
@@ -28,7 +27,7 @@
|
||||
pname = name;
|
||||
version = version;
|
||||
sha256 = sha256;
|
||||
installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin'';
|
||||
installPhase = ''mkdir -p $out/bin && cp -r tools/*/any/* $out/bin'';
|
||||
};
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
@@ -39,39 +38,19 @@
|
||||
'';
|
||||
};
|
||||
in {
|
||||
packages = {
|
||||
fantomas = dotnetTool "fantomas" "5.2.0-alpha-010" "sha256-CuoROZBBhaK0IFjbKNLvzgX4GXwuIybqIvCtuqROBMk=";
|
||||
fetchDeps = let
|
||||
flags = [];
|
||||
runtimeIds = map (system: pkgs.dotnetCorePackages.systemToDotnetRid system) dotnet-sdk.meta.platforms;
|
||||
in
|
||||
pkgs.writeShellScriptBin "fetch-${pname}-deps" (builtins.readFile (pkgs.substituteAll {
|
||||
src = ./nix/fetchDeps.sh;
|
||||
pname = pname;
|
||||
binPath = pkgs.lib.makeBinPath [pkgs.coreutils dotnet-sdk (pkgs.nuget-to-nix.override {inherit dotnet-sdk;})];
|
||||
projectFiles = toString (pkgs.lib.toList projectFile);
|
||||
testProjectFiles = toString (pkgs.lib.toList testProjectFile);
|
||||
rids = pkgs.lib.concatStringsSep "\" \"" runtimeIds;
|
||||
packages = dotnet-sdk.packages;
|
||||
storeSrc = pkgs.srcOnly {
|
||||
src = ./.;
|
||||
pname = pname;
|
||||
version = version;
|
||||
};
|
||||
}));
|
||||
packages = let
|
||||
deps = builtins.fromJSON (builtins.readFile ./nix/deps.json);
|
||||
in {
|
||||
fantomas = dotnetTool "fantomas" (builtins.fromJSON (builtins.readFile ./.config/dotnet-tools.json)).tools.fantomas.version (builtins.head (builtins.filter (elem: elem.pname == "fantomas") deps)).hash;
|
||||
default = pkgs.buildDotnetModule {
|
||||
pname = pname;
|
||||
version = version;
|
||||
inherit pname version projectFile testProjectFile dotnet-sdk dotnet-runtime;
|
||||
src = ./.;
|
||||
projectFile = projectFile;
|
||||
nugetDeps = ./nix/deps.nix;
|
||||
nugetDeps = ./nix/deps.json; # `nix build .#default.fetch-deps && ./result nix/deps.json`
|
||||
doCheck = true;
|
||||
dotnet-sdk = dotnet-sdk;
|
||||
dotnet-runtime = dotnet-runtime;
|
||||
};
|
||||
};
|
||||
devShells = let
|
||||
requirements = [pkgs.dotnet-sdk_7 pkgs.git pkgs.alejandra pkgs.nodePackages.markdown-link-check pkgs.jq];
|
||||
requirements = [dotnet-sdk pkgs.git pkgs.alejandra pkgs.nodePackages.markdown-link-check pkgs.jq];
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
buildInputs =
|
||||
@@ -83,6 +62,7 @@
|
||||
pkgs.ssh-to-age
|
||||
pkgs.nixos-rebuild
|
||||
pkgs.gnused
|
||||
pkgs.xmlstarlet
|
||||
]
|
||||
++ requirements;
|
||||
shellHook = ''
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
#!/usr/bin/python3
|
||||
#!/bin/sh
|
||||
|
||||
import subprocess
|
||||
|
||||
def check_fantomas():
|
||||
result = subprocess.run(["dotnet", "tool", "run", "fantomas", "--check", "-r", "."])
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"Formatting incomplete (return code: {result.returncode}). Consider running `dotnet tool run fantomas -r .`")
|
||||
|
||||
|
||||
def main():
|
||||
check_fantomas()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
dotnet tool run fantomas --check .
|
||||
|
||||
262
nix/deps.json
Normal file
262
nix/deps.json
Normal file
@@ -0,0 +1,262 @@
|
||||
[
|
||||
{
|
||||
"pname": "Ben.Demystifier",
|
||||
"version": "0.4.1",
|
||||
"hash": "sha256-Lkw67ask0hFtv+JoST304S8SzpM3U7nfhXLyyzfM9Os="
|
||||
},
|
||||
{
|
||||
"pname": "fantomas",
|
||||
"version": "6.3.16",
|
||||
"hash": "sha256-4tRdYf+/Q1iedx+DDuIKVGlIWQdr6erM51VdKzZkhCs="
|
||||
},
|
||||
{
|
||||
"pname": "FsCheck",
|
||||
"version": "3.0.0-rc3",
|
||||
"hash": "sha256-4Z9Qv+vccrXWh2Fjdwdmjc1YgW+Dcx73ESkdAnHqxOY="
|
||||
},
|
||||
{
|
||||
"pname": "FSharp.Core",
|
||||
"version": "5.0.2",
|
||||
"hash": "sha256-YOoosLEiszPsOOaNAkWhFGU04JJKDOFVoA/ggrZMN10="
|
||||
},
|
||||
{
|
||||
"pname": "FsUnit",
|
||||
"version": "7.0.0",
|
||||
"hash": "sha256-eoHwX2wPrmP8Wgq2v91tWJvQG+5v4iNYG5jMLPwKXNc="
|
||||
},
|
||||
{
|
||||
"pname": "Google.Protobuf",
|
||||
"version": "3.24.0",
|
||||
"hash": "sha256-J6BJTrhZ49O+JNmPaq4Fsvxln7fFnDLaxqRsJYLbjqo="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.AspNetCore.Server",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-8Sn11CCbsQtqN3g/Rx4M65gcieIvI5hlRyV5yiRDggM="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.AspNetCore.Server.Reflection",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-7HkH2fwbzhWMbynHdEPS1THvwJbV36ZLnn3MEFFWavs="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Core.Api",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-tPvrMdQoVn6quCOkfiDyuTPzJN55vghMeIWmn1Gy2Ig="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Net.Client",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-iq5O1Aa1SlBeuW5MoZnRotmQbPJmqSkhbyO53WVwSSk="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Net.Common",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-JHpSo+cymATjLloCXRATzkXJr6zYRM2X2B/nQfXAdQ0="
|
||||
},
|
||||
{
|
||||
"pname": "Grpc.Reflection",
|
||||
"version": "2.63.0",
|
||||
"hash": "sha256-h+wFmUTHeXCtu7oEnAXbtpnu9+pzETuxymne104nQYQ="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.CodeCoverage",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-lGjifppD0OBMBp28pjUfPipaeXg739n8cPhtHWoo5RE="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Configuration.Abstractions",
|
||||
"version": "9.0.0",
|
||||
"hash": "sha256-xtG2USC9Qm0f2Nn6jkcklpyEDT3hcEZOxOwTc0ep7uc="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-H1rEnq/veRWvmp8qmUsrQkQIcVlKilUNzmmKsxJ0md8="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
"version": "9.0.0",
|
||||
"hash": "sha256-CncVwkKZ5CsIG2O0+OM9qXuYXh3p6UGyueTHSLDVL+c="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-Bg3bFJPjQRJnPvlEc5v7lzwRaUTzKwXDtz81GjCTfMo="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging.Abstractions",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-cBBNcoREIdCDnwZtnTG+BoAFmVb71P1nhFOAH07UsfQ="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging.Abstractions",
|
||||
"version": "6.0.0",
|
||||
"hash": "sha256-QNqcQ3x+MOK7lXbWkCzSOWa/2QyYNbdM/OEEbWN15Sw="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Logging.Abstractions",
|
||||
"version": "9.0.0",
|
||||
"hash": "sha256-iBTs9twjWXFeERt4CErkIIcoJZU1jrd1RWCI8V5j7KU="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Options",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-EMvaXxGzueI8lT97bYJQr0kAj1IK0pjnAcWN82hTnzw="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Primitives",
|
||||
"version": "2.0.0",
|
||||
"hash": "sha256-q44LtMvyNEKSvgERvA+BrasKapP92Sc91QR4u2TJ9/Y="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.Extensions.Primitives",
|
||||
"version": "9.0.0",
|
||||
"hash": "sha256-ZNLusK1CRuq5BZYZMDqaz04PIKScE2Z7sS2tehU7EJs="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.NET.Test.Sdk",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-DKFEbhh2wPzahNeHdEoFig8tZh/LEVrFc5+zpT43Btg="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.ObjectModel",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-3XBHBSuCxggAIlHXmKNQNlPqMqwFlM952Av6RrLw1/w="
|
||||
},
|
||||
{
|
||||
"pname": "Microsoft.TestPlatform.TestHost",
|
||||
"version": "17.12.0",
|
||||
"hash": "sha256-rf8Sh0fQq44Sneuvs64unkkIHg8kOjDGWE35j9iLx5I="
|
||||
},
|
||||
{
|
||||
"pname": "Nager.PublicSuffix",
|
||||
"version": "3.4.0",
|
||||
"hash": "sha256-IpGhixzRVhzdIu2+V+1zm39e2FSaAmRdBJuqkx5ZMMY="
|
||||
},
|
||||
{
|
||||
"pname": "Namotion.Reflection",
|
||||
"version": "3.2.0",
|
||||
"hash": "sha256-yHTow9l4YkN3SKsCkW2htxcoCX3/ewXVavFzucl835M="
|
||||
},
|
||||
{
|
||||
"pname": "Newtonsoft.Json",
|
||||
"version": "13.0.1",
|
||||
"hash": "sha256-K2tSVW4n4beRPzPu3rlVaBEMdGvWSv/3Q1fxaDh4Mjo="
|
||||
},
|
||||
{
|
||||
"pname": "Newtonsoft.Json",
|
||||
"version": "13.0.3",
|
||||
"hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc="
|
||||
},
|
||||
{
|
||||
"pname": "NJsonSchema",
|
||||
"version": "11.1.0",
|
||||
"hash": "sha256-DaBs+DNbMzkzfEbMd2Y2dNrubNzaa1nu2wnno6y8+Wk="
|
||||
},
|
||||
{
|
||||
"pname": "NJsonSchema.Annotations",
|
||||
"version": "11.1.0",
|
||||
"hash": "sha256-oxr6gv3VIvk1vH0YZdAmWgyY0yobxtjFfRwnW1D8Pcc="
|
||||
},
|
||||
{
|
||||
"pname": "NJsonSchema.NewtonsoftJson",
|
||||
"version": "11.1.0",
|
||||
"hash": "sha256-GDE5l2n7Kj/WkOtYLLzBWXHRGsEeUsCRzsmrE2MmWOs="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
"version": "4.0.1",
|
||||
"hash": "sha256-jd1CD5nHVXkpvBNpVDJcJyfTggCHLyDBySVSvtrA8Uk="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit",
|
||||
"version": "4.3.1",
|
||||
"hash": "sha256-7XWgjdgEll4gDLa4p9LpizH+bJzFMIvkQ/olpAXJvCE="
|
||||
},
|
||||
{
|
||||
"pname": "NUnit3TestAdapter",
|
||||
"version": "4.6.0",
|
||||
"hash": "sha256-9Yav2fYhC4w0OgsyUwU4/5rDy4FVDTpKnWHuwl/uKJQ="
|
||||
},
|
||||
{
|
||||
"pname": "OneOf",
|
||||
"version": "3.0.216",
|
||||
"hash": "sha256-IORIcMHMzw10j1rw8i7pTfrmFrL//jTqXtB2qYaaC0I="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi",
|
||||
"version": "3.65.0",
|
||||
"hash": "sha256-0vvNYf4IaANEbcVDEgh4SmNiCgUJOGMbx3GKX/6UUdc="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi",
|
||||
"version": "3.71.0",
|
||||
"hash": "sha256-fvY7//FEozvAQ+zlEpFQGFUd0cCkHqoKTjGNhXD46D4="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi",
|
||||
"version": "3.71.1",
|
||||
"hash": "sha256-5KYPWPr+W/WmroQYBW31fIH9cCgpikOAq4LY7tnygHo="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi.Cloudflare",
|
||||
"version": "5.45.0",
|
||||
"hash": "sha256-4N8bBbvZ/qRHUHewARrMoe0pRKIBKmgGQy0jDB8TkXU="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi.Command",
|
||||
"version": "1.0.1",
|
||||
"hash": "sha256-IuxfDAezG5ZBD7vtFUDbYQ/O+rep3p85Aj+otvER2DY="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi.DigitalOcean",
|
||||
"version": "4.37.1",
|
||||
"hash": "sha256-BYwbZAArMNruKNNylCIq4tSNz7BAltBgx8cykDdwAMk="
|
||||
},
|
||||
{
|
||||
"pname": "Pulumi.Protobuf",
|
||||
"version": "3.27.3",
|
||||
"hash": "sha256-xeO3GoT5lqWvXfYXJfvYrBpQhd1usxCoEhofE470KJY="
|
||||
},
|
||||
{
|
||||
"pname": "Semver",
|
||||
"version": "2.1.0",
|
||||
"hash": "sha256-ZOAay0Kxz3ZIVpEU3ec7SQcrQzEEISNx6kFoBArEFwo="
|
||||
},
|
||||
{
|
||||
"pname": "Serilog",
|
||||
"version": "2.10.0",
|
||||
"hash": "sha256-+8wilkt+VVvW+KFWuLryj7cSFpz9D+sz92KYWICAcSE="
|
||||
},
|
||||
{
|
||||
"pname": "Serilog",
|
||||
"version": "2.8.0",
|
||||
"hash": "sha256-MBL9AWGV8UthhiHXnqH3EsfIyXnxdLWqAdFa6QvQ2To="
|
||||
},
|
||||
{
|
||||
"pname": "Serilog.Extensions.Logging",
|
||||
"version": "3.0.1",
|
||||
"hash": "sha256-KtHMMnepmEpOlHrIGlUkK6Vq1L0iBBnFGavbUtvxOBk="
|
||||
},
|
||||
{
|
||||
"pname": "Serilog.Sinks.Console",
|
||||
"version": "4.0.1",
|
||||
"hash": "sha256-n0LQOEsUg9M/T1aWryiG2690pyGBjHsk6TRZz2aCGyA="
|
||||
},
|
||||
{
|
||||
"pname": "System.Collections.NonGeneric",
|
||||
"version": "4.3.0",
|
||||
"hash": "sha256-8/yZmD4jjvq7m68SPkJZLBQ79jOTOyT5lyzX4SCYAx8="
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "1.6.0",
|
||||
"hash": "sha256-JJfgaPav7UfEh4yRAQdGhLZF1brr0tUWPl6qmfNWq/E="
|
||||
},
|
||||
{
|
||||
"pname": "System.Reflection.Metadata",
|
||||
"version": "5.0.0",
|
||||
"hash": "sha256-Wo+MiqhcP9dQ6NuFGrQTw6hpbJORFwp+TBNTq2yhGp8="
|
||||
}
|
||||
]
|
||||
709
nix/deps.nix
709
nix/deps.nix
@@ -1,709 +0,0 @@
|
||||
# This file was automatically generated by passthru.fetch-deps.
|
||||
# Please don't edit it manually, your changes might get overwritten!
|
||||
{fetchNuGet}: [
|
||||
(fetchNuGet {
|
||||
pname = "Ben.Demystifier";
|
||||
version = "0.4.1";
|
||||
sha256 = "1szlrhvwpwkjhpgvjlrpjg714bz1yhyljs72pxni3li4mgnklk1f";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FsCheck";
|
||||
version = "2.16.5";
|
||||
sha256 = "0h0k91myra1ricvmlvn27wp3kdr7ib3q55yg5isk6206wh9yhigr";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FSharp.Core";
|
||||
version = "7.0.0";
|
||||
sha256 = "1pgk3qk9p1s53wvja17744x4bf7zs3a3wf0dmxi66w1w06z7i85x";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "FsUnit";
|
||||
version = "5.0.0";
|
||||
sha256 = "0r535cw9ikm8xmyla6ah7qx3hb7nvz5m9fi0dqgbkd3wsrc8jlpl";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.AspNetCore.Server";
|
||||
version = "2.37.0";
|
||||
sha256 = "1wkdkfawdm5znhzwp21jwhs1hml08ks3308ak7zbf1f902jb9cad";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.Core.Api";
|
||||
version = "2.37.0";
|
||||
sha256 = "17fmhlkjn7r6jc448p3rlnqi528rpzxgdh3j9h0qmn0m1m3r19ar";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.Core.Api";
|
||||
version = "2.43.0";
|
||||
sha256 = "0aywd270inzfy3nizdvz7z1c083m11xfd76016q0c9sbmwrhv20j";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.Net.Client";
|
||||
version = "2.43.0";
|
||||
sha256 = "1yxm894lpn5sg6xg7i5ldd9bh7xg2s2c6xsx0yf7zrachy1bqbar";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.Net.Common";
|
||||
version = "2.37.0";
|
||||
sha256 = "1n15hmp5rzhpbrg8c36bd7n086dm3mgqimf6k601f78bbcym8c9r";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Grpc.Net.Common";
|
||||
version = "2.43.0";
|
||||
sha256 = "17gn73ccqq5aap7r8i6nir1260f5ndav2yc67wk2gnp94nsavbm2";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.CodeCoverage";
|
||||
version = "17.1.0";
|
||||
sha256 = "1ijl3w14lnj15hi052jlshf5k8vb90x0py7yrs897mf126qp8ivy";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.CSharp";
|
||||
version = "4.0.1";
|
||||
sha256 = "0zxc0apx1gcx361jlq8smc9pfdgmyjh6hpka8dypc9w23nlsh6yj";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.CSharp";
|
||||
version = "4.3.0";
|
||||
sha256 = "0gw297dgkh0al1zxvgvncqs0j15lsna9l1wpqas4rflmys440xvb";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.Extensions.DependencyInjection.Abstractions";
|
||||
version = "2.0.0";
|
||||
sha256 = "1pwrfh9b72k9rq6mb2jab5qhhi225d5rjalzkapiayggmygc8nhz";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.Extensions.Logging";
|
||||
version = "2.0.0";
|
||||
sha256 = "1jkwjcq1ld9znz1haazk8ili2g4pzfdp6i7r7rki4hg3jcadn386";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.Extensions.Logging.Abstractions";
|
||||
version = "3.1.16";
|
||||
sha256 = "1cd3wq6j01bczi9d4qq698gindj4bnf5byq25m22741i547ib90i";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.Extensions.Options";
|
||||
version = "2.0.0";
|
||||
sha256 = "0g4zadlg73f507krilhaaa7h0jdga216syrzjlyf5fdk25gxmjqh";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.Extensions.Primitives";
|
||||
version = "2.0.0";
|
||||
sha256 = "1xppr5jbny04slyjgngxjdm0maxdh47vq481ps944d7jrfs0p3mb";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NET.Test.Sdk";
|
||||
version = "17.1.0";
|
||||
sha256 = "1jaq11fhcfiylnn6wvbp2k9hrgq4cz755sfqjqjqcdxlkiyj2dkw";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Platforms";
|
||||
version = "1.0.1";
|
||||
sha256 = "01al6cfxp68dscl15z7rxfw9zvhm64dncsw09a1vmdkacsa2v6lr";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Platforms";
|
||||
version = "1.1.0";
|
||||
sha256 = "08vh1r12g6ykjygq5d3vq09zylgb84l63k49jc4v8faw9g93iqqm";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Targets";
|
||||
version = "1.0.1";
|
||||
sha256 = "0ppdkwy6s9p7x9jix3v4402wb171cdiibq7js7i13nxpdky7074p";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.NETCore.Targets";
|
||||
version = "1.1.0";
|
||||
sha256 = "193xwf33fbm0ni3idxzbr5fdq3i2dlfgihsac9jj7whj0gd902nh";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.TestPlatform.ObjectModel";
|
||||
version = "17.1.0";
|
||||
sha256 = "0jw577vbrplv9kga22lsipz91ww9iqi6j1wgpwga0vrayhggjsk2";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Microsoft.TestPlatform.TestHost";
|
||||
version = "17.1.0";
|
||||
sha256 = "0j9i078hv4qqrg2433p20pykmcjvmzarc1cy1k5f7kc7739q6vx5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Nager.PublicSuffix";
|
||||
version = "2.4.0";
|
||||
sha256 = "0v935sr0100w7j8b6yyi2ssh10az60biq32bvjqkhmgz1370q1ys";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Namotion.Reflection";
|
||||
version = "2.1.0";
|
||||
sha256 = "0ql10m9i5qm3cmcw6abk6wvm823vc4s8wzx351yffd6syd50mkb7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NETStandard.Library";
|
||||
version = "2.0.0";
|
||||
sha256 = "1bc4ba8ahgk15m8k4nd7x406nhi0kwqzbgjk2dmw52ss553xz7iy";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NETStandard.Library";
|
||||
version = "2.0.3";
|
||||
sha256 = "1fn9fxppfcg4jgypp2pmrpr6awl3qz1xmnri0cygpkwvyx27df1y";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Newtonsoft.Json";
|
||||
version = "13.0.1";
|
||||
sha256 = "0fijg0w6iwap8gvzyjnndds0q4b8anwxxvik7y8vgq97dram4srb";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Newtonsoft.Json";
|
||||
version = "9.0.1";
|
||||
sha256 = "0mcy0i7pnfpqm4pcaiyzzji4g0c8i3a5gjz28rrr28110np8304r";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NJsonSchema";
|
||||
version = "10.8.0";
|
||||
sha256 = "1mzqskv4vx5mzq0rykjwgc323afs2km0hslr2xr6r9fz9qygd28h";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NuGet.Frameworks";
|
||||
version = "5.11.0";
|
||||
sha256 = "0wv26gq39hfqw9md32amr5771s73f5zn1z9vs4y77cgynxr73s4z";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NUnit";
|
||||
version = "3.13.3";
|
||||
sha256 = "0wdzfkygqnr73s6lpxg5b1pwaqz9f414fxpvpdmf72bvh4jaqzv6";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NUnit.Analyzers";
|
||||
version = "3.3.0";
|
||||
sha256 = "00wp5q361f845aywrhhfbrpwd2srgygiam30pvn846b5dbl41vy0";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "NUnit3TestAdapter";
|
||||
version = "4.2.1";
|
||||
sha256 = "0gildh4xcb6gkxcrrgh5a1j7lq0a7l670jpbs71akl5b5bgy5gc3";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "OneOf";
|
||||
version = "3.0.216";
|
||||
sha256 = "0hhbka3ajxnhbvm39zpzn8bfdyjdx4pg5w2sixs0vkycq5q4ir10";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Pulumi";
|
||||
version = "3.53.0";
|
||||
sha256 = "0lalidv5kbn668h4517pgzv6di6x9i9ki1xi9fabbq2p9middwpj";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Pulumi.Cloudflare";
|
||||
version = "4.15.0";
|
||||
sha256 = "12wyz0slxgwwfk9ns322xgzqnix5mpx9nrmhs6rw2ssysf3jviv6";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Pulumi.Command";
|
||||
version = "4.5.0";
|
||||
sha256 = "01m3ap6prkkq8kaqdhjcs7m5ww7jb50vybadgx26381njgf24pk0";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Pulumi.DigitalOcean";
|
||||
version = "4.16.0";
|
||||
sha256 = "16xid3lv884csv1n4w3k0s9cqaikcbrpfavrp59c9aqc4l13a9v8";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Pulumi.Protobuf";
|
||||
version = "3.20.1";
|
||||
sha256 = "01qy17p1hayda462h48cdlmnhjf86m1fbjwfy6915jjajwcxb4pz";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Collections";
|
||||
version = "4.3.0";
|
||||
sha256 = "0bv5qgm6vr47ynxqbnkc7i797fdi8gbjjxii173syrx14nmrkwg0";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Diagnostics.Tools";
|
||||
version = "4.3.0";
|
||||
sha256 = "1wl76vk12zhdh66vmagni66h5xbhgqq7zkdpgw21jhxhvlbcl8pk";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Diagnostics.Tracing";
|
||||
version = "4.3.0";
|
||||
sha256 = "00j6nv2xgmd3bi347k00m7wr542wjlig53rmj28pmw7ddcn97jbn";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Globalization";
|
||||
version = "4.3.0";
|
||||
sha256 = "1daqf33hssad94lamzg01y49xwndy2q97i2lrb7mgn28656qia1x";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.IO";
|
||||
version = "4.3.0";
|
||||
sha256 = "0l8xz8zn46w4d10bcn3l4yyn4vhb3lrj2zw8llvz7jk14k4zps5x";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Reflection";
|
||||
version = "4.3.0";
|
||||
sha256 = "02c9h3y35pylc0zfq3wcsvc5nqci95nrkq0mszifc0sjx7xrzkly";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Reflection.Extensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "0zyri97dfc5vyaz9ba65hjj1zbcrzaffhsdlpxc9bh09wy22fq33";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Reflection.Primitives";
|
||||
version = "4.3.0";
|
||||
sha256 = "0x1mm8c6iy8rlxm8w9vqw7gb7s1ljadrn049fmf70cyh42vdfhrf";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Resources.ResourceManager";
|
||||
version = "4.3.0";
|
||||
sha256 = "03kickal0iiby82wa5flar18kyv82s9s6d4xhk5h4bi5kfcyfjzl";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Runtime";
|
||||
version = "4.3.0";
|
||||
sha256 = "1cqh1sv3h5j7ixyb7axxbdkqx6cxy00p4np4j91kpm492rf4s25b";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Runtime.Handles";
|
||||
version = "4.3.0";
|
||||
sha256 = "0bh5bi25nk9w9xi8z23ws45q5yia6k7dg3i4axhfqlnj145l011x";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Runtime.InteropServices";
|
||||
version = "4.3.0";
|
||||
sha256 = "0c3g3g3jmhlhw4klrc86ka9fjbl7i59ds1fadsb2l8nqf8z3kb19";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Text.Encoding";
|
||||
version = "4.3.0";
|
||||
sha256 = "0aqqi1v4wx51h51mk956y783wzags13wa7mgqyclacmsmpv02ps3";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Text.Encoding.Extensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "0lqhgqi0i8194ryqq6v2gqx0fb86db2gqknbm0aq31wb378j7ip8";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.any.System.Threading.Tasks";
|
||||
version = "4.3.0";
|
||||
sha256 = "03mnvkhskbzxddz4hm113zsch1jyzh2cs450dk3rgfjp8crlw1va";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "16rnxzpk5dpbbl1x354yrlsbvwylrq456xzpsha1n9y3glnhyx9d";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "0hkg03sgm2wyq8nqk6dbm9jh5vcq57ry42lkqdmfklrw89lsmr59";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "0c2p354hjx58xhhz7wv6div8xpi90sc6ibdm40qin21bvi7ymcaa";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.native.System";
|
||||
version = "4.3.0";
|
||||
sha256 = "15hgf6zaq9b8br2wi1i3x0zvmk410nlmsmva9p0bbg73v6hml5k4";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "18pzfdlwsg2nb1jjjjzyb5qlgy6xjxzmhnfaijq5s2jw3cm3ab97";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "0qyynf9nz5i7pc26cwhgi8j62ps27sqmf78ijcfgzab50z9g8ay3";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "1klrs545awhayryma6l7g2pvnp9xy4z0r1i40r80zb45q3i9nbyf";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "0zcxjv5pckplvkg0r6mw3asggm7aqzbdjimhvsasb0cgm59x09l3";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "0vhynn79ih7hw7cwjazn87rm9z9fj0rvxgzlab36jybgcpcgphsn";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "160p68l2c7cqmyqjwxydcvgw7lvl1cr0znkw8fp24d1by9mqc8p3";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "15zrc8fgd8zx28hdghcj5f5i34wf3l6bq5177075m2bc2j34jrqy";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl";
|
||||
version = "4.3.0";
|
||||
sha256 = "1p4dgxax6p7rlgj4q73k73rslcnz4wdcv8q2flg1s8ygwcm58ld5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.unix.System.Diagnostics.Debug";
|
||||
version = "4.3.0";
|
||||
sha256 = "1lps7fbnw34bnh3lm31gs5c0g0dh7548wfmb8zz62v0zqz71msj5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.unix.System.IO.FileSystem";
|
||||
version = "4.3.0";
|
||||
sha256 = "14nbkhvs7sji5r1saj2x8daz82rnf9kx28d3v2qss34qbr32dzix";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.unix.System.Private.Uri";
|
||||
version = "4.3.0";
|
||||
sha256 = "1jx02q6kiwlvfksq1q9qr17fj78y5v6mwsszav4qcz9z25d5g6vk";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "runtime.unix.System.Runtime.Extensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "0pnxxmm8whx38dp6yvwgmh22smknxmqs5n513fc7m4wxvs1bvi4p";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Semver";
|
||||
version = "2.1.0";
|
||||
sha256 = "02hpqh508s21x9qj6884651jn1s97gkxs54iar47dkxi8b5imq34";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Serilog";
|
||||
version = "2.10.0";
|
||||
sha256 = "08bih205i632ywryn3zxkhb15dwgyaxbhmm1z3b5nmby9fb25k7v";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Serilog";
|
||||
version = "2.8.0";
|
||||
sha256 = "0fnrs05yjnni06mbax7ig74wiiqjyyhrxmr1hrhlpwcmc40zs4ih";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Serilog.Extensions.Logging";
|
||||
version = "3.0.1";
|
||||
sha256 = "069qy7dm5nxb372ij112ppa6m99b4iaimj3sji74m659fwrcrl9a";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "Serilog.Sinks.Console";
|
||||
version = "4.0.1";
|
||||
sha256 = "080vh9kcyn9lx4j7p34146kp9byvhqlaz5jn9wzx70ql9cwd0hlz";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Buffers";
|
||||
version = "4.3.0";
|
||||
sha256 = "0fgns20ispwrfqll4q1zc1waqcmylb3zc50ys9x8zlwxh9pmd9jy";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Collections";
|
||||
version = "4.0.11";
|
||||
sha256 = "1ga40f5lrwldiyw6vy67d0sg7jd7ww6kgwbksm19wrvq9hr0bsm6";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Collections";
|
||||
version = "4.3.0";
|
||||
sha256 = "19r4y64dqyrq6k4706dnyhhw7fs24kpp3awak7whzss39dakpxk9";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Collections.NonGeneric";
|
||||
version = "4.3.0";
|
||||
sha256 = "07q3k0hf3mrcjzwj8fwk6gv3n51cb513w4mgkfxzm3i37sc9kz7k";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Diagnostics.Debug";
|
||||
version = "4.0.11";
|
||||
sha256 = "0gmjghrqmlgzxivd2xl50ncbglb7ljzb66rlx8ws6dv8jm0d5siz";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Diagnostics.Debug";
|
||||
version = "4.3.0";
|
||||
sha256 = "00yjlf19wjydyr6cfviaph3vsjzg3d5nvnya26i2fvfg53sknh3y";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Diagnostics.Tools";
|
||||
version = "4.0.1";
|
||||
sha256 = "19cknvg07yhakcvpxg3cxa0bwadplin6kyxd8mpjjpwnp56nl85x";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Diagnostics.Tracing";
|
||||
version = "4.3.0";
|
||||
sha256 = "1m3bx6c2s958qligl67q7grkwfz3w53hpy7nc97mh6f7j5k168c4";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Dynamic.Runtime";
|
||||
version = "4.0.11";
|
||||
sha256 = "1pla2dx8gkidf7xkciig6nifdsb494axjvzvann8g2lp3dbqasm9";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Dynamic.Runtime";
|
||||
version = "4.3.0";
|
||||
sha256 = "1d951hrvrpndk7insiag80qxjbf2y0y39y8h5hnq9612ws661glk";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Globalization";
|
||||
version = "4.0.11";
|
||||
sha256 = "070c5jbas2v7smm660zaf1gh0489xanjqymkvafcs4f8cdrs1d5d";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Globalization";
|
||||
version = "4.3.0";
|
||||
sha256 = "1cp68vv683n6ic2zqh2s1fn4c2sd87g5hpp6l4d4nj4536jz98ki";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO";
|
||||
version = "4.1.0";
|
||||
sha256 = "1g0yb8p11vfd0kbkyzlfsbsp5z44lwsvyc0h3dpw6vqnbi035ajp";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO";
|
||||
version = "4.3.0";
|
||||
sha256 = "05l9qdrzhm4s5dixmx68kxwif4l99ll5gqmh7rqgw554fx0agv5f";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO.FileSystem";
|
||||
version = "4.0.1";
|
||||
sha256 = "0kgfpw6w4djqra3w5crrg8xivbanh1w9dh3qapb28q060wb9flp1";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.IO.FileSystem.Primitives";
|
||||
version = "4.0.1";
|
||||
sha256 = "1s0mniajj3lvbyf7vfb5shp4ink5yibsx945k6lvxa96r8la1612";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Linq";
|
||||
version = "4.1.0";
|
||||
sha256 = "1ppg83svb39hj4hpp5k7kcryzrf3sfnm08vxd5sm2drrijsla2k5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Linq";
|
||||
version = "4.3.0";
|
||||
sha256 = "1w0gmba695rbr80l1k2h4mrwzbzsyfl2z4klmpbsvsg5pm4a56s7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Linq.Expressions";
|
||||
version = "4.1.0";
|
||||
sha256 = "1gpdxl6ip06cnab7n3zlcg6mqp7kknf73s8wjinzi4p0apw82fpg";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Linq.Expressions";
|
||||
version = "4.3.0";
|
||||
sha256 = "0ky2nrcvh70rqq88m9a5yqabsl4fyd17bpr63iy2mbivjs2nyypv";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Memory";
|
||||
version = "4.5.3";
|
||||
sha256 = "0naqahm3wljxb5a911d37mwjqjdxv9l0b49p5dmfyijvni2ppy8a";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.ObjectModel";
|
||||
version = "4.0.12";
|
||||
sha256 = "1sybkfi60a4588xn34nd9a58png36i0xr4y4v4kqpg8wlvy5krrj";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.ObjectModel";
|
||||
version = "4.3.0";
|
||||
sha256 = "191p63zy5rpqx7dnrb3h7prvgixmk168fhvvkkvhlazncf8r3nc2";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Private.Uri";
|
||||
version = "4.3.0";
|
||||
sha256 = "04r1lkdnsznin0fj4ya1zikxiqr0h6r6a1ww2dsm60gqhdrf0mvx";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection";
|
||||
version = "4.1.0";
|
||||
sha256 = "1js89429pfw79mxvbzp8p3q93il6rdff332hddhzi5wqglc4gml9";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection";
|
||||
version = "4.3.0";
|
||||
sha256 = "0xl55k0mw8cd8ra6dxzh974nxif58s3k1rjv1vbd7gjbjr39j11m";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit";
|
||||
version = "4.0.1";
|
||||
sha256 = "0ydqcsvh6smi41gyaakglnv252625hf29f7kywy2c70nhii2ylqp";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit";
|
||||
version = "4.3.0";
|
||||
sha256 = "11f8y3qfysfcrscjpjym9msk7lsfxkk4fmz9qq95kn3jd0769f74";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit.ILGeneration";
|
||||
version = "4.0.1";
|
||||
sha256 = "1pcd2ig6bg144y10w7yxgc9d22r7c7ww7qn1frdfwgxr24j9wvv0";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit.ILGeneration";
|
||||
version = "4.3.0";
|
||||
sha256 = "0w1n67glpv8241vnpz1kl14sy7zlnw414aqwj4hcx5nd86f6994q";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit.Lightweight";
|
||||
version = "4.0.1";
|
||||
sha256 = "1s4b043zdbx9k39lfhvsk68msv1nxbidhkq6nbm27q7sf8xcsnxr";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Emit.Lightweight";
|
||||
version = "4.3.0";
|
||||
sha256 = "0ql7lcakycrvzgi9kxz1b3lljd990az1x6c4jsiwcacrvimpib5c";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Extensions";
|
||||
version = "4.0.1";
|
||||
sha256 = "0m7wqwq0zqq9gbpiqvgk3sr92cbrw7cp3xn53xvw7zj6rz6fdirn";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Extensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "02bly8bdc98gs22lqsfx9xicblszr2yan7v2mmw3g7hy6miq5hwq";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Metadata";
|
||||
version = "1.6.0";
|
||||
sha256 = "1wdbavrrkajy7qbdblpbpbalbdl48q3h34cchz24gvdgyrlf15r4";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Metadata";
|
||||
version = "5.0.0";
|
||||
sha256 = "17qsl5nanlqk9iz0l5wijdn6ka632fs1m1fvx18dfgswm258r3ss";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Primitives";
|
||||
version = "4.0.1";
|
||||
sha256 = "1bangaabhsl4k9fg8khn83wm6yial8ik1sza7401621jc6jrym28";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.Primitives";
|
||||
version = "4.3.0";
|
||||
sha256 = "04xqa33bld78yv5r93a8n76shvc8wwcdgr1qvvjh959g3rc31276";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.TypeExtensions";
|
||||
version = "4.1.0";
|
||||
sha256 = "1bjli8a7sc7jlxqgcagl9nh8axzfl11f4ld3rjqsyxc516iijij7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Reflection.TypeExtensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "0y2ssg08d817p0vdag98vn238gyrrynjdj4181hdg780sif3ykp1";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Resources.ResourceManager";
|
||||
version = "4.0.1";
|
||||
sha256 = "0b4i7mncaf8cnai85jv3wnw6hps140cxz8vylv2bik6wyzgvz7bi";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Resources.ResourceManager";
|
||||
version = "4.3.0";
|
||||
sha256 = "0sjqlzsryb0mg4y4xzf35xi523s4is4hz9q4qgdvlvgivl7qxn49";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime";
|
||||
version = "4.1.0";
|
||||
sha256 = "02hdkgk13rvsd6r9yafbwzss8kr55wnj8d5c7xjnp8gqrwc8sn0m";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime";
|
||||
version = "4.3.0";
|
||||
sha256 = "066ixvgbf2c929kgknshcxqj6539ax7b9m570cp8n179cpfkapz7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.CompilerServices.Unsafe";
|
||||
version = "4.4.0";
|
||||
sha256 = "0a6ahgi5b148sl5qyfpyw383p3cb4yrkm802k29fsi4mxkiwir29";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.Extensions";
|
||||
version = "4.1.0";
|
||||
sha256 = "0rw4rm4vsm3h3szxp9iijc3ksyviwsv6f63dng3vhqyg4vjdkc2z";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.Extensions";
|
||||
version = "4.3.0";
|
||||
sha256 = "1ykp3dnhwvm48nap8q23893hagf665k0kn3cbgsqpwzbijdcgc60";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.Handles";
|
||||
version = "4.0.1";
|
||||
sha256 = "1g0zrdi5508v49pfm3iii2hn6nm00bgvfpjq1zxknfjrxxa20r4g";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.Handles";
|
||||
version = "4.3.0";
|
||||
sha256 = "0sw2gfj2xr7sw9qjn0j3l9yw07x73lcs97p8xfc9w1x9h5g5m7i8";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.InteropServices";
|
||||
version = "4.1.0";
|
||||
sha256 = "01kxqppx3dr3b6b286xafqilv4s2n0gqvfgzfd4z943ga9i81is1";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.InteropServices";
|
||||
version = "4.3.0";
|
||||
sha256 = "00hywrn4g7hva1b2qri2s6rabzwgxnbpw9zfxmz28z09cpwwgh7j";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Runtime.Serialization.Primitives";
|
||||
version = "4.1.1";
|
||||
sha256 = "042rfjixknlr6r10vx2pgf56yming8lkjikamg3g4v29ikk78h7k";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.Encoding";
|
||||
version = "4.0.11";
|
||||
sha256 = "1dyqv0hijg265dwxg6l7aiv74102d6xjiwplh2ar1ly6xfaa4iiw";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.Encoding";
|
||||
version = "4.3.0";
|
||||
sha256 = "1f04lkir4iladpp51sdgmis9dj4y8v08cka0mbmsy0frc9a4gjqr";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.Encoding.Extensions";
|
||||
version = "4.0.11";
|
||||
sha256 = "08nsfrpiwsg9x5ml4xyl3zyvjfdi4mvbqf93kjdh11j4fwkznizs";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Text.RegularExpressions";
|
||||
version = "4.1.0";
|
||||
sha256 = "1mw7vfkkyd04yn2fbhm38msk7dz2xwvib14ygjsb8dq2lcvr18y7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Threading";
|
||||
version = "4.0.11";
|
||||
sha256 = "19x946h926bzvbsgj28csn46gak2crv2skpwsx80hbgazmkgb1ls";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Threading";
|
||||
version = "4.3.0";
|
||||
sha256 = "0rw9wfamvhayp5zh3j7p1yfmx9b5khbf4q50d8k5rk993rskfd34";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Threading.Tasks";
|
||||
version = "4.0.11";
|
||||
sha256 = "0nr1r41rak82qfa5m0lhk9mp0k93bvfd7bbd9sdzwx9mb36g28p5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Threading.Tasks";
|
||||
version = "4.3.0";
|
||||
sha256 = "134z3v9abw3a6jsw17xl3f6hqjpak5l682k2vz39spj4kmydg6k7";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Threading.Tasks.Extensions";
|
||||
version = "4.0.0";
|
||||
sha256 = "1cb51z062mvc2i8blpzmpn9d9mm4y307xrwi65di8ri18cz5r1zr";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Xml.ReaderWriter";
|
||||
version = "4.0.11";
|
||||
sha256 = "0c6ky1jk5ada9m94wcadih98l6k1fvf6vi7vhn1msjixaha419l5";
|
||||
})
|
||||
(fetchNuGet {
|
||||
pname = "System.Xml.XDocument";
|
||||
version = "4.0.11";
|
||||
sha256 = "0n4lvpqzy9kc7qy1a4acwwd7b7pnvygv895az5640idl2y9zbz18";
|
||||
})
|
||||
]
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This file was adapted from
|
||||
# https://github.com/NixOS/nixpkgs/blob/b981d811453ab84fb3ea593a9b33b960f1ab9147/pkgs/build-support/dotnet/build-dotnet-module/default.nix#L173
|
||||
set -euo pipefail
|
||||
export PATH="@binPath@"
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--keep-sources|-k)
|
||||
keepSources=1
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
echo "usage: $0 [--keep-sources] [--help] <output path>"
|
||||
echo " <output path> The path to write the lockfile to. A temporary file is used if this is not set"
|
||||
echo " --keep-sources Don't remove temporary directories upon exit, useful for debugging"
|
||||
echo " --help Show this help message"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
done
|
||||
tmp=$(mktemp -td "@pname@-tmp-XXXXXX")
|
||||
export tmp
|
||||
HOME=$tmp/home
|
||||
exitTrap() {
|
||||
test -n "${ranTrap-}" && return
|
||||
ranTrap=1
|
||||
if test -n "${keepSources-}"; then
|
||||
echo -e "Path to the source: $tmp/src\nPath to the fake home: $tmp/home"
|
||||
else
|
||||
rm -rf "$tmp"
|
||||
fi
|
||||
# Since mktemp is used this will be empty if the script didnt succesfully complete
|
||||
if ! test -s "$depsFile"; then
|
||||
rm -rf "$depsFile"
|
||||
fi
|
||||
}
|
||||
trap exitTrap EXIT INT TERM
|
||||
dotnetRestore() {
|
||||
local -r project="${1-}"
|
||||
local -r rid="$2"
|
||||
dotnet restore "${project-}" \
|
||||
-p:ContinuousIntegrationBuild=true \
|
||||
-p:Deterministic=true \
|
||||
--packages "$tmp/nuget_pkgs" \
|
||||
--runtime "$rid" \
|
||||
--no-cache \
|
||||
--force
|
||||
}
|
||||
declare -a projectFiles=( @projectFiles@ )
|
||||
declare -a testProjectFiles=( @testProjectFiles@ )
|
||||
export DOTNET_NOLOGO=1
|
||||
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||
depsFile=$(realpath "${1:-$(mktemp -t "@pname@-deps-XXXXXX.nix")}")
|
||||
mkdir -p "$tmp/nuget_pkgs"
|
||||
storeSrc="@storeSrc@"
|
||||
src="$tmp/src"
|
||||
cp -rT "$storeSrc" "$src"
|
||||
chmod -R +w "$src"
|
||||
cd "$src"
|
||||
echo "Restoring project..."
|
||||
rids=("@rids@")
|
||||
for rid in "${rids[@]}"; do
|
||||
(( ${#projectFiles[@]} == 0 )) && dotnetRestore "" "$rid"
|
||||
for project in "${projectFiles[@]-}" "${testProjectFiles[@]-}"; do
|
||||
dotnetRestore "$project" "$rid"
|
||||
done
|
||||
done
|
||||
echo "Successfully restored project"
|
||||
echo "Writing lockfile..."
|
||||
echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please don't edit it manually, your changes might get overwritten!\n" > "$depsFile"
|
||||
nuget-to-nix "$tmp/nuget_pkgs" "@packages@" >> "$depsFile"
|
||||
echo "Successfully wrote lockfile to $depsFile"
|
||||
Reference in New Issue
Block a user