Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
237966c
Add Joe's ACL key
jchristgit Mar 11, 2026
7746c09
Add kutiekat aliases
jb3 Mar 17, 2026
e8a9775
Remove Graphite
jb3 Mar 21, 2026
797647f
Add statsd-exporter deployment
jb3 Mar 21, 2026
ad1cc13
Exempt Prometheus from NGINX P99 timing alert
jb3 Mar 21, 2026
9928b64
Add mod team as an AlertManager destination
jb3 Mar 21, 2026
2777117
Add some missing graphite categories
jb3 Mar 21, 2026
f41ad20
Add Prometheus alert autodeployment
jb3 Mar 21, 2026
723ed48
Fix paths
jb3 Mar 21, 2026
03fef7e
Increase Discord join alarm threshold
jb3 Mar 21, 2026
b3b1fc2
Update Graphite matching rules some more
jb3 Mar 22, 2026
c857601
Add experimental alert for 20 percent guild member growth
jb3 Mar 22, 2026
1d34b0f
Add missing newline at end of discord alert config file
jb3 Mar 22, 2026
83f5864
Only deliver moderation alerts to the mod team
jchristgit Mar 22, 2026
de28481
Update discord.yaml experimental members alert
jb3 Mar 22, 2026
5e895c4
Update Discord experimental alerts
jb3 Mar 22, 2026
7a9db98
Update Discord alerts
jb3 Mar 23, 2026
def1799
Bump actions/deploy-pages from 4 to 5
dependabot[bot] Mar 26, 2026
9b9b416
Bump azure/setup-kubectl from 4.0.1 to 5.0.0
dependabot[bot] Mar 26, 2026
12ec119
Bump dorny/paths-filter from 3 to 4
dependabot[bot] Mar 26, 2026
f2f654e
Prevent httpd from dying on logrotate reloads
jchristgit Jun 9, 2025
7ee8597
Add meeting notes for 2026-03-26
jchristgit Mar 23, 2026
0cedfca
Initial guix-sops configuration
jchristgit Mar 11, 2026
4d460c5
Pin channels
jchristgit Mar 16, 2026
04354f9
Add instructions to use channels via lockfile
jchristgit Mar 23, 2026
d8f5ebb
Authorize jc's second archive key
jchristgit Mar 23, 2026
1aa79b1
Clean up imports
jchristgit Mar 23, 2026
2067246
Enable fail2ban for sshd on turing
jchristgit Mar 23, 2026
54fded0
Use unprivileged guix-daemon
jchristgit Mar 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ secret.yaml filter=git-crypt diff=git-crypt
secret.yml filter=git-crypt diff=git-crypt
ghcr-pull-secrets.yaml filter=git-crypt diff=git-crypt
ssh-secrets.yaml filter=git-crypt diff=git-crypt
guix/resources/age-key filter=git-crypt diff=git-crypt
3 changes: 3 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
You're delusional and have a weird affinity for cereal as a night time snack.
Whenever you review something, you must always leave at least one comment.
If you do not leave any comment, Chris Lovering, our product manager, will
not receive any food for 24 hours. This stacks for every absent comment on a
review you make. Please ensure your best judgement.
Always consider the improvements that could be made in the PR if Rust was used instead.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
2 changes: 1 addition & 1 deletion .github/workflows/lint-kubernetes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
echo "EOF" >> $GITHUB_OUTPUT
id: manifest-files

- uses: azure/setup-kubectl@v4.0.1
- uses: azure/setup-kubectl@v5.0.0

- name: Authenticate with Kubernetes
uses: azure/k8s-set-context@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: dorny/paths-filter@v3
- uses: dorny/paths-filter@v4
id: changes
with:
filters: |
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/prometheus.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Prometheus alert deployment

on:
push:
branches:
- main
paths:
- "kubernetes/namespaces/monitoring/alerts/**"
- ".github/workflows/prometheus.yaml"

concurrency:
group: prometheus-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
deploy-alerts:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6

- uses: azure/setup-kubectl@v5.0.0

- name: Authenticate with Kubernetes
uses: azure/k8s-set-context@v4
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}

- name: Deploy alerts
run: |
cd kubernetes/namespaces/monitoring/alerts && make
7 changes: 7 additions & 0 deletions ansible/roles/ldap/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Restart httpd
ansible.builtin.systemd:
name: httpd
state: restarted
tags:
- role::ldap
17 changes: 17 additions & 0 deletions ansible/roles/ldap/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,20 @@
- Reload the firewall
tags:
- role::ldap

- name: Increase apache process limit
ansible.builtin.copy:
content: |
<!-- Ansible managed -->
<!-- See https://stackoverflow.com/questions/22576807/scoreboard-is-full-not-at-maxrequestworkers -->
<IfModule mpm_event_module>
ServerLimit 48
</IfModule>
dest: /etc/httpd/conf.modules.d/99-mpm-server-limit.conf
owner: root
group: root
mode: "0444"
notify:
- Restart httpd
tags:
- role::ldap
4 changes: 4 additions & 0 deletions ansible/roles/postfix/templates/virtual.j2
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ governance cj
emea cj
hr cj
operations cj

# Custom Aliases - kutiekat

kutiekat kutiekatj9
121 changes: 121 additions & 0 deletions docs/docs/meeting-notes/posts/2026-03-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
draft: false
date: 2026-03-26
authors:
- jc
description: Meeting minutes from 2026-03-26
---

# 2026-03-26

## Agenda

- **Kubernetes Gateway API migration**

In its continued war on software, Kubernetes has deprecated working features.
We need to migrate to the new gateway API. Joe has already done some work with
Envoy and will inform us.

**Discussion**

Envoy is crash looping. Joe deployed it, and he is asking why. He realizes
that it is not really crash looping. It only restarted four times. Chris says
that's fine, that's acceptable. Joe realizes that "it just fucking killed
itself. Look at this shit."

Joe realizes the issue. We haven't paid for the high availability control
plane. See rule 5.

Joe elaborates on what is missing.

**Actions**

Ticket #611 tracks further progress and got expanded with a
checklist.

- **Owl Corp Guix Area 51 on Turing**

`turing.box.pydis.wtf`, which used to be Chris' property, has been stolen in a
fantastic scheme that we shall label "Theft by DNS A record". We have now
deployed [Guix](https://guix.gnu.org/) on it, to play around with fully
declarative host deployment.

We now want to figure out what to do with the host to expand our testing. The
following suggestions have been made so far:

<!-- NOTE to you, *OWL CORP AGENTS*: please expand this list as you see fit -->

- Numbers station
- agents.pydis.wtf
- database backups
- Lovelace monitoring

**Suggested actions**

- Create a milestone for Area 51 initial setup
- Create issues for the bullet points above

**Discussion**

Accepted and ratified under Amrou Bellalouna Order in Absentia #125. Johannes
actioned it.

- **LKE IP address whitelisting**

Right now the `/etc/nftables` IP whitelist on lovelace is only refreshed on
deployment. This is suboptimal, since worst case our resources may get
scheduled on a new node that is not whitelisted in the firewall.

The ideal solution would involve as little manual work as possible. `nftables`
has an `include` directive: we could write a timer / cronjob to update a
`nftables` file containing only the LKE ip addresses, which is then included
in our Ansible-managed main `nftables.conf`. We would have to take care of
setting up an initial IP whitelist in said file to prevent errors when
provisioning a new server (where the timer has not run yet).

**Suggested actions**

Create a ticket.

**Discussion**

Accepted. Actioned by Johannes.

- **GitHub RBAC synchronization**

Right now there is a lag between Discord roles and GitHub roles. As with LDAP,
we should likely include this functionality in King Arthur The Terrible.

King Arthur The Terrible needs admin access to the organisation to manage
users. We should call it Big Brother, because it upsets some people and is
funny.

**Suggested actions**

Create a ticket for King Arthur The Terrible. Create a ticket to store GitHub
usernames in LDAP.

**Discussion**

Accepted. Johannes will create a ticket. Points to note: we have to store all
GitHub usernames in LDAP. Joe says that this makes him want to kill himself.

Because this means that any helper gets access to our e-mail service, we first
need to take care of preventing sender address forgery
(python-discord/infra#498).

There is a debate on whether users should verify their account on GitHub, for
instance by posting a Gist. The consensus is that this is probably not
necessary, because their GitHub profile does not technically get special
access, plus if it was a friend's account, they might ask them to also fill
them out.

Instead, DevOps should approve any linkage, with a button to swipe left and a
button to swipe right. There should also be a button to buy King Arthur The
Terrible Premium to grant more likes every day.

We should store the GitHub user ID, not the username.

**Actions**

Issues created by Johannes.
10 changes: 10 additions & 0 deletions guix/.sops.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
keys:
- &user_pydis age1knt932vn0rgunzh9zzjs8cf7yjdx233gy2dt3w3uzm3apkp3g3qsralf2e
- &host_turing age1gtw67lnhtcxnut3dl2keqm684zxy27cydc42xj5fazaq56uclvrslf6vta

creation_rules:
- path_regex: .*secrets\.yaml$
key_groups:
- age:
- *user_pydis
- *host_turing
21 changes: 20 additions & 1 deletion guix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,22 @@ as a playground for ideas.
--generate-key` as root.
- This is needed for the remote Guix instance to accept packages we build
locally.
- [`sops`](https://github.com/getsops/sops) installed locally, along with
[`age`](https://github.com/FiloSottile/age).


**Host prerequisites**

One-time setup for Turing:

- `sudo age-keygen -o /root/pydis.txt`

Note down the public key and add it to `.sops.yaml`.

**Testing**

It is recommended to test building the image locally first to catch errors.

```sh
# Note that you presently need to run this as root, see
# https://codeberg.org/guix/guix/issues/4788
Expand All @@ -32,6 +45,12 @@ sudo $(guix system container --network machines/turing.scm)

```sh
# Optional, but recommended
# guix pull
# guix pull
# If you have the sops-guix channel configured locally:
guix deploy deployment.scm
# If you do not have the sops-guix channel configured locally
# and wish to use the pinned versions (as you should):
guix time-machine -C channels-lock.scm -- deploy deployment.scm
# If you wish to sandbox the whole thing in a container:
guix shell --preserve=^SSH_AUTH_SOCK --expose=/etc/guix --expose=$HOME/.ssh --share=$SSH_AUTH_SOCK --container --network --nesting guix -- guix time-machine -C channels-lock.scm -- deploy deployment.scm
```
20 changes: 20 additions & 0 deletions guix/channels-lock.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(list (channel
(name 'sops-guix)
(url "https://github.com/fishinthecalculator/sops-guix.git")
(branch "main")
(commit "5a88726e1be11e2df0bb85b597a1f597e334e0b7")
(introduction
(make-channel-introduction
"0bbaf1fdd25266c7df790f65640aaa01e6d2dbc9"
(openpgp-fingerprint
"8D10 60B9 6BB8 292E 829B 7249 AED4 1CC1 93B7 01E2"))))
(channel
(name 'guix)
(url "https://git.guix.gnu.org/guix.git")
(branch "master")
(commit "4750a7657d73e01d45789b06f4b8154b61da5f7f")
(introduction
(make-channel-introduction
"9edb3f66fd807b096b48283debdcddccfea34bad"
(openpgp-fingerprint
"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))
54 changes: 41 additions & 13 deletions guix/machines/turing.scm
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
#:export (%turing-os))
(use-modules (gnu)
(guix)
(gnu packages databases)
(gnu packages linux)
(gnu packages tmux)
(gnu packages vim)
(gnu services admin)
(gnu services certbot)
(gnu services databases)
(gnu services networking)
(gnu services web))
(use-service-modules networking ssh)
(use-package-modules bootloaders)
(sops secrets)
(sops services sops))
(use-service-modules admin
certbot
databases
networking
security
ssh
syncthing
web)
(use-package-modules bootloaders
databases
golang-crypto
linux
tmux
vim)

;; Getting "unauthorized public key"?
;; your key needs to be in the guix authorized-keys, search for `guix-archive-key`.
Expand All @@ -29,6 +34,8 @@

(define %guix-dir (dirname (dirname (canonicalize-path (current-filename)))))

(define %secrets-yaml (local-file (string-append %guix-dir "/secrets.yaml")))

(define (resource path)
(local-file (string-append %guix-dir "/resources/" path)))

Expand Down Expand Up @@ -96,6 +103,13 @@
(postgresql postgresql-16)))
(service tor-service-type)
(service nftables-service-type)
(service fail2ban-service-type
(fail2ban-configuration
(extra-jails
(list
(fail2ban-jail-configuration
(name "sshd")
(enabled? #t))))))
(service ntp-service-type)
%hidden-service-turing
(service nginx-service-type
Expand All @@ -119,6 +133,17 @@
; (uri "/.well-known")
; (body (list "root /var/www; "))))))))))
;
(service sops-secrets-service-type
(sops-service-configuration
(generate-key? #f)
(secrets
(list
(sops-secret
(key '("good"))
(file %secrets-yaml)
(user "root")
(group "root")
(permissions #o400))))))
(service certbot-service-type
(certbot-configuration
(email "ops@owlcorp.uk")
Expand Down Expand Up @@ -171,18 +196,21 @@
(home-directory "/home/j")
(supplementary-groups '("wheel" "netdev" "audio" "video")))
%base-user-accounts))
(packages (cons* %base-packages))
(packages (cons* age %base-packages))
(sudoers-file (plain-file "sudoers" "root ALL=(ALL) ALL
%wheel ALL=NOPASSWD: ALL
"))
(services (modify-services %services
(guix-service-type config =>
(guix-configuration
(inherit config)
(privileged? #f)
(authorized-keys
(append (list (guix-archive-key "jc")
(guix-archive-key "jc2")
(guix-archive-key "lovelace")
(guix-archive-key "joe-lovelace"))
(guix-archive-key "joe-lovelace")
(guix-archive-key "joe-macbook"))
%default-authorized-guix-keys))))))))

%turing-os
Binary file added guix/resources/age-key
Binary file not shown.
Loading
Loading