forked from hswaw/hscloud
hswaw/machines: add sound.waw.hackerspace.pl
Change-Id: Id0e6a02d9ae4cf61d758713a99d21c6da0c72b66 Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1401 Reviewed-by: vuko <vuko@hackerspace.pl> Reviewed-by: informatic <informatic@hackerspace.pl>master
parent
0d22d0bcb6
commit
deeeff861e
|
@ -0,0 +1,214 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
hw = builtins.fromJSON (builtins.readFile ./hw.json);
|
||||||
|
ssh-keys = {
|
||||||
|
vuko = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFhaCaC/CVYv6hphqmEdKaPrIn+Q946+myvL9SSnzFZk vuko@eagle";
|
||||||
|
informatic = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDoKB2p/gFaKthQNXeQvSLzhOlLSq3vjVL3AEOBTMXGH informatic@atuin";
|
||||||
|
};
|
||||||
|
networks = {
|
||||||
|
lan = {
|
||||||
|
description = "LAN";
|
||||||
|
hw_addr = "4c:52:62:ba:a9:78";
|
||||||
|
ipv4 = "10.8.1.26";
|
||||||
|
#ipv6 = "2a0d:eb00:4242::1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
system-vim = pkgs.vim_configurable.customize {
|
||||||
|
name = "vim";
|
||||||
|
vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
|
||||||
|
start = [ vim-nix vim-lastplace ];
|
||||||
|
opt = [];
|
||||||
|
};
|
||||||
|
vimrcConfig.customRC = ''
|
||||||
|
set nocompatible
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
in {
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
time.timeZone = "Europe/Warsaw";
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-partuuid/${hw.rootUUID}";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.hostName = "newsound";
|
||||||
|
networking.domain = "waw.hackerspace.pl";
|
||||||
|
networking.useDHCP = false;
|
||||||
|
|
||||||
|
networking.defaultGateway = {
|
||||||
|
address = "10.8.1.2";
|
||||||
|
interface = "lan";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.interfaces = {
|
||||||
|
lan = {
|
||||||
|
ipv4.addresses = [
|
||||||
|
{
|
||||||
|
address = networks.lan.ipv4;
|
||||||
|
prefixLength = 16;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.nameservers = ["10.8.1.2"];
|
||||||
|
|
||||||
|
services.acpid.enable = true;
|
||||||
|
|
||||||
|
# TODO copy acls and paswords from old sound
|
||||||
|
services.mosquitto.enable = true;
|
||||||
|
services.mosquitto.listeners = [
|
||||||
|
{
|
||||||
|
settings.allow_anonymous = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.home-assistant = {
|
||||||
|
enable = true;
|
||||||
|
config = import ./home-assistant.nix;
|
||||||
|
|
||||||
|
# TODO if some components / packages are not needed
|
||||||
|
extraComponents = [
|
||||||
|
"default_config"
|
||||||
|
"mqtt"
|
||||||
|
"met"
|
||||||
|
"media_player"
|
||||||
|
"light"
|
||||||
|
"frontend"
|
||||||
|
"cast"
|
||||||
|
"spotify"
|
||||||
|
];
|
||||||
|
extraPackages = ps: [
|
||||||
|
ps.aiohttp-cors
|
||||||
|
ps.pillow
|
||||||
|
ps.sqlalchemy
|
||||||
|
ps.websockets
|
||||||
|
ps.fnvhash
|
||||||
|
ps.hass-nabucasa
|
||||||
|
ps.pymetno
|
||||||
|
ps.radios
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
sound.enable = true;
|
||||||
|
|
||||||
|
# TODO create config that setups volume, default output etc.
|
||||||
|
hardware.pulseaudio = {
|
||||||
|
enable = true;
|
||||||
|
systemWide = true;
|
||||||
|
zeroconf.publish.enable = true;
|
||||||
|
|
||||||
|
tcp.enable = true;
|
||||||
|
tcp.anonymousClients.allowAll = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"iot.waw.hackerspace.pl" = {
|
||||||
|
serverAliases = ["default_server"];
|
||||||
|
listen = [
|
||||||
|
{
|
||||||
|
addr = networks.lan.ipv4;
|
||||||
|
port = 80;
|
||||||
|
ssl = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
locations."/" = {
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $http_connection;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $host:$server_port;
|
||||||
|
proxy_set_header X-Forwarded-Server $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
'';
|
||||||
|
proxyPass = "http://localhost:8123";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
systemd.network.links = builtins.listToAttrs (map (
|
||||||
|
name: { name = "10-link-${name}"; value = {
|
||||||
|
enable = true;
|
||||||
|
matchConfig = {
|
||||||
|
MACAddress = networks."${name}".hw_addr;
|
||||||
|
};
|
||||||
|
linkConfig = {
|
||||||
|
Name = "${name}";
|
||||||
|
};
|
||||||
|
}; }
|
||||||
|
) (builtins.filter (name: builtins.hasAttr "hw_addr" networks."${name}") (builtins.attrNames networks)));
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = [
|
||||||
|
22 # ssh
|
||||||
|
80 # nginx http
|
||||||
|
1883 # mqtt (mosquitto)
|
||||||
|
4713 # pulseaudo
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
passwordAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO extract ssh keys synchronization from customs and add it here
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = [ ssh-keys.vuko ssh-keys.informatic ];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
system-vim tcpdump htop nmon tmux git file procps parted dmidecode ack utillinux
|
||||||
|
nmap mosh ncdu tree lz4 bind neovim hdparm usbutils
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.mtr.enable = true;
|
||||||
|
|
||||||
|
environment.variables = {
|
||||||
|
EDITOR = "vim";
|
||||||
|
};
|
||||||
|
|
||||||
|
#environment.extraInit = ''
|
||||||
|
# export NIX_PATH="nixpkgs=${config.channel-sources.nixpkgs}";
|
||||||
|
#'';
|
||||||
|
|
||||||
|
environment.etc."inputrc" = {
|
||||||
|
text = pkgs.lib.mkDefault( pkgs.lib.mkAfter ''
|
||||||
|
set colored-stats on
|
||||||
|
set show-all-if-ambiguous on
|
||||||
|
set completion-ignore-case on
|
||||||
|
|
||||||
|
# arrow up
|
||||||
|
"\e[A": history-search-backward
|
||||||
|
# arrow down
|
||||||
|
"\e[B": history-search-forward
|
||||||
|
|
||||||
|
"\e[5~": history-search-backward
|
||||||
|
"\e[6~": history-search-forward
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "22.05";
|
||||||
|
|
||||||
|
|
||||||
|
boot.vesa = false;
|
||||||
|
boot.loader.grub.splashImage = null;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# 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, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||||
|
}
|
|
@ -0,0 +1,289 @@
|
||||||
|
{
|
||||||
|
default_config = {};
|
||||||
|
|
||||||
|
homeassistant = {
|
||||||
|
auth_providers = [
|
||||||
|
{
|
||||||
|
type = "homeassistant";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "trusted_networks";
|
||||||
|
trusted_networks = ["127.0.0.1" "::1" "10.0.0.0/8" "fd00::/8"];
|
||||||
|
allow_bypass_login = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
customize = {
|
||||||
|
"light.left_par_brightness" = {hidden = true;};
|
||||||
|
"light.right_par_brightness" = {hidden = true;};
|
||||||
|
"switch.portable_spejsiot_node_b4a90f" = {icon = "mdi:power-plug";};
|
||||||
|
"switch.projection_screen" = {icon = "mdi:projector-screen";};
|
||||||
|
"switch.projector" = {icon = "mdi:projector";};
|
||||||
|
"switch.samsung_tv_mute" = {icon = "mdi:volume-off";};
|
||||||
|
"switch.samsung_tv_telelele" = {icon = "mdi:monitor";};
|
||||||
|
"switch.space_heater" = {icon = "mdi:fire";};
|
||||||
|
};
|
||||||
|
customize_glob = {"media_player.m*" = {custom_ui_state_card = "state-card-mini-media-player";};};
|
||||||
|
elevation = "106";
|
||||||
|
latitude = "52.25";
|
||||||
|
longitude = "21";
|
||||||
|
name = "Warsaw Hackerspace";
|
||||||
|
time_zone = "Europe/Warsaw";
|
||||||
|
unit_system = "metric";
|
||||||
|
};
|
||||||
|
|
||||||
|
http = {
|
||||||
|
use_x_forwarded_for = true;
|
||||||
|
trusted_proxies = [ "127.0.0.1" "::1" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
automation = [
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data_template = {
|
||||||
|
payload = "{{ states('input_number.polycom_hdmi_gain') }}";
|
||||||
|
retain = true;
|
||||||
|
topic = "iot/polycom/hdmi:main/gain/set";
|
||||||
|
};
|
||||||
|
service = "mqtt.publish";
|
||||||
|
};
|
||||||
|
hide_entity = true;
|
||||||
|
trigger = {
|
||||||
|
entity_id = "input_number.polycom_hdmi_gain";
|
||||||
|
platform = "state";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data_template = {
|
||||||
|
payload = "{{ states('input_number.polycom_aux1_gain') }}";
|
||||||
|
retain = true;
|
||||||
|
topic = "iot/polycom/aux1:main/gain/set";
|
||||||
|
};
|
||||||
|
service = "mqtt.publish";
|
||||||
|
};
|
||||||
|
hide_entity = true;
|
||||||
|
trigger = {
|
||||||
|
entity_id = "input_number.polycom_aux1_gain";
|
||||||
|
platform = "state";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data_template = {
|
||||||
|
payload = "{{ states.input_select.hdmi_source_a.attributes['options'].index(states('input_select.hdmi_source_a')) }}";
|
||||||
|
retain = true;
|
||||||
|
topic = "iot/3c189c/matrix/sourceA/set";
|
||||||
|
};
|
||||||
|
service = "mqtt.publish";
|
||||||
|
};
|
||||||
|
hide_entity = true;
|
||||||
|
trigger = {
|
||||||
|
entity_id = "input_select.hdmi_source_a";
|
||||||
|
platform = "state";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data_template = {
|
||||||
|
payload = "{{ states.input_select.hdmi_source_b.attributes['options'].index(states('input_select.hdmi_source_b')) }}";
|
||||||
|
retain = true;
|
||||||
|
topic = "iot/3c189c/matrix/sourceB/set";
|
||||||
|
};
|
||||||
|
service = "mqtt.publish";
|
||||||
|
};
|
||||||
|
hide_entity = true;
|
||||||
|
trigger = {
|
||||||
|
entity_id = "input_select.hdmi_source_b";
|
||||||
|
platform = "state";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data = {
|
||||||
|
entity_id = "input_select.hdmi_source_b";
|
||||||
|
option = "Input 1 / Kolumna";
|
||||||
|
};
|
||||||
|
service = "input_select.select_option";
|
||||||
|
};
|
||||||
|
alias = "Switch projector on HDMI1 connect";
|
||||||
|
trigger = {
|
||||||
|
payload = "true";
|
||||||
|
platform = "mqtt";
|
||||||
|
topic = "iot/3c189c/matrix/rx1_online";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data = {
|
||||||
|
entity_id = "input_select.hdmi_source_b";
|
||||||
|
option = "Chromecast";
|
||||||
|
};
|
||||||
|
service = "input_select.select_option";
|
||||||
|
};
|
||||||
|
alias = "Switch projector on HDMI1 disconnect";
|
||||||
|
trigger = {
|
||||||
|
payload = "false";
|
||||||
|
platform = "mqtt";
|
||||||
|
topic = "iot/3c189c/matrix/rx1_online";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = {
|
||||||
|
data_template = {
|
||||||
|
payload = "{{ states('input_number.heater_fan_speed') }}";
|
||||||
|
retain = true;
|
||||||
|
topic = "iot/ab20d2/heater/fan/set";
|
||||||
|
};
|
||||||
|
service = "mqtt.publish";
|
||||||
|
};
|
||||||
|
hide_entity = true;
|
||||||
|
trigger = {
|
||||||
|
entity_id = "input_number.heater_fan_speed";
|
||||||
|
platform = "state";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
cast = {media_player = [{host = "10.8.1.44";}];};
|
||||||
|
|
||||||
|
# TODO fix and enable
|
||||||
|
#frontend = {
|
||||||
|
# extra_html_url = ["/local/custom_ui/state-card-mini-media-player.html"];
|
||||||
|
# extra_html_url_es5 = ["/local/custom_ui/state-card-mini-media-player_es5.html"];
|
||||||
|
#};
|
||||||
|
|
||||||
|
group = {
|
||||||
|
av = {
|
||||||
|
control = "hidden";
|
||||||
|
entities = ["switch.projector" "switch.projection_screen" "input_select.hdmi_source_a" "input_number.polycom_hdmi_gain" "switch.samsung_tv_telelele" "switch.samsung_tv_mute" "input_select.hdmi_source_b" "input_number.polycom_aux1_gain" "switch.aux1_gain_mic" "media_player.mpd"];
|
||||||
|
name = "HackAV";
|
||||||
|
};
|
||||||
|
heater = {
|
||||||
|
control = "hidden";
|
||||||
|
entities = ["switch.space_heater" "input_number.heater_fan_speed"];
|
||||||
|
name = "Heater";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
input_number = {
|
||||||
|
heater_fan_speed = {
|
||||||
|
max = 100;
|
||||||
|
min = 0;
|
||||||
|
name = "Fan Speed";
|
||||||
|
step = 1;
|
||||||
|
};
|
||||||
|
polycom_aux1_gain = {
|
||||||
|
max = 10;
|
||||||
|
min = -40;
|
||||||
|
name = "AUX1 Audio Gain";
|
||||||
|
step = 1;
|
||||||
|
};
|
||||||
|
polycom_hdmi_gain = {
|
||||||
|
max = 0;
|
||||||
|
min = -40;
|
||||||
|
name = "HDMI Audio Gain";
|
||||||
|
step = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
input_select = {
|
||||||
|
hdmi_source_b = {
|
||||||
|
name = "Projector HDMI Source (Conn A/TX1)";
|
||||||
|
options = ["PS3" "Input 1 / Kolumna" "Unused" "Chromecast"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
media_player = [
|
||||||
|
{
|
||||||
|
host = "10.8.1.16";
|
||||||
|
platform = "mpd";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
mqtt = {
|
||||||
|
light = [
|
||||||
|
{
|
||||||
|
command_topic = "iot/077521/relay/on/set";
|
||||||
|
name = "Main room";
|
||||||
|
payload_off = "false";
|
||||||
|
payload_on = "true";
|
||||||
|
retain = true;
|
||||||
|
state_topic = "iot/077521/relay/on";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
fan = [
|
||||||
|
{
|
||||||
|
command_topic = "iot/c0dbe7/relay/on/set";
|
||||||
|
name = "Wyciąg";
|
||||||
|
payload_off = "false";
|
||||||
|
payload_on = "true";
|
||||||
|
retain = true;
|
||||||
|
state_topic = "iot/c0dbe7/relay/on";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
sensor = [
|
||||||
|
{
|
||||||
|
name = "DCR01 Temperature";
|
||||||
|
qos = 0;
|
||||||
|
state_topic = "iot/3394f5/environment/degree";
|
||||||
|
unit_of_measurement = "ºC";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "DCR01 Humidity";
|
||||||
|
qos = 0;
|
||||||
|
state_topic = "iot/3394f5/environment/humidity";
|
||||||
|
unit_of_measurement = "%";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
switch = [
|
||||||
|
{
|
||||||
|
command_topic = "iot/b4a90f/relay/on/set";
|
||||||
|
name = "Portable SpejsIoT node (b4a90f)";
|
||||||
|
payload_off = "false";
|
||||||
|
payload_on = "true";
|
||||||
|
retain = true;
|
||||||
|
state_topic = "iot/b4a90f/relay/on";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command_topic = "iot/d106e1/screen/down/set";
|
||||||
|
name = "Projection screen";
|
||||||
|
payload_off = "false";
|
||||||
|
payload_on = "true";
|
||||||
|
retain = true;
|
||||||
|
state_topic = "iot/d106e1/screen/down";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command_topic = "iot/craptrap/windows10/state/set";
|
||||||
|
name = "Windows 10 VM (Craptrap)";
|
||||||
|
payload_off = "pmsuspended";
|
||||||
|
payload_on = "running";
|
||||||
|
state_topic = "iot/craptrap/windows10/state";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command_topic = "iot/ab20d2/heater/on/set";
|
||||||
|
name = "Space Heater";
|
||||||
|
payload_off = "false";
|
||||||
|
payload_on = "true";
|
||||||
|
retain = true;
|
||||||
|
state_topic = "iot/ab20d2/heater/on";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
scene = [
|
||||||
|
{
|
||||||
|
entities = {
|
||||||
|
"light.main_room" = false;
|
||||||
|
"switch.projection_screen" = true;
|
||||||
|
"switch.projector" = true;
|
||||||
|
};
|
||||||
|
name = "Cinema";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
entities = {
|
||||||
|
"light.main_room" = true;
|
||||||
|
"switch.projection_screen" = false;
|
||||||
|
"switch.projector" = false;
|
||||||
|
};
|
||||||
|
name = "Standard";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"rootUUID": "77a096b7-3e3b-1040-957e-1e2094d0dd54"}
|
|
@ -144,6 +144,18 @@ let
|
||||||
"tv2.waw.hackerspace.pl" = mkMachine self pkgsArm [
|
"tv2.waw.hackerspace.pl" = mkMachine self pkgsArm [
|
||||||
../hswaw/machines/tv/tv2.nix
|
../hswaw/machines/tv/tv2.nix
|
||||||
];
|
];
|
||||||
|
"sound.waw.hackerspace.pl" = let
|
||||||
|
# TODO update global pkgs to >= 22.05 and remove this override
|
||||||
|
# building on current pkgs gives error:
|
||||||
|
# error: The option `services.home-assistant.extraComponents' does not exist.
|
||||||
|
pkgs = import (fetchTarball {
|
||||||
|
# NixOS/nixpkgs/nixos-unstable 2022-09-10
|
||||||
|
url = "https://api.github.com/repos/NixOS/nixpkgs/tarball/2da64a81275b68fdad38af669afeda43d401e94b";
|
||||||
|
sha256 = "1k71lmzdaa48yqkmsnd22n177qmxxi4gj2qcmdbv0mc6l4f27wd0";
|
||||||
|
}) {};
|
||||||
|
in mkMachine self pkgs [
|
||||||
|
../hswaw/machines/sound.waw.hackerspace.pl/configuration.nix
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
in pkgs.lib.fix machines
|
in pkgs.lib.fix machines
|
||||||
|
|
Loading…
Reference in New Issue