From 7eb52ca92e6903aea495e71bbc76902f12f3f3f9 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sun, 13 Aug 2023 19:55:48 +0200 Subject: [PATCH 01/44] .gitignore: ignore IntelliJ config directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6e4284 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea/ From 645f6631ea86e4b509259fea2702bc07295bfd6a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sun, 13 Aug 2023 19:56:44 +0200 Subject: [PATCH 02/44] ctor: enable Kubernetes for codingteam.org.ru --- .editorconfig | 3 ++ .../kubernetes/codingteam.org.ru.service.yaml | 11 ++++++ ctor/kubernetes/codingteam.org.ru.yaml | 38 +++++++++++++++++++ ctor/kubernetes/deploy.ps1 | 4 ++ 4 files changed, 56 insertions(+) create mode 100644 ctor/kubernetes/codingteam.org.ru.service.yaml create mode 100644 ctor/kubernetes/codingteam.org.ru.yaml create mode 100644 ctor/kubernetes/deploy.ps1 diff --git a/.editorconfig b/.editorconfig index 2225fd9..eb8cecc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,3 +6,6 @@ indent_style = space indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true + +[*.yaml] +indent_size = 2 diff --git a/ctor/kubernetes/codingteam.org.ru.service.yaml b/ctor/kubernetes/codingteam.org.ru.service.yaml new file mode 100644 index 0000000..7ebb028 --- /dev/null +++ b/ctor/kubernetes/codingteam.org.ru.service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: ctor +spec: + ports: + - nodePort: 32603 + port: 80 + selector: + app: ctor + type: NodePort diff --git a/ctor/kubernetes/codingteam.org.ru.yaml b/ctor/kubernetes/codingteam.org.ru.yaml new file mode 100644 index 0000000..3ebe423 --- /dev/null +++ b/ctor/kubernetes/codingteam.org.ru.yaml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + deployment.kubernetes.io/revision: "1" + labels: + app: ctor + name: ctor + namespace: default +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: ctor + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: ctor + spec: + containers: + - image: codingteam/codingteam.org.ru:v1.1.0 + imagePullPolicy: IfNotPresent + name: codingteam-org-ru + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/ctor/kubernetes/deploy.ps1 b/ctor/kubernetes/deploy.ps1 new file mode 100644 index 0000000..7cf88ba --- /dev/null +++ b/ctor/kubernetes/deploy.ps1 @@ -0,0 +1,4 @@ +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +kubectl apply -f $PSScriptRoot From bde958e45b9db3ac9db887beb3278afbca2009a6 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 20 Dec 2023 21:53:18 +0100 Subject: [PATCH 03/44] ctor: add deployment skeleton --- .gitignore | 4 ++++ Codingteam.Devops.sln | 27 +++++++++++++++++++++++++++ ctor/Codingteam.Ctor.fsproj | 12 ++++++++++++ ctor/Program.fs | 2 ++ 4 files changed, 45 insertions(+) create mode 100644 .gitignore create mode 100644 Codingteam.Devops.sln create mode 100644 ctor/Codingteam.Ctor.fsproj create mode 100644 ctor/Program.fs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4467200 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/.idea/ + +bin/ +obj/ diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln new file mode 100644 index 0000000..2c816d8 --- /dev/null +++ b/Codingteam.Devops.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Codingteam.Ctor", "ctor\Codingteam.Ctor.fsproj", "{E08EC4D8-5FD7-45CB-B48A-689005546B10}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A37A2B6B-F09B-4105-8AA5-47BA5D74B68A}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj new file mode 100644 index 0000000..5a3c697 --- /dev/null +++ b/ctor/Codingteam.Ctor.fsproj @@ -0,0 +1,12 @@ + + + + Exe + net8.0 + + + + + + + diff --git a/ctor/Program.fs b/ctor/Program.fs new file mode 100644 index 0000000..4d0a957 --- /dev/null +++ b/ctor/Program.fs @@ -0,0 +1,2 @@ +printfn "TODO: Deployment" +exit 1 From fc166af27ed4c5b8d8df11578398c3db9da33056 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 20 Dec 2023 21:56:38 +0100 Subject: [PATCH 04/44] Deployment: add a rudimentary test --- .editorconfig | 3 +++ .github/workflows/main.yml | 55 ++++++++++++++++++++++++++++++++++++++ Codingteam.Devops.sln | 11 ++++++++ 3 files changed, 69 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.editorconfig b/.editorconfig index 2225fd9..e2139a6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,3 +6,6 @@ indent_style = space indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true + +[*.yml] +indent_size = 2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..2f675b3 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,55 @@ +name: Main +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '0 0 * * 6' + + workflow_dispatch: + +jobs: + main: + strategy: + fail-fast: false + matrix: + config: + - name: 'macos' + image: 'macos-12' + - name: 'linux' + image: 'ubuntu-22.04' + - name: 'windows' + image: 'windows-2022' + + name: main.${{ matrix.config.name }} + runs-on: ${{ matrix.config.image }} + + # noinspection SpellCheckingInspection + env: + DOTNET_NOLOGO: 1 + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + NUGET_PACKAGES: ${{ github.workspace }}/.github/nuget-packages + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: NuGet cache + uses: actions/cache@v3 + with: + path: ${{ env.NUGET_PACKAGES }} + key: ${{ runner.os }}.nuget.${{ hashFiles('**/*.fsproj') }} + + - name: Set up .NET SDK + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' + + - name: Build + run: dotnet build + + - name: Test + run: dotnet run --project ctor -- verify diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln index 2c816d8..ac65655 100644 --- a/Codingteam.Devops.sln +++ b/Codingteam.Devops.sln @@ -8,6 +8,14 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A37A2B6B-F09B-4105-8AA5-47BA5D74B68A}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + .editorconfig = .editorconfig + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{C4672A21-FB21-4BBF-A0A1-512AC1B66C9A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67164D20-A669-4BC3-A40E-751D3045BA89}" + ProjectSection(SolutionItems) = preProject + .github\workflows\main.yml = .github\workflows\main.yml EndProjectSection EndProject Global @@ -24,4 +32,7 @@ Global {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.ActiveCfg = Release|Any CPU {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {67164D20-A669-4BC3-A40E-751D3045BA89} = {C4672A21-FB21-4BBF-A0A1-512AC1B66C9A} + EndGlobalSection EndGlobal From 19db3aee0b7ca486111674980ce8ea45e8af0d93 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 20 Dec 2023 22:00:09 +0100 Subject: [PATCH 05/44] Deployment: add a Fabricator dependency (temporarily as a submodule) --- .gitmodules | 3 +++ Codingteam.Devops.sln | 16 ++++++++++++++++ Fabricator | 1 + 3 files changed, 20 insertions(+) create mode 100644 .gitmodules create mode 160000 Fabricator diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..83afccf --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Fabricator"] + path = Fabricator + url = git@github.com:ForNeVeR/Fabricator.git diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln index ac65655..d275ce7 100644 --- a/Codingteam.Devops.sln +++ b/Codingteam.Devops.sln @@ -18,6 +18,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\main.yml = .github\workflows\main.yml EndProjectSection EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Console", "Fabricator\Fabricator.Console\Fabricator.Console.fsproj", "{0157906C-006C-45F8-A79A-0D55F16B16B2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fabricator", "Fabricator", "{853E359A-18C5-4472-A712-D5C80EE99D6B}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Core", "Fabricator\Fabricator.Core\Fabricator.Core.fsproj", "{C57439E9-20AF-4EEB-8C91-5D74D346374B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,8 +37,18 @@ Global {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Debug|Any CPU.Build.0 = Debug|Any CPU {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.ActiveCfg = Release|Any CPU {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.Build.0 = Release|Any CPU + {0157906C-006C-45F8-A79A-0D55F16B16B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0157906C-006C-45F8-A79A-0D55F16B16B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0157906C-006C-45F8-A79A-0D55F16B16B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0157906C-006C-45F8-A79A-0D55F16B16B2}.Release|Any CPU.Build.0 = Release|Any CPU + {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67164D20-A669-4BC3-A40E-751D3045BA89} = {C4672A21-FB21-4BBF-A0A1-512AC1B66C9A} + {0157906C-006C-45F8-A79A-0D55F16B16B2} = {853E359A-18C5-4472-A712-D5C80EE99D6B} + {C57439E9-20AF-4EEB-8C91-5D74D346374B} = {853E359A-18C5-4472-A712-D5C80EE99D6B} EndGlobalSection EndGlobal diff --git a/Fabricator b/Fabricator new file mode 160000 index 0000000..429cd9a --- /dev/null +++ b/Fabricator @@ -0,0 +1 @@ +Subproject commit 429cd9a8c882ece78e43c1108e094a1d5b598576 From 373effdab9057f80244480e9fd31f9f3d5f1bc8c Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 20 Dec 2023 23:36:03 +0100 Subject: [PATCH 06/44] Deployment: preliminary GreenCaptchaBot schema --- .gitignore | 2 ++ Codingteam.Devops.sln | 7 +++++++ Codingteam.Devops.sln.DotSettings | 2 ++ ctor/Codingteam.Ctor.fsproj | 7 +++++++ ctor/GreenCaptchaBot.fs | 21 +++++++++++++++++++++ ctor/GreenCaptchaBot.template.json | 6 ++++++ ctor/Program.fs | 20 ++++++++++++++++++-- 7 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 Codingteam.Devops.sln.DotSettings create mode 100644 ctor/GreenCaptchaBot.fs create mode 100644 ctor/GreenCaptchaBot.template.json diff --git a/.gitignore b/.gitignore index 4467200..90e413f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ bin/ obj/ + +*.private.json diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln index d275ce7..324521f 100644 --- a/Codingteam.Devops.sln +++ b/Codingteam.Devops.sln @@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fabricator", "Fabricator", EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Core", "Fabricator\Fabricator.Core\Fabricator.Core.fsproj", "{C57439E9-20AF-4EEB-8C91-5D74D346374B}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Resources", "Fabricator\Fabricator.Resources\Fabricator.Resources.fsproj", "{414C5063-3201-43AC-9DA1-B18A18802C0D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,10 +47,15 @@ Global {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Debug|Any CPU.Build.0 = Debug|Any CPU {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.ActiveCfg = Release|Any CPU {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.Build.0 = Release|Any CPU + {414C5063-3201-43AC-9DA1-B18A18802C0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {414C5063-3201-43AC-9DA1-B18A18802C0D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67164D20-A669-4BC3-A40E-751D3045BA89} = {C4672A21-FB21-4BBF-A0A1-512AC1B66C9A} {0157906C-006C-45F8-A79A-0D55F16B16B2} = {853E359A-18C5-4472-A712-D5C80EE99D6B} {C57439E9-20AF-4EEB-8C91-5D74D346374B} = {853E359A-18C5-4472-A712-D5C80EE99D6B} + {414C5063-3201-43AC-9DA1-B18A18802C0D} = {853E359A-18C5-4472-A712-D5C80EE99D6B} EndGlobalSection EndGlobal diff --git a/Codingteam.Devops.sln.DotSettings b/Codingteam.Devops.sln.DotSettings new file mode 100644 index 0000000..2f3a410 --- /dev/null +++ b/Codingteam.Devops.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj index 5a3c697..6ab6cae 100644 --- a/ctor/Codingteam.Ctor.fsproj +++ b/ctor/Codingteam.Ctor.fsproj @@ -6,7 +6,14 @@ + + + + + + + diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs new file mode 100644 index 0000000..de55876 --- /dev/null +++ b/ctor/GreenCaptchaBot.fs @@ -0,0 +1,21 @@ +module internal Codingteam.Ctor.GreenCaptchaBot + +open Fabricator.Core +open Fabricator.Resources.Files + +let private hostConfigDirectory = "/opt/green-captcha-bot/" +let private docker = docker { + let version = "v1.15.1" + fromSources <| sources { + gitRepository "https://github.com/ImoutoChan/GreenCaptchaBot.git" + reference $"tags/{version}" + } + withDockerfile "CaptchaBot/Dockerfile" + withTag version + withName "green-captcha-bot" + withVolume(hostPath = hostConfigDirectory, containerPath = "/app/Configuration") +} + +let private configFile = FileResource(templatedFile "GreenCaptchaBot.template.json", $"{hostConfigDirectory}/appsettings.json") + +let resources: IResource[] = [| configFile; docker |] diff --git a/ctor/GreenCaptchaBot.template.json b/ctor/GreenCaptchaBot.template.json new file mode 100644 index 0000000..b42143b --- /dev/null +++ b/ctor/GreenCaptchaBot.template.json @@ -0,0 +1,6 @@ +{ + "Configuration": { + "BotToken": "$BOT_TOKEN", + "DeleteJoinMessages": "Unsuccessful" + } +} diff --git a/ctor/Program.fs b/ctor/Program.fs index 4d0a957..2359df6 100644 --- a/ctor/Program.fs +++ b/ctor/Program.fs @@ -1,2 +1,18 @@ -printfn "TODO: Deployment" -exit 1 +open Codingteam.Ctor +open Fabricator.Console +open Fabricator.Core + +let private cluster mode = + let connectionsFileName = if mode = RunMode.Verify then "connections.stub.json" else "connections.private.json" + [| + { + Name = "ctor" + Designator = Designators.fromConnectionsFile connectionsFileName "ctor" + Resources = GreenCaptchaBot.resources + Type = MachineType.Linux + } + |] + +let main (args: string[]): int = + let cluster = + EntryPoint.main args cluster From aea03c5443686954888ae41f82cc68a553557859 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 23 Dec 2023 00:09:27 +0100 Subject: [PATCH 07/44] Deployment: improve the docker specifications --- ctor/GreenCaptchaBot.fs | 22 +++++++++++++--------- ctor/Program.fs | 1 - 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs index de55876..cb0d67a 100644 --- a/ctor/GreenCaptchaBot.fs +++ b/ctor/GreenCaptchaBot.fs @@ -2,19 +2,23 @@ open Fabricator.Core open Fabricator.Resources.Files +open Fabricator.Resources.Docker let private hostConfigDirectory = "/opt/green-captcha-bot/" -let private docker = docker { +let private docker = let version = "v1.15.1" - fromSources <| sources { - gitRepository "https://github.com/ImoutoChan/GreenCaptchaBot.git" - reference $"tags/{version}" + dockerContainer { + Sources = { + GitRepository = "https://github.com/ImoutoChan/GreenCaptchaBot.git" + GitReference = $"tags/{version}" + } + DockerfilePath = "CaptchaBot/Dockerfile" + Tag = version + Name = "green-captcha-bot" + Options = [| + Volume(hostPath = hostConfigDirectory, containerPath = "/app/Configuration") + |] } - withDockerfile "CaptchaBot/Dockerfile" - withTag version - withName "green-captcha-bot" - withVolume(hostPath = hostConfigDirectory, containerPath = "/app/Configuration") -} let private configFile = FileResource(templatedFile "GreenCaptchaBot.template.json", $"{hostConfigDirectory}/appsettings.json") diff --git a/ctor/Program.fs b/ctor/Program.fs index 2359df6..5dbc4ae 100644 --- a/ctor/Program.fs +++ b/ctor/Program.fs @@ -14,5 +14,4 @@ let private cluster mode = |] let main (args: string[]): int = - let cluster = EntryPoint.main args cluster From 9968ebb6328fed9356edc51d220b91dc34259128 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 23 Dec 2023 20:54:56 +0100 Subject: [PATCH 08/44] Deployment: initial templated version --- Codingteam.Devops.sln | 7 +++++++ Fabricator | 2 +- ctor/Codingteam.Ctor.fsproj | 1 + ctor/GreenCaptchaBot.fs | 8 ++++++-- ctor/Program.fs | 18 +++++++++++------- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln index 324521f..e1a92c3 100644 --- a/Codingteam.Devops.sln +++ b/Codingteam.Devops.sln @@ -26,6 +26,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Core", "Fabricat EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Resources", "Fabricator\Fabricator.Resources\Fabricator.Resources.fsproj", "{414C5063-3201-43AC-9DA1-B18A18802C0D}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Templates", "Fabricator\Fabricator.Templates\Fabricator.Templates.fsproj", "{E4F7858D-B0F7-4B42-928F-02688E843566}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,11 +53,16 @@ Global {414C5063-3201-43AC-9DA1-B18A18802C0D}.Debug|Any CPU.Build.0 = Debug|Any CPU {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.ActiveCfg = Release|Any CPU {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.Build.0 = Release|Any CPU + {E4F7858D-B0F7-4B42-928F-02688E843566}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4F7858D-B0F7-4B42-928F-02688E843566}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4F7858D-B0F7-4B42-928F-02688E843566}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4F7858D-B0F7-4B42-928F-02688E843566}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67164D20-A669-4BC3-A40E-751D3045BA89} = {C4672A21-FB21-4BBF-A0A1-512AC1B66C9A} {0157906C-006C-45F8-A79A-0D55F16B16B2} = {853E359A-18C5-4472-A712-D5C80EE99D6B} {C57439E9-20AF-4EEB-8C91-5D74D346374B} = {853E359A-18C5-4472-A712-D5C80EE99D6B} {414C5063-3201-43AC-9DA1-B18A18802C0D} = {853E359A-18C5-4472-A712-D5C80EE99D6B} + {E4F7858D-B0F7-4B42-928F-02688E843566} = {853E359A-18C5-4472-A712-D5C80EE99D6B} EndGlobalSection EndGlobal diff --git a/Fabricator b/Fabricator index 429cd9a..b5b64d1 160000 --- a/Fabricator +++ b/Fabricator @@ -1 +1 @@ -Subproject commit 429cd9a8c882ece78e43c1108e094a1d5b598576 +Subproject commit b5b64d10005b1fd45f4cbe2172e17c1f91e21f9d diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj index 6ab6cae..58c3f3a 100644 --- a/ctor/Codingteam.Ctor.fsproj +++ b/ctor/Codingteam.Ctor.fsproj @@ -14,6 +14,7 @@ + diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs index cb0d67a..a706483 100644 --- a/ctor/GreenCaptchaBot.fs +++ b/ctor/GreenCaptchaBot.fs @@ -3,6 +3,7 @@ open Fabricator.Core open Fabricator.Resources.Files open Fabricator.Resources.Docker +open Fabricator.Templates.FileTemplates let private hostConfigDirectory = "/opt/green-captcha-bot/" let private docker = @@ -20,6 +21,9 @@ let private docker = |] } -let private configFile = FileResource(templatedFile "GreenCaptchaBot.template.json", $"{hostConfigDirectory}/appsettings.json") +let private configFile parameters = FileResource( + templatedFile "GreenCaptchaBot.template.json" parameters, + $"{hostConfigDirectory}/appsettings.json" +) -let resources: IResource[] = [| configFile; docker |] +let resources(parameters: Map): IResource[] = [| configFile parameters; docker |] diff --git a/ctor/Program.fs b/ctor/Program.fs index 5dbc4ae..78dee2a 100644 --- a/ctor/Program.fs +++ b/ctor/Program.fs @@ -1,17 +1,21 @@ -open Codingteam.Ctor -open Fabricator.Console +open Fabricator.Console open Fabricator.Core +open Fabricator.Templates.FileTemplates -let private cluster mode = - let connectionsFileName = if mode = RunMode.Verify then "connections.stub.json" else "connections.private.json" - [| +open Codingteam.Ctor + +let private cluster mode = task { + let connectionsFileName = if mode = EntryPoint.RunMode.Verify then "connections.stub.json" else "connections.private.json" + let! parameters = readParameterFile "parameters.json" + return [| { Name = "ctor" Designator = Designators.fromConnectionsFile connectionsFileName "ctor" - Resources = GreenCaptchaBot.resources + Resources = GreenCaptchaBot.resources parameters Type = MachineType.Linux } |] +} let main (args: string[]): int = - EntryPoint.main args cluster + EntryPoint.main args (fun m -> (cluster m).GetAwaiter().GetResult()) From 652bede3a2ce6735733302ac5dfc3e430627ab97 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 00:33:33 +0200 Subject: [PATCH 09/44] (#39) xmpp2: start the host specification --- README.md | 2 ++ xmpp2/HOST.md | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 xmpp2/HOST.md diff --git a/README.md b/README.md index d18859b..0b6ca66 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Host specification - [codingteam.org.ru][hosts/ctor] - [cthulhu-3][hosts/cthulhu-3] - [omnissiah][hosts/omnissiah] +- [xmpp2][hosts.xmpp2] Documentation ------------- @@ -40,6 +41,7 @@ The license indication in the project's sources is compliant with the [REUSE spe [codingteam.org.ru]: https://codingteam.org.ru [devops]: https://ru.wikipedia.org/wiki/DevOps [docs.license]: LICENSES/MIT.txt +[host.xmpp2]: xmpp2/HOST.md [hosts/cthulhu-3]: cthulhu-3/Host.md [hosts/ctor]: ctor/Host.md [hosts/omnissiah]: omnissiah/Host.md diff --git a/xmpp2/HOST.md b/xmpp2/HOST.md new file mode 100644 index 0000000..763b920 --- /dev/null +++ b/xmpp2/HOST.md @@ -0,0 +1,4 @@ +xmpp2 host +========== +- **Provider:** Digital Ocean +- **OS**: Ubuntu 24.04 From f8fb4f9ee06e32b87d18d43ba2b937ffdfc38286 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 23:23:34 +0200 Subject: [PATCH 10/44] (#39) xmpp2: set up the users via Ansible --- README.md | 2 +- xmpp2/.gitignore | 7 +++++++ xmpp2/HOST.md | 4 ---- xmpp2/README.md | 20 +++++++++++++++++++ xmpp2/ansible-playbook.ps1 | 5 +++++ xmpp2/default.yml | 5 +++++ xmpp2/hosts.example.ini | 6 ++++++ xmpp2/users.yml | 39 +++++++++++++++++++++++++++++++++++++ xmpp2/vars/vars.example.yml | 3 +++ 9 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 xmpp2/.gitignore delete mode 100644 xmpp2/HOST.md create mode 100644 xmpp2/README.md create mode 100644 xmpp2/ansible-playbook.ps1 create mode 100644 xmpp2/default.yml create mode 100644 xmpp2/hosts.example.ini create mode 100644 xmpp2/users.yml create mode 100644 xmpp2/vars/vars.example.yml diff --git a/README.md b/README.md index 0b6ca66..e287c5d 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The license indication in the project's sources is compliant with the [REUSE spe [codingteam.org.ru]: https://codingteam.org.ru [devops]: https://ru.wikipedia.org/wiki/DevOps [docs.license]: LICENSES/MIT.txt -[host.xmpp2]: xmpp2/HOST.md +[host.xmpp2]: xmpp2/README.md [hosts/cthulhu-3]: cthulhu-3/Host.md [hosts/ctor]: ctor/Host.md [hosts/omnissiah]: omnissiah/Host.md diff --git a/xmpp2/.gitignore b/xmpp2/.gitignore new file mode 100644 index 0000000..861afe3 --- /dev/null +++ b/xmpp2/.gitignore @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +hosts.ini + +vars/vars.yml diff --git a/xmpp2/HOST.md b/xmpp2/HOST.md deleted file mode 100644 index 763b920..0000000 --- a/xmpp2/HOST.md +++ /dev/null @@ -1,4 +0,0 @@ -xmpp2 host -========== -- **Provider:** Digital Ocean -- **OS**: Ubuntu 24.04 diff --git a/xmpp2/README.md b/xmpp2/README.md new file mode 100644 index 0000000..7ffbd1a --- /dev/null +++ b/xmpp2/README.md @@ -0,0 +1,20 @@ + + +xmpp2 host +========== +- **Provider:** Digital Ocean +- **OS**: Ubuntu 24.04 + +How to Deploy +------------- +1. Copy `hosts.example.ini` to `hosts.ini`, fix the host connection details if needed. +2. Copy `vars/vars.example.yml` to `vars/vars.yml` and adjust it accordingly. +3. To **check the results** without applying, run `ansible-playbook --check --diff default.yml`. + + To **deploy**, run `ansible-playbook default.yml`. + +If on Windows, feel free to use scripts `ansible-playbook.ps1` as a substitute to use Ansible from WSL. diff --git a/xmpp2/ansible-playbook.ps1 b/xmpp2/ansible-playbook.ps1 new file mode 100644 index 0000000..4e40c4e --- /dev/null +++ b/xmpp2/ansible-playbook.ps1 @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +wsl --distribution Ubuntu ansible-playbook --inventory hosts.ini @args -e 'ansible_ssh_pipelining=True' diff --git a/xmpp2/default.yml b/xmpp2/default.yml new file mode 100644 index 0000000..452bfef --- /dev/null +++ b/xmpp2/default.yml @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +- import_playbook: users.yml diff --git a/xmpp2/hosts.example.ini b/xmpp2/hosts.example.ini new file mode 100644 index 0000000..512c65d --- /dev/null +++ b/xmpp2/hosts.example.ini @@ -0,0 +1,6 @@ +; SPDX-FileCopyrightText: 2025 Friedrich von Never +; +; SPDX-License-Identifier: MIT + +[xmpp2] +xmpp2 ansible_user=mario ansible_ssh_private_key_file=/home/mario/.ssh/xmpp2 diff --git a/xmpp2/users.yml b/xmpp2/users.yml new file mode 100644 index 0000000..a265d24 --- /dev/null +++ b/xmpp2/users.yml @@ -0,0 +1,39 @@ +--- +- name: Set up user + hosts: xmpp2 + become: true + + vars_files: + - vars.yml + + handlers: + - name: Reload sshd + ansible.builtin.service: + name: ssh + state: reloaded + + tasks: + - name: Ensure a group exists for those who can connect with SSH + ansible.builtin.group: + name: sshuser + + - name: Ensure a user exists and can SSH into the machine + ansible.builtin.user: + name: '{{ user.name }}' + shell: /bin/sh + groups: [ 'sudo', 'sshuser' ] + append: true + home: '/home/{{ user.name }}' + password_lock: true + + - name: Ensure the user can use SSH + ansible.posix.authorized_key: + user: '{{ user.name }}' + key: '{{ user.ssh_key }}' + + - name: Ensure only members of sshuser group can connect via SSH + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + line: 'AllowGroups sshuser' + validate: 'sshd -f %s -t' + notify: Reload sshd diff --git a/xmpp2/vars/vars.example.yml b/xmpp2/vars/vars.example.yml new file mode 100644 index 0000000..1847e4b --- /dev/null +++ b/xmpp2/vars/vars.example.yml @@ -0,0 +1,3 @@ +user: + name: mario + ssh_key: 'ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXX/XXX username1@hostname' From bc5e86c870456317be461017b5625e484542875d Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 23:25:13 +0200 Subject: [PATCH 11/44] (#39) CI: enable Ansible lint --- .github/workflows/main.yml | 10 ++++++++++ ansible-lint.yml | 7 +++++++ requirements.yml | 8 ++++++++ 3 files changed, 25 insertions(+) create mode 100644 ansible-lint.yml create mode 100644 requirements.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b24358c..6023103 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,6 +14,16 @@ on: workflow_dispatch: jobs: + lint: + runs-on: ubuntu-24.04 + steps: + - name: Check out the repository + uses: actions/checkout@v4 + - name: Run ansible-lint + uses: ansible/ansible-lint@v25 + with: + args: "-c ansible-lint.yml" + encoding: runs-on: ubuntu-24.04 steps: diff --git a/ansible-lint.yml b/ansible-lint.yml new file mode 100644 index 0000000..87c7275 --- /dev/null +++ b/ansible-lint.yml @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +exclude_paths: + - .github/ # no Ansible plays in there + - xmpp2/default.yml # just a list of other files diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..391265a --- /dev/null +++ b/requirements.yml @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +--- +collections: + - name: ansible.posix + version: 1.5.4 From ef6596669d2f339343e1f15cf432cec3ed86138d Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 23:29:44 +0200 Subject: [PATCH 12/44] Deployment: update the file encodings --- Codingteam.Devops.sln | 2 +- ctor/Codingteam.Ctor.fsproj | 2 +- ctor/GreenCaptchaBot.fs | 2 +- ctor/GreenCaptchaBot.template.json | 2 +- ctor/Program.fs | 2 +- ctor/kubernetes/deploy.ps1 | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln index e1a92c3..144a8b0 100644 --- a/Codingteam.Devops.sln +++ b/Codingteam.Devops.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj index 58c3f3a..295945d 100644 --- a/ctor/Codingteam.Ctor.fsproj +++ b/ctor/Codingteam.Ctor.fsproj @@ -1,4 +1,4 @@ - + Exe diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs index a706483..f04743a 100644 --- a/ctor/GreenCaptchaBot.fs +++ b/ctor/GreenCaptchaBot.fs @@ -1,4 +1,4 @@ -module internal Codingteam.Ctor.GreenCaptchaBot +module internal Codingteam.Ctor.GreenCaptchaBot open Fabricator.Core open Fabricator.Resources.Files diff --git a/ctor/GreenCaptchaBot.template.json b/ctor/GreenCaptchaBot.template.json index b42143b..49b9e6b 100644 --- a/ctor/GreenCaptchaBot.template.json +++ b/ctor/GreenCaptchaBot.template.json @@ -1,4 +1,4 @@ -{ +{ "Configuration": { "BotToken": "$BOT_TOKEN", "DeleteJoinMessages": "Unsuccessful" diff --git a/ctor/Program.fs b/ctor/Program.fs index 78dee2a..bab02b1 100644 --- a/ctor/Program.fs +++ b/ctor/Program.fs @@ -1,4 +1,4 @@ -open Fabricator.Console +open Fabricator.Console open Fabricator.Core open Fabricator.Templates.FileTemplates diff --git a/ctor/kubernetes/deploy.ps1 b/ctor/kubernetes/deploy.ps1 index 7cf88ba..5487805 100644 --- a/ctor/kubernetes/deploy.ps1 +++ b/ctor/kubernetes/deploy.ps1 @@ -1,4 +1,4 @@ -Set-StrictMode -Version Latest +Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' kubectl apply -f $PSScriptRoot From 0d449b169cb9f1fc64f3022d48405726820c053a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 23:34:20 +0200 Subject: [PATCH 13/44] Legal: specify the licenses everywhere --- .gitmodules | 4 ++++ Codingteam.Devops.sln.DotSettings | 2 -- Codingteam.Devops.sln.license | 3 +++ ctor/Codingteam.Ctor.fsproj | 6 ++++++ ctor/GreenCaptchaBot.fs | 4 ++++ ctor/GreenCaptchaBot.template.json.license | 3 +++ ctor/Program.fs | 4 ++++ ctor/kubernetes/codingteam.org.ru.service.yaml | 4 ++++ ctor/kubernetes/codingteam.org.ru.yaml | 4 ++++ ctor/kubernetes/deploy.ps1 | 4 ++++ xmpp2/users.yml | 4 ++++ xmpp2/vars/vars.example.yml | 4 ++++ 12 files changed, 44 insertions(+), 2 deletions(-) delete mode 100644 Codingteam.Devops.sln.DotSettings create mode 100644 Codingteam.Devops.sln.license create mode 100644 ctor/GreenCaptchaBot.template.json.license diff --git a/.gitmodules b/.gitmodules index 83afccf..cc72787 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + [submodule "Fabricator"] path = Fabricator url = git@github.com:ForNeVeR/Fabricator.git diff --git a/Codingteam.Devops.sln.DotSettings b/Codingteam.Devops.sln.DotSettings deleted file mode 100644 index 2f3a410..0000000 --- a/Codingteam.Devops.sln.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - True \ No newline at end of file diff --git a/Codingteam.Devops.sln.license b/Codingteam.Devops.sln.license new file mode 100644 index 0000000..fcafafa --- /dev/null +++ b/Codingteam.Devops.sln.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023-2025 Friedrich von Never + +SPDX-License-Identifier: MIT diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj index 295945d..0ad0387 100644 --- a/ctor/Codingteam.Ctor.fsproj +++ b/ctor/Codingteam.Ctor.fsproj @@ -1,3 +1,9 @@ + + diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs index f04743a..86a8d6f 100644 --- a/ctor/GreenCaptchaBot.fs +++ b/ctor/GreenCaptchaBot.fs @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +// +// SPDX-License-Identifier: MIT + module internal Codingteam.Ctor.GreenCaptchaBot open Fabricator.Core diff --git a/ctor/GreenCaptchaBot.template.json.license b/ctor/GreenCaptchaBot.template.json.license new file mode 100644 index 0000000..fcafafa --- /dev/null +++ b/ctor/GreenCaptchaBot.template.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023-2025 Friedrich von Never + +SPDX-License-Identifier: MIT diff --git a/ctor/Program.fs b/ctor/Program.fs index bab02b1..405da44 100644 --- a/ctor/Program.fs +++ b/ctor/Program.fs @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +// +// SPDX-License-Identifier: MIT + open Fabricator.Console open Fabricator.Core open Fabricator.Templates.FileTemplates diff --git a/ctor/kubernetes/codingteam.org.ru.service.yaml b/ctor/kubernetes/codingteam.org.ru.service.yaml index 7ebb028..d650e26 100644 --- a/ctor/kubernetes/codingteam.org.ru.service.yaml +++ b/ctor/kubernetes/codingteam.org.ru.service.yaml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + apiVersion: v1 kind: Service metadata: diff --git a/ctor/kubernetes/codingteam.org.ru.yaml b/ctor/kubernetes/codingteam.org.ru.yaml index 3ebe423..e0c2528 100644 --- a/ctor/kubernetes/codingteam.org.ru.yaml +++ b/ctor/kubernetes/codingteam.org.ru.yaml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + apiVersion: apps/v1 kind: Deployment metadata: diff --git a/ctor/kubernetes/deploy.ps1 b/ctor/kubernetes/deploy.ps1 index 5487805..848dc8f 100644 --- a/ctor/kubernetes/deploy.ps1 +++ b/ctor/kubernetes/deploy.ps1 @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' diff --git a/xmpp2/users.yml b/xmpp2/users.yml index a265d24..b0b6bcf 100644 --- a/xmpp2/users.yml +++ b/xmpp2/users.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + --- - name: Set up user hosts: xmpp2 diff --git a/xmpp2/vars/vars.example.yml b/xmpp2/vars/vars.example.yml index 1847e4b..2b947c9 100644 --- a/xmpp2/vars/vars.example.yml +++ b/xmpp2/vars/vars.example.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + user: name: mario ssh_key: 'ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXX/XXX username1@hostname' From 183d19da75468b8e079a905b036dfb830d19f2cd Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 Jun 2025 23:36:40 +0200 Subject: [PATCH 14/44] (#39) Tune the Ansible lint --- ansible-lint.yml | 1 + xmpp2/users.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ansible-lint.yml b/ansible-lint.yml index 87c7275..41f463a 100644 --- a/ansible-lint.yml +++ b/ansible-lint.yml @@ -4,4 +4,5 @@ exclude_paths: - .github/ # no Ansible plays in there + - ctor/kubernetes/ # TODO: Drop this before merge - xmpp2/default.yml # just a list of other files diff --git a/xmpp2/users.yml b/xmpp2/users.yml index b0b6bcf..24c6e7a 100644 --- a/xmpp2/users.yml +++ b/xmpp2/users.yml @@ -25,7 +25,7 @@ ansible.builtin.user: name: '{{ user.name }}' shell: /bin/sh - groups: [ 'sudo', 'sshuser' ] + groups: ['sudo', 'sshuser'] append: true home: '/home/{{ user.name }}' password_lock: true From e3a9542de9fd0f1bd056f9170c126d64575a0c91 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 11 Jun 2025 00:23:51 +0200 Subject: [PATCH 15/44] (#39) xmpp2: improve the auth instruction, start implementing nginx --- xmpp2/.gitignore | 1 + xmpp2/README.md | 10 +++++++--- xmpp2/ansible-vault.ps1 | 5 +++++ xmpp2/{users.yml => auth.yml} | 8 +++++--- xmpp2/default.yml | 3 ++- xmpp2/nginx.yml | 20 ++++++++++++++++++++ xmpp2/vars/secrets.example.yml | 6 ++++++ xmpp2/vars/vars.example.yml | 2 +- 8 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 xmpp2/ansible-vault.ps1 rename xmpp2/{users.yml => auth.yml} (84%) create mode 100644 xmpp2/nginx.yml create mode 100644 xmpp2/vars/secrets.example.yml diff --git a/xmpp2/.gitignore b/xmpp2/.gitignore index 861afe3..fb781b9 100644 --- a/xmpp2/.gitignore +++ b/xmpp2/.gitignore @@ -4,4 +4,5 @@ hosts.ini +vars/secrets.yml vars/vars.yml diff --git a/xmpp2/README.md b/xmpp2/README.md index 7ffbd1a..ae3e371 100644 --- a/xmpp2/README.md +++ b/xmpp2/README.md @@ -13,8 +13,12 @@ How to Deploy ------------- 1. Copy `hosts.example.ini` to `hosts.ini`, fix the host connection details if needed. 2. Copy `vars/vars.example.yml` to `vars/vars.yml` and adjust it accordingly. -3. To **check the results** without applying, run `ansible-playbook --check --diff default.yml`. +3. Copy `vars/secrets.example.yml` to `vars/secrets.yml` and adjust it accordingly. +4. `ansible-vault encrypt vars/secrets.yml` +5. To **check the results** without applying, run `ansible-playbook --ask-vault-pass --ask-become-pass --check --diff default.yml`. - To **deploy**, run `ansible-playbook default.yml`. + To **deploy**, run `ansible-playbook --ask-vault-pass --ask-become-pass default.yml`. -If on Windows, feel free to use scripts `ansible-playbook.ps1` as a substitute to use Ansible from WSL. +If on Windows, feel free to use scripts `ansible-vault.ps1`, `ansible-playbook.ps1` as a substitute to use Ansible from WSL. + +If running deployment for the first time, then run `ansible-playbook --ask-vault-pass auth.yml` to set up the user accounts and access properly. diff --git a/xmpp2/ansible-vault.ps1 b/xmpp2/ansible-vault.ps1 new file mode 100644 index 0000000..f818024 --- /dev/null +++ b/xmpp2/ansible-vault.ps1 @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +wsl --distribution Ubuntu ansible-vault @args diff --git a/xmpp2/users.yml b/xmpp2/auth.yml similarity index 84% rename from xmpp2/users.yml rename to xmpp2/auth.yml index 24c6e7a..492639e 100644 --- a/xmpp2/users.yml +++ b/xmpp2/auth.yml @@ -3,11 +3,12 @@ # SPDX-License-Identifier: MIT --- -- name: Set up user +- name: Set up the users and authentication hosts: xmpp2 become: true vars_files: + - secrets.yml - vars.yml handlers: @@ -28,12 +29,13 @@ groups: ['sudo', 'sshuser'] append: true home: '/home/{{ user.name }}' - password_lock: true + password_lock: false + password: '{{ user_secrets.password_hash }}' - name: Ensure the user can use SSH ansible.posix.authorized_key: user: '{{ user.name }}' - key: '{{ user.ssh_key }}' + key: '{{ user.ssh_public_key }}' - name: Ensure only members of sshuser group can connect via SSH ansible.builtin.lineinfile: diff --git a/xmpp2/default.yml b/xmpp2/default.yml index 452bfef..2e55066 100644 --- a/xmpp2/default.yml +++ b/xmpp2/default.yml @@ -2,4 +2,5 @@ # # SPDX-License-Identifier: MIT -- import_playbook: users.yml +- import_playbook: auth.yml +- import_playbook: nginx.yml diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml new file mode 100644 index 0000000..a022b73 --- /dev/null +++ b/xmpp2/nginx.yml @@ -0,0 +1,20 @@ +--- +- name: Install and configure Nginx + hosts: xmpp2 + become: true + tasks: + - name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 3600 + + - name: Install nginx package + apt: + name: nginx + state: present + + - name: Start and enable nginx service + service: + name: nginx + state: started + enabled: yes diff --git a/xmpp2/vars/secrets.example.yml b/xmpp2/vars/secrets.example.yml new file mode 100644 index 0000000..b9b6b6b --- /dev/null +++ b/xmpp2/vars/secrets.example.yml @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +user_secrets: + password_hash: '' # Use `mkpasswd --method=sha-512` to generate. diff --git a/xmpp2/vars/vars.example.yml b/xmpp2/vars/vars.example.yml index 2b947c9..111a554 100644 --- a/xmpp2/vars/vars.example.yml +++ b/xmpp2/vars/vars.example.yml @@ -4,4 +4,4 @@ user: name: mario - ssh_key: 'ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXX/XXX username1@hostname' + ssh_public_key: 'ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXX/XXX username1@hostname' From d6338591bb1e3e38838a2aa344afdd49c79e25a1 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 11 Jun 2025 00:24:47 +0200 Subject: [PATCH 16/44] (#39) Legal: specify the license for a new file --- xmpp2/nginx.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index a022b73..bef9e18 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + --- - name: Install and configure Nginx hosts: xmpp2 From e365f05f11ff515b89607c40f62390a7d43d9490 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Wed, 11 Jun 2025 00:25:48 +0200 Subject: [PATCH 17/44] (#39) nginx: fix lint issues --- xmpp2/nginx.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index bef9e18..803ede4 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -8,17 +8,17 @@ become: true tasks: - name: Update apt cache - apt: - update_cache: yes + ansible.builtin.apt: + update_cache: true cache_valid_time: 3600 - name: Install nginx package - apt: + ansible.builtin.apt: name: nginx state: present - name: Start and enable nginx service - service: + ansible.builtin.service: name: nginx state: started - enabled: yes + enabled: true From 2df39967d7f23a258a22f8adc67354f6efc1b280 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Thu, 12 Jun 2025 23:36:52 +0200 Subject: [PATCH 18/44] (#39) xmpp2: let the default shell be Bash --- xmpp2/auth.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmpp2/auth.yml b/xmpp2/auth.yml index 492639e..157f2bf 100644 --- a/xmpp2/auth.yml +++ b/xmpp2/auth.yml @@ -25,7 +25,7 @@ - name: Ensure a user exists and can SSH into the machine ansible.builtin.user: name: '{{ user.name }}' - shell: /bin/sh + shell: /bin/bash groups: ['sudo', 'sshuser'] append: true home: '/home/{{ user.name }}' From 240cd10e68b662fe2d1802d5c8c6ec2fff61a4ac Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Thu, 12 Jun 2025 23:47:59 +0200 Subject: [PATCH 19/44] (#39) xmpp2: set up Nginx --- xmpp2/files/nginx/nginx.conf | 30 ++++++++++++++++++++++++++++++ xmpp2/nginx.yml | 27 ++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 xmpp2/files/nginx/nginx.conf diff --git a/xmpp2/files/nginx/nginx.conf b/xmpp2/files/nginx/nginx.conf new file mode 100644 index 0000000..f9b0c9f --- /dev/null +++ b/xmpp2/files/nginx/nginx.conf @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2016-2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +user www-data; +worker_processes auto; +pid /run/nginx.pid; +error_log /var/log/nginx/error.log; + +events { + worker_connections 768; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 60; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index 803ede4..4396f80 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -6,6 +6,13 @@ - name: Install and configure Nginx hosts: xmpp2 become: true + + handlers: + - name: Reload nginx + ansible.builtin.service: + name: nginx + state: reloaded + tasks: - name: Update apt cache ansible.builtin.apt: @@ -17,8 +24,18 @@ name: nginx state: present - - name: Start and enable nginx service - ansible.builtin.service: - name: nginx - state: started - enabled: true + - name: Remove the *-enabled and *-available directories + ansible.builtin.file: + path: "/etc/nginx/{{ item }}" + state: absent + loop: + - modules-available + - modules-enabled + - sites-available + - sites-enabled + + - name: Set up the main nginx configuration file + ansible.builtin.copy: + src: nginx/nginx.conf + dest: /etc/nginx/nginx.conf + notify: Reload nginx From 946cd03bf6adda110f6aa43472c9f0aec593be8c Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:00:25 +0200 Subject: [PATCH 20/44] (#39) xmpp2: set up codingteam.org.ru --- Folder.DotSettings | 2 + xmpp2/codingteam.org.ru.yml | 43 +++++++++++++++++++ xmpp2/default.yml | 1 + .../files/nginx/conf.d/codingteam.org.ru.conf | 40 +++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 Folder.DotSettings create mode 100644 xmpp2/codingteam.org.ru.yml create mode 100644 xmpp2/files/nginx/conf.d/codingteam.org.ru.conf diff --git a/Folder.DotSettings b/Folder.DotSettings new file mode 100644 index 0000000..1f22513 --- /dev/null +++ b/Folder.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/xmpp2/codingteam.org.ru.yml b/xmpp2/codingteam.org.ru.yml new file mode 100644 index 0000000..2921483 --- /dev/null +++ b/xmpp2/codingteam.org.ru.yml @@ -0,0 +1,43 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +--- +- name: Main site for codingteam.org.ru + hosts: xmpp2 + vars: + codingteam_org_ru_version: v1.2.1 + + handlers: + - name: Prune Docker + community.docker.docker_prune: + containers: true + images: true + images_filters: + dangling: false + networks: true + volumes: true + builder_cache: true + + - name: Reload nginx + ansible.builtin.service: + name: nginx + state: reloaded + + tasks: + - name: Set up the Docker container + community.docker.docker_container: + name: codingteam.org.ru + image_name_mismatch: recreate + image: codingteam/codingteam.org.ru:{{ codingteam_org_ru_version }} + published_ports: + - 80:5000 + restart_policy: unless-stopped + default_host_ip: '' + notify: Prune Docker + + - name: Set up the nginx configuration file + ansible.builtin.copy: + src: nginx/conf.d/codingteam.org.ru.conf + dest: /etc/nginx/conf.d/codingteam.org.ru.conf + notify: Reload nginx diff --git a/xmpp2/default.yml b/xmpp2/default.yml index 2e55066..69af22a 100644 --- a/xmpp2/default.yml +++ b/xmpp2/default.yml @@ -4,3 +4,4 @@ - import_playbook: auth.yml - import_playbook: nginx.yml +- import_playbook: codingteam.org.ru.yml diff --git a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf new file mode 100644 index 0000000..3f37b6a --- /dev/null +++ b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf @@ -0,0 +1,40 @@ +# SPDX-FileCopyrightText: 2016-2025 codingteam/devops contributors +# +# SPDX-License-Identifier: MIT + +server { + listen 443 ssl http2; + server_name codingteam.org.ru; + + # TODO: old logs + #location /_logs/ { + # proxy_set_header X-Forwarded-Host $host; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # proxy_set_header X-Forwarded-Proto $scheme; + # proxy_http_version 1.1; + # proxy_pass https://chatlogs.jabber.ru/; + #} + + location /old-logs/ { + alias /opt/codingteam/old-logs/; + index index.html; + } + + location / { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host codingteam.org.ru; + proxy_http_version 1.1; + proxy_pass http://localhost:5000/; + } +} + +server { + listen 80; + server_name codingteam.org.ru; + + location / { + rewrite ^(.*)$ https://codingteam.org.ru$1 permanent; + } +} From b5743a16b897fb4fda22d3b426b0ddaaa58fb62f Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:06:59 +0200 Subject: [PATCH 21/44] (#39) xmpp2: install Docker --- Folder.DotSettings | 4 +++- xmpp2/default.yml | 1 + xmpp2/docker.yml | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 xmpp2/docker.yml diff --git a/Folder.DotSettings b/Folder.DotSettings index 1f22513..5e5bbbc 100644 --- a/Folder.DotSettings +++ b/Folder.DotSettings @@ -1,2 +1,4 @@  - True \ No newline at end of file + True + True + True \ No newline at end of file diff --git a/xmpp2/default.yml b/xmpp2/default.yml index 69af22a..ab85d32 100644 --- a/xmpp2/default.yml +++ b/xmpp2/default.yml @@ -4,4 +4,5 @@ - import_playbook: auth.yml - import_playbook: nginx.yml +- import_playbook: docker.yml - import_playbook: codingteam.org.ru.yml diff --git a/xmpp2/docker.yml b/xmpp2/docker.yml new file mode 100644 index 0000000..5bacbc1 --- /dev/null +++ b/xmpp2/docker.yml @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +--- +- name: Install Docker + hosts: xmpp2 + become: true + + tasks: + - name: Update apt cache + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + + - name: Install the Docker package + ansible.builtin.apt: + name: docker.io + state: present From f52b106bd227da0f84a816d036259f9186d43e38 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:12:56 +0200 Subject: [PATCH 22/44] (#39) codingteam.org.ru: drop the old log location proxy --- xmpp2/files/nginx/conf.d/codingteam.org.ru.conf | 9 --------- 1 file changed, 9 deletions(-) diff --git a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf index 3f37b6a..901c5a0 100644 --- a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf +++ b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf @@ -6,15 +6,6 @@ server { listen 443 ssl http2; server_name codingteam.org.ru; - # TODO: old logs - #location /_logs/ { - # proxy_set_header X-Forwarded-Host $host; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_http_version 1.1; - # proxy_pass https://chatlogs.jabber.ru/; - #} - location /old-logs/ { alias /opt/codingteam/old-logs/; index index.html; From 30dc23dc5d25b6054d82e4ff6f828865f87dcc1b Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:13:11 +0200 Subject: [PATCH 23/44] (#39) codingteam.org.ru: enable the old log location --- xmpp2/codingteam.org.ru.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xmpp2/codingteam.org.ru.yml b/xmpp2/codingteam.org.ru.yml index 2921483..c52ec95 100644 --- a/xmpp2/codingteam.org.ru.yml +++ b/xmpp2/codingteam.org.ru.yml @@ -41,3 +41,11 @@ src: nginx/conf.d/codingteam.org.ru.conf dest: /etc/nginx/conf.d/codingteam.org.ru.conf notify: Reload nginx + + - name: Create a directory for the old logs # uploaded manually + ansible.builtin.file: + path: /opt/codingteam/old-logs + state: directory + owner: www-data + group: www-data + mode: "u=rx,go=rx" From 93c90e3c19d6da6b3c956ef3c8a776d51d42d83b Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:48:45 +0200 Subject: [PATCH 24/44] (#39) Legal: set up license for a new file --- REUSE.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 REUSE.toml diff --git a/REUSE.toml b/REUSE.toml new file mode 100644 index 0000000..7bd1cfb --- /dev/null +++ b/REUSE.toml @@ -0,0 +1,10 @@ +version = 1 +SPDX-PackageName = "devops" +SPDX-PackageSupplier = "codingteam/devops contributors " +SPDX-PackageDownloadLocation = "https://github.com/codingteam/devops" + +[[annotations]] +path = "**.DotSettings" +precedence = "aggregate" +SPDX-FileCopyrightText = "2025 Friedrich von Never " +SPDX-License-Identifier = "MIT" From c964456847e7475d1d5c55b77cda10e96e910f04 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:49:03 +0200 Subject: [PATCH 25/44] (#39) codingteam.org.ru: missing become --- xmpp2/codingteam.org.ru.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xmpp2/codingteam.org.ru.yml b/xmpp2/codingteam.org.ru.yml index c52ec95..2dd0677 100644 --- a/xmpp2/codingteam.org.ru.yml +++ b/xmpp2/codingteam.org.ru.yml @@ -5,6 +5,8 @@ --- - name: Main site for codingteam.org.ru hosts: xmpp2 + become: true + vars: codingteam_org_ru_version: v1.2.1 From 4195bb598f40e7187fd6e5070aacf229b2c2ce2f Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:49:21 +0200 Subject: [PATCH 26/44] (#39) xmpp2: docker group should enable the admin user --- xmpp2/docker.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xmpp2/docker.yml b/xmpp2/docker.yml index 5bacbc1..4942d67 100644 --- a/xmpp2/docker.yml +++ b/xmpp2/docker.yml @@ -7,6 +7,9 @@ hosts: xmpp2 become: true + vars_files: + - vars.yml + tasks: - name: Update apt cache ansible.builtin.apt: @@ -17,3 +20,9 @@ ansible.builtin.apt: name: docker.io state: present + + - name: Add the admin user to docker group + ansible.builtin.user: + name: '{{ user.name }}' + groups: docker + append: yes From f0587be14e794a9d653d348d66232d7049f81741 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:49:40 +0200 Subject: [PATCH 27/44] (#39) xmpp2: enable ansible-lint to see the package --- requirements.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.yml b/requirements.yml index 391265a..34de14d 100644 --- a/requirements.yml +++ b/requirements.yml @@ -6,3 +6,5 @@ collections: - name: ansible.posix version: 1.5.4 + - name: community.docker + version: 3.7.0 From 37f09701894c22aea00c64443479674fa0676426 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 00:53:15 +0200 Subject: [PATCH 28/44] (#39) xmpp2: ansible-lint warning cleanup --- xmpp2/codingteam.org.ru.yml | 1 + xmpp2/docker.yml | 2 +- xmpp2/nginx.yml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/xmpp2/codingteam.org.ru.yml b/xmpp2/codingteam.org.ru.yml index 2dd0677..3aad5f4 100644 --- a/xmpp2/codingteam.org.ru.yml +++ b/xmpp2/codingteam.org.ru.yml @@ -42,6 +42,7 @@ ansible.builtin.copy: src: nginx/conf.d/codingteam.org.ru.conf dest: /etc/nginx/conf.d/codingteam.org.ru.conf + mode: "u=rx,go=rx" notify: Reload nginx - name: Create a directory for the old logs # uploaded manually diff --git a/xmpp2/docker.yml b/xmpp2/docker.yml index 4942d67..a0200b1 100644 --- a/xmpp2/docker.yml +++ b/xmpp2/docker.yml @@ -25,4 +25,4 @@ ansible.builtin.user: name: '{{ user.name }}' groups: docker - append: yes + append: true diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index 4396f80..2e8eb80 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -38,4 +38,5 @@ ansible.builtin.copy: src: nginx/nginx.conf dest: /etc/nginx/nginx.conf + mode: "u=rx,go=rx" notify: Reload nginx From a4a6aa1e1847f3201d1e40d817a5ed2aad1f6248 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 01:26:32 +0200 Subject: [PATCH 29/44] (#39) codingteam.org.ru: disable SSL for the time of setup --- xmpp2/files/nginx/conf.d/codingteam.org.ru.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf index 901c5a0..25d1274 100644 --- a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf +++ b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf @@ -3,7 +3,9 @@ # SPDX-License-Identifier: MIT server { - listen 443 ssl http2; + # TODO: enable back after we set up SSL + # listen 443 ssl http2; + listen 443; server_name codingteam.org.ru; location /old-logs/ { From 80e0464ced06ecd51e46945fe89ec1f787b347ad Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 01:26:49 +0200 Subject: [PATCH 30/44] (#39) codingteam.org.ru: deal with the ports on Docker --- xmpp2/codingteam.org.ru.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xmpp2/codingteam.org.ru.yml b/xmpp2/codingteam.org.ru.yml index 3aad5f4..78e6ee0 100644 --- a/xmpp2/codingteam.org.ru.yml +++ b/xmpp2/codingteam.org.ru.yml @@ -33,9 +33,11 @@ image_name_mismatch: recreate image: codingteam/codingteam.org.ru:{{ codingteam_org_ru_version }} published_ports: - - 80:5000 + - '5000:5000' restart_policy: unless-stopped default_host_ip: '' + env: + ASPNETCORE_URLS: "http://+:5000" # otherwise, it can't be reached (listens to "localhost" only?) notify: Prune Docker - name: Set up the nginx configuration file From 25fe7107531654b619c925d75d7c007d33e82faa Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Fri, 13 Jun 2025 01:33:06 +0200 Subject: [PATCH 31/44] (#39) codingteam.org.ru: drop the Kubernetes setup We are migrating to Ansible anyway. --- .../kubernetes/codingteam.org.ru.service.yaml | 15 ------- ctor/kubernetes/codingteam.org.ru.yaml | 42 ------------------- ctor/kubernetes/deploy.ps1 | 8 ---- 3 files changed, 65 deletions(-) delete mode 100644 ctor/kubernetes/codingteam.org.ru.service.yaml delete mode 100644 ctor/kubernetes/codingteam.org.ru.yaml delete mode 100644 ctor/kubernetes/deploy.ps1 diff --git a/ctor/kubernetes/codingteam.org.ru.service.yaml b/ctor/kubernetes/codingteam.org.ru.service.yaml deleted file mode 100644 index d650e26..0000000 --- a/ctor/kubernetes/codingteam.org.ru.service.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -# -# SPDX-License-Identifier: MIT - -apiVersion: v1 -kind: Service -metadata: - name: ctor -spec: - ports: - - nodePort: 32603 - port: 80 - selector: - app: ctor - type: NodePort diff --git a/ctor/kubernetes/codingteam.org.ru.yaml b/ctor/kubernetes/codingteam.org.ru.yaml deleted file mode 100644 index e0c2528..0000000 --- a/ctor/kubernetes/codingteam.org.ru.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -# -# SPDX-License-Identifier: MIT - -apiVersion: apps/v1 -kind: Deployment -metadata: - annotations: - deployment.kubernetes.io/revision: "1" - labels: - app: ctor - name: ctor - namespace: default -spec: - progressDeadlineSeconds: 600 - replicas: 1 - revisionHistoryLimit: 10 - selector: - matchLabels: - app: ctor - strategy: - rollingUpdate: - maxSurge: 25% - maxUnavailable: 25% - type: RollingUpdate - template: - metadata: - labels: - app: ctor - spec: - containers: - - image: codingteam/codingteam.org.ru:v1.1.0 - imagePullPolicy: IfNotPresent - name: codingteam-org-ru - resources: {} - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 diff --git a/ctor/kubernetes/deploy.ps1 b/ctor/kubernetes/deploy.ps1 deleted file mode 100644 index 848dc8f..0000000 --- a/ctor/kubernetes/deploy.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -# -# SPDX-License-Identifier: MIT - -Set-StrictMode -Version Latest -$ErrorActionPreference = 'Stop' - -kubectl apply -f $PSScriptRoot From 82ac9c483534f1ac1420e0a670afa0a528136c3c Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 18:55:52 +0200 Subject: [PATCH 32/44] (#39) xmpp2: set up loglist app and database --- Folder.DotSettings | 3 + xmpp2/default.yml | 1 + xmpp2/files/loglist/app.conf | 31 +++++++++ xmpp2/files/loglist/init_db.sql | 1 + xmpp2/loglist.yml | 109 ++++++++++++++++++++++++++++++++ xmpp2/vars/secrets.example.yml | 17 +++++ 6 files changed, 162 insertions(+) create mode 100644 xmpp2/files/loglist/app.conf create mode 100644 xmpp2/files/loglist/init_db.sql create mode 100644 xmpp2/loglist.yml diff --git a/Folder.DotSettings b/Folder.DotSettings index 5e5bbbc..7e7a370 100644 --- a/Folder.DotSettings +++ b/Folder.DotSettings @@ -1,4 +1,7 @@  True True + True + True + True True \ No newline at end of file diff --git a/xmpp2/default.yml b/xmpp2/default.yml index ab85d32..fbeff8a 100644 --- a/xmpp2/default.yml +++ b/xmpp2/default.yml @@ -6,3 +6,4 @@ - import_playbook: nginx.yml - import_playbook: docker.yml - import_playbook: codingteam.org.ru.yml +- import_playbook: loglist.yml diff --git a/xmpp2/files/loglist/app.conf b/xmpp2/files/loglist/app.conf new file mode 100644 index 0000000..b8d5dd9 --- /dev/null +++ b/xmpp2/files/loglist/app.conf @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +play.http.secret.key = ${HTTP_SECRET_KEY} +play.i18n.langs = ["en"] + +feed.limit = 30 + +db.default.driver = org.postgresql.Driver +db.default.url = ${DATABASE_URL} + +play.evolutions.autocommit = false +play.evolutions.db.default.autoApply = ${APPLY_EVOLUTIONS_SILENTLY} + +recaptcha.publickey = ${RECAPTCHA_PUBLIC_KEY} +recaptcha.privatekey = ${RECAPTCHA_PRIVATE_KEY} + +basicAuth.username = ${BASIC_AUTH_USERNAME} +basicAuth.password = ${BASIC_AUTH_PASSWORD} + +approval.smtpHost = ${APPROVAL_SMTP_HOST} +approval.email = ${APPROVAL_EMAIL} +approval.emailPassword = ${APPROVAL_EMAIL_PASSWORD} + +play.modules.enabled += "scalikejdbc.PlayModule" + +play.filters.enabled += play.filters.hosts.AllowedHostsFilter +play.filters.hosts { + allowed = ["loglist.xyz"] +} diff --git a/xmpp2/files/loglist/init_db.sql b/xmpp2/files/loglist/init_db.sql new file mode 100644 index 0000000..328a8c9 --- /dev/null +++ b/xmpp2/files/loglist/init_db.sql @@ -0,0 +1 @@ +CREATE EXTENSION pgcrypto; diff --git a/xmpp2/loglist.yml b/xmpp2/loglist.yml new file mode 100644 index 0000000..64d6c58 --- /dev/null +++ b/xmpp2/loglist.yml @@ -0,0 +1,109 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +--- +- name: Application service for loglist.xyz + hosts: xmpp2 + become: true + + vars: + # Container versions: + postgresql_version: 9.3 + loglist_version: 2.0.1 + + # Paths on host: + host_db_init_scripts_dir: /opt/codingteam/loglist/init_db_scripts + host_data_dir: /opt/codingteam/loglist/data + host_config_dir: /opt/codingteam/loglist/config + + # Paths in containers: + container_data_dir: /data + + vars_files: + - secrets.yml + + handlers: + - name: Prune Docker + community.docker.docker_prune: + containers: true + images: true + images_filters: + dangling: false + networks: true + volumes: true + builder_cache: true + + tasks: + - name: Create directories + ansible.builtin.file: + path: '{{ item }}' + state: directory + mode: 'u=rwx,g,o=rx' + loop: + - '{{ host_db_init_scripts_dir }}' + - '{{ host_data_dir }}' + - '{{ host_config_dir }}' + + - name: Create the Docker network + community.docker.docker_network: + name: loglist + + - name: Copy the database initialization script + ansible.builtin.copy: + src: loglist/init_db.sql + dest: '{{ host_db_init_scripts_dir }}/init_db.sql' + mode: 'u,g,o=rx' + + - name: Set up the database container + community.docker.docker_container: + name: loglist.postgresql + image_name_mismatch: recreate + image: postgres:{{ postgresql_version }} + published_ports: + - '5423' + env: + POSTGRES_DB: loglist + POSTGRES_USER: loglist + POSTGRES_PASSWORD: '{{ loglist_secrets.db_password }}' + PGDATA: '{{ container_data_dir }}' + volumes: + - '{{ host_db_init_scripts_dir }}/:/docker-entrypoint-initdb.d/' + - '{{ host_data_dir }}/:/{{ container_data_dir }}/' + networks: + - name: loglist + default_host_ip: '' + notify: Prune Docker + + - name: Copy the application configuration file + ansible.builtin.copy: + src: loglist/app.conf + dest: '{{ host_config_dir }}/app.conf' + mode: 'u,g,o=r' + + - name: Set up the application container + community.docker.docker_container: + name: loglist.app + image_name_mismatch: recreate + image: codingteam/loglist:{{ loglist_version }} + published_ports: + - '9000:9000' + env: + APPLY_EVOLUTIONS_SILENTLY: 'true' + APPROVAL_EMAIL: '{{ loglist_secrets.approval_email.name }}' + APPROVAL_EMAIL_PASSWORD: '{{ loglist_secrets.approval_email.password }}' + APPROVAL_SMTP_HOST: '{{ loglist_secrets.approval_email.smtp_host }}' + BASIC_AUTH_PASSWORD: '{{ loglist_secrets.basic_auth.password }}' + BASIC_AUTH_USERNAME: '{{ loglist_secrets.basic_auth.username }}' + DATABASE_URL: 'jdbc:postgresql://loglist.postgresql/loglist?user=loglist&password={{ loglist_secrets.db_password }}' + JAVA_OPTS: '-Xmx200m -Xss512k -XX:+UseCompressedOops' + RECAPTCHA_PRIVATE_KEY: '{{ loglist_secrets.recaptcha.private_key }}' + RECAPTCHA_PUBLIC_KEY: '{{ loglist_secrets.recaptcha.public_key }}' + HTTP_SECRET_KEY: '{{ loglist_secrets.http_secret_key }}' + volumes: + - '{{ host_db_init_scripts_dir }}/:/docker-entrypoint-initdb.d/' + - '{{ host_data_dir }}/:/{{ container_data_dir }}/' + networks: + - name: loglist + default_host_ip: '' + notify: Prune Docker diff --git a/xmpp2/vars/secrets.example.yml b/xmpp2/vars/secrets.example.yml index b9b6b6b..6310a41 100644 --- a/xmpp2/vars/secrets.example.yml +++ b/xmpp2/vars/secrets.example.yml @@ -4,3 +4,20 @@ user_secrets: password_hash: '' # Use `mkpasswd --method=sha-512` to generate. + +loglist_secrets: + db_password: '' + http_secret_key: '' + + approval_email: + name: '' + password: '' + smtp_host: '' + + basic_auth: + username: '' + password: '' + + recaptcha: + private_key: '' + public_key: '' From 94cd686635716c2e83c58fe667b5957470e81a1a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 19:11:57 +0200 Subject: [PATCH 33/44] (#39) loglist: add nginx configuration --- xmpp2/files/nginx/conf.d/loglist.conf | 47 +++++++++++++++++++++++++++ xmpp2/loglist.yml | 12 +++++++ 2 files changed, 59 insertions(+) create mode 100644 xmpp2/files/nginx/conf.d/loglist.conf diff --git a/xmpp2/files/nginx/conf.d/loglist.conf b/xmpp2/files/nginx/conf.d/loglist.conf new file mode 100644 index 0000000..a7eef03 --- /dev/null +++ b/xmpp2/files/nginx/conf.d/loglist.conf @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: 2016-2025 codingteam/devops contributors +# +# SPDX-License-Identifier: MIT + +server { + # TODO: enable back after we set up SSL + # listen 443 ssl http2; + server_name loglist.xyz; + # TODO: include /etc/nginx/ssl.conf; + + location / { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host loglist.xyz; + proxy_http_version 1.1; + proxy_pass http://localhost:9000/; + } +} + +server { + # TODO: enable back after we set up SSL + # listen 443 ssl http2; + server_name *.loglist.xyz; + # TODO: include /etc/nginx/ssl.conf; + + location / { + return 301 https://loglist.xyz$request_uri; + } +} + +server { + listen 80; + server_name loglist.xyz; + + location / { + rewrite ^(.*)$ https://loglist.xyz$1 permanent; + } +} + +server { + listen 80; + server_name *.loglist.xyz; + location / { + return 301 https://loglist.xyz$request_uri; + } +} diff --git a/xmpp2/loglist.yml b/xmpp2/loglist.yml index 64d6c58..2d4e914 100644 --- a/xmpp2/loglist.yml +++ b/xmpp2/loglist.yml @@ -34,6 +34,11 @@ volumes: true builder_cache: true + - name: Reload nginx + ansible.builtin.service: + name: nginx + state: reloaded + tasks: - name: Create directories ansible.builtin.file: @@ -107,3 +112,10 @@ - name: loglist default_host_ip: '' notify: Prune Docker + + - name: Set up the nginx configuration file + ansible.builtin.copy: + src: nginx/conf.d/loglist.conf + dest: /etc/nginx/conf.d/loglist.conf + mode: "u=rx,go=rx" + notify: Reload nginx From 35005939446a9c8f90965ade6b7a94267a90488b Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 19:19:44 +0200 Subject: [PATCH 34/44] (#39) loglist: apply the configuration --- xmpp2/files/loglist/{app.conf => application.conf} | 0 xmpp2/loglist.yml | 5 +++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename xmpp2/files/loglist/{app.conf => application.conf} (100%) diff --git a/xmpp2/files/loglist/app.conf b/xmpp2/files/loglist/application.conf similarity index 100% rename from xmpp2/files/loglist/app.conf rename to xmpp2/files/loglist/application.conf diff --git a/xmpp2/loglist.yml b/xmpp2/loglist.yml index 2d4e914..e5fd227 100644 --- a/xmpp2/loglist.yml +++ b/xmpp2/loglist.yml @@ -82,8 +82,8 @@ - name: Copy the application configuration file ansible.builtin.copy: - src: loglist/app.conf - dest: '{{ host_config_dir }}/app.conf' + src: loglist/application.conf + dest: '{{ host_config_dir }}/application.conf' mode: 'u,g,o=r' - name: Set up the application container @@ -108,6 +108,7 @@ volumes: - '{{ host_db_init_scripts_dir }}/:/docker-entrypoint-initdb.d/' - '{{ host_data_dir }}/:/{{ container_data_dir }}/' + - '{{ host_config_dir }}/application.conf:/app/conf/application.conf' networks: - name: loglist default_host_ip: '' From 5c713b24f448f24ef56cfa49a06edbbf4285043e Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 20:04:34 +0200 Subject: [PATCH 35/44] (#39) xmpp2: standard operating procedures --- xmpp2/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xmpp2/README.md b/xmpp2/README.md index ae3e371..49022f3 100644 --- a/xmpp2/README.md +++ b/xmpp2/README.md @@ -22,3 +22,17 @@ How to Deploy If on Windows, feel free to use scripts `ansible-vault.ps1`, `ansible-playbook.ps1` as a substitute to use Ansible from WSL. If running deployment for the first time, then run `ansible-playbook --ask-vault-pass auth.yml` to set up the user accounts and access properly. + +Standard Operating Procedures +----------------------------- + +### Dump Database Backup for LogList +```console +$ docker exec -i loglist.postgresql pg_dump -d loglist -U postgres -F custom --no-acl > loglist.dmp +``` + +### Restore Database Backup for LogList +```console +$ docker cp loglist.dmp loglist.postgresql:/loglist.dmp +$ docker exec -i loglist.postgresql pg_restore -d loglist -U loglist --clean -1 /loglist.dmp +``` From 4837c0b11dcfd109fa2954dcf4459f98873c0b5b Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 22:57:54 +0200 Subject: [PATCH 36/44] (#39) xmpp2: preliminary certbot setup --- Folder.DotSettings | 1 + xmpp2/certbot.yml | 23 +++++++++++++++++++ xmpp2/default.yml | 1 + .../files/nginx/conf.d/codingteam.org.ru.conf | 5 ++-- xmpp2/files/nginx/conf.d/loglist.conf | 10 ++++---- xmpp2/files/nginx/ssl.conf | 9 ++++++++ xmpp2/nginx.yml | 9 +++++--- 7 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 xmpp2/certbot.yml create mode 100644 xmpp2/files/nginx/ssl.conf diff --git a/Folder.DotSettings b/Folder.DotSettings index 7e7a370..385f3df 100644 --- a/Folder.DotSettings +++ b/Folder.DotSettings @@ -1,4 +1,5 @@  + True True True True diff --git a/xmpp2/certbot.yml b/xmpp2/certbot.yml new file mode 100644 index 0000000..cc3815e --- /dev/null +++ b/xmpp2/certbot.yml @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2025 Friedrich von Never +# +# SPDX-License-Identifier: MIT + +--- +- name: Configure Certbot for certificate renewal + hosts: xmpp2 + become: true + + tasks: + - name: Install certbot + community.general.snap: + name: certbot + classic: true + + # One-time setup should be performed manually, see the documentation: + # https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=standard + # + # sudo certbot certonly --nginx -d codingteam.org.ru -d loglist.xyz -d www.loglist.xyz + # + # Verify the changes to the web server configuration files performed by this command. + # + # Further updates are done by snap.certbot.renew.timer — see `systemctl list-timers` for details. diff --git a/xmpp2/default.yml b/xmpp2/default.yml index fbeff8a..69564ed 100644 --- a/xmpp2/default.yml +++ b/xmpp2/default.yml @@ -7,3 +7,4 @@ - import_playbook: docker.yml - import_playbook: codingteam.org.ru.yml - import_playbook: loglist.yml +- import_playbook: certbot.yml diff --git a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf index 25d1274..b6e5af8 100644 --- a/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf +++ b/xmpp2/files/nginx/conf.d/codingteam.org.ru.conf @@ -3,10 +3,9 @@ # SPDX-License-Identifier: MIT server { - # TODO: enable back after we set up SSL - # listen 443 ssl http2; - listen 443; + listen 443 ssl http2; server_name codingteam.org.ru; + include /etc/nginx/ssl.conf; location /old-logs/ { alias /opt/codingteam/old-logs/; diff --git a/xmpp2/files/nginx/conf.d/loglist.conf b/xmpp2/files/nginx/conf.d/loglist.conf index a7eef03..5440a9d 100644 --- a/xmpp2/files/nginx/conf.d/loglist.conf +++ b/xmpp2/files/nginx/conf.d/loglist.conf @@ -3,10 +3,9 @@ # SPDX-License-Identifier: MIT server { - # TODO: enable back after we set up SSL - # listen 443 ssl http2; + listen 443 ssl http2; server_name loglist.xyz; - # TODO: include /etc/nginx/ssl.conf; + include /etc/nginx/ssl.conf; location / { proxy_set_header X-Forwarded-Host $host; @@ -19,10 +18,9 @@ server { } server { - # TODO: enable back after we set up SSL - # listen 443 ssl http2; + listen 443 ssl http2; server_name *.loglist.xyz; - # TODO: include /etc/nginx/ssl.conf; + include /etc/nginx/ssl.conf; location / { return 301 https://loglist.xyz$request_uri; diff --git a/xmpp2/files/nginx/ssl.conf b/xmpp2/files/nginx/ssl.conf new file mode 100644 index 0000000..3e72804 --- /dev/null +++ b/xmpp2/files/nginx/ssl.conf @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2017-2025 codingteam/devops contributors +# +# SPDX-License-Identifier: MIT + +ssl_certificate /etc/letsencrypt/live/codingteam.org.ru-0001/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/codingteam.org.ru-0001/privkey.pem; +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_ciphers "HIGH:!aNULL:!MD5:!kEDH"; +add_header Strict-Transport-Security 'max-age=15552000'; diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index 2e8eb80..0c5784c 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -26,7 +26,7 @@ - name: Remove the *-enabled and *-available directories ansible.builtin.file: - path: "/etc/nginx/{{ item }}" + path: '/etc/nginx/{{ item }}' state: absent loop: - modules-available @@ -36,7 +36,10 @@ - name: Set up the main nginx configuration file ansible.builtin.copy: - src: nginx/nginx.conf - dest: /etc/nginx/nginx.conf + src: 'nginx/{{ item }}' + dest: '/etc/nginx/{{ item }}' mode: "u=rx,go=rx" + loop: + - nginx.conf + - ssl.conf notify: Reload nginx From cfbe485be5861e9c05c97c885162bc11a01fbb3a Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:31:09 +0200 Subject: [PATCH 37/44] Legal: specify the license for the DB initialization script --- xmpp2/files/loglist/init_db.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xmpp2/files/loglist/init_db.sql b/xmpp2/files/loglist/init_db.sql index 328a8c9..24c1713 100644 --- a/xmpp2/files/loglist/init_db.sql +++ b/xmpp2/files/loglist/init_db.sql @@ -1 +1,5 @@ +-- SPDX-FileCopyrightText: 2025 Friedrich von Never +-- +-- SPDX-License-Identifier: MIT + CREATE EXTENSION pgcrypto; From 42784e7c3a2f0c996ebaf87d1e41dfc28f8995ea Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:31:53 +0200 Subject: [PATCH 38/44] (#39) Docs: improve the maintenance instructions --- xmpp2/README.md | 3 ++- xmpp2/certbot.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xmpp2/README.md b/xmpp2/README.md index 49022f3..5fcef69 100644 --- a/xmpp2/README.md +++ b/xmpp2/README.md @@ -34,5 +34,6 @@ $ docker exec -i loglist.postgresql pg_dump -d loglist -U postgres -F custom --n ### Restore Database Backup for LogList ```console $ docker cp loglist.dmp loglist.postgresql:/loglist.dmp -$ docker exec -i loglist.postgresql pg_restore -d loglist -U loglist --clean -1 /loglist.dmp +$ docker exec -i loglist.postgresql pg_restore -d loglist -U loglist --clean --no-owner -1 /loglist.dmp +$ docker exec -i loglist.postgresql rm /loglist.dmp ``` diff --git a/xmpp2/certbot.yml b/xmpp2/certbot.yml index cc3815e..d89ee39 100644 --- a/xmpp2/certbot.yml +++ b/xmpp2/certbot.yml @@ -16,7 +16,7 @@ # One-time setup should be performed manually, see the documentation: # https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=standard # - # sudo certbot certonly --nginx -d codingteam.org.ru -d loglist.xyz -d www.loglist.xyz + # sudo certbot --nginx -d codingteam.org.ru -d loglist.xyz -d www.loglist.xyz # # Verify the changes to the web server configuration files performed by this command. # From 06d5aab923b008ab0bceb1eba6acd4b06af61f11 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:34:04 +0200 Subject: [PATCH 39/44] (#39) ansible-lint: add community.general --- requirements.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.yml b/requirements.yml index 34de14d..5b744d9 100644 --- a/requirements.yml +++ b/requirements.yml @@ -8,3 +8,5 @@ collections: version: 1.5.4 - name: community.docker version: 3.7.0 + - name: community.general + version: 8.3.0 From 9e4c848cceda60d5243a24393d3ddca3aea21778 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:41:25 +0200 Subject: [PATCH 40/44] (#39) xmpp2: better update for apt --- xmpp2/docker.yml | 6 +----- xmpp2/nginx.yml | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/xmpp2/docker.yml b/xmpp2/docker.yml index a0200b1..2eb9f84 100644 --- a/xmpp2/docker.yml +++ b/xmpp2/docker.yml @@ -11,13 +11,9 @@ - vars.yml tasks: - - name: Update apt cache - ansible.builtin.apt: - update_cache: true - cache_valid_time: 3600 - - name: Install the Docker package ansible.builtin.apt: + cache_valid_time: 86400 name: docker.io state: present diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index 0c5784c..dc6b0a8 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -14,13 +14,9 @@ state: reloaded tasks: - - name: Update apt cache - ansible.builtin.apt: - update_cache: true - cache_valid_time: 3600 - - name: Install nginx package ansible.builtin.apt: + cache_valid_time: 86400 name: nginx state: present From 558f6a5dc63f35c4244a1e6b10c03ef71c9509f3 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:50:36 +0200 Subject: [PATCH 41/44] (#39) xmpp2: minor SSL-related changes --- xmpp2/files/nginx/ssl.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xmpp2/files/nginx/ssl.conf b/xmpp2/files/nginx/ssl.conf index 3e72804..5e80eab 100644 --- a/xmpp2/files/nginx/ssl.conf +++ b/xmpp2/files/nginx/ssl.conf @@ -2,8 +2,8 @@ # # SPDX-License-Identifier: MIT -ssl_certificate /etc/letsencrypt/live/codingteam.org.ru-0001/fullchain.pem; -ssl_certificate_key /etc/letsencrypt/live/codingteam.org.ru-0001/privkey.pem; +ssl_certificate /etc/letsencrypt/live/codingteam.org.ru/fullchain.pem; +ssl_certificate_key /etc/letsencrypt/live/codingteam.org.ru/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -ssl_ciphers "HIGH:!aNULL:!MD5:!kEDH"; +ssl_ciphers "HIGH:!aNULL:!MD5:!kEDH"; add_header Strict-Transport-Security 'max-age=15552000'; From ea08d414a81667b5d441502357e2d9e65facbdbb Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:50:46 +0200 Subject: [PATCH 42/44] (#39) xmpp2: tune permissions --- xmpp2/loglist.yml | 2 +- xmpp2/nginx.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xmpp2/loglist.yml b/xmpp2/loglist.yml index e5fd227..f25e6fe 100644 --- a/xmpp2/loglist.yml +++ b/xmpp2/loglist.yml @@ -44,7 +44,7 @@ ansible.builtin.file: path: '{{ item }}' state: directory - mode: 'u=rwx,g,o=rx' + mode: 'u=rx,g,o=r' loop: - '{{ host_db_init_scripts_dir }}' - '{{ host_data_dir }}' diff --git a/xmpp2/nginx.yml b/xmpp2/nginx.yml index dc6b0a8..23b30a4 100644 --- a/xmpp2/nginx.yml +++ b/xmpp2/nginx.yml @@ -34,7 +34,7 @@ ansible.builtin.copy: src: 'nginx/{{ item }}' dest: '/etc/nginx/{{ item }}' - mode: "u=rx,go=rx" + mode: 'u=rw,go=r' loop: - nginx.conf - ssl.conf From 1f34753a064297cabe5e32fe577d86f643864ae1 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:54:04 +0200 Subject: [PATCH 43/44] (#39) ctor: get rid of Fabricator-based deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next time, maybe… --- .gitignore | 5 -- .gitmodules | 7 --- Codingteam.Devops.sln | 68 ---------------------- Codingteam.Devops.sln.license | 3 - Fabricator | 1 - ctor/Codingteam.Ctor.fsproj | 26 --------- ctor/GreenCaptchaBot.fs | 33 ----------- ctor/GreenCaptchaBot.template.json | 6 -- ctor/GreenCaptchaBot.template.json.license | 3 - ctor/Program.fs | 25 -------- 10 files changed, 177 deletions(-) delete mode 100644 .gitmodules delete mode 100644 Codingteam.Devops.sln delete mode 100644 Codingteam.Devops.sln.license delete mode 160000 Fabricator delete mode 100644 ctor/Codingteam.Ctor.fsproj delete mode 100644 ctor/GreenCaptchaBot.fs delete mode 100644 ctor/GreenCaptchaBot.template.json delete mode 100644 ctor/GreenCaptchaBot.template.json.license delete mode 100644 ctor/Program.fs diff --git a/.gitignore b/.gitignore index a006da1..5227ce2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,3 @@ # IntelliJ-based IDE stuff: /.idea/ - -bin/ -obj/ - -*.private.json diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cc72787..0000000 --- a/.gitmodules +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -# -# SPDX-License-Identifier: MIT - -[submodule "Fabricator"] - path = Fabricator - url = git@github.com:ForNeVeR/Fabricator.git diff --git a/Codingteam.Devops.sln b/Codingteam.Devops.sln deleted file mode 100644 index 144a8b0..0000000 --- a/Codingteam.Devops.sln +++ /dev/null @@ -1,68 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Codingteam.Ctor", "ctor\Codingteam.Ctor.fsproj", "{E08EC4D8-5FD7-45CB-B48A-689005546B10}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A37A2B6B-F09B-4105-8AA5-47BA5D74B68A}" - ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore - .editorconfig = .editorconfig - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{C4672A21-FB21-4BBF-A0A1-512AC1B66C9A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67164D20-A669-4BC3-A40E-751D3045BA89}" - ProjectSection(SolutionItems) = preProject - .github\workflows\main.yml = .github\workflows\main.yml - EndProjectSection -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Console", "Fabricator\Fabricator.Console\Fabricator.Console.fsproj", "{0157906C-006C-45F8-A79A-0D55F16B16B2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fabricator", "Fabricator", "{853E359A-18C5-4472-A712-D5C80EE99D6B}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Core", "Fabricator\Fabricator.Core\Fabricator.Core.fsproj", "{C57439E9-20AF-4EEB-8C91-5D74D346374B}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Resources", "Fabricator\Fabricator.Resources\Fabricator.Resources.fsproj", "{414C5063-3201-43AC-9DA1-B18A18802C0D}" -EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fabricator.Templates", "Fabricator\Fabricator.Templates\Fabricator.Templates.fsproj", "{E4F7858D-B0F7-4B42-928F-02688E843566}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E08EC4D8-5FD7-45CB-B48A-689005546B10}.Release|Any CPU.Build.0 = Release|Any CPU - {0157906C-006C-45F8-A79A-0D55F16B16B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0157906C-006C-45F8-A79A-0D55F16B16B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0157906C-006C-45F8-A79A-0D55F16B16B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0157906C-006C-45F8-A79A-0D55F16B16B2}.Release|Any CPU.Build.0 = Release|Any CPU - {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C57439E9-20AF-4EEB-8C91-5D74D346374B}.Release|Any CPU.Build.0 = Release|Any CPU - {414C5063-3201-43AC-9DA1-B18A18802C0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {414C5063-3201-43AC-9DA1-B18A18802C0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {414C5063-3201-43AC-9DA1-B18A18802C0D}.Release|Any CPU.Build.0 = Release|Any CPU - {E4F7858D-B0F7-4B42-928F-02688E843566}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4F7858D-B0F7-4B42-928F-02688E843566}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4F7858D-B0F7-4B42-928F-02688E843566}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4F7858D-B0F7-4B42-928F-02688E843566}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {67164D20-A669-4BC3-A40E-751D3045BA89} = {C4672A21-FB21-4BBF-A0A1-512AC1B66C9A} - {0157906C-006C-45F8-A79A-0D55F16B16B2} = {853E359A-18C5-4472-A712-D5C80EE99D6B} - {C57439E9-20AF-4EEB-8C91-5D74D346374B} = {853E359A-18C5-4472-A712-D5C80EE99D6B} - {414C5063-3201-43AC-9DA1-B18A18802C0D} = {853E359A-18C5-4472-A712-D5C80EE99D6B} - {E4F7858D-B0F7-4B42-928F-02688E843566} = {853E359A-18C5-4472-A712-D5C80EE99D6B} - EndGlobalSection -EndGlobal diff --git a/Codingteam.Devops.sln.license b/Codingteam.Devops.sln.license deleted file mode 100644 index fcafafa..0000000 --- a/Codingteam.Devops.sln.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2023-2025 Friedrich von Never - -SPDX-License-Identifier: MIT diff --git a/Fabricator b/Fabricator deleted file mode 160000 index b5b64d1..0000000 --- a/Fabricator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b5b64d10005b1fd45f4cbe2172e17c1f91e21f9d diff --git a/ctor/Codingteam.Ctor.fsproj b/ctor/Codingteam.Ctor.fsproj deleted file mode 100644 index 0ad0387..0000000 --- a/ctor/Codingteam.Ctor.fsproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - Exe - net8.0 - - - - - - - - - - - - - - - diff --git a/ctor/GreenCaptchaBot.fs b/ctor/GreenCaptchaBot.fs deleted file mode 100644 index 86a8d6f..0000000 --- a/ctor/GreenCaptchaBot.fs +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -// -// SPDX-License-Identifier: MIT - -module internal Codingteam.Ctor.GreenCaptchaBot - -open Fabricator.Core -open Fabricator.Resources.Files -open Fabricator.Resources.Docker -open Fabricator.Templates.FileTemplates - -let private hostConfigDirectory = "/opt/green-captcha-bot/" -let private docker = - let version = "v1.15.1" - dockerContainer { - Sources = { - GitRepository = "https://github.com/ImoutoChan/GreenCaptchaBot.git" - GitReference = $"tags/{version}" - } - DockerfilePath = "CaptchaBot/Dockerfile" - Tag = version - Name = "green-captcha-bot" - Options = [| - Volume(hostPath = hostConfigDirectory, containerPath = "/app/Configuration") - |] - } - -let private configFile parameters = FileResource( - templatedFile "GreenCaptchaBot.template.json" parameters, - $"{hostConfigDirectory}/appsettings.json" -) - -let resources(parameters: Map): IResource[] = [| configFile parameters; docker |] diff --git a/ctor/GreenCaptchaBot.template.json b/ctor/GreenCaptchaBot.template.json deleted file mode 100644 index 49b9e6b..0000000 --- a/ctor/GreenCaptchaBot.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "Configuration": { - "BotToken": "$BOT_TOKEN", - "DeleteJoinMessages": "Unsuccessful" - } -} diff --git a/ctor/GreenCaptchaBot.template.json.license b/ctor/GreenCaptchaBot.template.json.license deleted file mode 100644 index fcafafa..0000000 --- a/ctor/GreenCaptchaBot.template.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2023-2025 Friedrich von Never - -SPDX-License-Identifier: MIT diff --git a/ctor/Program.fs b/ctor/Program.fs deleted file mode 100644 index 405da44..0000000 --- a/ctor/Program.fs +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023-2025 Friedrich von Never -// -// SPDX-License-Identifier: MIT - -open Fabricator.Console -open Fabricator.Core -open Fabricator.Templates.FileTemplates - -open Codingteam.Ctor - -let private cluster mode = task { - let connectionsFileName = if mode = EntryPoint.RunMode.Verify then "connections.stub.json" else "connections.private.json" - let! parameters = readParameterFile "parameters.json" - return [| - { - Name = "ctor" - Designator = Designators.fromConnectionsFile connectionsFileName "ctor" - Resources = GreenCaptchaBot.resources parameters - Type = MachineType.Linux - } - |] -} - -let main (args: string[]): int = - EntryPoint.main args (fun m -> (cluster m).GetAwaiter().GetResult()) From 3a6089f9018fc7c3b518d001aec368430d883d07 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sat, 14 Jun 2025 23:54:56 +0200 Subject: [PATCH 44/44] (#39) ansible-lint: clean up --- ansible-lint.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ansible-lint.yml b/ansible-lint.yml index 41f463a..87c7275 100644 --- a/ansible-lint.yml +++ b/ansible-lint.yml @@ -4,5 +4,4 @@ exclude_paths: - .github/ # no Ansible plays in there - - ctor/kubernetes/ # TODO: Drop this before merge - xmpp2/default.yml # just a list of other files