4
0
Fork 2
mirror of https://gerrit.hackerspace.pl/hscloud synced 2025-01-21 21:33:54 +00:00
Commit graph

1530 commits

Author SHA1 Message Date
f95751d0f3 app/mastodon: bump to 4.2.15
Change-Id: I8beb1a4ead34f770c14c2b4eb1751900945cd138
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2150
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-21 16:29:44 +00:00
92d1f56b2d app/matrix: fix labs settings option, enable image reactions
This fixes full labs settings tab visibility in newer Element versions
(only Beta options were listed, not all experimental features), and
enables quite common custom reaction packs support.

Base config adjusted to more closely resemble official sample:
https://github.com/element-hq/element-web/blob/develop/config.sample.json

Change-Id: Id6f30ebec9dd6bfe5c87de0648031fa14fc417dd
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2144
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-20 20:59:11 +00:00
4a01378278 cluster/k1: add dcr03s19n02.hswaw.net keys&certs
Change-Id: Iadbedb10ab08458804b953aa42489ccfe06bddf8
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2148
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-20 20:58:36 +00:00
2975caa1bd cluster: remove vestiges of bc01n{01,02,03}
These machines have been dead for a long time

Change-Id: Idf10da9945cb0ae2284740775b15997991a8f789
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2142
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-20 20:58:30 +00:00
16d1802157 cluster/k1: add metallb
According to https://metallb.universe.tf/configuration/calico/ - we can now integrate with calico "the easy way", by disabling metallb speaker, and letting calico announce LoadBalancer IPs

Change-Id: I3ab36b13b6529c61907f8c124cae5c908a64d4be
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2139
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-20 14:59:17 +00:00
13e47c61b2 hswaw: remove cebulacamp/landing, pretalx
cebula.camp is moving to its own infra

Change-Id: Ic0c86d81d913ba9e65259baf9f7385b4cba99c5a
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2147
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-20 08:45:35 +00:00
259baee463 cluster/k1: add calico
Adds Calico network fabric & CNI plugin, as well as its BGP configuration and IP Pools.

Updates IP addresses for coredns, ingress, prodvider, now that IP ranges have been determined.

Change-Id: Ic7214ad946bc486978444582b7c7dcb49f68e8f1
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2138
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-20 06:23:41 +00:00
2a5e6baf26 cluster/kube: add cebulacamp-backups s3 bucket
Change-Id: I4c0676c204540446dd1b71ee7907dda92a46e9ec
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2141
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-18 22:30:10 +00:00
a02d438f8e cluster/kube: fix broken jsonnet
oopsie that happened in 17d71bd, but was only caught after everything.jsonnet was merged. Sorry!

Change-Id: I12de7be673fd1f355c2e47583957aea06d2f130d
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2140
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-18 22:29:31 +00:00
e11404c28a cluster: add missing k1 certs/keys
Change-Id: Ie1fe06fc801edc0feb2c0eb74343164ccda6c944
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2136
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-18 20:08:01 +00:00
ca61948290 clustercfg: add missing certs generation
Change-Id: I55f4e0028b9e122733378b9d2c0264aa8fb11241
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2135
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-18 20:08:01 +00:00
0be30b6676 h/m/sound: update to 24.11 + related changes
TODO:
* fix polycom volume control on iot.
  * spejsiot-api, spejsiot-polycom, and socat-polycom appear to be working, but manipulating aux1 audio gain on iot. doesn't seem to affect volume coming from sound.

./.: driveby: nixfmt

./audio.nix:
* `sound.enable` is no more
* migration to pipewire
* disable cache in spotifyd
* bluez-simple-agent moved to its own package because of GI_TYPELIB_PATH shenanigans
* enable avahi to allow pipewire to publish itself
* explicitly set audio backend for spotifyd to pulseaudio, otherwise it attempts to use native pipewire and fails because that lives in a specific user's session now
* pipewire modules require a dbus session; workaround it by making pipewire user a normal user with lingering units and pipewire user service wanted as by default.target
* make starting user sessions depend on network-online.target, to avoid a race condition between pipewire{,-pulse} zeroconf publishing and network status; added a load-bearing sleep to pipewire-pulse because it *sometimes* (once every >10 reboots) still wasn't enough
* added airplay/raop sink (shairport-sync)

./configuration.nix:
* sshd setting rename
* add my key
* add alsa-utils for alsamixer
* migrate to networkd, make networkd only wait for "lan" interface for online status
* spejsiot-api listens on 127.0.0.1; change nginx backend explicitly to that address; localhost resolved to ip6 ::1 and caused errors

./bluez-simple-agent.py:
* automagic shebangs interferred with running the script as a systemd unit
* reworked import from gi.repository because MainLoop() is now in GLib
* moved to hswaw/bluez-simple-agent to avoid unnecessary rebuilds

./spejsiot-api.nix:
* fix for deprecated import
* driveby: remove unused variable binding

ops/hive.nix: move customs pinned commit to outer scope and use it for sound as well

hswaw/lib/flask_spaceauth/example.py: fix for deprecated import

Change-Id: Ic9993836e334236ac842525a0fd167906a91fc37
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2119
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-18 16:53:50 +00:00
42b0858c3f cluster/k1: add ingress-nginx-controller
Because of a large k8s version difference (and hence ingress controller version), it's not practical to reuse k0's config in total.

As we're starting from a blank slate, this setup is a bit simpler (closer to vendored yaml) than k0's:

- We don't have to rename namespace, maintain old labels, and so on.
- We can include {cluster,}role{binding,}s, service account as is.
- The deployment is also just a modified version of the vendored deployment (changing replicas, args, resources, volume only from the default)

For ConfigMaps, we reuse k0's as much as practical for the transition period.

For Services, I propose a convention of tying `ingress-$N.k1.hswaw.net` to `svc/ingress-$N-k1-hswaw-net`, so that in the future, we can point code.hackerspace.pl to ingress-2.k1.hswaw.net instead of an IP. This should be easier to read and understand than the old setup.

Change-Id: I81e1570411e574c1ce828ac94e2251f7ecf90b00
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2131
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-18 07:40:18 +00:00
1f54958832 kube: introduce everything.jsonnet
This convention is meant to aid during mass refactoring of jsonnets (such as kube.libsonnet additions). However, this can also be used to do global diff between master and production.

Currently, this is only helpful to handful of secretstore keyholders, otherwise not all jsonnets can evaluate. However, in principle it should be possible to evaluate jsonnets sans secrets to allow non-admins to do this type of maintenance.

Change-Id: I5afb9ee3ab478b2f0939c8bacec7cdb2c96011de
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2122
Reviewed-by: implr <implr@hackerspace.pl>
2025-01-18 07:25:09 +00:00
31a32a816c cluster/prodaccess: use the correct cluster CA cert
Adds //cluster/k1/certs go package, and changes prodaccess to look up the correct one based on the -cluster flag. This should complete the transition of prodaccess to multicluster.

Change-Id: If65fab8f898a48ec16e6de7eeb02fd0aacee30b4
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2117
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-17 22:35:29 +00:00
bed52d89db cluster/k1: add cert-manager
Change-Id: Ic3385ae10a4ce9542d7972425ed5669164f6bb84
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2132
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:34:59 +00:00
9a05ad8003 cluster/k1: add metrics-server
Change-Id: Ic9de293aba45b97c1e802405f838d7e78099d113
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2130
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:34:50 +00:00
bcbf93e67f cluster/k1: add coredns
Change-Id: Id51aadbab36e79b3a8a6af5aecf00681d55dd47e
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2133
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:34:40 +00:00
cb09dea085 cluster/k1: init
This adds a stub of k1/cluster.libsonnet and k1.jsonnet, mirroring k0 configuration structure.

There are no nodes to deploy this to yet, but it is at least valid jsonnet.

It contains all cluster services/config that are k1-ready as of this commit:

- basic roles and bindings
- letsencrypt certificate issuer
- prodvider
- pki
- admitomatic
- namespace admins

admitomatic and admin config is shared with k0 at this stage.

Change-Id: I51326dae43739b1cbee89d54b8ac490430d49256
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2127
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:34:02 +00:00
2594a3bfc9 app/matrix: upgrade synapse, element-web
Change-Id: I6f05c40d33ba955c9ff9aac0609763ea5277554b
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2125
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:33:59 +00:00
e96971dc33 kube: introduce kube.libsonnet override convention
This introduces a way to replace kube.libsonnet with k1.libsonnet in all places that will be used both on k0 and k1.

We need this because of k8s API incompatibilities.

Change-Id: Id10bafea85c04fc214d5a766c33cadc979183992
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2134
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:33:44 +00:00
47c83206f1 WORKSPACE: drop rules_docker completely
Change-Id: Ib7db0a6ff3f9549afaffa8e695b4fda356b76888
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2116
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 22:30:44 +00:00
38d2b530be personal/q3k: migrate to rules_docker
Change-Id: I4a6aa1c8de26ec50f93272006fee90241bd06498
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2115
Reviewed-by: radex <radex@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-17 22:30:44 +00:00
c3e36bae20 *: fix ci_presubmit post-update
Change-Id: I9ada89e294a84ba538be28a9c51752047a0ecf25
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2111
Reviewed-by: radex <radex@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-17 22:30:44 +00:00
81e381fe4e *: migrate to embedsrcs
Change-Id: Ifafb0d6f58c2f51af56f4592704b5c9fa994c653
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2110
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-17 22:30:24 +00:00
b4f1da7eef kube: add k1.libsonnet
This contains changes that will be required for k1 but are (AFAICT) incompatible with k0. The idea is for apps deployed on k1 to import this instead of hscloud.libsonnet

Change-Id: I133bf71c1610469674089041c3996a9d7f7117a8
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2126
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 21:22:55 +00:00
17d71bd252 cluster/kube: extract roles.libsonnet
Extracting this part of cluster.libsonnet, primarily for ease of reuse in k1 config.

Additionally, removed an unused cluster cfg field

Change-Id: I66a527f0090fa5e3833287bfea267db485977f21
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2128
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-17 21:22:49 +00:00
53f4a7dfc3 cluster/kube: move pki imports to cluster.libsonnet
This will allow affected libsonnets to be reused for k1

Change-Id: I30e7dfd6c391e479270c78f8a245d6f330e65027
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2124
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-14 17:47:32 +00:00
52ab741686 *: bump prodimage to noble, deploy
Change-Id: I3f4cce02eb6bb34c2fd66062b122464daeaae7bb
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2120
Reviewed-by: pl <pl@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-14 16:31:16 +00:00
bdba8b2b58 kube: fix broken jsonnets
matrix.0x3c.pl.jsonnet and pretalx.libsonnet would not evaluate correctly due to errors

Change-Id: I919cc5065dd22fb6aa44928c00acbfa2a10db939
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2123
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-14 15:53:59 +00:00
d7ecb5333c machines/snowflake: bump nixpkgs to 24.11
Also:
- update implr's keys
- drop noXlibs as nixos dropped it
- remove sshd patch as 24.11 is on 9.9 which is not affected

Change-Id: Id81291b7d5949fa390ac3b72104ada7e5a16c00c
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2067
Reviewed-by: ar <ar@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-12 23:00:09 +00:00
3cceac8e3d *: add more OWNERS
There should not be a bus factor of 1 in OWNERS files with inherited: false

Change-Id: Ie5862e956b34fc2e5445c817fc85a93f3e317500
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2118
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-12 14:43:33 +00:00
6f7c7971ff h/m/customs: update to 24.11 + related changes
./configuration.nix:
* environment.noXlibs is no more
* iproute -> iproute2
* rxvt_unicode -> rxvt-unicode-unwrapped
./laserproxy:
* remove `-hspki_disable` after mirko dep removal in d78b495659
* driveby remove unneeded `pkgs` import
./beyondspace.nix: oauth2_proxy -> oauth2-proxy
hswaw/checkinator: iproute -> iproute2
hswaw/laserproxy: driveby remove unused import and unneeded `rec`

Change-Id: Ibc80cc2e6fc9233059ad5b18cf9dd66e51fb228d
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2114
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-12 13:10:03 +00:00
00f4d0dd5e hswaw/laserproxy: fix contexts after demirkoification
(also drive-by gofmt)

Change-Id: If2d77de4e6363ce02b7b748f42b604b2777a9196
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2113
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-12 12:41:10 +00:00
770b0db668 bazel: fix broken clustercfg, prodaccess
Change-Id: Idc79d575a2efc4ad5de56cfd02e95f6e5f670378
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2109
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-12 08:36:40 +00:00
a0eed97030 *: migrate to rules_oci, fix cross-compilation
Change-Id: I29742930ec0053aa41e2bcac915f8e2678e9095d
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2097
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 21:31:45 +00:00
b95b8c223c h/m/sound: add a2dp sink and spotifyd
This introduces pulseaudio/bluez-based A2DP sink. Authentication is
handled by a custom agent python script that allows everything without
any manual input (with fallback to "1234" code if that's requested by
connecting party) - "NoInputNoOutput" mode that's supposed to allow
pairing without any code/interaction seems to be broken.

spotifyd (spotify connect-capable receiver) is added now too.

Change-Id: I22b4d946a61e84e7c0387448a0d8021910bf1451
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1952
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-11 20:53:52 +00:00
d78b495659 hswaw/laserproxy: remove mirko dependency, simplify nix build
Change-Id: I99706c63338978226c09e0628fd800f62c250896
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2107
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 20:40:37 +00:00
81ca386a15 bgpwtf/speedtest: migrate to go embed
Change-Id: I704fe3229d60e388915cf515df728cf42141928d
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2096
Reviewed-by: radex <radex@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 20:40:37 +00:00
8c34a8588f hswaw/site: migrate to go embed
Change-Id: I98dc72d3a52b931aa4a219274a84d2da5ce0e426
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2095
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-11 20:40:37 +00:00
3c180eb5aa hswaw/laserproxy: migrate to go embed
Change-Id: I69553b14403b330c2a2c3d460bb03ee1d89da06e
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2094
Reviewed-by: radex <radex@hackerspace.pl>
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 20:40:37 +00:00
1254c9905b bazel: rename io_bazel_rules_go to rules_go
Change-Id: Ib66d48dd4b5eab23c31bb4931855b2f9c7a6d57c
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2093
Reviewed-by: q3k <q3k@hackerspace.pl>
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-11 20:40:37 +00:00
f87a2e60c2 bazel: migrate to bzlmod
Change-Id: If9aca699d2ca5810651cefd7e974137706a681bf
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2092
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 20:40:37 +00:00
1728443a68 *: bump bazel version, bump nixpkgs, add prebuilt container image
Change-Id: I1af176369086b243f316fc06ed33d2d6bdc9616f
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1862
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-11 20:40:37 +00:00
eabf2104dc kube: standardize on omitting replicas: 1
Across the hscloud, few deployments have number of replicas other than 1. And not every app is even built to support more than 1 replica (notably, nothing with waw-hdd-redundant-3 mounts will work). Also, replicas=1 is the default. Therefore, it doesn't make sense to explicitly say `replicas: 1` unless other value is needed.

Change-Id: I12250ceb053d2041c06ecfe685fe7f8f10d20679
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2084
Reviewed-by: pl <pl@hackerspace.pl>
Reviewed-by: krnlexception <krnlexception@hackerspace.pl>
Reviewed-by: informatic <informatic@hackerspace.pl>
2025-01-11 16:45:33 +00:00
45bf1472a9 kube: rename SimpleIngress to TLSIngress & split up
The abstraction and name of SimpleIngress didn't feel right to me. I realized it's actually a few related things. One is just the simplified syntax to point `target` to `hosts`, and that should live in the (upstream-able) kube.libsonnet (similar to what we do with Service, PVC). Second is k0-specific default for all ingresses of proxy-body-size=0. Third is TLS-specific stuff, which includes the (standard) spec.tls, and k0-specific acme/cert-manager annotations.

In the end, for cluster users this is basically just a rename of SimpleIngress to TLSIngress. But it's a bit better encapsulated I think, and if someone wants a non-TLS Ingress or if we ever upstream kube.libsonnet, this may be helpful

Change-Id: I4587549699c40fe71c4fff358faac8748ecc44ef
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2085
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 16:45:22 +00:00
9601a1c030 personal/radex: update static
Change-Id: I23e3a198f09f7e851c8d52257977144d283e0c40
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2104
2025-01-11 15:24:53 +00:00
63f0adde2f cluster/prodaccess: add multi-cluster support
- allow passing -cluster to select another cluster (k0 remains the default for the time being)
- default prodvider dns to prodvider.<cluster>.hswaw.net
- scope kube config username and certs storage by cluster name

additionally:

- force username to be lowercase (LDAP is case-insensitive, but e.g. kubernetes namespaces are not)
- fix some Go deprecations

Change-Id: Ibf4a6ced7a635940f6a7c568c79714cd8ac60ce9
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2101
Reviewed-by: radex <radex@hackerspace.pl>
2025-01-11 15:22:45 +00:00
0565af617a cluster/prodvider: deploy & modernize jsonnet
Change-Id: I4de71cb7770a16fd4bfdcd171f01c0af2808f4e7
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2103
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 15:18:54 +00:00
20288e8aa9 cluster/prodvider: add multi-cluster support + tweaks
- remove defaults for -kubernetes_host and -prodvider_cn
- pass cluster fqdn to KubernetesKeys.Cluster
- hardcode prodvider.hswaw.net as one of prodvider cert's DNSNames to allow graceful transition to prodvider.k0.hswaw.net
- add optional -crdb_cluster flag

BONUS CONTENT:

- use consistent credential duration for all certs + allow configuration via -credential_duration
- fixes broken prodviding if username isn't all lowercase

Change-Id: Ia801a16d7245d746e72f199a0900100ffc614dcf
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/2100
Reviewed-by: q3k <q3k@hackerspace.pl>
2025-01-11 15:18:24 +00:00