Compare commits

..

6 commits

Author SHA1 Message Date
sinavir
b85d86c685 update liminix 2024-03-15 13:15:41 +01:00
sinavir
0698cbb25c update liminix 2024-02-22 22:16:09 +01:00
sinavir
3251fc2698 router: update liminix, refactor 2024-01-26 19:43:04 +01:00
sinavir
ccd7e80da7 liminix: add fancy ping 2024-01-24 13:33:30 +01:00
sinavir
886b9e7c0c router: add all my hacks to make ubifs work 2024-01-23 13:36:46 +01:00
sinavir
aa55031cfd router: use liminix submodule 2024-01-23 13:36:46 +01:00
121 changed files with 589 additions and 2555 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "machines/router/liminix"]
path = machines/router/liminix
url = https://git.dgnum.eu/HackENS/liminix-fork.git

View file

@ -6,51 +6,39 @@ let
inherit (defaultNixpkgs) lib;
revision =
node:
(builtins.fromJSON (builtins.readFile ./npins/sources.json)).pins.${pkgsVersion node}.revision;
revision = node: (builtins.fromJSON (builtins.readFile ./npins/sources.json)).pins.${pkgsVersion node}.revision;
mkNode = node: {
${node} =
{
${node} = {
name,
nodes,
...
}:
{
imports = [
./machines/${node}/_configuration.nix
] ++ lib.attrByPath [ "imports" ] [ ] metadata.nodes.${node};
}: {
imports = [./machines/${node}/_configuration.nix] ++ lib.attrByPath [ "imports" ] [] metadata.nodes.${node};
inherit (metadata.nodes.${node}) deployment;
nix.nixPath = builtins.map (n: "${n}=${sources.${n}}") (builtins.attrNames sources) ++ [
"nixpkgs=${mkNixpkgsPath name}"
];
nix.nixPath =
builtins.map (n: "${n}=${sources.${n}}") (builtins.attrNames sources)
++ ["nixpkgs=${mkNixpkgsPath name}"];
system.nixos.tags = [
(revision node)
];
};
};
pkgsVersion =
node:
lib.attrByPath [
node
"nixpkgs"
] "nixos-unstable" metadata.nodes;
pkgsVersion = node: lib.attrByPath [ node "nixpkgs" ] "nixos-unstable" metadata.nodes;
mkNixpkgsPath = node: sources.${pkgsVersion node};
mkNixpkgs = node: {
${node} = importNixpkgsPath (lib.attrByPath [ "arch" ] "x86_64-linux" metadata.nodes.${node}) (
mkNixpkgsPath node
);
${node} =
importNixpkgsPath
(lib.attrByPath [ "arch" ] "x86_64-linux" metadata.nodes.${node})
(mkNixpkgsPath node);
};
importNixpkgsPath =
arch: p:
import p {
importNixpkgsPath = arch: p: import p {
config.allowUnfree = true;
overlays = import ./pkgs/overlays.nix { inherit sources; };
overlays = import ./pkgs/overlays.nix;
system = arch;
};
@ -60,9 +48,7 @@ let
in
{
meta = {
specialArgs = {
inherit sources metadata;
};
specialArgs = {inherit metadata;};
nixpkgs = defaultNixpkgs;
nodeNixpkgs = concatAttrs (builtins.map mkNixpkgs nodes);
specialArgs = {

View file

@ -1,54 +0,0 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/installer/sd-card/sd-image-aarch64.nix") # this holds the hardware-config
./bootloader.nix
./secrets
./networking.nix
./users.nix
];
nix.settings.substituters = lib.mkForce [];
networking.hostName = "agb01"; # Define your hostname.
environment.systemPackages = [
(pkgs.writeShellApplication {
name = "run-gw";
runtimeInputs = [
pkgs.curl
(pkgs.python3.withPackages (ps: [
ps.pyjecteur
ps.colour
ps.requests
]))
];
text = "curl -s -n https://agb.hackens.org/api/sse | python ${./script.py}";
})
];
services.openssh.enable = true;
programs.mosh = {
enable = true;
openFirewall = true;
};
# Set your time zone.
time.timeZone = "Europe/Paris";
fonts.enableDefaultPackages = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "unstable"; # Did you read the comment?
}

View file

@ -1,4 +0,0 @@
{pkgs, ...}: {
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
}

View file

@ -1,98 +0,0 @@
{
config,
lib,
pkgs,
...
}: {
boot.kernel.sysctl."net.ipv4.ip_forward" = true;
systemd.network = {
enable = true;
wait-online.anyInterface = true;
networks = {
"10-uplink" = {
name = "enu1u1";
DHCP = "yes";
};
"50-wg0" = {
name = "wg0";
address = [
"10.10.10.5/24"
];
};
"10-wifi" = {
name = "wlan0";
networkConfig.DHCPServer = "yes";
address = [
"192.168.55.1/24"
];
};
};
netdevs = {
"50-wg0" = {
netdevConfig = {
Name = "wg0";
Kind = "wireguard";
};
wireguardConfig.PrivateKeyFile = config.age.secrets."wg".path;
wireguardPeers = [
{
AllowedIPs = [
"10.10.10.0/24"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/hackens-org.pub);
Endpoint = "129.199.129.76:1194";
PersistentKeepalive = 5;
}
];
};
};
};
networking = {
useDHCP = false;
nameservers = [
"2620:fe::fe"
"2620:fe::9"
"9.9.9.9"
"149.112.112.112"
];
nftables = {
enable = true;
tables.nat = {
family = "ip";
content = ''
chain postrouting {
type nat hook postrouting priority 100;
ip saddr 192.168.55.0/24 masquerade
}
'';
};
};
firewall.allowedUDPPorts = [ 67 ];
};
services.hostapd = {
enable = true;
radios.wlan0 = {
# countryCode = "FR";
wifi4.enable = false;
wifi5.enable = false;
channel = 7; # ACS doesn't work
networks.wlan0 = {
settings = {
ieee80211w = 0;
wmm_enabled = false;
};
ssid = "agb - wifi";
logLevel = 0;
authentication = {
mode = "wpa2-sha1";
wpaPasswordFile = pkgs.writeText "psk" "azertyuiop"; # TODO : secret
};
};
};
};
}

View file

@ -1,105 +0,0 @@
#!/nix/store/q1p072dnnx7fh7qfcavkmpwn3rgf2xh1-python3-3.12.5-env/bin/python
import json
import logging
import sys
import requests
from colour import Color
from pyjecteur.fixtures import Blinder, LedBar48Ch, Tradi, Wash, Lyre
from pyjecteur.lights import Universe
from pyjecteur.widget import Widget
if False: # True: # True:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
w = Widget("/dev/ttyUSB0")
DIM = {
"blinder": 0.1,
"led_tub": 0.3,
"spot": 0.3,
}
u = Universe(w)
def strToProj(s):
match s:
case "spot":
return Tradi()
case "led_tub":
return LedBar48Ch()
case "blinder":
return LedBar48Ch()
r = requests.get("https://agb.hackens.org/api-docs/patch.json")
patch = r.json()
lights = {}
update = {}
current_addr = 0
for k, v in patch["lights"].items():
lights[k] = strToProj(v["kind"])
u.register(lights[k], v["channels"][0]*3)
print(v["kind"], v["channels"])
# update dmx since some params are set before
lights[k].update_dmx()
logging.info(
f"Light {k} of kind {v['kind']} is at DMX{v['channels'][0]*3+1} (PLS convention)"
)
for i, chan in enumerate(v["channels"]):
update[chan] = (k, i) # put the light name
current_addr += lights[k].address_size
l = Lyre()
u.register(l, 489)
def update_light(address, red, green, blue):
if address not in update:
return
light, chan = update[address]
kind = patch["lights"][light]["kind"]
r, g, b = red * DIM[kind] / 255, (green * DIM[kind]) / 255, (blue * DIM[kind]) / 255
match kind:
case "blinder":
lights[light].colors[chan] = Color(rgb=(r, g, b))
case "led_tub":
lights[light].colors[chan] = Color(rgb=(r, g, b))
case "spot":
lights[light].color = Color(rgb=(r, g, b))
def run():
logging.info("Started")
bump = False
bump_color = None
for line in sys.stdin:
logging.debug(line)
if line.startswith("data:"):
dataStr = line[5:]
logging.info(f"Received: {dataStr}")
data = json.loads(dataStr)
if data["type"] == "Color":
if data["address"] == 90:
r, g, b = data["value"]["red"] /255, data["value"]["green"] /255, data["value"]["blue"] /255
w.color = Color(rgb = (r, g, b))
else:
update_light(data["address"], **data["value"])
else:
l.pan = data["pan"]
l.tilt = data["tilt"]
l.dimmer = data["focus"]
l.color = data["white_button"] *7 + 3
run()

View file

@ -1,11 +0,0 @@
{
pkgs,
config,
lib,
...
}: {
age.secrets."wg" = {
file = ./wg.age;
owner = "systemd-network";
};
}

View file

@ -1,9 +0,0 @@
let
lib = (import <nixpkgs> {}).lib;
readPubkeys = user:
builtins.filter (k: k != "") (lib.splitString "\n"
(builtins.readFile (../../../pubkeys + "/${user}.keys")));
in {
"wg.age".publicKeys = (readPubkeys "catvayor") ++ (readPubkeys "sinavir") ++ (readPubkeys "agb01");
}

View file

@ -1,11 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 5rrg4g Q11014nLdGOukZJV5enI4qoAqDrysWAxYtRN7VTSnTA
oEK2C8A28KrNh4WNcGGQNB9/3ADNHgGxTzOegL49TT8
-> ssh-ed25519 JGx7Ng NH6IB+2tB8fyvE81GF7p8SflY7HH2R3uvx9xC/5HFyQ
4x0x1L0wv6+k04ESLIy+qY/RhVCWtOeyETo1FkAK+8A
-> ssh-ed25519 kXobKQ 7J0f+l8+/mNQ7q8nW0jcg2LqGDARN1K63IJttdQ7JQw
SfFDS4HgjYkp+vGmCwy0c5GIqqWcc4m7mRVQmcsW/pM
-> ssh-ed25519 OZDL4Q M3Lztf8lPH4G7a+QPMY32u3UyhcHMoC08ZRV5UE6Gmo
Kc7116r+3+xa2qRSe22lctbTd/a133tVZzLkWt0XI6k
--- lsOrVi/OJ6AxtmEbB67VKvlFlDnt+sdv1TucqWqGk2w
õnDÜg4ܲ¯*ßM<C39F>!ÙY¿™hA<68>š6‡IÝbFgö{3¢*7d¤¤¦A¬:¼×Ȫ á“±½}ÀˆÝ+lu·¨9Þê

View file

@ -1,14 +0,0 @@
{ ... }:
{
users = {
mutableUsers = false;
users = {
root.openssh.authorizedKeys.keyFiles = [
../../pubkeys/sinavir.keys
../../pubkeys/catvayor.keys
../../pubkeys/soyouzpanda.keys
../../pubkeys/sel.keys
];
};
};
}

View file

@ -1,38 +0,0 @@
{ config, pkgs, lib, modulesPath, ... }:
let
agb-control-box = pkgs.callPackage ./agb { };
in
{
imports = [
"${modulesPath}/installer/sd-card/sd-image-aarch64.nix"
./secrets
./networking.nix
./users.nix
];
sdImage.compressImage = false;
services = {
getty.autologinUser = "root";
openssh.enable = true;
};
networking.hostName = "agb02";
networking.networkmanager.enable = true;
environment.systemPackages = [
agb-control-box
pkgs.libgpiod
];
systemd.services."agb-control-box" = {
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
unitConfig.Description = "The program of the control-box";
serviceConfig = {
Restart = "always";
ExecStart = "${agb-control-box}/bin/agb /dev/gpiochip0";
};
};
system.stateVersion = "24.11";
}

View file

@ -1,214 +0,0 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <gpiod.hpp>
#include <iostream>
#include <fstream>
#include <thread>
using namespace std::literals::chrono_literals;
constexpr std::chrono::microseconds debounce = 40ms;
constexpr std::chrono::microseconds poll_period = 5ms;
constexpr std::chrono::microseconds autorepeat_delay = 70ms;
constexpr std::chrono::microseconds server_ratelimit = 50ms;
constexpr std::chrono::microseconds retry_timeout = 500ms;
constexpr double joystick_movement = 0.2;
const gpiod::line::offsets drive_down = { 21, 13, 6 };
const gpiod::line::offsets decoder = { 3, 4, 17, 27, 24, 23, 18, 2 }; // lsbf
const gpiod::line::offsets joystick = { 19, 26, 5, 0 }; // x+, y+, x-, y-
const gpiod::line::offset black_button = 20;
const gpiod::line::offset white_button = 16;
const gpiod::line_settings input_settings =
gpiod::line_settings()
.set_direction(gpiod::line::direction::INPUT)
.set_bias(gpiod::line::bias::PULL_UP)
.set_active_low(false)
.set_debounce_period(debounce);
constexpr std::array<uint8_t, 256> decoder_table =
#include "decoder_table.inl"
uint8_t read_decoder_realpos(gpiod::line_request& line_reader){
static gpiod::line::values decoder_read(8);
line_reader.get_values(decoder, decoder_read);
uint8_t graycode = 0;
for(uint8_t i = 0; i < 8; ++i) graycode |= uint8_t(decoder_read[i]) << i;
return decoder_table[graycode];
};
inline void clamp_decoder(uint8_t& decoder, int move){
decoder = uint8_t(std::clamp(decoder + move, 0, 255));
}
int main(const int argc, char const* const* const argv) {
if(argc < 2) {
std::cerr << "usage: agb gpiodevice" << std::endl;
return 1;
}
/// init gpio chip ///
gpiod::chip chip(argv[1]);
gpiod::line_request line_reader =
chip.prepare_request()
.set_consumer("AGB")
.add_line_settings(drive_down,
gpiod::line_settings()
.set_direction(gpiod::line::direction::OUTPUT)
.set_drive(gpiod::line::drive::OPEN_DRAIN)
.set_output_value(gpiod::line::value::INACTIVE)
)
.add_line_settings({ black_button, white_button }, input_settings)
.add_line_settings(joystick,
gpiod::line_settings(input_settings)
.set_active_low(true))
.add_line_settings(decoder,
gpiod::line_settings(input_settings)
.set_debounce_period(0ms))
.do_request();
// let the settings apply
std::this_thread::sleep_for(poll_period);
/// internal state and buffers ///
std::chrono::time_point now = std::chrono::system_clock::now();
gpiod::line::values joystick_read(4);
gpiod::line::values joystick_last_read(4);
line_reader.get_values(joystick, joystick_read);
std::vector<std::chrono::time_point<std::chrono::system_clock>> rising_point = { now, now, now, now };
std::pair<double, double> spot_pos(0.0, 0.0); //TODO: init from server
auto joystick_move = [&](int i) -> double {
if (! bool(joystick_read[i]))
return 0.0;
else if (bool(joystick_last_read[i])){
if (now - rising_point[i] < autorepeat_delay)
return 0.0;
else
return joystick_movement;
} else {
rising_point[i] = now;
return 1.0;
}
};
uint8_t decoder_pos = 0; //TODO: init from server
uint8_t decoder_realpos = read_decoder_realpos(line_reader);
uint8_t white_state = 0;
bool white_pressed = false;
bool black_pressed = false;
bool has_changed = true;
std::chrono::time_point last_send = now;
std::string postData;
/// init server communication ///
int socket_file_desc;
connection:
socket_file_desc = socket(AF_INET, SOCK_STREAM, 0);
{
sockaddr_in socket_addr = {
.sin_family = AF_INET,
.sin_port = htons(1235),
.sin_addr = { .s_addr = inet_addr("10.10.10.1") }
};
while (connect(socket_file_desc,
reinterpret_cast<const sockaddr*>(&socket_addr),
sizeof(socket_addr)) < 0) {
std::cerr << "Failed to open tcp socket, retrying..." << std::endl;
std::this_thread::sleep_for(retry_timeout);
}
std::cout << "Connected." << std::endl;
}
for(;;){
std::this_thread::sleep_for(poll_period);
now = std::chrono::system_clock::now();
/// joystick ///
std::swap(joystick_read, joystick_last_read);
line_reader.get_values(joystick, joystick_read);
spot_pos.first += joystick_move(0);
spot_pos.second += joystick_move(1);
spot_pos.first -= joystick_move(2);
spot_pos.second -= joystick_move(3);
if (bool(joystick_read[0]) || bool(joystick_read[1])
|| bool(joystick_read[2]) || bool(joystick_read[3])){
spot_pos.first = std::clamp(spot_pos.first, 0.0, 255.0);
spot_pos.second = std::clamp(spot_pos.second, 0.0, 255.0);
has_changed = true;
}
/// Buttons ///
bool pressed = bool(line_reader.get_value(black_button));
if(pressed ^ black_pressed)
has_changed = true;
black_pressed = pressed;
pressed = bool(line_reader.get_value(white_button));
if(pressed && !white_pressed){
has_changed = true;
white_state = (white_state + 1)%9;
}
white_pressed = pressed;
/// decoder ///
uint8_t new_realpos = read_decoder_realpos(line_reader);
uint8_t seen_travel = std::abs(int(new_realpos) - int(decoder_realpos));
// CCW
if(seen_travel < 50 && new_realpos < decoder_realpos)
clamp_decoder(decoder_pos, -seen_travel);
if(seen_travel >= 50 && new_realpos > decoder_realpos)
clamp_decoder(decoder_pos, seen_travel - 128);
// CW
if(seen_travel < 50 && new_realpos > decoder_realpos)
clamp_decoder(decoder_pos, seen_travel);
if(seen_travel >= 50 && new_realpos < decoder_realpos)
clamp_decoder(decoder_pos, 128 - seen_travel);
decoder_realpos = new_realpos;
if(seen_travel)
has_changed = true;
/// server notification
if(has_changed && (now - last_send > server_ratelimit)){
postData.clear();
std::format_to(std::back_inserter(postData), "{{"
"\"pan\": {},"
"\"tilt\": {},"
"\"focus\": {},"
"\"white_button\": {},"
"\"black_button\": {}"
"}}\n",
uint8_t(spot_pos.first),
uint8_t(spot_pos.second),
int(decoder_pos),
white_state,
black_pressed
);
int wrote = write(socket_file_desc, postData.data(), postData.size());
if(wrote < postData.size()){
std::cerr << "Failed to send data, reconnecting..." << std::endl;
close(socket_file_desc);
std::this_thread::sleep_for(retry_timeout);
goto connection;
} else {
has_changed = false;
last_send = now;
}
}
}
}

View file

@ -1,132 +0,0 @@
[]() {
std::array<uint8_t, 256> table;
table[127] = 0;
table[63] = 1;
table[62] = 2;
table[58] = 3;
table[56] = 4;
table[184] = 5;
table[152] = 6;
table[24] = 7;
table[8] = 8;
table[72] = 9;
table[73] = 10;
table[77] = 11;
table[79] = 12;
table[15] = 13;
table[47] = 14;
table[175] = 15;
table[191] = 16;
table[159] = 17;
table[31] = 18;
table[29] = 19;
table[28] = 20;
table[92] = 21;
table[76] = 22;
table[12] = 23;
table[4] = 24;
table[36] = 25;
table[164] = 26;
table[166] = 27;
table[167] = 28;
table[135] = 29;
table[151] = 30;
table[215] = 31;
table[223] = 32;
table[207] = 33;
table[143] = 34;
table[142] = 35;
table[14] = 36;
table[46] = 37;
table[38] = 38;
table[6] = 39;
table[2] = 40;
table[18] = 41;
table[82] = 42;
table[83] = 43;
table[211] = 44;
table[195] = 45;
table[203] = 46;
table[235] = 47;
table[239] = 48;
table[231] = 49;
table[199] = 50;
table[71] = 51;
table[7] = 52;
table[23] = 53;
table[19] = 54;
table[3] = 55;
table[1] = 56;
table[9] = 57;
table[41] = 58;
table[169] = 59;
table[233] = 60;
table[225] = 61;
table[229] = 62;
table[245] = 63;
table[247] = 64;
table[243] = 65;
table[227] = 66;
table[163] = 67;
table[131] = 68;
table[139] = 69;
table[137] = 70;
table[129] = 71;
table[128] = 72;
table[132] = 73;
table[148] = 74;
table[212] = 75;
table[244] = 76;
table[240] = 77;
table[242] = 78;
table[250] = 79;
table[251] = 80;
table[249] = 81;
table[241] = 82;
table[209] = 83;
table[193] = 84;
table[197] = 85;
table[196] = 86;
table[192] = 87;
table[64] = 88;
table[66] = 89;
table[74] = 90;
table[106] = 91;
table[122] = 92;
table[120] = 93;
table[121] = 94;
table[125] = 95;
table[253] = 96;
table[252] = 97;
table[248] = 98;
table[232] = 99;
table[224] = 100;
table[226] = 101;
table[98] = 102;
table[96] = 103;
table[32] = 104;
table[33] = 105;
table[37] = 106;
table[53] = 107;
table[61] = 108;
table[60] = 109;
table[188] = 110;
table[190] = 111;
table[254] = 112;
table[126] = 113;
table[124] = 114;
table[116] = 115;
table[112] = 116;
table[113] = 117;
table[49] = 118;
table[48] = 119;
table[16] = 120;
table[144] = 121;
table[146] = 122;
table[154] = 123;
table[158] = 124;
table[30] = 125;
table[94] = 126;
table[95] = 127;
return table;
} ();

View file

@ -1,15 +0,0 @@
{ stdenv, libgpiod }:
stdenv.mkDerivation rec {
pname = "agb";
version = "oct-24";
src = ./.;
buildPhase = ''
g++ --std=c++23 agb.cpp -o agb \
-L${libgpiod}/lib -lgpiodcxx -I${libgpiod}/include \
'';
installPhase = ''
mkdir -p $out/bin
cp agb $out/bin
'';
}

View file

@ -1,47 +0,0 @@
{
config,
lib,
pkgs,
...
}: {
systemd.network = {
enable = true;
networks = {
"50-wg0" = {
name = "wg0";
address = [
"10.10.10.6/24"
];
};
};
netdevs = {
"50-wg0" = {
netdevConfig = {
Name = "wg0";
Kind = "wireguard";
};
wireguardConfig.PrivateKeyFile = config.age.secrets."wg".path;
wireguardPeers = [
{
AllowedIPs = [
"10.10.10.0/24"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/hackens-org.pub);
Endpoint = "129.199.129.76:1194";
PersistentKeepalive = 5;
}
];
};
};
};
networking = {
nameservers = [
"2620:fe::fe"
"2620:fe::9"
"9.9.9.9"
"149.112.112.112"
];
};
}

View file

@ -1,11 +0,0 @@
{
pkgs,
config,
lib,
...
}: {
age.secrets."wg" = {
file = ./wg.age;
owner = "systemd-network";
};
}

View file

@ -1,8 +0,0 @@
let
lib = (import <nixpkgs> {}).lib;
readPubkeys = user:
builtins.filter (k: k != "") (lib.splitString "\n"
(builtins.readFile (../../../pubkeys + "/${user}.keys")));
in {
"wg.age".publicKeys = (readPubkeys "catvayor") ++ (readPubkeys "sinavir") ++ (readPubkeys "agb02");
}

Binary file not shown.

View file

@ -1,14 +0,0 @@
{ ... }:
{
users = {
mutableUsers = false;
users = {
root.openssh.authorizedKeys.keyFiles = [
../../pubkeys/sinavir.keys
../../pubkeys/catvayor.keys
../../pubkeys/soyouzpanda.keys
../../pubkeys/sel.keys
];
};
};
}

View file

@ -5,32 +5,28 @@
{ config, pkgs, ... }:
{
imports = [
imports =
[
# Include the results of the hardware scan.
./hardware-configuration.nix
./aarch64.nix
./audio.nix
./dns
./gnome.nix
./i18n.nix
./no-sleep.nix
./programs.nix
./system.nix
./users.nix
./vim.nix
./pixiecore
./networking.nix
./secrets
./shared-hackens
];
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot = {
enable = true;
};
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.efiSupport = true;
boot.loader.grub.efiInstallAsRemovable = true;
boot.loader.efi.efiSysMountPoint = "/boot";
boot.loader.grub.device = "nodev"; # or "nodev" for efi only
boot.loader.grub.configurationLimit = 2;
networking.hostName = "hackens-milieu"; # Define your hostname.
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.kernelParams = [
];
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
# Per-interface useDHCP will be mandatory in the future, so this generated config
# replicates the default behaviour.
@ -45,3 +41,4 @@
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "20.09"; # Did you read the comment?
}

View file

@ -1,5 +0,0 @@
{ pkgs, ... }:
{
# Enable sound.
# hardware.pulseaudio.enable = true;
}

View file

@ -1,6 +0,0 @@
{ pkgs, ... }:
{
imports =
[
];
}

View file

@ -1,49 +1,36 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
{
imports = [
imports =
[
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [
"ehci_pci"
"ahci"
"usbhid"
"sd_mod"
"sr_mod"
];
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# boot.kernelParams = [ "nomodeset" ];
fileSystems."/" = {
fileSystems."/" =
{
device = "/dev/disk/by-label/nixos-root";
fsType = "btrfs";
options = [
"ssd"
"noatime"
"ssd_spread"
"discard"
"space_cache"
];
options = [ "ssd" "noatime" "ssd_spread" "discard" "space_cache" ];
};
fileSystems."/boot" = {
fileSystems."/boot" =
{
device = "/dev/disk/by-label/BOOT";
fsType = "vfat";
};
swapDevices = [ { device = "/dev/disk/by-label/SWAP"; } ];
swapDevices =
[{ device = "/dev/disk/by-label/SWAP"; }];
nix.maxJobs = lib.mkDefault 4;
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";

View file

@ -1,33 +0,0 @@
{ lib, config, ... }: {
systemd.network = {
enable = true;
networks."50-wg0" = {
name = "wg0";
address = [
"10.10.10.4/24"
];
};
netdevs = {
"50-wg0" = {
netdevConfig = {
Name = "wg0";
Kind = "wireguard";
};
wireguardConfig.PrivateKeyFile = config.age.secrets."wg".path;
wireguardPeers = [
{
AllowedIPs = [
"10.10.10.0/24"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/hackens-org.pub);
Endpoint = "129.199.129.76:1194";
PersistentKeepalive = 5;
}
];
};
};
};
}

View file

@ -1,16 +0,0 @@
{ pkgs, config, ... }:
let
netboot_efi = pkgs.fetchurl rec {
version = "2.0.82";
url = "https://github.com/netbootxyz/netboot.xyz/releases/download/${version}/netboot.xyz.efi";
hash = "sha256-cO8MCkroQ0s/j8wnwwIWfnxEvChLeOZw+gD4wrYBAog=";
};
in
{
services.pixiecore = rec {
enable = true;
openFirewall = true;
kernel = "${netboot_efi}";
extraArguments = [ "-d" "--ipxe-efi64" "${kernel}" ];
};
}

View file

@ -1,11 +0,0 @@
{
pkgs,
config,
lib,
...
}: {
age.secrets."wg" = {
file = ./wg.age;
owner = "systemd-network";
};
}

View file

@ -1,8 +0,0 @@
let
lib = (import <nixpkgs> {}).lib;
readPubkeys = user:
builtins.filter (k: k != "") (lib.splitString "\n"
(builtins.readFile (../../../pubkeys + "/${user}.keys")));
in {
"wg.age".publicKeys = (readPubkeys "catvayor") ++ (readPubkeys "sinavir") ++ (readPubkeys "hackens-milieu");
}

View file

@ -1,12 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 5rrg4g B36oMQ2IqhBXDaltfkba8gBjhTzHujh/KtpXmoBfIkE
ga5w9MzfwR2LwlSmeA0ddyx2Fms/ZSp1c8p/rC46OSE
-> ssh-ed25519 JGx7Ng wis78jvQlXpeK0rb50RNgliWwVaPqUYR66Dfxxq8+nk
awK/Il5jYV2s95GxDLkeRas0PjDKKnVE2HjKTOFyQco
-> ssh-ed25519 kXobKQ gYW3wXPQr756wsRQ6nKo4qQtT09OaEsnQmAX4G41PXQ
sa8Bhxfosqf1VNXfj+rS2ryJs9T4sZK13tx5j+NOCm4
-> ssh-ed25519 Dx1R2Q 2BLCykYc4lKLyBnDfJ6J7ZCD8CeX3vt2S2fLkwjeunw
ueU6TaxgeX9Cp98LkHy5pkaUaRGdcTHtV8CopEILv10
--- Ah6a49hN7wxxfR8C8Jczc/2jMAoTJoumYMj4PPKax2I
î)Bš+£Ín
c™ï<EFBFBD>ÁY<EFBFBD>ú-l™k<E284A2>ÛMF+ÞÙ<C39E>r1)æÞ¸aU=<3D>}%\õÔ²¶ =W~ã)Àp6nÜG%ð*ðâšk> ä

View file

@ -0,0 +1,6 @@
{ pkgs, ... }:
{
# Enable sound.
sound.enable = true;
hardware.pulseaudio.enable = true;
}

View file

@ -0,0 +1,14 @@
{ pkgs, ... }: {
imports = [
./aarch64.nix
./audio.nix
./dns
./gnome.nix
./i18n.nix
./no-sleep.nix
./programs.nix
./system.nix
./users.nix
./vim.nix
];
}

View file

@ -6,10 +6,7 @@ let
in
{
networking = {
nameservers = [
"127.0.0.1"
"::1"
];
nameservers = [ "127.0.0.1" "::1" ];
};
services.dnscrypt-proxy2 = {
@ -20,13 +17,9 @@ in
forwarding_rules = ./forwarding.txt;
query_log =
if debugDNS then
{
query_log = if debugDNS then {
file = "/dev/stdout";
}
else
{ };
} else {};
sources.public-resolvers = {
urls = [

View file

@ -1,5 +1,4 @@
{ pkgs, ... }:
{
{ pkgs, ... }: {
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";

View file

@ -1,5 +1,4 @@
{ ... }:
{
{ ... }: {
systemd.targets = {
sleep.enable = false;
suspend.enable = false;

View file

@ -16,7 +16,6 @@
vscodium
emacs
neovim
arduino
smartmontools
wget
@ -29,7 +28,6 @@
dnsutils
ncdu
lazygit
alacritty
# Networking
speedtest-cli
@ -37,10 +35,6 @@
# Serial
minicom
tio
# Deploy
colmena
];
programs.chromium = {

View file

@ -1,5 +1,4 @@
{ pkgs, ... }:
{
{ pkgs, ... }: {
# Upgrades
system.autoUpgrade = {
enable = true;
@ -13,10 +12,8 @@
# Auto-GC and store optimizations
nix = {
trustedUsers = [
"root"
"hackens"
];
trustedUsers = [ "root" "hackens" ];
package = pkgs.nixUnstable;
gc = {
automatic = true;
dates = "weekly";

View file

@ -1,24 +1,16 @@
{ pkgs, ... }:
let
superadmins = [
../../pubkeys/raito.keys
../../pubkeys/gdd.keys
../../pubkeys/BiBi.keys
../../pubkeys/sinavir.keys
../../pubkeys/soyouzpanda.keys
../../pubkeys/catvayor.keys
../../pubkeys/sel.keys
../../../pubkeys/raito.keys
../../../pubkeys/gdd.keys
../../../pubkeys/BiBi.keys
../../../pubkeys/sinavir.keys
];
in
{
users.users.hackens = {
isNormalUser = true;
extraGroups = [
"wheel"
"dialout"
"audio"
"video"
];
extraGroups = [ "wheel" "dialout" "audio" "video" ];
openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDcKULx/AgnqBsgwRX2BfV8waq6JXIkvZHhu9Y8paofM8awq6Om56BZoA7AV45YOcJxO/eFDOxSegXXmt22s4WjIf8I049aMdsW54BNpFpC/h18cMzm5ylKVGHl1ier/WXxpBsA8YU++YdRlGHPpKnhCtYLnBzD4Q5h+05GMIHismNZP1aGpE9s01FuP8eaDDkZUba7oSpn03AA77DBw4/2ZreSbqo96Z6WwiG09KeZvxFtEIk98EQtmiExB2fwsK3/JIxIBCoZHh4SzERcslxxGgzdppd6NhhSh7g523zhiihLaTAPNXBovGm5wcKOU9uWe+pUWEbwV04E+809aVbkJOdYBCtIf8M91meqpupA8jK38uquePHEFvpNr5UmY0qUlJCoqTvoqg9XgrfJVjlPEmYknj/QjQzkA4k19y8njsyEjnYOBL6tsztg6Igl+NZXjBAPuAzxCsfHOtWw1WM5gANwqOL0V9f7+14yST3HwweqjHRj4xky6ritxK+ujfc= hackens@hackens-desktop"
@ -29,4 +21,5 @@ in
users.users.root = {
openssh.authorizedKeys.keyFiles = superadmins;
};
}

View file

@ -1,7 +1,6 @@
{ pkgs, ... }:
{
{ pkgs, ... }: {
environment.systemPackages = with pkgs; [
nixfmt-rfc-style
nixfmt
git
(neovim.override {
vimAlias = true;

View file

@ -5,26 +5,21 @@
{ config, pkgs, ... }:
{
imports = [
imports =
[
./_bootloader.nix
./_networking.nix
./_ssh.nix
./_users.nix
./dokuwiki.nix
./thelounge.nix
./hardware-configuration.nix
./matterbridge.nix
./nginx.nix
./orga
./ragb.nix
./snipe-it.nix
./secrets
./static-sites.nix
./legacy-redir.nix
./webpass.nix
./prometheus.nix
./grafana.nix
./kfet-monitor
];
time.timeZone = "Europe/Paris";
@ -40,3 +35,4 @@
system.stateVersion = "22.11"; # Did you read the comment?
}

View file

@ -18,7 +18,7 @@
};
networks = {
"10-uplink" = {
name = "enp1s0";
name = "eth0";
DHCP = "no";
address = [
"129.199.129.76/24"
@ -38,8 +38,5 @@
};
};
};
networking.nameservers = [
"1.1.1.1"
"8.8.8.8"
];
networking.nameservers = [ "1.1.1.1" "8.8.8.8" ];
}

View file

@ -1,18 +1,11 @@
{ ... }:
{
{ ... }: {
# Enable the OpenSSH daemon.
services.openssh.enable = true;
services.openssh.settings.PasswordAuthentication = false;
services.openssh.ports = [
22
2222
];
services.openssh.ports = [ 22 2222 ];
# Open ports in the firewall. (In fact not needed)
networking.firewall.allowedTCPPorts = [
22
2222
];
networking.firewall.allowedTCPPorts = [ 22 2222 ];
# Mosh <3
programs.mosh.enable = true;

View file

@ -1,12 +1,12 @@
{ ... }:
{
{ ... }: {
users = {
mutableUsers = false;
users = {
rlahfa = {
isNormalUser = true;
extraGroups = [ "wheel" ];
hashedPassword = "$6$y/I6nKCMYUku7$91vTR5kYz4nHyhbuA/j6kPsD8Vfo/Rg7ri6Ympftra9V6emOt/mPg0AScECtYjSIxretvfQ3sPUF1Ho0IWx381";
hashedPassword =
"$6$y/I6nKCMYUku7$91vTR5kYz4nHyhbuA/j6kPsD8Vfo/Rg7ri6Ympftra9V6emOt/mPg0AScECtYjSIxretvfQ3sPUF1Ho0IWx381";
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/raito.keys ];
};
gdoriathdohler = {
@ -17,15 +17,10 @@
mdebray = {
isNormalUser = true;
extraGroups = [ "wheel" ];
hashedPassword = "$6$ujz06kXa4TgvPAbF$NaXkDuOUpf3.fBRh7JuygtS0V2U/Bz4N3DpbOznO.md44xEdlKwPH/pSbL9CQJBhI5kodaKZeSaoCyhzybBPA/";
hashedPassword =
"$6$ujz06kXa4TgvPAbF$NaXkDuOUpf3.fBRh7JuygtS0V2U/Bz4N3DpbOznO.md44xEdlKwPH/pSbL9CQJBhI5kodaKZeSaoCyhzybBPA/";
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/sinavir.keys ];
};
ecoppens = {
isNormalUser = true;
extraGroups = [ "wheel" ];
hashedPassword = "$2b$05$c7kIDOunRJvgncWq5pmbXupy/wzUzCvN3b/RHgl/BjlUw891wI.Oa";
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/soyouzpanda.keys ];
};
hbarral = {
isNormalUser = true;
extraGroups = [ "wheel" ];
@ -34,9 +29,6 @@
root.openssh.authorizedKeys.keyFiles = [
../../pubkeys/beigbeder.keys
../../pubkeys/sinavir.keys
../../pubkeys/soyouzpanda.keys
../../pubkeys/catvayor.keys
../../pubkeys/sel.keys
];
};
};

View file

@ -1,10 +1,4 @@
{
config,
pkgs,
lib,
...
}:
{
{ config, pkgs, lib, ... }: {
services.nginx.virtualHosts."hackens.org" = {
enableACME = true;

View file

@ -1,91 +0,0 @@
{
pkgs,
lib,
config,
...
}:
let
src = pkgs.fetchgit {
url = "https://git.rz.ens.wtf/HackENS/gestiojeux.git";
rev = "HEAD";
hash = "sha256-ly786xct9U4hdsHr7NLl23smnOfE891au9/GXqxpFb4=";
};
in
{
imports =
[
];
systemd.services.django-gestiohackens.serviceConfig = {
DynamicUser = lib.mkForce false;
User = "django-gestiohackens";
SupplementaryGroups = [ "nginx" ];
};
users.users.django-gestiohackens = {
group = "django-gestiohackens";
isSystemUser = true;
};
users.groups.django-gestiohackens = { };
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts."inventaire.hackens.org" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
proxyPass = "http://localhost:51667";
};
"/media/".alias = "/var/lib/django-gestiohackens/media/";
"/static".root = config.services.django.gestiohackens.staticAssets;
};
};
};
services.django.gestiohackens = {
inherit src;
enable = true;
mainModule = "gestiojeux";
port = 51667;
settings = {
DEBUG = false;
CSRF_COOKIE_SECURE = true;
AUTHENS_ALLOW_STAFF = true;
SESSION_COOKIE_SECURE = true;
MEDIA_URL = "media/";
ALLOWED_HOSTS = [ "inventaire.hackens.org" ];
DATABASES = {
"default" = {
"ENGINE" = "django.db.backends.sqlite3";
"NAME" = "/var/lib/django-gestiohackens/db.sqlite3";
};
};
HAYSTACK_CONNECTIONS = {
"default" = {
"ENGINE" = "haystack.backends.whoosh_backend.WhooshEngine";
"PATH" = "/var/lib/django-gestiohackens/whoosh_index";
};
};
MEDIA_ROOT = "/var/lib/django-gestiohackens/media";
};
extraPackages = ps: [
ps.django-autoslug
ps.loadcredential
ps.django-cleanup
ps.django-haystack
ps.django-markdownx
ps.django-tables2
ps.pillow
ps.whoosh
ps.markdown-icons
ps.authens
ps.qrcode
ps.pillow
# Django haystack is drunk
ps.setuptools
];
secrets = {
SECRET_KEY = config.age.secrets.django-gestiohackens.path;
};
};
}

View file

@ -1,59 +0,0 @@
{ config, ... }:
let
host = "grafana.hackens.org";
port = 3033;
in
{
services = {
grafana = {
enable = true;
settings = {
database = {
type = "postgres";
user = "grafana";
host = "/run/postgresql";
};
server = {
domain = host;
enable_gzip = true;
enforce_domain = true;
http_port = port;
root_url = "https://${host}";
router_logging = true;
};
users = {
default_theme = "system";
default_language = "en-GB";
};
};
};
postgresql = {
enable = true;
ensureDatabases = [ "grafana" ];
ensureUsers = [
{
name = "grafana";
ensureDBOwnership = true;
}
];
};
nginx.virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
recommendedProxySettings = true;
};
};
};
}

View file

@ -1,39 +1,32 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{
config,
lib,
pkgs,
modulesPath,
...
}:
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
imports =
[
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [
"uhci_hcd"
"ahci"
"virtio_pci"
"virtio_blk"
];
boot.initrd.availableKernelModules = [ "uhci_hcd" "ahci" "virtio_pci" "virtio_blk" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
fileSystems."/" =
{
device = "/dev/disk/by-uuid/8deb32c9-ee6a-4de8-94da-239c8ec509a2";
fsType = "btrfs";
};
fileSystems."/boot" = {
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/0795-75ED";
fsType = "vfat";
};
swapDevices = [ { device = "/dev/disk/by-uuid/bd7c1c01-ce31-4db3-9c06-70716020e24a"; } ];
swapDevices =
[{ device = "/dev/disk/by-uuid/bd7c1c01-ce31-4db3-9c06-70716020e24a"; }];
}

View file

@ -1,25 +0,0 @@
{ lib, pkgs, ... }:
let
wsScraper = pkgs.callPackage ./websocket-exporter.nix { };
in
{
systemd.services.kfet-open-recorder = {
environment = {
WEBSOCKET_EXPORTER_URI = "wss://cof.ens.fr/ws/k-fet/open";
WEBSOCKET_EXPORTER_MATCH_TYPE = "contains";
WEBSOCKET_EXPORTER_EXPECTED_MESSAGE = "open";
WEBSOCKET_EXPORTER_LISTEN_ADDR = "127.0.0.1";
};
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
wants = [ "network.target" ];
serviceConfig = {
ExecStart = "${lib.getExe wsScraper}";
Restart = "always";
RestartSec = 5;
DynamicUser = true;
StateDirectory = "kfet-open-recorder";
};
};
}

View file

@ -1,61 +0,0 @@
diff --git a/websocket_exporter/probe.py b/websocket_exporter/probe.py
index a95b97e..a7b057e 100644
--- a/websocket_exporter/probe.py
+++ b/websocket_exporter/probe.py
@@ -3,28 +3,29 @@ import logging
from time import perf_counter
from typing import Union
-from websockets import NegotiationError, client, InvalidStatusCode
+from websockets import InvalidStatusCode, NegotiationError, client
-
-EXACT_MATCH = 'exact'
-CONTAINS_MATCH = 'contains'
+EXACT_MATCH = "exact"
+CONTAINS_MATCH = "contains"
class ProbResults(object):
def __init__(self, up: int, latency: float = 0, received: int = 0):
self.up = up
self.latency = round(latency, 2)
- self.received = int(received) if received is not None else "NaN"
+ self.received = int(received) if received is not None else 0
def __str__(self):
if self.up:
return f'Websocket up, latency:{self.latency}s, expected response {"" if self.received else "NOT"} received'
- return f'Webserver DOWN'
+ return f"Webserver DOWN"
class WebSocketProbe(object):
- def __init__(self, uri, message=None, expected=None, match=CONTAINS_MATCH, timeout=10):
+ def __init__(
+ self, uri, message=None, expected=None, match=CONTAINS_MATCH, timeout=10
+ ):
"""
Create a websocket probe that tries establishing a connection and reports the metrics
:param uri: starts with 'ws://' or ws://
@@ -68,13 +69,17 @@ class WebSocketProbe(object):
elapsed = 0
while elapsed < self.timeout:
try:
- resp = await asyncio.wait_for(connection.recv(), timeout=(self.timeout-elapsed))
+ resp = await asyncio.wait_for(
+ connection.recv(), timeout=(self.timeout - elapsed)
+ )
if self._match(resp):
return True
await asyncio.sleep(1)
elapsed += 1
except asyncio.TimeoutError:
- logging.info(f'Time out while waiting for {self.expected_message} from {self.uri}')
+ logging.info(
+ f"Time out while waiting for {self.expected_message} from {self.uri}"
+ )
return None
return None

View file

@ -1,40 +0,0 @@
{
lib,
python3,
fetchFromGitHub,
}:
python3.pkgs.buildPythonApplication rec {
pname = "blackbox-websocket-exporter";
version = "unstable-2021-12-15";
pyproject = true;
src = fetchFromGitHub {
owner = "smohsensh";
repo = "blackbox-websocket-exporter";
rev = "6f9f32396f740fe606bf1b0118a27ad5caa3d9a6";
hash = "sha256-+G7xw5631TllDGNzVK9swbSNfVu4r4glbYIblEa0WqA=";
};
patches = [
./patch
];
nativeBuildInputs = [
python3.pkgs.setuptools
python3.pkgs.wheel
];
propagatedBuildInputs = with python3.pkgs; [
prometheus-client
websockets
];
meta = with lib; {
description = "A Blackbox Websocket Uptime Exporter for Prometheus";
homepage = "https://github.com/smohsensh/blackbox-websocket-exporter";
license = licenses.mit;
maintainers = with maintainers; [ ];
mainProgram = "websocket_exporter";
};
}

View file

@ -1,9 +1,4 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
let
port = 52187;
configFile = pkgs.writeText "metterbridge.toml" ''
@ -42,6 +37,7 @@ in
${pkgs.matterbridge}/bin/matterbridge -conf ${configFile}
'';
serviceConfig = {
User = "matterbridge";
Group = "matterbridge";

View file

@ -1,24 +1,12 @@
{
python-cas,
django,
ldap,
buildPythonPackage,
}:
{ lib, pythoncas, django, ldap, buildPythonPackage }:
buildPythonPackage rec {
pname = "authens";
version = "v0.1b5";
doCheck = false;
patches = [
./01-get-success_url.patch
];
src = builtins.fetchGit {
url = "https://git.eleves.ens.fr/klub-dev-ens/authens.git";
#rev = "master";
#sha256 = "sha256-R0Nw212/BOPHfpspT5wzxtji1vxZ/JOuwr00naklWE8=";
};
propagatedBuildInputs = [
django
ldap
python-cas
];
propagatedBuildInputs = [ django ldap pythoncas ];
}

View file

@ -1,23 +1,22 @@
{
pkgs,
lib,
config,
...
}:
{ pkgs, lib, config, ... }:
let
src = pkgs.fetchgit {
assets = import ./mkAssets.nix {
inherit pkgs;
app = "hackens_orga";
settings = config.services.django.hackens_orga.settings;
source = pkgs.fetchgit {
url = "https://git.rz.ens.wtf/HackENS/hackens-orga.git";
rev = "HEAD";
hash = "sha256-BiOKGeDPVp7EV/q4S9Zc54jUeBTpfOs5e/MsCPGAk/I=";
rev = "75fe83a41f";
hash = "sha256-cfUjSfZrsMpGRO3HOWOk6zdc9+e+ZaJLiJQ5OpIKxos=";
};
};
in
{
imports =
[
imports = [
./module.nix
];
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts."hackens.org" = {
locations = {
"/orga" = {
@ -26,29 +25,18 @@ in
proxy_set_header SCRIPT_NAME /orga;
'';
};
"/static".root = config.services.django.hackens-orga.staticAssets;
"/static".root = assets.static-assets;
};
};
};
services.django.hackens-orga = {
inherit src;
services.django.hackens_orga = {
enable = true;
mainModule = "hackens_orga";
assets = assets;
settings = {
DEBUG = false;
ALLOWED_HOSTS = [ "hackens.org" ];
DATABASES = {
"default" = {
"ENGINE" = "django.db.backends.sqlite3";
"NAME" = "/var/lib/django-hackens-orga/db.sqlite3";
};
};
};
extraPackages = p: [
p.authens
];
secrets = {
SECRET_KEY = config.age.secrets.django.path;
HACKENS_ORGA_DEBUG = "0";
HACKENS_ORGA_ALLOWED_HOSTS = [ "hackens.org" ];
HACKENS_ORGA_SECRET_KEY._file = config.age.secrets.django.path;
HACKENS_ORGA_DB_FILE = "/var/lib/hackens-orga/db.sqlite3";
};
};
}

View file

@ -0,0 +1,27 @@
{ pkgs, settings, source, app }:
let
manage-py-file = "${source}/${app}/manage.py";
python = import ./python.nix { inherit pkgs; };
static-assets = pkgs.callPackage ./static-assets.nix { inherit python source app; envPrefix = "HACKENS_ORGA_"; };
mkEnv = settings: let # make env file to source before using manage.py and other commands
lib = pkgs.lib;
mkVarVal = v: let
isHasAttr = s: lib.isAttrs v && lib.hasAttr s v;
in
if builtins.isString v then v
else if builtins.isList v && lib.any lib.strings.isConvertibleWithToString v then (lib.concatMapStringsSep "," toString v)
else if builtins.isInt v then toString v
else if builtins.isBool v then toString (if v then 1 else 0)
else if isHasAttr "_file" then "$(cat ${v._file} | xargs)"
else if isHasAttr "_raw" then v._raw
else abort "The django conf value ${lib.generators.toPretty {} v} can not be encoded.";
in lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "export ${k}=${mkVarVal v}") settings);
envFile = pkgs.writeScript "django-${app}-env.sh" (mkEnv settings);
managePy = pkgs.writeScript "manage-${app}" ''
source ${envFile}
${python}/bin/python ${manage-py-file} $@
'';
in
{
inherit managePy static-assets envFile source python;
}

View file

@ -0,0 +1,65 @@
{ pkgs, lib, config, ... }:
let
app = "hackens_orga";
cfg = config.services.django.${app};
assets = cfg.assets;
in
{
options = {
services.django.${app} = {
enable = lib.mkEnableOption (lib.mdDoc "Enable django ${app}");
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = with lib.types; attrsOf anything;
options = {
HACKENS_ORGA_STATIC_ROOT = lib.mkOption {
type = lib.types.path;
default = builtins.toString assets.static-assets;
};
};
};
};
assets = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
description = lib.mdDoc "Assets for django";
};
port = lib.mkOption {
type = lib.types.port;
default = 51666;
};
processes = lib.mkOption {
type = lib.types.int;
default = 2;
};
threads = lib.mkOption {
type = lib.types.int;
default = 2;
};
};
};
config = lib.mkIf cfg.enable {
systemd.services."django-${app}" = {
description = "${app} django service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
User = "django-${app}";
};
script = ''
source ${assets.envFile}
${assets.managePy} migrate
${assets.python}/bin/gunicorn ${app}.wsgi \
--pythonpath ${assets.source}/${app} \
-b 127.0.0.1:${toString cfg.port} \
--workers=${toString cfg.processes} \
--threads=${toString cfg.threads}
'';
};
users.users."django-${app}" = {
isSystemUser = true;
group = "django-${app}";
};
users.groups."django-${app}" = {};
};
}

View file

@ -1,10 +1,4 @@
{
requests,
lxml,
six,
buildPythonPackage,
fetchFromGitHub,
}:
{ lib, requests, lxml, six, buildPythonPackage, fetchFromGitHub }:
buildPythonPackage rec {
pname = "python-cas";
version = "1.6.0";
@ -15,9 +9,5 @@ buildPythonPackage rec {
rev = "v1.6.0";
sha512 = "sha512-qnYzgwELUij2EdqA6H17q8vnNUsfI7DkbZSI8CCIGfXOM+cZ7vsWe7CJxzsDUw73sBPB4+zzpLxvb7tpm/IDeg==";
};
propagatedBuildInputs = [
requests
lxml
six
];
propagatedBuildInputs = [ requests lxml six ];
}

View file

@ -0,0 +1,20 @@
{ pkgs ? import ../nix { }, debug ? false }:
let
python = pkgs.python310.override {
packageOverrides = self: super: {
django = super.django_4;
authens = self.callPackage ./authens.nix { };
pythoncas = self.callPackage ./python-cas.nix { };
};
};
in
python.withPackages (ps: [
ps.django
ps.djangorestframework
ps.authens
ps.gunicorn
] ++ pkgs.lib.optionals debug [
ps.django-debug-toolbar
ps.black
ps.isort
])

View file

@ -0,0 +1,6 @@
{ pkgs ? import ../nix { } }:
pkgs.mkShell {
buildInputs = [
(import ./python.nix { inherit pkgs; debug = true; })
];
}

View file

@ -0,0 +1,10 @@
{ pkgs, python, source, app, envPrefix ? ""}:
pkgs.runCommand "django-static" { } ''
mkdir -p $out/static
export ${envPrefix}SECRET_KEY="collectstatic"
export ${envPrefix}STATIC_ROOT=$out/static
export ${envPrefix}DEBUG=0
export ${envPrefix}ALLOWED_HOSTS=
export ${envPrefix}DB_FILE=
${python}/bin/python ${source}/${app}/manage.py collectstatic
''

View file

@ -1,5 +1,4 @@
{ pkgs, ... }:
{
{ pkgs, ... }: {
environment.systemPackages = [
pkgs.vim
];

View file

@ -1,68 +0,0 @@
{ config, ... }:
let
host = "prometheus.hackens.org";
port = 9091;
in
{
services.prometheus = {
enable = true;
inherit port;
checkConfig = "syntax-only";
enableReload = true;
listenAddress = "127.0.0.1";
webConfigFile = config.age.secrets."prometheus-webconf".path;
webExternalUrl = "https://${host}";
retentionTime = "5y";
extraFlags = [ "--storage.tsdb.retention.size=2GB" ];
rules = [
''
groups:
- name: Chrony
rules:
- record: instance:chrony_clock_error_seconds:abs
expr: >
abs(chrony_tracking_last_offset_seconds)
+
chrony_tracking_root_dispersion_seconds
+
(0.5 * chrony_tracking_root_delay_seconds)
''
];
scrapeConfigs = [
{
job_name = "prometheus";
static_configs = [ { targets = [ "localhost:9090" ]; } ];
}
{
job_name = "chrony";
static_configs = [ { targets = [ "10.10.10.3:9123" ]; } ];
}
{
job_name = "kfet";
static_configs = [ { targets = [ "127.0.0.1:9802" ]; } ];
}
];
};
services.nginx.virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
recommendedProxySettings = true;
};
};
}

View file

@ -1,80 +0,0 @@
{
sources,
lib,
pkgs,
config,
...
}:
{
services.django.ragb = {
enable = true;
src = pkgs.ragb-src + "/frontend";
settings = {
DEBUG = false;
WEBSOCKET_ENDPOINT = "https://agb.hackens.org/api";
ALLOWED_HOSTS = [
"127.0.0.1"
"agb.hackens.org"
];
DATABASES = {
"default" = {
"ENGINE" = "django.db.backends.sqlite3";
"NAME" = "/var/lib/django-ragb/ragb_frontend.sqlite3";
};
};
};
processes = 2;
threads = 4;
port = 9991;
extraPackages = p: [
p.authens
p.pyjwt
];
secrets = {
SECRET_KEY = config.age.secrets.ragb.path;
JWT_SECRET = config.age.secrets.ragbJWT.path;
};
};
services.nginx.virtualHosts."agb.hackens.org" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://localhost:9991";
};
"/api" = {
proxyPass = "http://localhost:9999";
proxyWebsockets = true;
};
"/static".root = config.services.django.ragb.staticAssets;
"= /api-docs" = {
return = "302 /api-docs/";
};
"/api-docs/" = {
alias = "${pkgs.ragb-src + "/api-docs/"}/";
extraConfig = "autoindex on;";
};
"= /api-docs/patch.json".alias = pkgs.ragb-src + "/frontend/patch.json";
};
};
systemd.services.django-ragb.serviceConfig = {
Wants = [ "ragb-backend.service" ];
};
systemd.services.ragb-backend = {
script = ''
export JWT_SECRET=$(cat $CREDENTIALS_DIRECTORY/jwt_secret)
export BK_FILE="$STATE_DIRECTORY/data.json"
export BIND_TCP="10.10.10.1:1235"
export RUST_LOG=debug
${pkgs.ragb-backend}/bin/ragb-backend
'';
serviceConfig = {
LoadCredential = [
"jwt_secret:${config.age.secrets.ragbJWT.path}"
];
DynamicUser = true;
StateDirectory = "ragb-backend";
};
};
}

View file

@ -1,20 +1,7 @@
{ ... }:
{
{ ... }: {
age.secrets."django" = {
file = ./django.age;
};
age.secrets."ragbJWT" = {
file = ./ragbJWT.age;
};
age.secrets."ragb" = {
file = ./ragb.age;
};
age.secrets."snipeit" = {
file = ./snipeit.age;
owner = "snipeit";
};
age.secrets."django-gestiohackens" = {
file = ./django-gestiohackens.age;
owner = "django-hackens_orga";
};
age.secrets."matterbridge-env" = {
file = ./matterbridge-env.age;
@ -22,10 +9,5 @@
};
age.secrets."wg-key" = {
file = ./wg-key.age;
owner = "systemd-network";
};
age.secrets."prometheus-webconf" = {
file = ./prometheus-webconf;
owner = "prometheus";
};
}

View file

@ -1,30 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 JGx7Ng UMbo24t6bweWPSYr1MUpjW96t3+usu+M3+WmLkJpSTc
vW8wOX/E6p3YEh8rRObScdcKB+uCtVIEOQ58HXSHYRU
-> ssh-ed25519 kXobKQ wEsnzLjnW+tdNvBHYBL+pLQh0GsAviTiD7tODc+5nSc
gW8TEewhh4N0ed6KNe+PYBQuEmuL8iO+KxLQt2imbbo
-> ssh-ed25519 7hZk0g 2Y9Y3DSR9Zt5N1XXckNMlHEpczvsyruqBue54fC4lQY
1UTRMGuN4uXR2ljP+3h7y58dU9C4GCkfKMY6l6GgRas
-> ssh-ed25519 5rrg4g 6ILvq1I6OlTmvxhgo145YUdpNxZomFvCYl7nguL10kI
7DPETzO4s3J4+lHIlkWvo4M0zH2792NttKBIJ09xii4
-> ssh-rsa krWCLQ
LdJzAaTTOSSxXTjLEv2n3pRjDJ8Cv/rLZZCsadK2vIK/2swax5loeprUzx60xRUt
3qLZuXocsE1S8sUq4E0lzyQXmJj3DtgjWFvvhDhsx+UnUPB/S7yojlNPLsqSxJkO
r5p6dvXsngF78BDDlFU/DnDI/tMnH6wL5PqV7iZiosSmASWxHMAQYcWGNZqdV1xl
9q2txZF7LxvE1S2eUOFcXTC7r8Z/kBt7XqPfGyBWI1wYPG2r2Zw+tbO8S04iZExT
Lj2YGnrNGGwNbREoqhMwAxDM6fLVoNnhHXoVQvCkr/wxk+sh2/Lt1ivcTT7Ua2YG
ApaavUan7cEs3ghnanM+6A
-> ssh-ed25519 /vwQcQ oaIOirE4++Kx76xSCoQ8EKmnI3Zh8rzou0XACYVY3Gw
H9DsHQPdKaN/5bz4kf224NiJ8W1ykGx9tARd5UUrMbc
-> ssh-ed25519 0R97PA SujU6d2DMDGX4zxsQwQTLFM2ap/3ni2y7zpU8BksTw0
zLuD8EwORd5aDOFBpE0Nm5gHpi8ChRobg6v7r1sNfMU
-> ssh-ed25519 cvTB5g t62LJ9atiYi5K+CBXXLB9obIZRWBKxrC896q6iCz/mA
WYkA2muGBMuXlO5ebnul3NkidNcyIWecAdNTo03trf0
-> ssh-ed25519 Wu8JLQ 3gzrf2TLDbG3YtMmO0qKVKiEPw+arN8DJvNiC09/4wg
bYCCgA0ve55hKEjGFa+nAelWiYWy6WFHss9R6uEjiUI
-> ssh-ed25519 EIt1vA kKs5NcxlLTt3iGD8stN7nOgOfomKEv2aZZ969dZNFlg
IQT3Fx9Egd4kJ6Q3gsbiymu8EHSrjG1F7T5Uz76Z6Bo
-> ssh-ed25519 X51wxg GU838E9JPhdAkYgRRcYi+gMsFFUTvY4iciFi9b43WhY
vsHQ70mCsW0NUzMKjgRq6czFD8FwIFj6uo/jklPzI68
--- axO8MoSOSkcp2HcVpAz9tQuuf0Unh2Ri20S60/Yq6xA
i¸0ä<36,Û{àu$apG7¢—Ú10Y•&«Øf7(&{3Û]àƒcÝ“ ¶>l¶P"$`ÝU(9¨ì5+°îJî^¼æé‚Ï»|†Õ:~

View file

@ -1,30 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 JGx7Ng 6s1XuhN3TFuW433ZrghssoyScvjqG6tg+ZSvHBwYOjQ
54ijsvv7CO/1L9ib4fgiRAQHmlU2r3j/fbc79qiAo38
-> ssh-ed25519 kXobKQ WMApvaovS/ddPbz7Eh9bCF3SzmUJN1NQGMKzWCJ6jQc
3NehvO3X7uMU/H7g7d4nFsmHk0PhXrRT1XetWUBHAnY
-> ssh-ed25519 7hZk0g RqNPzJqoSY1umAJE/FPZ+MR0R9eCDdxonzuh3uMBRhI
Cfou0mqV4gHGP7OJbgPm8VotU4cM5YVX3iUkd6myU+E
-> ssh-ed25519 5rrg4g mSZUVF9y4vYfBbjgP0UnSfgaGTC3/Yx+fAFquA5022E
1yiri7+CZTSUhPpJlo9f1EraRVl3Ihw4wtjgXJPMRqY
-> ssh-rsa krWCLQ
gMc7ogvibqMuboKqSgqfedIxqyhhljJFp5zI2bK6D5rdcV5CIPVz2xQdk4h678Qg
8pYlg1+UDu+JyXvJgtWZHYMGSs17woIYZmw9UQh+IYMo4Qn89tn4QN4exYwB+7gm
dWEqo7GggWG0Mu2w2OVu2oB1D5aUvF940hUCyl40V7hIkMpJwFfMfvvD04XsScXV
GLpWNYcWIQNaBAxTWRGkpt9jvD1W/DjsOUhOk0BP5hnSPm39awfLFRo3wWFBiaDq
yPRi6P8AJdVWS2n+KdQ1j5dLo19DngkUAmepIR+oiNvgIFKqDAvIB5y30d3guGdP
7zCS7IEOOMLQvBiq99DU2Q
-> ssh-ed25519 /vwQcQ GWEth3AXh2blSPzXzyqaHdRlA+Qmopvdk9DfL69PVlk
sVq7EbVmJ0SnYLueCHB5zOr/aR9QurTqtMIXGdL22cY
-> ssh-ed25519 0R97PA gZLoe8C+FTOXM0i4VWBwBSNSxZhfxG6U3pakRBDwZ0k
LKxzJofqUfdY1swAbRNcOcWfZJ1lbp7S20y+dfjKvUU
-> ssh-ed25519 cvTB5g GbEB6Z/6A/ntU8truri+tshuy5tqYSSo5SF0Brt0VgI
DOkGd68tE85ajEBmKUx9HXiKLjCdUf/tKME6+Ems/RA
-> ssh-ed25519 Wu8JLQ tOF/Dc72uMnmQy4rNjPoRzVhQEuwiYLrmmdCsmJ5wEk
RS5erkX1HIvTDw6g8qrOtZy1zpCphnGw/bqT4F0Q6/8
-> ssh-ed25519 EIt1vA tSBgk0ljTD1pLRsw7axRh2zl+vIMISjrw7zrr01TBB0
hb3kb12kRHCxMeBlxjg6tJpgQpHzJkovH5ncuM4MzNA
-> ssh-ed25519 X51wxg Gy0QJbua5ZoNYDnuQXlPVFxQvm7SSOMUR0uDRI719gk
VEYU1qazlM62F2xsXIFhIAEL4ssWW8o2/e07NguMp88
--- VwkrST6cm5HpWtRWBM4tkk14C/NwtxpBbXHVj6ouyxk
(`WÊ;+u'oÓj Ý<> —õ{ïMÄP0žDèÈ™J}Å<>¯»È{ìætˆ°ïj`ÂK:׸ŠI;™çA2ÿCÕ+ ö\Nú

View file

@ -1,32 +1,17 @@
let
lib = (import <nixpkgs> { }).lib;
readpubkeys =
user:
builtins.filter (k: k != "") (
lib.splitString "\n" (builtins.readFile (../../../pubkeys + "/${user}.keys"))
);
keys =
(readpubkeys "sinavir")
++ (readpubkeys "hackens-host")
++ (readpubkeys "catvayor")
++ (readpubkeys "raito")
++ (readpubkeys "gdd")
++ (readpubkeys "backslash");
readpubkeys = user:
builtins.filter (k: k != "")
(lib.splitString "\n" (builtins.readFile (../../../pubkeys + "/${user}.keys")));
in
{
"matterbridge-env.age".publicKeys = keys;
"snipeit.age".publicKeys =
keys;
"ragbJWT.age".publicKeys =
keys;
"ragb.age".publicKeys =
keys;
"django.age".publicKeys =
keys;
"django-gestiohackens.age".publicKeys =
keys;
"wg-key.age".publicKeys =
keys;
"prometheus-webconf".publicKeys =
keys;
"matterbridge-env.age".publicKeys = (readpubkeys "sinavir")
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
"django.age".publicKeys = (readpubkeys "sinavir")
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
"wg-key.age".publicKeys = (readpubkeys "sinavir")
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
}

View file

@ -1,30 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 JGx7Ng XPTwmcI9Xyu3ulX68UgyFhORwDsbTAvcaTDhGKzcAFs
EkDJhGqFqtW4VMIKN9SMU3MrwIf+3Y50Ku0ToKf/wJI
-> ssh-ed25519 kXobKQ /Z+Qh1kUFI+X97VsebUHv51+XyJT2fZWsDF0TFdl0A0
8W13NrPTb1aoDYA5M7Xej5R/DJ2YLyngx/UzIAIVnXU
-> ssh-ed25519 7hZk0g xRggNYJuJGAR4uSeZeoZI7tNqorkc1BDEO+Jz6saKH4
xYKIqp/E0GQ1t5VhOWBpCi8WgLSDDZuKbOg6l7Htjuk
-> ssh-ed25519 5rrg4g hW1VZuxL+eCGeUJDhDXg3L9h1KMp/OTpTvj2bOPIwnU
s3Fvjx/jFCPa6dG5RgJseJPYf4LcojDSq4mtbEza+sc
-> ssh-rsa krWCLQ
AwxiOyNOxRKOA3B6sbnFm97UABVXnuXdddHhl0Qk0jGdJtK/Gg3IQ3RAUPdW46e4
S3LsQ+REqcA33h3DUhh6Yaz3agAvNtqFfp3h3Wy1+tVsIKQx9T6rEg7XcyWlQGg6
/sLkLMKg2kcMxTZFjGlYfoRMu/yMD3I+M/3DMZiccSYTa+Z+cJ13ERDmhLVh5X+j
R/v3JMM0vupwjxWnVdMJNAz2dLNawWTFIBN1IVAgYPyaVrL99H65CPLUAeN2CVx6
I8bEOJ15tk5q8yzX8DwTfJnXYBP+FyN8WVS0v5WfxSvB/ME6VtjeuZRd2h/nPpbc
FKZgZZt94GDjZLl+zHff5w
-> ssh-ed25519 /vwQcQ ct0vQfUsUO8gg2kU41lVDB2acgxuT8hCKWHZwymkFzM
Eu3YaXAVUoF6q2xhk4B77mCTYCqL87rbqZeFNBtYrWA
-> ssh-ed25519 0R97PA xwM4ukaEfI0B93YHSU9f77F6VvnZZctR03regzrDDF4
uoL8wz3iqzB5dnS8z+wRIAu5CmHM8yjnJFduoDtjlAM
-> ssh-ed25519 cvTB5g czmtpirWtnbAjcJEOkLSc2Sfr4SXmtE+e7pS+AE86Co
s20XHgWekxWvP4nypSUZ0YgKWyDobm/3lNA4REUvUGQ
-> ssh-ed25519 Wu8JLQ l4hH8MAJesz5jXzSDf8SDCXNcp8jWJnq0SRYyCCPNB0
Y4XOuoxWXGDnrdhu7aCf8sJNYN/loaKc1bx81KaDAFc
-> ssh-ed25519 EIt1vA eMUqUckKwH5ubKSY8swqT3jfUi9loZKerl9WljV8Hxo
AJL3yBcCaitwOYHL74dymm1cngBf47Yq2jiGJoxeC0g
-> ssh-ed25519 X51wxg I8aIi5liVlYQointFhCCIj5OiRrjhyxWOJdu7JAg3x8
rqPx/8e8e2nNiRwzH61HXA++a5HTyRjMU46c1Tm97yk
--- t53Ft5ztsJLbK0jJZ7uolsbf+NZij6A++98DeqroOro
ºåjKË}§Ú³Ý9QŸ<ïm#ž>EÔ—9+)Äí_³äaTaÔiSR̵}½ RoP= Õëž-Æ<JœÈ”66 Æ+<2B>

View file

@ -1,30 +1,31 @@
age-encryption.org/v1
-> ssh-ed25519 JGx7Ng HCBkB8gfYUDnWwaPlGquE39fnEBvm0cEVxL8Vuh/f2Y
yJapxn2cVn0QjEnpGUq+gfdf+V8f5Mji2JhqPUH13WI
-> ssh-ed25519 kXobKQ 9flhpuGn/MgqRlT4AlphvNRf9ktnuyFvyQrK7eeKbXE
hHpPk2m4XWKgbwNv16Vzh8uJkpk0kwN1WqC4G4rGL5E
-> ssh-ed25519 7hZk0g /DQi1BAovPKmel2zgchEhZkxr9v8ZxVXe6SRuX/yjxg
KALPbUNK6YGvSiNfgQGSdZriJokpHUmO/vVtW9Sfm+I
-> ssh-ed25519 5rrg4g NqFtTNIaoTYEhq7SzFCVD+t2AZ03ANe+kqhDQHmd7zA
NDYBZIdGLItcHPmYRHZ1DZ5vhlR1Qt0PPtDqRxfo9hg
-> ssh-ed25519 JGx7Ng JuynqiiXmLBIlGc6o6HEwsFS8FLiFo86iTWr3kpxEQ0
KjFX3rP7RjvXK42+8qiyRfITDppi7jg9+WPt2afsCuo
-> ssh-ed25519 kXobKQ 8jEmn9hh3I2JeE+l8EZ9npJPGDXr6QcZvtsJhjrmpXE
69W+pHMdgmBOhLw8Hnp+l/IZLvzFtqatYoEKn3nqiSo
-> ssh-ed25519 7hZk0g XSZkyOjMqXtVthQTj8KmDCgM6+ilpktgk8ha1wu/23U
N0IUwdftKBzma5EXfUyswn/RT6RWoXo8hOYH451H2Lg
-> ssh-rsa krWCLQ
tylZdWKOsro4O2g5Oa34ALB3hDmb5krinvk7sXBKQWj+QaRA/J6geAUq7pHGM+zs
MehzMsdJX4tklCUE8ECh5clwdfnTl57m+V9jdD88CAgscyFsMHdX2BEIjzGN3kB1
jYzDO7sLoOx6k8eiQaPFtxkT/tYPI9vpdyyyxKS5thowmQ99NSZQUHaMTqmC36H3
sCr1uyFPrKTEoCZe9Klsdz2KxaPPd7oOo7J5VU4SeiosPfNFhO9kDQ5xRn3SDClD
PMUFhjRxmWjNY4aQqUxi9lJWK35pb87mZNdaPZXH18mbraTIuI08B3KTrR5112PW
oDTckZo3szhzR2JJ0cTG6Q
-> ssh-ed25519 /vwQcQ b9mdEG1+JMJxDBp6b0wU/JGM4Mldh7w7jf4pghb+ejw
1GfaMyOkfHD/I/OvHNjd1kzdT1vWnbR1fAP4za++c5g
-> ssh-ed25519 0R97PA 0DdkxpjsoA6ERi43skpS7/lyttMlJu5BcNFSAF3+g34
tz3fM0C+zT6enFgiqbKwiBWLTdOS2xKLZQOngRpf5q4
-> ssh-ed25519 cvTB5g aL+EY/DYolrhoaKHPpAvPr3rNO3vThV+uqX9m39jEG4
cnFq0cgCWac07x+6Fu+M9os6wxPxfoHcSJ+8ispYkPk
-> ssh-ed25519 Wu8JLQ wwQGruBxZ8tUHGw08B7ezoPj1ddPlWmemmm8aI6EIRE
0WUod40m3tVP+mTx2B9b/4AoT1kcXAeNVMnj8BLFRuM
-> ssh-ed25519 EIt1vA zYOPPPZgk4NIUyInXyoapCRkg/dshOuRPnKuwJyM7lM
Jn8J2sQn1qrtH4OANx73OYsBChGUB2fuWaB38pEhbm8
-> ssh-ed25519 X51wxg 9ofVG6z1+KwMkk97WViCDfnAXTNgFzQYBBsEYhBP1yw
wwWlCbJ2xOWR9FZw+apjn11MQqKSeyHsRJYvFEV+0VU
--- QU5Ewm2faKYtF6HK7hagXVPSjzqjQbaZ6/wPJ61eDCI
<EFBFBD>ž×ÝnšÓ£*¨…¯;©uï~õls0Ô¤¾íM5fÎjhâå§iž¤Ÿ£ŒÈ6«í%ôH»cv`®$©˜ùYÑ0WW¢
JwqNEu6Xr9fwov++Ct/8Jfxaz6Z2F0KpxqJHTZ6PLt5weOVul83AdINfIzq7dJUo
gR4KZJrwM27iY7aTHdbiImzmVSD0KPUeM0KoWjmLcU0xtLIXpoiBAEn0w9YXKTOF
n4wTvpNtXCMkgQPtAYsPOBIdIgQKdEm9Q877mtjHPDlyppn8y7U4z7S1zp71ugc5
B68HyMh1lzDWh43aqYOr5WIanscBjJNHRK1XqM0IhtuWg84cl0EsQ1wOKJxHwwJQ
vjHLoaBulqTxRentvi//4eRz+fKFZ1uJmeHlySlqSYKCN55QZgIFJHGxpSb8kEhl
CFqRx6v+uHeKhBK3yftSQA
-> ssh-ed25519 /vwQcQ ZfgSXru0ZABSLKkyAxdxM4cPs5A1wmNJVqK67UmfdH4
exrZlcFV0BZEnPrT+aRuCSyIKTS0Nbvdd7zWPqepQrc
-> ssh-ed25519 0R97PA VNBEjlLbNQixIXvrkyWVpQ3cWbKQW5XcLcI3Aniy93Y
WXt/rWJYI0mqELcS9+4t1y+cWXyvD4mSudoT/K0da1c
-> ssh-ed25519 cvTB5g 2FWQYQkoMxWf7lf6ZCgF5hL46fmR1zKAmDKw/qGtnjU
xwe9JcDzGLPW+jJwNkMssO21A/pr2baWoQUBYcO5pjk
-> ssh-ed25519 Wu8JLQ ukKMgxBbbHa9TBXo0PGKkk5K1zdQvrk2Qp6BRYguumo
l5k71S4x1VlLCm8BHadDrMMvvJ2927EkTtH8Hu1KNEE
-> ssh-ed25519 EIt1vA yEpFCXXu6iayLUQKj9vgiQGwuRgyduceks6LMFXRGmI
I4iGlWSVye16ZnwHYOfFWWbg6oLYmA1k9LcMyzWoBKA
-> ssh-ed25519 X51wxg 8vkI4rsB3ETq1zMpqkFUr0u6s1OerUjEN1wnz/onjX8
XvbOSMD58qI/yO03zwCg67R1H36AWM8MfT0FVFJnE34
-> DP.[|9G-grease 1H80A YV&\ uG'R";.
DtOW39f0bJ6uFAmxiXhmq3bpV5qnJ3TTb7BjCXND8LtgCj9HcyaOpt4HtNFqAZd9
5hPJeoyr6AMB6TYVAMIKoCfmq2zRe4ilDe3Q5TOL5A
--- yZCsgaQ3oxOkOyyP96+znN03pbyVfqc8ZP0S0x1JZc4
žbl3¹(Š“:¨¾uÚ®Ôº!Ô–$5í]AŽñ)§šß,VJØQC—·†;Qõ§Ô¦ˆMtj.<2E>Àq*ˆüþN™¶š<C2B6>z

View file

@ -1,22 +0,0 @@
{ config, ... }:
{
services.snipe-it = {
enable = true;
appKeyFile = config.age.secrets."snipeit".path;
config = {
APP_LOCALE = "fr-FR";
APP_TIMEZONE = "Europe/Paris";
};
database = {
createLocally = true;
user = "snipeit";
};
user = "snipeit";
group = "snipeit";
hostName = "inventaire.hackens.org";
nginx = {
enableACME = true;
forceSSL = true;
};
};
}

View file

@ -24,8 +24,5 @@ in
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View file

@ -1,40 +0,0 @@
{
pkgs,
lib,
config,
...
}: {
services.thelounge = {
enable = true;
port = 9000;
extraConfig = {
reverseProxy = true;
host = "127.0.0.1";
public = false;
prefetch = true;
fileUpload = {
enable = true;
};
defaults= {
name= "ulminfo";
host= "ulminfo.fr";
port= 3725;
password= "";
tls= true;
rejectUnauthorized= true;
join= "#hackens";
};
};
};
services.nginx.enable = true;
services.nginx.virtualHosts."irc.hackens.org" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:9000";
proxyWebsockets = true;
};
};
networking.firewall.allowedTCPPorts = [80 443];
}

View file

@ -37,8 +37,5 @@
proxyWebsockets = true;
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View file

@ -3,9 +3,7 @@
lib,
pkgs,
...
}:
{
networking.firewall.trustedInterfaces = [ "wg0" ];
}: {
systemd.network = {
enable = true;
networks = {
@ -14,15 +12,12 @@
address = [
"10.10.10.1/24"
];
networkConfig = {
IPv4Forwarding = true;
};
routes = [
{
routes = [{
routeConfig = {
Destination = "10.10.10.0/24";
Scope = "link";
}
];
};
}];
};
};
netdevs = {
@ -37,55 +32,6 @@
};
wireguardPeers = [
{
# hackens-desktop
AllowedIPs = [
"10.10.10.3/32"
];
PublicKey = "h4Nf+e4JIjqOMuM5JtLN298BF/fym9fWKGtRZmS5MVA=";
}
{
# hackens-milieu
AllowedIPs = [
"10.10.10.4/32"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/hackens-milieu.pub);
}
{
# agb01
AllowedIPs = [
"10.10.10.5/32"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/agb01.pub);
}
{
# agb02
AllowedIPs = [
"10.10.10.6/32"
];
PublicKey = lib.trim (builtins.readFile ../../wg-keys/agb02.pub);
}
{
# soyouzpanda
AllowedIPs = [
"10.10.10.11/32"
];
PublicKey = "/xjWqkiyHY93wqo/Apj5SHP8UaXF4mKQRVwylKC2wy8=";
}
{
# sinavir
AllowedIPs = [
"10.10.10.12/32"
];
PublicKey = "kmc3PexCMKm1Tg8WUDbHaOkcWLl8KUh52CtrDOODf0M=";
}
{
# catvayor
AllowedIPs = [
"10.10.10.13/32"
];
PublicKey = "zIHvCSzk5a94jvnXU4iscbp9RUGzbWpARDMRgHNtMl4=";
}
];
};
};

View file

@ -1,11 +0,0 @@
Put pls key in keys.keys
Put pls mac in networking
# How to get an sd image
```
DRV_PATH=$(colmena eval -E "{ nodes, ...}: nodes.rigel.config.system.build.sdImage.drvPath")
nix-store -r $DRV_PATH
```

View file

@ -1,64 +0,0 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
let
launchpad = pkgs.python3.withPackages (ps: [
(ps.callPackage ./launchpad.nix { lpminimk3 = ps.callPackage ./lpminimk3.nix { }; })
]);
in
{
imports = [
(modulesPath + "/installer/sd-card/sd-image-aarch64.nix")
./bootloader.nix
./networking.nix
./nix-conf.nix
./programs.nix
./ssh.nix
./users.nix
];
nix.settings.substituters = lib.mkForce [ ];
networking.hostName = "rigel"; # Define your hostname.
# Set your time zone.
time.timeZone = "Europe/Paris";
environment.systemPackages = [
launchpad
];
systemd.services.launchpad = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [
launchpad
pkgs.unixtools.ping
];
script = ''
while ! ping -n -w 1 -c 1 10.1.1.2 &> /dev/null
do
echo "waiting eos"
done
sleep 0.1
python -m eos_midi 10.1.1.2
'';
};
environment.shellAliases = {
r = "systemctl restart launchpad.service";
};
fonts.enableDefaultPackages = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "unstable"; # Did you read the comment?
}

View file

@ -1,5 +0,0 @@
{ pkgs, ... }:
{
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
}

View file

@ -1 +0,0 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBRA2W8T8rnWIn0xnP2LXSmmB92YuQygkLwLK60rpBG+ PLS@DESKTOP-KK74B9P

View file

@ -1,38 +0,0 @@
{
lib,
buildPythonPackage,
fetchgit,
poetry,
lpminimk3,
python-osc,
}:
buildPythonPackage rec {
pname = "kfet-launchpad-controller";
version = "unstable";
pyproject = true;
src = fetchgit {
url = "https://git.soyouzpanda.fr/soyouzpanda/kfet_launchpad_controller.git";
rev = "58f1086ca7a8a9258da7240987bf26c03182b152";
hash = "sha256-c21BbRKK1AK6roIjdEg3zfMThyijRTK5Z87DBBBjoL0=";
};
nativeBuildInputs = [
poetry
];
propagatedBuildInputs = [
lpminimk3
python-osc
];
pythonImportsCheck = [ "eos_midi" ];
meta = with lib; {
description = "";
homepage = "https://git.soyouzpanda.fr/soyouzpanda/kfet_launchpad_controller.git";
license = licenses.mit;
maintainers = with maintainers; [ ];
};
}

View file

@ -1,40 +0,0 @@
{
lib,
buildPythonPackage,
fetchgit,
poetry-core,
lpminimk3,
python-osc,
}:
buildPythonPackage rec {
pname = "kfet-launchpad-controller";
version = "unstable";
pyproject = true;
src = fetchgit {
url = "https://git.soyouzpanda.fr/soyouzpanda/kfet_launchpad_controller";
rev = "6d7df83cfd2f558d4837474ea101f98439a4f8c5";
hash = "sha256-HkaR1+9NxvyRQ3+iP6pq3Wn6QT+qQRFJBvxHNH6qM0k=";
};
patches = [ ./launchpad.patch ];
nativeBuildInputs = [
poetry-core
];
propagatedBuildInputs = [
lpminimk3
python-osc
];
pythonImportsCheck = [ "eos_midi" ];
meta = with lib; {
description = "";
homepage = "https://git.soyouzpanda.fr/soyouzpanda/kfet_launchpad_controller";
license = licenses.mit;
maintainers = with maintainers; [ ];
};
}

View file

@ -1,13 +0,0 @@
diff --git a/pyproject.toml b/pyproject.toml
index dd2e48c..48339c9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,7 +42,7 @@ black = "*"
[build-system]
-requires = ["poetry>=1.7.1"]
+requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.isort]

View file

@ -1,43 +0,0 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
setuptools,
wheel,
jsonschema,
python-rtmidi,
websockets,
}:
buildPythonPackage rec {
pname = "lpminimk3";
version = "0.6.2";
pyproject = true;
src = fetchFromGitHub {
owner = "obeezzy";
repo = "lpminimk3";
rev = "v${version}";
hash = "sha256-CVjBUKjLOFaIgCpwNIO/PJ55s7nQ0WMRKKqVS3xOI3g=";
};
nativeBuildInputs = [
setuptools
wheel
];
propagatedBuildInputs = [
jsonschema
python-rtmidi
websockets
];
pythonImportsCheck = [ "lpminimk3" ];
meta = with lib; {
description = "Python API for the Launchpad Mini MK3";
homepage = "https://github.com/obeezzy/lpminimk3";
license = licenses.mit;
maintainers = with maintainers; [ ];
};
}

View file

@ -1,47 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
networking.useDHCP = false;
networking.firewall.allowedUDPPorts = [ 67 ];
systemd.network = {
enable = true;
networks = {
"10-uplink" = {
name = "end0";
networkConfig = {
Address = "10.1.1.1/24";
DHCPServer = "yes";
IPMasquerade = "ipv4";
};
dhcpServerConfig = {
PoolOffset = 100;
PoolSize = 20;
UplinkInterface = ":none";
EmitDNS = "no";
EmitNTP = "no";
EmitSIP = "no";
EmitRouter = "no";
};
dhcpServerStaticLeases = [
{
dhcpServerStaticLeaseConfig = {
Address = "10.1.1.2";
MACAddress = "14:b3:1f:06:3c:2e";
};
}
];
};
};
};
networking.nameservers = [
"2620:fe::fe"
"2620:fe::9"
"9.9.9.9"
"149.112.112.112"
];
}

View file

@ -1,21 +0,0 @@
{
lib,
pkgs,
config,
metadata,
nodes,
name,
...
}:
{
nix.settings = {
trusted-users = [
"root"
"@wheel"
];
extra-experimental-features = [
"nix-command"
"flakes"
];
};
}

View file

@ -1,28 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
environment.systemPackages = with pkgs; [
sqlite-web
dhcpdump
dig
git
htop
jq
nmap
npins
ripgrep
screen
tcpdump
unzip
vim
wireguard-tools
];
programs.mtr.enable = true;
programs.vim.defaultEditor = true;
}

View file

@ -1,5 +0,0 @@
{ ... }:
{
services.openssh.enable = true;
services.openssh.settings.PasswordAuthentication = true;
}

View file

@ -1,12 +0,0 @@
{ ... }:
{
users.mutableUsers = false;
users.users.root = {
openssh.authorizedKeys.keyFiles = [
../../pubkeys/sinavir.keys
../../pubkeys/soyouzpanda.keys
./keys.keys
];
hashedPassword = "$y$j9T$p6Fe9Gm/C4iLIQBYXCjBn.$zLCzaxrsUDd4/2H5eTXqNch.bVJubrpZNOZgAZqbeV/";
};
}

1
machines/router/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
belkin-boot*.log

6
machines/router/build.sh Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
#
mkdir output/
nom-build -A outputs.tftpboot -o output/result

View file

@ -0,0 +1,59 @@
# This is an example configuration for a "typical" small office/home
# router and wifi access point.
# You need to copy it to another filename and change the configuration
# wherever the text "EDIT" appears - please consult the tutorial
# documentation for details.
{ config, pkgs, lib, modulesPath, ... } :
let
inherit (pkgs.liminix.services) bundle oneshot longrun;
inherit (pkgs) serviceFns;
# EDIT: you can pick your preferred RFC1918 address space
# for NATted connections, if you don't like this one.
svc = config.system.service;
in rec {
boot = {
tftp = {
freeSpaceBytes = 3 * 1024 * 1024;
serverip = "10.0.0.1";
ipaddr = "10.0.0.8";
};
};
hardware = {
flash = {
eraseBlockSize = 131072;
};
};
hardware.ubi = {
# PLEASE remove this when using the real ROM. These are just tweaks to make tftpboot working
minIOSize = lib.mkForce "1";
eraseBlockSize = lib.mkForce "130944";
};
imports = [
(modulesPath + "/network")
(modulesPath + "/ssh")
(modulesPath + "/outputs/ubimage.nix")
];
rootfsType = "ubifs";
hostname = "hackens-router"; # EDIT
services.int = svc.network.address.build {
interface = config.hardware.networkInterfaces.wan;
family = "inet";
address = "10.0.0.8";
prefixLength = 24;
};
services.sshd = svc.ssh.build { };
users.root = {
# EDIT: choose a root password and then use
# "mkpasswd -m sha512crypt" to determine the hash.
# It should start wirh $6$.
passwd = "$6$9XlVymX951ai.c2C$SYtEF2Ykcud8VRuLRxfQRfuc9h7oJpVo.xDEv6fTWjBngMj3bPN9GbFMv3r.T.K2wIj1rTo9j1m58G.GTPKWo/";
};
}

View file

@ -0,0 +1,8 @@
{ liminix ? (import ./npins).liminix
, nixpkgs ? (import ./npins).nixpkgs
, liminix-config ? ./configuration.nix
}:
let
liminix = builtins.toString ./liminix;
in
(import liminix { inherit nixpkgs liminix-config; device = import (liminix + "/devices/belkin-rt3200"); })

View file

@ -0,0 +1,47 @@
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
mkSource = spec:
assert spec ? type; let
path =
if spec.type == "Git" then mkGitSource spec
else if spec.type == "GitRelease" then mkGitSource spec
else if spec.type == "PyPi" then mkPyPiSource spec
else if spec.type == "Channel" then mkChannelSource spec
else builtins.throw "Unknown source type ${spec.type}";
in
spec // { outPath = path; };
mkGitSource = { repository, revision, url ? null, hash, ... }:
assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball
if url != null then
(builtins.fetchTarball {
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
})
else assert repository.type == "Git"; builtins.fetchGit {
url = repository.url;
rev = revision;
# hash = hash;
};
mkPyPiSource = { url, hash, ... }:
builtins.fetchurl {
inherit url;
sha256 = hash;
};
mkChannelSource = { url, hash, ... }:
builtins.fetchTarball {
inherit url;
sha256 = hash;
};
in
if version == 3 then
builtins.mapAttrs (_: mkSource) data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"

View file

@ -0,0 +1,11 @@
{
"pins": {
"nixpkgs": {
"type": "Channel",
"name": "nixpkgs-unstable",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre586231.f33dd27a47eb/nixexprs.tar.xz",
"hash": "15i504pd3y9r0c2fwyjwsc1j8055h20w0j2sj4ij5igvin7v3k9l"
}
},
"version": 3
}

3
machines/router/serve.sh Executable file
View file

@ -0,0 +1,3 @@
#! /usr/bin/env bash
sudo capsh --keep=1 --user="$USER" --inh='cap_net_bind_service' --addamb='cap_net_bind_service' -- -c 'tftpy_server.py -r ./output'

10
machines/router/shell.nix Normal file
View file

@ -0,0 +1,10 @@
let
pkgs = import (import ./npins).nixpkgs {};
in
pkgs.mkShell {
packages = with pkgs; [
python3.pkgs.tftpy
minicom
];
}

Some files were not shown because too many files have changed in this diff Show more