workhorse done and nixpkgs-fmt

This commit is contained in:
Ingolf Wagner 2021-11-01 09:20:42 +01:00
parent 87be340dfa
commit fc33e57a54
No known key found for this signature in database
GPG key ID: 76BF5F1928B9618B
124 changed files with 3142 additions and 2590 deletions

View file

@ -19,7 +19,8 @@
system = "x86_64-linux"; system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
writeCommand = krops.packages.${system}.writeCommand; writeCommand = krops.packages.${system}.writeCommand;
in { in
{
# deploy like this: # deploy like this:
# nix run ".#deploy.sterni" # nix run ".#deploy.sterni"
apps.${system}.deploy = pkgs.callPackage ./nixos/krops.nix { apps.${system}.deploy = pkgs.callPackage ./nixos/krops.nix {

View file

@ -11,7 +11,8 @@ let
rev = "2f5c44f017bdfd8abfe908d419ef26bac300f809"; rev = "2f5c44f017bdfd8abfe908d419ef26bac300f809";
sha256 = "0dxhk1ah6wwbsxyk4hd32rz7886w7r5gfy16485gjbvky1qsi8gd"; sha256 = "0dxhk1ah6wwbsxyk4hd32rz7886w7r5gfy16485gjbvky1qsi8gd";
}; };
in { in
{
# setup ftp # setup ftp
services.vsftpd = { services.vsftpd = {

View file

@ -4,28 +4,31 @@
{ modulesPath, config, lib, pkgs, ... }: { modulesPath, config, lib, pkgs, ... }:
{ {
imports = [ "${modulesPath}/installer/scan/not-detected.nix" imports = [
"${modulesPath}/installer/scan/not-detected.nix"
(let mediaUUID = "29ebe5ba-7599-4dd3-99a3-37b9bf8e4d61"; (
in { let mediaUUID = "29ebe5ba-7599-4dd3-99a3-37b9bf8e4d61";
fileSystems."/media" = { in {
device = "/dev/disk/by-uuid/${mediaUUID}"; fileSystems."/media" = {
fsType = "ext4"; device = "/dev/disk/by-uuid/${mediaUUID}";
options = [ fsType = "ext4";
"nofail" options = [
"noauto" "nofail"
#"x-systemd.device-timeout=1ms" "noauto"
]; #"x-systemd.device-timeout=1ms"
}; ];
systemd.mounts = [{ };
enable = true; systemd.mounts = [{
options = "nofail,noauto"; enable = true;
type = "ext4"; options = "nofail,noauto";
wantedBy = [ "multi-user.target" ]; type = "ext4";
what = "/dev/disk/by-uuid/${mediaUUID}"; wantedBy = [ "multi-user.target" ];
where = "/media"; what = "/dev/disk/by-uuid/${mediaUUID}";
}]; where = "/media";
}) }];
}
)
]; ];
boot.initrd.availableKernelModules = boot.initrd.availableKernelModules =

View file

@ -154,12 +154,13 @@
{ {
alias = "reset everything when back home"; alias = "reset everything when back home";
trigger = map (entity_id: { trigger = map
platform = "state"; (entity_id: {
entity_id = entity_id; platform = "state";
from = "off"; entity_id = entity_id;
to = "on"; from = "off";
}) [ to = "on";
}) [
"binary_sensor.motion_sensor_1" "binary_sensor.motion_sensor_1"
"binary_sensor.motion_sensor_2" "binary_sensor.motion_sensor_2"
"binary_sensor.motion_sensor_3" "binary_sensor.motion_sensor_3"
@ -185,57 +186,59 @@
]; ];
group = let group =
create_room = { name, description }: { let
"${name}" = { create_room = { name, description }: {
name = "${description}"; "${name}" = {
name = "${description}";
entities = [ ];
};
};
create_rooms = rooms:
lib.foldr (a: b: a // b) { } (map create_room rooms);
# rooms
# -----
in
(create_rooms [
{
name = "floor_room";
description = "Flur";
}
{
name = "bed_room";
description = "Schlafzimmer";
}
{
name = "living_room";
description = "Wohnzimmer";
}
{
name = "kitchen_room";
description = "Küche";
}
{
name = "bath_room";
description = "Klo";
}
]) // {
# overview
# --------
all_sensors = { name = "Alle Sensoren"; };
today = {
name = "Today";
entities = [ "input_select.scene" ];
};
# other stuff
# -----------
tv = { name = "TV"; };
all_lights = { name = "Alle Lampen"; };
unknown = {
name = "Not Used";
entities = [ ]; entities = [ ];
}; };
};
create_rooms = rooms:
lib.foldr (a: b: a // b) { } (map create_room rooms);
# rooms
# -----
in (create_rooms [
{
name = "floor_room";
description = "Flur";
}
{
name = "bed_room";
description = "Schlafzimmer";
}
{
name = "living_room";
description = "Wohnzimmer";
}
{
name = "kitchen_room";
description = "Küche";
}
{
name = "bath_room";
description = "Klo";
}
]) // {
# overview
# --------
all_sensors = { name = "Alle Sensoren"; };
today = {
name = "Today";
entities = [ "input_select.scene" ];
}; };
# other stuff
# -----------
tv = { name = "TV"; };
all_lights = { name = "Alle Lampen"; };
unknown = {
name = "Not Used";
entities = [ ];
};
};
}; };

View file

@ -5,7 +5,8 @@ let
folderPath = config.services.home-assistant.configDir; folderPath = config.services.home-assistant.configDir;
filePath = "${folderPath}/${name}.json"; filePath = "${folderPath}/${name}.json";
in { in
{
services.homeAssistantConfig = { services.homeAssistantConfig = {
sensor = [ sensor = [

View file

@ -66,163 +66,167 @@
[ "zigbee2mqtt/motion_sensor_7" "zigbee2mqtt/door_sensor_4" ]; [ "zigbee2mqtt/motion_sensor_7" "zigbee2mqtt/door_sensor_4" ];
} }
]; ];
sensors = let sensors =
door = { topic, room }: { let
topic = topic; door = { topic, room }: {
key = "contact"; topic = topic;
room = room; key = "contact";
invert_state = true; room = room;
delay = 90; invert_state = true;
}; delay = 90;
motion = { topic, room }: {
topic = topic;
key = "occupancy";
room = room;
delay = 60;
};
in [
(motion {
topic = "zigbee2mqtt/motion_sensor_1";
room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_2";
room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_6";
room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_8";
room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_7";
room = "sleeping_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_5";
room = "kitchen";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_4";
room = "storage_room";
})
(door {
topic = "zigbee2mqtt/door_sensor_1";
room = "storage_room";
})
(door {
topic = "zigbee2mqtt/door_sensor_5";
room = "sleeping_room";
})
(door {
# house door
topic = "zigbee2mqtt/door_sensor_4";
room = "floor";
})
];
switches = let
sonoff = { id, rooms, delay ? 0 }: {
topic = "stat/${id}/RESULT";
key = "POWER";
rooms = rooms;
delay = delay;
command = {
command = "{{state}}";
init_command = "(null)";
topic = "cmnd/${id}/POWER";
on = "ON";
off = "OFF";
}; };
}; motion = { topic, room }: {
light = { topic, rooms, delay ? 0 }: { topic = topic;
topic = topic; key = "occupancy";
key = "state"; room = room;
rooms = rooms; delay = 60;
delay = delay;
command = {
command = ''{"state":"{{state}}","brightness":{{brightness}}}'';
topic = "${topic}/set";
on = "ON";
off = "OFF";
}; };
}; in
led = { topic, rooms, delay ? 0 }: { [
topic = topic;
key = "state"; (motion {
rooms = rooms; topic = "zigbee2mqtt/motion_sensor_1";
delay = delay; room = "office_room";
command = { })
# Configure it once to the color you like (motion {
# {"state":"{{state}}","brightness":{{brightness}},"color":{"hex":"#FFFFFF},"color_temp":255","transition":0} topic = "zigbee2mqtt/motion_sensor_2";
command = '' room = "office_room";
{"state":"{{state}}","brightness":{{brightness}},"transition":0}''; })
topic = "${topic}/set"; (motion {
on = "ON"; topic = "zigbee2mqtt/motion_sensor_6";
off = "OFF"; room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_8";
room = "office_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_7";
room = "sleeping_room";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_5";
room = "kitchen";
})
(motion {
topic = "zigbee2mqtt/motion_sensor_4";
room = "storage_room";
})
(door {
topic = "zigbee2mqtt/door_sensor_1";
room = "storage_room";
})
(door {
topic = "zigbee2mqtt/door_sensor_5";
room = "sleeping_room";
})
(door {
# house door
topic = "zigbee2mqtt/door_sensor_4";
room = "floor";
})
];
switches =
let
sonoff = { id, rooms, delay ? 0 }: {
topic = "stat/${id}/RESULT";
key = "POWER";
rooms = rooms;
delay = delay;
command = {
command = "{{state}}";
init_command = "(null)";
topic = "cmnd/${id}/POWER";
on = "ON";
off = "OFF";
};
}; };
}; light = { topic, rooms, delay ? 0 }: {
in [ topic = topic;
key = "state";
rooms = rooms;
delay = delay;
command = {
command = ''{"state":"{{state}}","brightness":{{brightness}}}'';
topic = "${topic}/set";
on = "ON";
off = "OFF";
};
};
led = { topic, rooms, delay ? 0 }: {
topic = topic;
key = "state";
rooms = rooms;
delay = delay;
command = {
# Configure it once to the color you like
# {"state":"{{state}}","brightness":{{brightness}},"color":{"hex":"#FFFFFF},"color_temp":255","transition":0}
command = ''
{"state":"{{state}}","brightness":{{brightness}},"transition":0}'';
topic = "${topic}/set";
on = "ON";
off = "OFF";
};
};
in
[
(light { (light {
topic = "zigbee2mqtt/light_2"; topic = "zigbee2mqtt/light_2";
rooms = [ "office_room" ]; rooms = [ "office_room" ];
}) })
(light { (light {
topic = "zigbee2mqtt/light_4"; topic = "zigbee2mqtt/light_4";
rooms = [ "office_room" ]; rooms = [ "office_room" ];
}) })
(light { (light {
topic = "zigbee2mqtt/light_5"; topic = "zigbee2mqtt/light_5";
rooms = [ "storage_room" ]; rooms = [ "storage_room" ];
}) })
(light { (light {
topic = "zigbee2mqtt/light_7"; topic = "zigbee2mqtt/light_7";
rooms = [ "sleeping_room" ]; rooms = [ "sleeping_room" ];
}) })
(led { (led {
topic = "zigbee2mqtt/led_1"; topic = "zigbee2mqtt/led_1";
rooms = [ "office_room" ]; rooms = [ "office_room" ];
}) })
(led { (led {
topic = "zigbee2mqtt/led_2"; topic = "zigbee2mqtt/led_2";
rooms = [ "kitchen" ]; rooms = [ "kitchen" ];
}) })
#(sonoff { #(sonoff {
# id = "PAL01"; # id = "PAL01";
# rooms = [ "bed_room" ]; # rooms = [ "bed_room" ];
#}) #})
#(sonoff { #(sonoff {
# id = "PAL03"; # id = "PAL03";
# rooms = [ "living_room" ]; # rooms = [ "living_room" ];
#}) #})
#(sonoff { #(sonoff {
# id = "PAL04"; # id = "PAL04";
# rooms = [ "bed_room" ]; # rooms = [ "bed_room" ];
#}) #})
#(sonoff { #(sonoff {
# id = "PAL06"; # id = "PAL06";
# rooms = [ "kitchen" ]; # rooms = [ "kitchen" ];
#}) #})
## monitor and speakers ## monitor and speakers
#(sonoff { #(sonoff {
# id = "PAL07"; # id = "PAL07";
# rooms = [ "bed_room" ]; # rooms = [ "bed_room" ];
# delay = 180; # delay = 180;
#}) #})
#(sonoff { #(sonoff {
# id = "PAL08"; # id = "PAL08";
# rooms = [ "bed_room" ]; # rooms = [ "bed_room" ];
# delay = 180; # delay = 180;
#}) #})
]; ];
}; };
} }

View file

@ -39,7 +39,8 @@ let
toSwitch = name: "switch.${name}"; toSwitch = name: "switch.${name}";
in { in
{
imports = [ ./mqtt.nix ]; imports = [ ./mqtt.nix ];
@ -47,28 +48,32 @@ in {
# nicer names # nicer names
# ----------- # -----------
homeassistant.customize = lib.mapAttrs' (entity: homeassistant.customize = lib.mapAttrs'
{ label, icon ? "mdi:power-plug-off", ... }: { (entity:
name = toSwitch entity; { label, icon ? "mdi:power-plug-off", ... }: {
value = { name = toSwitch entity;
friendly_name = label; value = {
icon = icon; friendly_name = label;
}; icon = icon;
}) sonoffSwitches; };
})
sonoffSwitches;
# define switches # define switches
# --------------- # ---------------
switch = lib.mapAttrsToList (name: switch = lib.mapAttrsToList
{ ... }: { (name:
name = name; { ... }: {
platform = "mqtt"; name = name;
command_topic = "cmnd/${lib.toUpper name}/POWER"; platform = "mqtt";
state_topic = "stat/${lib.toUpper name}/POWER"; command_topic = "cmnd/${lib.toUpper name}/POWER";
payload_on = "ON"; state_topic = "stat/${lib.toUpper name}/POWER";
payload_off = "OFF"; payload_on = "ON";
state_on = "ON"; payload_off = "OFF";
state_off = "OFF"; state_on = "ON";
}) sonoffSwitches; state_off = "OFF";
})
sonoffSwitches;
# discover state on init # discover state on init
# ---------------------- # ----------------------
@ -78,27 +83,34 @@ in {
platform = "homeassistant"; platform = "homeassistant";
event = "start"; event = "start";
}; };
action = lib.mapAttrsToList (name: action = lib.mapAttrsToList
{ ... }: { (name:
service = "mqtt.publish"; { ... }: {
data = { service = "mqtt.publish";
topic = "cmnd/${lib.toUpper name}/power"; data = {
payload = ""; topic = "cmnd/${lib.toUpper name}/power";
}; payload = "";
}) sonoffSwitches; };
})
sonoffSwitches;
}]; }];
# append to groups # append to groups
# ---------------- # ----------------
group = let group =
# sort lights into given groups. let
sortedInGroups = let # sort lights into given groups.
groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name: sortedInGroups =
{ groups ? [ ], ... }: let
map (groupName: { "${groupName}" = "switch.${name}"; }) groups) groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList
sonoffSwitches)); (name:
in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries; { groups ? [ ], ... }:
in sortedInGroups; map (groupName: { "${groupName}" = "switch.${name}"; }) groups)
sonoffSwitches));
in
lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
in
sortedInGroups;
}; };
} }

View file

@ -27,40 +27,43 @@ let
cleanup_list = list: lib.filter (entry: entry != { }) (lib.flatten list); cleanup_list = list: lib.filter (entry: entry != { }) (lib.flatten list);
in { in
{
services.homeAssistantConfig = { services.homeAssistantConfig = {
sensor = cleanup_list (map ({ name, currency, own ? { }, ... }: [ sensor = cleanup_list (map
{ ({ name, currency, own ? { }, ... }: [
platform = "file"; {
name = "stock_${name}"; platform = "file";
file_path = filePath name; name = "stock_${name}";
value_template = "{{ value_json.price}} ${currency}"; file_path = filePath name;
value_template = "{{ value_json.price}} ${currency}";
} }
{ {
platform = "file"; platform = "file";
name = "stock_${name}_change"; name = "stock_${name}_change";
file_path = filePath name; file_path = filePath name;
value_template = "{{ value_json.change}} ${currency}"; value_template = "{{ value_json.change}} ${currency}";
} }
{ {
platform = "file"; platform = "file";
name = "stock_${name}_change_percent"; name = "stock_${name}_change_percent";
file_path = filePath name; file_path = filePath name;
value_template = "{{ value_json.change_percent}} %"; value_template = "{{ value_json.change_percent}} %";
} }
(lib.optionalAttrs (own != { }) { (lib.optionalAttrs (own != { }) {
platform = "file"; platform = "file";
name = "stock_${name}_profit"; name = "stock_${name}_profit";
file_path = filePath name; file_path = filePath name;
value_template = '' value_template = ''
{{ "{:,.2f}".format( value_json.price * ${toString own.pieces} - ${ {{ "{:,.2f}".format( value_json.price * ${toString own.pieces} - ${
toString (own.pieces * own.price) toString (own.pieces * own.price)
} ) }} ${currency}''; } ) }} ${currency}'';
}) })
]) stocks); ])
stocks);
homeassistant = { homeassistant = {
whitelist_external_dirs = [ folderPath ]; whitelist_external_dirs = [ folderPath ];
@ -94,7 +97,8 @@ in {
friendly_name = "Profit"; friendly_name = "Profit";
}; };
}) })
]) stocks)); ])
stocks));
}; };
group = (builtins.listToAttrs (map group = (builtins.listToAttrs (map
@ -108,66 +112,71 @@ in {
"sensor.stock_${name}_change_percent" "sensor.stock_${name}_change_percent"
] ++ (lib.optional (own != { }) "sensor.stock_${name}_profit"); ] ++ (lib.optional (own != { }) "sensor.stock_${name}_profit");
}; };
}) stocks)); })
stocks));
}; };
systemd.services = let systemd.services =
pullService = { name, symbol, currency, ... }: { let
name = "pull_stock_${name}"; pullService = { name, symbol, currency, ... }: {
value = { name = "pull_stock_${name}";
enable = true; value = {
before = [ "home-assistant.service" ]; enable = true;
wantedBy = [ "home-assistant.service" ]; before = [ "home-assistant.service" ];
serviceConfig = { wantedBy = [ "home-assistant.service" ];
User = "hass"; serviceConfig = {
Type = "oneshot"; User = "hass";
}; Type = "oneshot";
description = "pull stock_${name} for homeassistant"; };
script = '' description = "pull stock_${name} for homeassistant";
SYMBOL="${symbol}" script = ''
CURRENCY="${currency}" SYMBOL="${symbol}"
APIKEY=${ CURRENCY="${currency}"
lib.fileContents <secrets/home-assistant/alphavantage/apikey> APIKEY=${
} lib.fileContents <secrets/home-assistant/alphavantage/apikey>
}
${pkgs.curl}/bin/curl --location --silent \ ${pkgs.curl}/bin/curl --location --silent \
"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \ "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \
| ${pkgs.jq}/bin/jq --compact-output \ | ${pkgs.jq}/bin/jq --compact-output \
'.["Global Quote"] | '.["Global Quote"] |
{ {
price: .["05. price"] | tonumber, price: .["05. price"] | tonumber,
currency: "'$CURRENCY'", currency: "'$CURRENCY'",
change_percent: .["10. change percent"] | .[0:-1] | tonumber, change_percent: .["10. change percent"] | .[0:-1] | tonumber,
change: .["09. change"] | tonumber, change: .["09. change"] | tonumber,
last_date: .["07. latest trading day"], last_date: .["07. latest trading day"],
}' \ }' \
>> ${filePath name} >> ${filePath name}
# old and stupid # old and stupid
#${pkgs.curl}/bin/curl --location --silent \ #${pkgs.curl}/bin/curl --location --silent \
#"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=$SYMBOL&interval=5min&apikey=$APIKEY" \ #"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=$SYMBOL&interval=5min&apikey=$APIKEY" \
#| ${pkgs.jq}/bin/jq --compact-output \ #| ${pkgs.jq}/bin/jq --compact-output \
# '.["Time Series (5min)"] | to_entries | [ .[] # '.["Time Series (5min)"] | to_entries | [ .[]
# | { date : .key , value : .value["4. close"], currency: "'$CURRENCY'" } ] # | { date : .key , value : .value["4. close"], currency: "'$CURRENCY'" } ]
# | sort_by(.date) | reverse | .[0]' \ # | sort_by(.date) | reverse | .[0]' \
''; '';
};
};
in builtins.listToAttrs (map pullService stocks);
systemd.timers = let
pullTimer = { name, ... }: {
name = "pull_stock_${name}";
value = {
enable = true;
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnCalendar = "hourly";
Persistent = "true";
}; };
}; };
}; in
in builtins.listToAttrs (map pullTimer stocks); builtins.listToAttrs (map pullService stocks);
systemd.timers =
let
pullTimer = { name, ... }: {
name = "pull_stock_${name}";
value = {
enable = true;
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnCalendar = "hourly";
Persistent = "true";
};
};
};
in
builtins.listToAttrs (map pullTimer stocks);
} }

View file

@ -2,7 +2,7 @@
let let
holiday-range = month: dayA: dayB: holiday-range = month: dayA: dayB:
map (day: "${month}-${toString day}") map (day: "${month}-${toString day}")
(map (lib.fixedWidthNumber 2) (lib.range dayA dayB)); (map (lib.fixedWidthNumber 2) (lib.range dayA dayB));
privateHolidays = import <secrets/home-assistant/holidays>; privateHolidays = import <secrets/home-assistant/holidays>;
# for example : # for example :
# holidays = lib.flatten [ # holidays = lib.flatten [
@ -11,7 +11,8 @@ let
#]; #];
holidays = lib.flatten (privateHolidays holiday-range); holidays = lib.flatten (privateHolidays holiday-range);
in { in
{
services.homeAssistantConfig = { services.homeAssistantConfig = {
binary_sensor = [ binary_sensor = [

View file

@ -32,81 +32,91 @@ let
}; };
}; };
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
}; friendly_name = name;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
# define input_boolean # define input_boolean
# -------------------- # --------------------
# which get toggled by the buttons # which get toggled by the buttons
input_boolean = let stripEmpty = lib.filter (a: a != { }); input_boolean =
in builtins.listToAttrs (stripEmpty (lib.flatten (lib.mapAttrsToList (name: let stripEmpty = lib.filter (a: a != { });
{ states ? { }, ... }: [ in builtins.listToAttrs (stripEmpty (lib.flatten (lib.mapAttrsToList
(lib.optionalAttrs (!lib.hasAttr "single" states) { (name:
name = "single_${name}"; { states ? { }, ... }: [
value = { icon = "mdi:toggle-switch"; }; (lib.optionalAttrs (!lib.hasAttr "single" states) {
}) name = "single_${name}";
(lib.optionalAttrs (!lib.hasAttr "double" states) { value = { icon = "mdi:toggle-switch"; };
name = "double_${name}"; })
value = { icon = "mdi:toggle-switch"; }; (lib.optionalAttrs (!lib.hasAttr "double" states) {
}) name = "double_${name}";
(lib.optionalAttrs (!lib.hasAttr "hold" states) { value = { icon = "mdi:toggle-switch"; };
name = "hold_${name}"; })
value = { icon = "mdi:toggle-switch"; }; (lib.optionalAttrs (!lib.hasAttr "hold" states) {
}) name = "hold_${name}";
]) allDevices))); value = { icon = "mdi:toggle-switch"; };
})
])
allDevices)));
# define meta information sensors # define meta information sensors
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
platform = "mqtt"; {
name = name; platform = "mqtt";
icon = "mdi:toggle-switch"; name = name;
state_topic = "zigbee2mqtt/${name}"; icon = "mdi:toggle-switch";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
value_template = "{{ value_json.click }}"; availability_topic = "zigbee2mqtt/bridge/state";
} value_template = "{{ value_json.click }}";
{ }
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
]) allDevices); }
])
allDevices);
binary_sensor = lib.mapAttrsToList (name: binary_sensor = lib.mapAttrsToList
{ ... }: { (name:
name = name; { ... }: {
platform = "mqtt"; name = name;
device_class = "motion"; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; device_class = "motion";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
payload_on = true; availability_topic = "zigbee2mqtt/bridge/state";
payload_off = false; payload_on = true;
value_template = "{{ value_json.occupancy }}"; payload_off = false;
}) allDevices; value_template = "{{ value_json.occupancy }}";
})
allDevices;
# create groups # create groups
# ------------- # -------------
@ -144,82 +154,96 @@ in {
# create automation # create automation
# ----------------- # -----------------
automation = let automation =
let
# single click # single click
toggle_single_button_input = lib.mapAttrsToList (name: toggle_single_button_input = lib.mapAttrsToList
{ states ? { }, ... }: (name:
let { states ? { }, ... }:
entityId = if (lib.hasAttr "single" states) then let
states.single entityId =
else if (lib.hasAttr "single" states) then
"input_boolean.single_${name}"; states.single
in { else
alias = "toggle single click ${name}"; "input_boolean.single_${name}";
trigger = { in
platform = "mqtt"; {
topic = "zigbee2mqtt/${name}"; alias = "toggle single click ${name}";
}; trigger = {
condition = { platform = "mqtt";
condition = "template"; topic = "zigbee2mqtt/${name}";
value_template = ''{{ "single" == trigger.payload_json.click}}''; };
}; condition = {
action = { condition = "template";
service = "input_boolean.toggle"; value_template = ''{{ "single" == trigger.payload_json.click}}'';
data.entity_id = entityId; };
}; action = {
}) allDevices; service = "input_boolean.toggle";
data.entity_id = entityId;
};
})
allDevices;
# double click # double click
toggle_double_button_input = lib.mapAttrsToList (name: toggle_double_button_input = lib.mapAttrsToList
{ states ? { }, ... }: (name:
let { states ? { }, ... }:
entityId = if (lib.hasAttr "double" states) then let
states.double entityId =
else if (lib.hasAttr "double" states) then
"input_boolean.double_${name}"; states.double
in { else
alias = "toggle double click ${name}"; "input_boolean.double_${name}";
trigger = { in
platform = "mqtt"; {
topic = "zigbee2mqtt/${name}"; alias = "toggle double click ${name}";
}; trigger = {
condition = { platform = "mqtt";
condition = "template"; topic = "zigbee2mqtt/${name}";
value_template = ''{{ "double" == trigger.payload_json.click}}''; };
}; condition = {
action = { condition = "template";
service = "input_boolean.toggle"; value_template = ''{{ "double" == trigger.payload_json.click}}'';
data.entity_id = entityId; };
}; action = {
}) allDevices; service = "input_boolean.toggle";
data.entity_id = entityId;
};
})
allDevices;
# hold # hold
toggle_hold_button_input = lib.mapAttrsToList (name: toggle_hold_button_input = lib.mapAttrsToList
{ states ? { }, ... }: (name:
let { states ? { }, ... }:
entityId = if (lib.hasAttr "hold" states) then let
states.hold entityId =
else if (lib.hasAttr "hold" states) then
"input_boolean.hold_${name}"; states.hold
in { else
alias = "toggle hold ${name}"; "input_boolean.hold_${name}";
trigger = { in
platform = "mqtt"; {
topic = "zigbee2mqtt/${name}"; alias = "toggle hold ${name}";
}; trigger = {
condition = { platform = "mqtt";
condition = "template"; topic = "zigbee2mqtt/${name}";
value_template = ''{{ "hold" == trigger.payload_json.action}}''; };
}; condition = {
action = { condition = "template";
service = "input_boolean.toggle"; value_template = ''{{ "hold" == trigger.payload_json.action}}'';
data.entity_id = entityId; };
}; action = {
}) allDevices; service = "input_boolean.toggle";
data.entity_id = entityId;
};
})
allDevices;
in lib.flatten (toggle_single_button_input ++ toggle_double_button_input in
++ toggle_hold_button_input); lib.flatten (toggle_single_button_input ++ toggle_double_button_input
++ toggle_hold_button_input);
}; };

View file

@ -10,77 +10,91 @@ let
"door_sensor_5" = { id = "0x00158d0003120d3e"; }; "door_sensor_5" = { id = "0x00158d0003120d3e"; };
}; };
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
}; friendly_name = name;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
# define meta information sensors # define meta information sensors
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
]) allDevices); }
])
allDevices);
binary_sensor = lib.mapAttrsToList (name: binary_sensor = lib.mapAttrsToList
{ ... }: { (name:
name = name; { ... }: {
platform = "mqtt"; name = name;
device_class = "door"; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; device_class = "door";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
payload_on = false; availability_topic = "zigbee2mqtt/bridge/state";
payload_off = true; payload_on = false;
value_template = "{{ value_json.contact}}"; payload_off = true;
}) allDevices; value_template = "{{ value_json.contact}}";
})
allDevices;
# create groups # create groups
# ------------- # -------------
group = let group =
# to have nice panels for every device let
sensorGroups = lib.mapAttrs (name: # to have nice panels for every device
{ ... }: { sensorGroups = lib.mapAttrs
entities = [ (name:
"binary_sensor.${name}" { ... }: {
"sensor.battery_${name}" entities = [
"sensor.link_${name}" "binary_sensor.${name}"
]; "sensor.battery_${name}"
}) allDevices; "sensor.link_${name}"
# sort lights into given groups. ];
sortedInGroups = let })
groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList (name: allDevices;
{ groups ? [ ], ... }: # sort lights into given groups.
map (groupName: { "${groupName}" = "binary_sensor.${name}"; }) groups) sortedInGroups =
allDevices)); let
in lib.mapAttrs (name: entities: { inherit entities; }) groupEntries; groupEntries = lib.zipAttrs (lib.flatten (lib.mapAttrsToList
in sortedInGroups // sensorGroups // { (name:
all_sensors.entities = { groups ? [ ], ... }:
lib.mapAttrsToList (name: { ... }: "binary_sensor.${name}") allDevices; map (groupName: { "${groupName}" = "binary_sensor.${name}"; }) groups)
}; allDevices));
in
lib.mapAttrs (name: entities: { inherit entities; }) groupEntries;
in
sortedInGroups // sensorGroups // {
all_sensors.entities =
lib.mapAttrsToList (name: { ... }: "binary_sensor.${name}") allDevices;
};
}; };

View file

@ -11,41 +11,46 @@ let
# -t "zigbee2mqtt/fyrtur1/set" -m '{"position":100}' # -t "zigbee2mqtt/fyrtur1/set" -m '{"position":100}'
# -t "zigbee2mqtt/fyrtur1/set" -m '{"position":15}' # -t "zigbee2mqtt/fyrtur1/set" -m '{"position":15}'
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
transition = 0.1; friendly_name = name;
}; transition = 0.1;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
]) allDevices); }
])
allDevices);
}; };

View file

@ -12,68 +12,73 @@ let
# -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"auto","current_heating_setpoint":23}' # -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"auto","current_heating_setpoint":23}'
# -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"off"}' # -t "zigbee2mqtt/heater3/set" -m '{"system_mode":"off"}'
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
legacy = false; value = {
retain = false; legacy = false;
friendly_name = name; retain = false;
transition = 1; friendly_name = name;
debounce = 0.5; transition = 1;
filtered_attributes = [ debounce = 0.5;
"battery_low" filtered_attributes = [
"eurotronic_host_flags" "battery_low"
"eurotronic_system_mode" "eurotronic_host_flags"
#"occupied_heating_setpoint" "eurotronic_system_mode"
#"pi_heating_demand" #"occupied_heating_setpoint"
#"unoccupied_heating_setpoint" #"pi_heating_demand"
]; #"unoccupied_heating_setpoint"
}; ];
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
{ }
platform = "mqtt"; {
name = "temperature_${name}"; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = "temperature_${name}";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "°C"; availability_topic = "zigbee2mqtt/bridge/state";
device_class = "temperature"; unit_of_measurement = "°C";
value_template = "{{ value_json.local_temperature }}"; device_class = "temperature";
} value_template = "{{ value_json.local_temperature }}";
{ }
platform = "mqtt"; {
name = "pi_heating_demand_${name}"; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = "pi_heating_demand_${name}";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
value_template = "{{ value_json.pi_heating_demand }}"; unit_of_measurement = "%";
} value_template = "{{ value_json.pi_heating_demand }}";
]) allDevices); }
])
allDevices);
}; };

View file

@ -11,32 +11,37 @@ let
# -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF","transition":0, "color_temp":255}' # -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF","transition":0, "color_temp":255}'
# -t "zigbee2mqtt/led_1/set" -m '{"state":"ON","brightness":255,"color":{"hex":"#00FFFF"}}' # -t "zigbee2mqtt/led_1/set" -m '{"state":"ON","brightness":255,"color":{"hex":"#00FFFF"}}'
# -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF"}' # -t "zigbee2mqtt/led_1/set" -m '{"state":"OFF"}'
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
transition = 1; friendly_name = name;
}; transition = 1;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
light = lib.mapAttrsToList (name: light = lib.mapAttrsToList
{ ... }: { (name:
platform = "mqtt"; { ... }: {
name = name; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = name;
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
command_topic = "zigbee2mqtt/${name}/set"; availability_topic = "zigbee2mqtt/bridge/state";
value_template = "{{ value_json.click }}"; command_topic = "zigbee2mqtt/${name}/set";
brightness = true; value_template = "{{ value_json.click }}";
color_temp = true; brightness = true;
schema = "json"; color_temp = true;
}) allDevices; schema = "json";
})
allDevices;
}; };

View file

@ -13,32 +13,37 @@ let
"light_8" = { id = "0x7cb03eaa0a0384d3"; }; "light_8" = { id = "0x7cb03eaa0a0384d3"; };
}; };
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
osram_set_transition = 2; # time in seconds (integer or float) friendly_name = name;
}; osram_set_transition = 2; # time in seconds (integer or float)
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
light = lib.mapAttrsToList (name: light = lib.mapAttrsToList
{ ... }: { (name:
platform = "mqtt"; { ... }: {
name = name; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = name;
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
command_topic = "zigbee2mqtt/${name}/set"; availability_topic = "zigbee2mqtt/bridge/state";
value_template = "{{ value_json.click }}"; command_topic = "zigbee2mqtt/${name}/set";
brightness = true; value_template = "{{ value_json.click }}";
color_temp = true; brightness = true;
schema = "json"; color_temp = true;
}) allDevices; schema = "json";
})
allDevices;
# sensor = with lib; # sensor = with lib;
# mapAttrsToList (name: # mapAttrsToList (name:

View file

@ -14,56 +14,63 @@ let
"motion_sensor_8" = { id = "0x00158d0002f04637"; }; "motion_sensor_8" = { id = "0x00158d0002f04637"; };
}; };
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, timeout ? 65, ... }: { (name:
name = id; { id, timeout ? 65, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
# should not be set below 60 seconds friendly_name = name;
occupancy_timeout = timeout; # should not be set below 60 seconds
}; occupancy_timeout = timeout;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
# define meta information sensors # define meta information sensors
binary_sensor = lib.flatten (lib.mapAttrsToList (name: binary_sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [{ (name:
name = "${name}"; { ... }: [{
platform = "mqtt"; name = "${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
value_template = "{{ value_json.occupancy }}"; availability_topic = "zigbee2mqtt/bridge/state";
#icon = "mdi:battery-10"; value_template = "{{ value_json.occupancy }}";
payload_on = true; #icon = "mdi:battery-10";
payload_off = false; payload_on = true;
device_class = "motion"; payload_off = false;
}]) allDevices); device_class = "motion";
}])
allDevices);
# define meta information sensors # define meta information sensors
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
]) allDevices); }
])
allDevices);
}; };
} }

View file

@ -9,10 +9,13 @@ let
"repeater4" = { id = "0x680ae2fffe8e2e71"; }; "repeater4" = { id = "0x680ae2fffe8e2e71"; };
}; };
in { in
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: {
{ id, ... }: { services.zigbee2mqttConfiguration = lib.mapAttrs'
name = id; (name:
value = { friendly_name = name; }; { id, ... }: {
}) allDevices; name = id;
value = { friendly_name = name; };
})
allDevices;
} }

View file

@ -26,7 +26,8 @@ let
# is copied from the store on startup # is copied from the store on startup
devices = "devices.yaml"; devices = "devices.yaml";
}; };
in { in
{
options.custom.services.zigbee2mqtt = { options.custom.services.zigbee2mqtt = {
enable = mkEnableOption "enable zigbee2mqtt service"; enable = mkEnableOption "enable zigbee2mqtt service";

View file

@ -13,68 +13,73 @@ let
}; };
}; };
in { in
{
services.zigbee2mqttConfiguration = lib.mapAttrs' (name: services.zigbee2mqttConfiguration = lib.mapAttrs'
{ id, ... }: { (name:
name = id; { id, ... }: {
value = { name = id;
retain = false; value = {
friendly_name = name; retain = false;
}; friendly_name = name;
}) allDevices; };
})
allDevices;
services.homeAssistantConfig = { services.homeAssistantConfig = {
# define meta information sensors # define meta information sensors
sensor = lib.flatten (lib.mapAttrsToList (name: sensor = lib.flatten (lib.mapAttrsToList
{ ... }: [ (name:
{ { ... }: [
platform = "mqtt"; {
name = name; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = name;
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "°C"; availability_topic = "zigbee2mqtt/bridge/state";
device_class = "temperature"; unit_of_measurement = "°C";
value_template = "{{ value_json.temperature }}"; device_class = "temperature";
} value_template = "{{ value_json.temperature }}";
{ }
platform = "mqtt"; {
name = "humidity_${name}"; platform = "mqtt";
state_topic = "zigbee2mqtt/${name}"; name = "humidity_${name}";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
device_class = "humidity"; unit_of_measurement = "%";
value_template = "{{ value_json.humidity }}"; device_class = "humidity";
} value_template = "{{ value_json.humidity }}";
#{ }
# platform = "mqtt"; #{
# name = "pressure_${name}"; # platform = "mqtt";
# state_topic = "zigbee2mqtt/${name}"; # name = "pressure_${name}";
# availability_topic = "zigbee2mqtt/bridge/state"; # state_topic = "zigbee2mqtt/${name}";
# unit_of_measurement = "hPa"; # availability_topic = "zigbee2mqtt/bridge/state";
# device_class = "pressure"; # unit_of_measurement = "hPa";
# value_template = "{{ value_json.pressure }}"; # device_class = "pressure";
#} # value_template = "{{ value_json.pressure }}";
{ #}
name = "battery_${name}"; {
platform = "mqtt"; name = "battery_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
unit_of_measurement = "%"; availability_topic = "zigbee2mqtt/bridge/state";
icon = "mdi:battery-10"; unit_of_measurement = "%";
value_template = "{{ value_json.battery }}"; icon = "mdi:battery-10";
} value_template = "{{ value_json.battery }}";
{ }
name = "link_${name}"; {
platform = "mqtt"; name = "link_${name}";
state_topic = "zigbee2mqtt/${name}"; platform = "mqtt";
availability_topic = "zigbee2mqtt/bridge/state"; state_topic = "zigbee2mqtt/${name}";
icon = "mdi:signal"; availability_topic = "zigbee2mqtt/bridge/state";
unit_of_measurement = "lqi"; icon = "mdi:signal";
value_template = "{{ value_json.linkquality }}"; unit_of_measurement = "lqi";
} value_template = "{{ value_json.linkquality }}";
]) allDevices); }
])
allDevices);
# create groups # create groups
# ------------- # -------------

View file

@ -5,7 +5,8 @@ let
ipAddress = "10.1.0.2"; ipAddress = "10.1.0.2";
prefixLength = 24; prefixLength = 24;
in { in
{
networking.extraHosts = '' networking.extraHosts = ''
10.1.0.1 workout.lan 10.1.0.1 workout.lan

View file

@ -30,63 +30,63 @@
services.spotifyd.enable = true; services.spotifyd.enable = true;
services.spotifyd.config = '' services.spotifyd.config = ''
[global] [global]
username_cmd = "cat ${config.sops.secrets.spotify_user.path}" username_cmd = "cat ${config.sops.secrets.spotify_user.path}"
password_cmd = "cat ${config.sops.secrets.spotify_pass.path}" password_cmd = "cat ${config.sops.secrets.spotify_pass.path}"
backend = "alsa" # use portaudio for macOS [homebrew] backend = "alsa" # use portaudio for macOS [homebrew]
# The alsa audio device to stream audio to. To get a # The alsa audio device to stream audio to. To get a
# list of valid devices, run `aplay -L`, # list of valid devices, run `aplay -L`,
#device = "alsa_audio_device" # omit for macOS #device = "alsa_audio_device" # omit for macOS
# The alsa mixer used by `spotifyd`. # The alsa mixer used by `spotifyd`.
mixer = "PCM" # omit for macOS mixer = "PCM" # omit for macOS
# A script that gets evaluated in the user's shell when the song changes [aliases: onevent] # A script that gets evaluated in the user's shell when the song changes [aliases: onevent]
on-song-change-hook = "${pkgs.mpc_cli}/bin/mpc --host localhost --port 6600 stop" on-song-change-hook = "${pkgs.mpc_cli}/bin/mpc --host localhost --port 6600 stop"
# The volume controller. Each one behaves different to # The volume controller. Each one behaves different to
# volume increases. For possible values, run # volume increases. For possible values, run
# `spotifyd --help`. # `spotifyd --help`.
volume_controller = "alsa" # use softvol for macOS volume_controller = "alsa" # use softvol for macOS
# The name that gets displayed under the connect tab on # The name that gets displayed under the connect tab on
# official clients. Spaces are not allowed! # official clients. Spaces are not allowed!
device_name = "DJane" device_name = "DJane"
# The audio bitrate. 96, 160 or 320 kbit/s # The audio bitrate. 96, 160 or 320 kbit/s
bitrate = 320 bitrate = 320
# The directory used to cache audio data. This setting can save # The directory used to cache audio data. This setting can save
# a lot of bandwidth when activated, as it will avoid re-downloading # a lot of bandwidth when activated, as it will avoid re-downloading
# audio files when replaying them. # audio files when replaying them.
# #
# Note: The file path does not get expanded. Environment variables and # Note: The file path does not get expanded. Environment variables and
# shell placeholders like $HOME or ~ don't work! # shell placeholders like $HOME or ~ don't work!
#cache_path = "cache_directory" #cache_path = "cache_directory"
# If set to true, audio data does NOT get cached. # If set to true, audio data does NOT get cached.
no_audio_cache = true no_audio_cache = true
# Volume on startup between 0 and 100 # Volume on startup between 0 and 100
# NOTE: This variable's type will change in v0.4, to a number (instead of string) # NOTE: This variable's type will change in v0.4, to a number (instead of string)
initial_volume = "90" initial_volume = "90"
# If set to true, enables volume normalisation between songs. # If set to true, enables volume normalisation between songs.
volume_normalisation = false volume_normalisation = false
# The normalisation pregain that is applied for each song. # The normalisation pregain that is applied for each song.
# normalisation_pregain = -10 # normalisation_pregain = -10
# The port `spotifyd` uses to announce its service over the network. # The port `spotifyd` uses to announce its service over the network.
zeroconf_port = 1234 zeroconf_port = 1234
# The proxy `spotifyd` will use to connect to spotify. # The proxy `spotifyd` will use to connect to spotify.
#proxy = "http://proxy.example.org:8080" #proxy = "http://proxy.example.org:8080"
# The displayed device type in Spotify clients. # The displayed device type in Spotify clients.
# Can be unknown, computer, tablet, smartphone, speaker, t_v, # Can be unknown, computer, tablet, smartphone, speaker, t_v,
# a_v_r (Audio/Video Receiver), s_t_b (Set-Top Box), and audio_dongle. # a_v_r (Audio/Video Receiver), s_t_b (Set-Top Box), and audio_dongle.
device_type = "computer" device_type = "computer"
''; '';
} }

View file

@ -11,7 +11,7 @@
services.taskwarrior-pushover = { services.taskwarrior-pushover = {
enable = true; enable = true;
recurrence="on"; recurrence = "on";
onCalendar = "06:30:00"; onCalendar = "06:30:00";
server = "taskd.ingolf-wagner.de:53589"; server = "taskd.ingolf-wagner.de:53589";
pushoverApiTokenFile = config.sops.secrets.pushoverApiToken.path; pushoverApiTokenFile = config.sops.secrets.pushoverApiToken.path;
@ -19,6 +19,6 @@
caFile = config.sops.secrets.taskwarriorCa.path; caFile = config.sops.secrets.taskwarriorCa.path;
certificateFile = config.sops.secrets.taskwarriorCertificate.path; certificateFile = config.sops.secrets.taskwarriorCertificate.path;
keyFile = config.sops.secrets.taskwarriorKey.path; keyFile = config.sops.secrets.taskwarriorKey.path;
credentials= "1337/palo/ed0fdbe8-2dc3-408b-84cb-d07d363bccd2"; credentials = "1337/palo/ed0fdbe8-2dc3-408b-84cb-d07d363bccd2";
}; };
} }

View file

@ -10,7 +10,8 @@ let
ssid = "palosiot"; ssid = "palosiot";
wifiPassword = lib.fileContents <secrets/iot_wifi>; wifiPassword = lib.fileContents <secrets/iot_wifi>;
in { in
{
# todo only open needed ports # todo only open needed ports
networking.firewall.trustedInterfaces = [ wifi ]; networking.firewall.trustedInterfaces = [ wifi ];

View file

@ -27,26 +27,28 @@
# automount # automount
# --------- # ---------
(let mediaUUID = "3d106f56-89e5-400d-9d6b-1dd957919548"; (
in { let mediaUUID = "3d106f56-89e5-400d-9d6b-1dd957919548";
fileSystems."/media" = { in {
device = "/dev/disk/by-uuid/${mediaUUID}"; fileSystems."/media" = {
fsType = "ext4"; device = "/dev/disk/by-uuid/${mediaUUID}";
options = [ fsType = "ext4";
"nofail" options = [
"noauto" "nofail"
#"x-systemd.device-timeout=1ms" "noauto"
]; #"x-systemd.device-timeout=1ms"
}; ];
systemd.mounts = [{ };
enable = true; systemd.mounts = [{
options = "nofail,noauto"; enable = true;
type = "ext4"; options = "nofail,noauto";
wantedBy = [ "multi-user.target" ]; type = "ext4";
what = "/dev/disk/by-uuid/${mediaUUID}"; wantedBy = [ "multi-user.target" ];
where = "/media"; what = "/dev/disk/by-uuid/${mediaUUID}";
}]; where = "/media";
}) }];
}
)
]; ];
# NTFS support # NTFS support

View file

@ -54,7 +54,12 @@
after = [ "media.mount" ]; after = [ "media.mount" ];
}; };
users.groups."syncthing".members = [ mpd" "syncthing" "kodi" "palo" ]; users.groups."syncthing".members = [
"mpd"
"syncthing"
"kodi"
"palo"
];
backup.dirs = [ "/var/lib/syncthing/finance" ]; backup.dirs = [ "/var/lib/syncthing/finance" ];

View file

@ -8,7 +8,8 @@ let
ssid = "palosiot"; ssid = "palosiot";
wifiPassword = lib.fileContents <secrets/iot_wifi>; wifiPassword = lib.fileContents <secrets/iot_wifi>;
in { in
{
# todo only open needed ports # todo only open needed ports
networking.firewall.trustedInterfaces = [ wifi ]; networking.firewall.trustedInterfaces = [ wifi ];

View file

@ -1,4 +1,2 @@
{ config, lib, ... }: { config, lib, ... }:
{ { }
}

View file

@ -3,7 +3,8 @@ let
domain = "io.ingolf-wagner.de"; domain = "io.ingolf-wagner.de";
publicIp = "195.201.134.247"; publicIp = "195.201.134.247";
pw = import <secrets/iodinepw.nix>; pw = import <secrets/iodinepw.nix>;
in { in
{
services.iodine.server = { services.iodine.server = {
enable = true; enable = true;

View file

@ -28,7 +28,8 @@ let
root = "${errorPages}/"; root = "${errorPages}/";
}; };
}; };
in { in
{
networking.firewall.allowedTCPPorts = networking.firewall.allowedTCPPorts =
[ 80 443 4443 config.services.taskserver.listenPort ]; [ 80 443 4443 config.services.taskserver.listenPort ];
@ -117,7 +118,7 @@ in {
} // error.locations; } // error.locations;
}; };
"grocy.ingolf-wagner.de" = { "grocy.ingolf-wagner.de" = {
listen = [ listen = [
{ {
addr = "0.0.0.0"; addr = "0.0.0.0";
@ -439,10 +440,11 @@ in {
systemd.services."socat-taskd" = { systemd.services."socat-taskd" = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = let port = toString config.services.taskserver.listenPort; script =
in '' let port = toString config.services.taskserver.listenPort;
${pkgs.socat}/bin/socat TCP-LISTEN:${port},fork TCP:workhorse.private:${port} in ''
''; ${pkgs.socat}/bin/socat TCP-LISTEN:${port},fork TCP:workhorse.private:${port}
'';
}; };
} }

View file

@ -8,7 +8,8 @@ let
ssid = "bumbumbum"; ssid = "bumbumbum";
wifiPassword = lib.fileContents <secrets/wifi-access-point>; wifiPassword = lib.fileContents <secrets/wifi-access-point>;
in { in
{
# todo only open needed ports # todo only open needed ports
networking.firewall.trustedInterfaces = [ wifi ]; networking.firewall.trustedInterfaces = [ wifi ];

View file

@ -9,7 +9,8 @@ let
https://nextcloud.ingolf-wagner.de/remote.php/webdav/${folder} https://nextcloud.ingolf-wagner.de/remote.php/webdav/${folder}
''; '';
in { in
{
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [

View file

@ -8,7 +8,8 @@ let
ssid = "bumbumbum"; ssid = "bumbumbum";
wifiPassword = lib.fileContents <secrets/wifi-access-point>; wifiPassword = lib.fileContents <secrets/wifi-access-point>;
in { in
{
# todo only open needed ports # todo only open needed ports
networking.firewall.trustedInterfaces = [ wifi ]; networking.firewall.trustedInterfaces = [ wifi ];

View file

@ -3,7 +3,8 @@ let
home = "/home/syncthing/podcasts"; home = "/home/syncthing/podcasts";
in { in
{
custom.services.castget = { custom.services.castget = {
enable = true; enable = true;
user = "root"; user = "root";

View file

@ -20,7 +20,8 @@ let
stocks = import ../../private_assets/finance/stocks; stocks = import ../../private_assets/finance/stocks;
stocksFile = toString /home/syncthing/finance/hledger/stocks.journal; stocksFile = toString /home/syncthing/finance/hledger/stocks.journal;
in { in
{
systemd.services.pull_stocks = { systemd.services.pull_stocks = {
enable = true; enable = true;
@ -30,18 +31,20 @@ in {
Type = "oneshot"; Type = "oneshot";
}; };
script = let script =
command = { symbol, name, currency, ... }: '' let
APIKEY=${lib.fileContents ../../private_assets/finance/alphavantage/apiKey} command = { symbol, name, currency, ... }: ''
SYMBOL="${symbol}" APIKEY=${lib.fileContents ../../private_assets/finance/alphavantage/apiKey}
${pkgs.curl}/bin/curl --location --silent \ SYMBOL="${symbol}"
"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \ ${pkgs.curl}/bin/curl --location --silent \
| ${pkgs.jq}/bin/jq --raw-output '.["Global Quote"] "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=$SYMBOL&apikey=$APIKEY" \
| "P \(.["07. latest trading day"]) ${name} ${currency}\(.["05. price"] | tonumber)"' \ | ${pkgs.jq}/bin/jq --raw-output '.["Global Quote"]
>> ${stocksFile} | "P \(.["07. latest trading day"]) ${name} ${currency}\(.["05. price"] | tonumber)"' \
sleep 1 >> ${stocksFile}
''; sleep 1
in lib.concatStringsSep "\n" (map command stocks); '';
in
lib.concatStringsSep "\n" (map command stocks);
}; };
systemd.timers.pull_stocks = { systemd.timers.pull_stocks = {

View file

@ -28,7 +28,8 @@ let
}; };
}; };
in { in
{
services.nginx = { services.nginx = {
enable = true; enable = true;

View file

@ -70,47 +70,51 @@ in {
imports = [ imports = [
# automount # automount
# --------- # ---------
(let mediaUUID = "b8ba192e-e2aa-47dd-85ec-dcf97ec9310a"; (
in { let mediaUUID = "b8ba192e-e2aa-47dd-85ec-dcf97ec9310a";
fileSystems."/media" = { in {
device = "/dev/disk/by-uuid/${mediaUUID}"; fileSystems."/media" = {
fsType = "ext4"; device = "/dev/disk/by-uuid/${mediaUUID}";
options = [ fsType = "ext4";
"nofail" options = [
"noauto" "nofail"
#"x-systemd.device-timeout=1ms" "noauto"
]; #"x-systemd.device-timeout=1ms"
}; ];
systemd.mounts = [{ };
enable = true; systemd.mounts = [{
options = "nofail,noauto"; enable = true;
type = "ext4"; options = "nofail,noauto";
wantedBy = [ "multi-user.target" ]; type = "ext4";
what = "/dev/disk/by-uuid/${mediaUUID}"; wantedBy = [ "multi-user.target" ];
where = "/media"; what = "/dev/disk/by-uuid/${mediaUUID}";
}]; where = "/media";
}) }];
}
)
(let backupUUID = "f7fa1c0e-ac9f-4955-b4bd-644c1ddb0d89"; (
in { let backupUUID = "f7fa1c0e-ac9f-4955-b4bd-644c1ddb0d89";
fileSystems."/backup" = { in {
device = "/dev/disk/by-uuid/${backupUUID}"; fileSystems."/backup" = {
fsType = "ext4"; device = "/dev/disk/by-uuid/${backupUUID}";
options = [ fsType = "ext4";
"nofail" options = [
"noauto" "nofail"
#"x-systemd.device-timeout=1ms" "noauto"
]; #"x-systemd.device-timeout=1ms"
}; ];
systemd.mounts = [{ };
enable = true; systemd.mounts = [{
options = "nofail,noauto"; enable = true;
type = "ext4"; options = "nofail,noauto";
wantedBy = [ "multi-user.target" ]; type = "ext4";
what = "/dev/disk/by-uuid/${backupUUID}"; wantedBy = [ "multi-user.target" ];
where = "/backup"; what = "/dev/disk/by-uuid/${backupUUID}";
}]; where = "/backup";
}) }];
}
)
]; ];
} }

View file

@ -9,7 +9,8 @@ let
sync-repo = library.jenkins.syncJob; sync-repo = library.jenkins.syncJob;
job = library.jenkins.job; job = library.jenkins.job;
in { in
{
environment.systemPackages = [ pkgs.cabal-install ]; environment.systemPackages = [ pkgs.cabal-install ];
@ -62,139 +63,145 @@ in {
accessUser = "admin"; accessUser = "admin";
# https://docs.openstack.org/infra/jenkins-job-builder/definition.html#modules # https://docs.openstack.org/infra/jenkins-job-builder/definition.html#modules
nixJobs = let nixJobs =
# ssh username + key let
gogs-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2"; # ssh username + key
# ssh username + key gogs-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2";
github-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2"; # ssh username + key
# ssh username + key github-id = "bc584c99-0fb7-43fb-af75-4076d64c51b2";
sshSputnik = "d91eb57c-5bff-434c-b317-68aad46848d7"; # ssh username + key
sshSputnik = "d91eb57c-5bff-434c-b317-68aad46848d7";
sync-to-github = name: source: target: sync-to-github = name: source: target:
sync-repo name { sync-repo name
url = source; {
credentialsId = gogs-id; url = source;
} { credentialsId = gogs-id;
url = target; }
credentialsId = github-id; {
}; url = target;
credentialsId = github-id;
};
in [ in
[
(job "sync-retiolum" { (job "sync-retiolum"
url = "git@github.com:krebs/retiolum.git"; {
credentialsId = github-id; url = "git@github.com:krebs/retiolum.git";
triggers = [{ timed = "H/30 * * * *"; }];
} [
{
"Download Files" = [
"chmod 755 hosts"
"chmod 755 -R hosts"
''
nix-shell -p curl -p gnutar -p bzip2 --run "curl https://lassul.us/retiolum-hosts.tar.bz2 | tar xvjf - || true"''
"chmod 755 -R etc.hosts"
''
nix-shell -p curl --run "curl https://lassul.us/retiolum.hosts > etc.hosts || true"''
];
}
{
"update repo" = [
''nix-shell -p git --run "git add ."''
''
nix-shell -p git --run "git -c user.name=\'Ingolf Wagner\' -c user.email=\'contact@ingolf-wagner.de\' commit -m update-`date +%Y-%m-%dT%H:%M:%S` || exit 0"''
];
}
{
Push = [{
script = ''nix-shell -p git --run "git push origin master"'';
credentialsId = github-id; credentialsId = github-id;
}]; triggers = [{ timed = "H/30 * * * *"; }];
} } [
]) {
"Download Files" = [
"chmod 755 hosts"
"chmod 755 -R hosts"
''
nix-shell -p curl -p gnutar -p bzip2 --run "curl https://lassul.us/retiolum-hosts.tar.bz2 | tar xvjf - || true"''
"chmod 755 -R etc.hosts"
''
nix-shell -p curl --run "curl https://lassul.us/retiolum.hosts > etc.hosts || true"''
];
}
{
"update repo" = [
''nix-shell -p git --run "git add ."''
''
nix-shell -p git --run "git -c user.name=\'Ingolf Wagner\' -c user.email=\'contact@ingolf-wagner.de\' commit -m update-`date +%Y-%m-%dT%H:%M:%S` || exit 0"''
];
}
{
Push = [{
script = ''nix-shell -p git --run "git push origin master"'';
credentialsId = github-id;
}];
}
])
(job "test-taskninja" { (job "test-taskninja"
url = "ssh://gogs@workhorse.private:2222/palo/taskninja.git"; {
credentialsId = gogs-id; url = "ssh://gogs@workhorse.private:2222/palo/taskninja.git";
} [ credentialsId = gogs-id;
{ } [
"Create Shell" = [ {
'' "Create Shell" = [
nix-shell -p cabal2nix --run "cabal2nix --shell file://. > jenkins.nix"'' ''
]; nix-shell -p cabal2nix --run "cabal2nix --shell file://. > jenkins.nix"''
} ];
{ Update = [ ''nix-shell ./jenkins.nix --run "cabal update"'' ]; } }
{ { Update = [ ''nix-shell ./jenkins.nix --run "cabal update"'' ]; }
Configure = [ {
''nix-shell ./jenkins.nix --run "cabal configure --enable-tests"'' Configure = [
'' ''nix-shell ./jenkins.nix --run "cabal configure --enable-tests"''
nix-shell ./jenkins.nix --run "cabal install --only-dependencies"'' ''
]; nix-shell ./jenkins.nix --run "cabal install --only-dependencies"''
} ];
{ Build = [ ''nix-shell ./jenkins.nix --run "cabal build"'' ]; } }
{ Test = [ ''nix-shell ./jenkins.nix --run "cabal test"'' ]; } { Build = [ ''nix-shell ./jenkins.nix --run "cabal build"'' ]; }
]) { Test = [ ''nix-shell ./jenkins.nix --run "cabal test"'' ]; }
])
# sync to github # sync to github
# -------------- # --------------
(sync-to-github "sync-radiodj" (sync-to-github "sync-radiodj"
"ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj2.git" "ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj2.git"
"git@github.com:crashburn-radio/radio-dj.git") "git@github.com:crashburn-radio/radio-dj.git")
(sync-to-github "sync-radiodj-tracks" (sync-to-github "sync-radiodj-tracks"
"ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj-tracks.git" "ssh://gogs@workhorse.private:2222/crashburn_radio/radio-dj-tracks.git"
"git@github.com:crashburn-radio/radio-dj-tracks.git") "git@github.com:crashburn-radio/radio-dj-tracks.git")
(sync-to-github "sync-krops-module" (sync-to-github "sync-krops-module"
"ssh://gogs@workhorse.private:2222/nix-modules/krops.git" "ssh://gogs@workhorse.private:2222/nix-modules/krops.git"
"git@github.com:mrVanDalo/module.krops.git") "git@github.com:mrVanDalo/module.krops.git")
(sync-to-github "sync-cluster-module" (sync-to-github "sync-cluster-module"
"ssh://gogs@workhorse.private:2222/nix-modules/cluster.git" "ssh://gogs@workhorse.private:2222/nix-modules/cluster.git"
"git@github.com:mrVanDalo/module.cluster.git") "git@github.com:mrVanDalo/module.cluster.git")
(sync-to-github "sync-backup-module" (sync-to-github "sync-backup-module"
"ssh://gogs@workhorse.private:2222/nix-modules/backup.git" "ssh://gogs@workhorse.private:2222/nix-modules/backup.git"
"git@github.com:mrVanDalo/module.backup.git") "git@github.com:mrVanDalo/module.backup.git")
(sync-to-github "sync-module-tinc" (sync-to-github "sync-module-tinc"
"ssh://gogs@workhorse.private:2222/palo/nixos-tinc.git" "ssh://gogs@workhorse.private:2222/palo/nixos-tinc.git"
"git@github.com:mrVanDalo/nixos-tinc.git") "git@github.com:mrVanDalo/nixos-tinc.git")
(sync-to-github "sync-memo" (sync-to-github "sync-memo"
"ssh://gogs@workhorse.private:2222/palo/memo.git" "ssh://gogs@workhorse.private:2222/palo/memo.git"
"git@github.com:mrVanDalo/memo.git") "git@github.com:mrVanDalo/memo.git")
(sync-to-github "sync-diagrams-template" (sync-to-github "sync-diagrams-template"
"ssh://gogs@workhorse.private:2222/palo/diagrams-template.git" "ssh://gogs@workhorse.private:2222/palo/diagrams-template.git"
"git@github.com:mrVanDalo/diagrams.git") "git@github.com:mrVanDalo/diagrams.git")
(sync-to-github "sync-plops" (sync-to-github "sync-plops"
"ssh://gogs@workhorse.private:2222/palo/plops.git" "ssh://gogs@workhorse.private:2222/palo/plops.git"
"git@github.com:mrVanDalo/plops.git") "git@github.com:mrVanDalo/plops.git")
(sync-to-github "sync-image-generator" (sync-to-github "sync-image-generator"
"ssh://gogs@workhorse.private:2222/palo/image-generator2.git" "ssh://gogs@workhorse.private:2222/palo/image-generator2.git"
"git@github.com:mrVanDalo/image-generator.git") "git@github.com:mrVanDalo/image-generator.git")
(sync-to-github "sync-image-generator-lib" (sync-to-github "sync-image-generator-lib"
"ssh://gogs@workhorse.private:2222/palo/image-generator-lib.git" "ssh://gogs@workhorse.private:2222/palo/image-generator-lib.git"
"git@github.com:mrVanDalo/image-generator-examples.git") "git@github.com:mrVanDalo/image-generator-examples.git")
(sync-to-github "sync-tech.ingolf-wagner.de" (sync-to-github "sync-tech.ingolf-wagner.de"
"ssh://gogs@workhorse.private:2222/palo/tech.ingolf-wagner.de.git" "ssh://gogs@workhorse.private:2222/palo/tech.ingolf-wagner.de.git"
"git@github.com:mrVanDalo/tech.ingolf-wagner.de.git") "git@github.com:mrVanDalo/tech.ingolf-wagner.de.git")
(sync-to-github "sync-LineageOS-build" (sync-to-github "sync-LineageOS-build"
"ssh://gogs@git.ingolf-wagner.de:443/palo/LineagoOS-build.git" "ssh://gogs@git.ingolf-wagner.de:443/palo/LineagoOS-build.git"
"git@github.com:mrVanDalo/LineagoOS-build.git") "git@github.com:mrVanDalo/LineagoOS-build.git")
(sync-to-github "sync-http-errors" (sync-to-github "sync-http-errors"
"ssh://gogs@git.ingolf-wagner.de:443/palo/http-errors.git" "ssh://gogs@git.ingolf-wagner.de:443/palo/http-errors.git"
"git@github.com:mrVanDalo/http-errors.git") "git@github.com:mrVanDalo/http-errors.git")
(sync-to-github "sync-light-control" (sync-to-github "sync-light-control"
"ssh://gogs@git.ingolf-wagner.de:443/palo/light-control.git" "ssh://gogs@git.ingolf-wagner.de:443/palo/light-control.git"
"git@github.com:mrVanDalo/light-control.git") "git@github.com:mrVanDalo/light-control.git")
]; ];
}; };
}; };

View file

@ -9,37 +9,39 @@
#NOTE: you need to keep the single quote inside nix string. #NOTE: you need to keep the single quote inside nix string.
password = "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'"; password = "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'";
kernels = { kernels = {
python3 = let python3 =
env = (pkgs.python3.withPackages (pythonPackages: let
with pythonPackages; [ env = (pkgs.python3.withPackages (pythonPackages:
ipykernel with pythonPackages; [
pandas ipykernel
pandas
# database stuff # database stuff
mysqlclient mysqlclient
databases databases
asyncpg asyncpg
psycopg2 psycopg2
aiomysql aiomysql
pymysql pymysql
aiosqlite aiosqlite
#aiopg #aiopg
sqlalchemy sqlalchemy
# pdf export # pdf export
nbconvert nbconvert
])); ]));
in { in
displayName = "Python 3"; {
argv = [ displayName = "Python 3";
"${env.interpreter}" argv = [
"-m" "${env.interpreter}"
"ipykernel_launcher" "-m"
"-f" "ipykernel_launcher"
"{connection_file}" "-f"
]; "{connection_file}"
language = "python"; ];
}; language = "python";
};
}; };
}; };

View file

@ -364,55 +364,60 @@ let
} }
]; ];
notmuchTagging = let notmuchTagging =
let
template = index: template = index:
{ tags, query, message ? "generic", ... }: { tags, query, message ? "generic", ... }:
let let
command = '' command = ''
${pkgs.notmuch}/bin/notmuch tag ${ ${pkgs.notmuch}/bin/notmuch tag ${lib.concatStringsSep " " tags} -- "${query}"
lib.concatStringsSep " " tags '';
} -- "${query}" in
''
echo '${command}'
${command}
''; '';
in '' junk_template = index: query:
echo '${command}' template index {
${command} tags = [ "+junk" "-unread" "-inbox" ];
''; query = query;
junk_template = index: query: message = "generic junk filter";
template index { };
tags = [ "+junk" "-unread" "-inbox" ];
query = query;
message = "generic junk filter";
};
in pkgs.writers.writeBash "notmuch-tagging" (lib.concatStringsSep "\n" in
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters))); pkgs.writers.writeBash "notmuch-tagging" (lib.concatStringsSep "\n"
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters)));
notmuchTaggingNew = let notmuchTaggingNew =
let
template = index: template = index:
{ tags, query, message ? "generic", ... }: { tags, query, message ? "generic", ... }:
let let
command = '' command = ''
${pkgs.notmuch}/bin/notmuch tag ${ ${pkgs.notmuch}/bin/notmuch tag ${
lib.concatStringsSep " " tags lib.concatStringsSep " " tags
} -- "${query} AND tag:new" } -- "${query} AND tag:new"
'';
in
''
echo '${command}'
${command}
''; '';
in ''
echo '${command}'
${command}
'';
junk_template = index: query: junk_template = index: query:
template index { template index {
tags = [ "+junk" "-unread" "-inbox" ]; tags = [ "+junk" "-unread" "-inbox" ];
query = query; query = query;
message = "generic junk filter"; message = "generic junk filter";
}; };
in pkgs.writers.writeBash "notmuch-tagging-new" (lib.concatStringsSep "\n" in
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters))); pkgs.writers.writeBash "notmuch-tagging-new" (lib.concatStringsSep "\n"
((lib.imap0 junk_template junk_filter) ++ (lib.imap0 template filters)));
in { in
{
backup.dirs = [ "/home/mailfetcher" ]; backup.dirs = [ "/home/mailfetcher" ];
@ -431,12 +436,30 @@ in {
name = "mailfetcher"; name = "mailfetcher";
}; };
sops.secrets.mail_terranix.owner = "mailUser"; sops.secrets.mail_terranix = {
sops.secrets.mail_gmail.owner = "mailUser"; owner = config.users.users.mailUser.name;
sops.secrets.mail_gmx_palo.owner = "mailUser"; group = config.users.users.mailUser.group;
sops.secrets.mail_gmx_ingolf.owner = "mailUser"; };
sops.secrets.mail_web.owner = "mailUser"; sops.secrets.mail_gmail = {
sops.secrets.mail_siteground.owner = "mailUser"; owner = config.users.users.mailUser.name;
group = config.users.users.mailUser.group;
};
sops.secrets.mail_gmx_palo = {
owner = config.users.users.mailUser.name;
group = config.users.users.mailUser.group;
};
sops.secrets.mail_gmx_ingolf = {
owner = config.users.users.mailUser.name;
group = config.users.users.mailUser.group;
};
sops.secrets.mail_web = {
owner = config.users.users.mailUser.name;
group = config.users.users.mailUser.group;
};
sops.secrets.mail_siteground = {
owner = config.users.users.mailUser.name;
group = config.users.users.mailUser.group;
};
environment.systemPackages = [ pkgs.muchsync ]; environment.systemPackages = [ pkgs.muchsync ];
@ -595,34 +618,32 @@ in {
systemd.services.fetchmail = systemd.services.fetchmail =
let let
threadTag = tag: '' threadTag = tag: ''
echo "tag threads with ${tag}" echo "tag threads with ${tag}"
${pkgs.notmuch}/bin/notmuch tag +${tag} $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:${tag}) ${pkgs.notmuch}/bin/notmuch tag +${tag} $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:${tag})
''; '';
in { in
enable = true; {
serviceConfig = { User = config.users.users.mailUser.name; }; enable = true;
environment.NOTMUCH_CONFIG = serviceConfig = { User = config.users.users.mailUser.name; };
"${config.users.users.mailUser.home}/.config/notmuch/notmuchrc"; environment.NOTMUCH_CONFIG =
script = '' "${config.users.users.mailUser.home}/.config/notmuch/notmuchrc";
echo "run mbsync" script = ''
${pkgs.isync}/bin/mbsync \ echo "run mbsync"
--all ${pkgs.isync}/bin/mbsync \
--all
echo "run getmail"
${pkgs.getmail}/bin/getmail \
--quiet \
--rcfile getmailingolf-wagner-de
echo "run getmail" echo "run notmuch"
${pkgs.getmail}/bin/getmail \ ${pkgs.notmuch}/bin/notmuch new
--quiet \ ${notmuchTaggingNew}
--rcfile getmailingolf-wagner-de ${threadTag "muted"}
${threadTag "wohnung"}
echo "run notmuch" ${threadTag "flagged"}
${pkgs.notmuch}/bin/notmuch new '';
${notmuchTaggingNew} };
${threadTag "muted"}
${threadTag "wohnung"}
${threadTag "flagged"}
echo "delete threads"
${pkgs.notmuch}/bin/notmuch tag +deleted $(${pkgs.notmuch}/bin/notmuch search --output=threads tag:deleted)
'';
};
systemd.timers.fetchmail = { systemd.timers.fetchmail = {
enable = true; enable = true;
# timerConfig.OnCalendar = " *-*-* *:00:00"; # timerConfig.OnCalendar = " *-*-* *:00:00";
@ -635,9 +656,5 @@ in {
enable = true; enable = true;
new.tags = [ "unread" "inbox" "new" ]; new.tags = [ "unread" "inbox" "new" ];
}; };
#home-manager.users.mailUser.home.file."notmuch" = {
# source = "${config.users.users.mailUser.home}/.config/notmuch/notmuchrc";
# target = ".notmuch-config";
#};
} }

View file

@ -7,7 +7,8 @@ let
rig = config.networking.hostName; rig = config.networking.hostName;
recheckInterval = 2000; recheckInterval = 2000;
package = pkgs.ethminer; package = pkgs.ethminer;
in { in
{
systemd.services.ethminer = { systemd.services.ethminer = {
description = "ethminer ethereum mining service"; description = "ethminer ethereum mining service";

View file

@ -4,11 +4,22 @@ let
hostAddress = "192.168.100.10"; hostAddress = "192.168.100.10";
containerAddress = "192.168.100.11"; containerAddress = "192.168.100.11";
#syncthingGid = config.users.groups.syncthing.gid; #syncthingGid = config.users.groups.syncthing.gid;
nextcloudUid = 1000;
in { in
{
sops.secrets.nextcloud_database_password = {}; sops.secrets.nextcloud_database_password = {
sops.secrets.nextcloud_root_password = {}; owner = "nextcloud";
};
sops.secrets.nextcloud_root_password = {
owner = "nextcloud";
};
users.users.nextcloud = {
isSystemUser = true;
uid = nextcloudUid;
};
containers.nextcloud = { containers.nextcloud = {
@ -16,20 +27,20 @@ in {
bindMounts = { bindMounts = {
rootpassword = { rootpassword = {
hostPath = hostPath =
"/run/secrets/nextcloud_root_password"; "/run/secrets/nextcloud_root_password";
#toString <secrets/nextcloud/root_password>; #toString <secrets/nextcloud/root_password>;
mountPoint = mountPoint =
"/run/secrets/nextcloud_root_password"; "/run/secrets/nextcloud_root_password";
#toString <secrets/nextcloud/root_password>; #toString <secrets/nextcloud/root_password>;
isReadOnly = true; isReadOnly = true;
}; };
databasepassword = { databasepassword = {
hostPath = hostPath =
"/run/secrets/nextcloud_database_password"; "/run/secrets/nextcloud_database_password";
#toString <secrets/nextcloud/database_password>; #toString <secrets/nextcloud/database_password>;
mountPoint = mountPoint =
"/run/secrets/nextcloud_database_password"; "/run/secrets/nextcloud_database_password";
#toString <secrets/nextcloud/database_password>; #toString <secrets/nextcloud/database_password>;
isReadOnly = true; isReadOnly = true;
}; };
@ -85,6 +96,8 @@ in {
config = { config, pkgs, lib, ... }: { config = { config, pkgs, lib, ... }: {
users.users.nextcloud.uid = nextcloudUid;
services.nginx = { services.nginx = {
# Use recommended settings # Use recommended settings
recommendedGzipSettings = lib.mkDefault true; recommendedGzipSettings = lib.mkDefault true;
@ -93,28 +106,30 @@ in {
recommendedTlsSettings = lib.mkDefault true; recommendedTlsSettings = lib.mkDefault true;
# for graylog logging # for graylog logging
commonHttpConfig = let commonHttpConfig =
access_log_sink = "${hostAddress}:12304"; let
error_log_sink = "${hostAddress}:12305"; access_log_sink = "${hostAddress}:12304";
in '' error_log_sink = "${hostAddress}:12305";
log_format graylog2_json escape=json '{ "timestamp": "$time_iso8601", ' in
'"facility": "nginx", ' ''
'"src_addr": "$remote_addr", ' log_format graylog2_json escape=json '{ "timestamp": "$time_iso8601", '
'"body_bytes_sent": $body_bytes_sent, ' '"facility": "nginx", '
'"request_time": $request_time, ' '"src_addr": "$remote_addr", '
'"response_status": $status, ' '"body_bytes_sent": $body_bytes_sent, '
'"request": "$request", ' '"request_time": $request_time, '
'"request_method": "$request_method", ' '"response_status": $status, '
'"host": "$host",' '"request": "$request", '
'"upstream_cache_status": "$upstream_cache_status",' '"request_method": "$request_method", '
'"upstream_addr": "$upstream_addr",' '"host": "$host",'
'"http_x_forwarded_for": "$http_x_forwarded_for",' '"upstream_cache_status": "$upstream_cache_status",'
'"http_referrer": "$http_referer", ' '"upstream_addr": "$upstream_addr",'
'"http_user_agent": "$http_user_agent" }'; '"http_x_forwarded_for": "$http_x_forwarded_for",'
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent" }';
access_log syslog:server=${access_log_sink} graylog2_json; access_log syslog:server=${access_log_sink} graylog2_json;
error_log syslog:server=${error_log_sink}; error_log syslog:server=${error_log_sink};
''; '';
}; };
# don't forget the database backup before doing this # don't forget the database backup before doing this
@ -331,8 +346,8 @@ in {
doInit = true; doInit = true;
encryption = { encryption = {
mode = "repokey-blake2"; mode = "repokey-blake2";
passCommand = passCommand =
"cat ${config.sops.secrets.backup_repository_passphrase.path}"; "cat ${config.sops.secrets.backup_repository_passphrase.path}";
}; };
startAt = "0/3:00:00"; startAt = "0/3:00:00";
prune.keep = { prune.keep = {

View file

@ -1,12 +1,18 @@
{ pkgs, ... }: { pkgs, config, ... }:
let let
hostAddress = "192.168.100.30"; hostAddress = "192.168.100.30";
containerAddress = "192.168.100.31"; containerAddress = "192.168.100.31";
in { in
{
sops.secrets.nordvpn = {}; #users.users.transmission = {
# isSystemUser = true;
# uid = config.ids.uids.transmission;
#};
sops.secrets.nordvpn = { };
containers.torrent = { containers.torrent = {
@ -185,7 +191,7 @@ in {
remote-cert-tls server remote-cert-tls server
auth-user-pass /run/secrets/nordvpn.txt auth-user-pass /run/secrets/nordvpn
verb 3 verb 3
pull pull

View file

@ -5,7 +5,8 @@ let
ipAddress = "10.1.0.1"; ipAddress = "10.1.0.1";
prefixLength = 24; prefixLength = 24;
in { in
{
networking.extraHosts = '' networking.extraHosts = ''
10.1.0.1 workout.lan 10.1.0.1 workout.lan

View file

@ -4,8 +4,10 @@
nixpkgs.overlays = [ (import <mozilla-overlay/rust-overlay.nix>) ]; nixpkgs.overlays = [ (import <mozilla-overlay/rust-overlay.nix>) ];
nixpkgs.config.packageOverrides = pkgs: { nixpkgs.config.packageOverrides = pkgs: {
nur = import (builtins.fetchTarball nur = import
"https://github.com/nix-community/NUR/archive/master.tar.gz") { (builtins.fetchTarball
"https://github.com/nix-community/NUR/archive/master.tar.gz")
{
inherit pkgs; inherit pkgs;
}; };
}; };

View file

@ -199,6 +199,28 @@
"type": "github" "type": "github"
} }
}, },
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs-fmt",
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1631067971,
"narHash": "sha256-z+qlJaCaw/OAoFGdzm0nDKkjRdCwstHzduF74nMn3bY=",
"owner": "nix-community",
"repo": "fenix",
"rev": "0771140f0a6a6622c509fb2d6d2c87f0bfda703d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"locked": { "locked": {
"lastModified": 1623875721, "lastModified": 1623875721,
@ -215,6 +237,21 @@
} }
}, },
"flake-utils_2": { "flake-utils_2": {
"locked": {
"lastModified": 1629481132,
"narHash": "sha256-JHgasjPR0/J1J3DRm4KxM4zTyAj4IOJY8vIl75v/kPI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "997f7efcb746a9c140ce1f13c72263189225f482",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"locked": { "locked": {
"lastModified": 1631561581, "lastModified": 1631561581,
"narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=", "narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=",
@ -286,6 +323,27 @@
"url": "https://git.ingolf-wagner.de/nix-modules/krops.git" "url": "https://git.ingolf-wagner.de/nix-modules/krops.git"
} }
}, },
"naersk": {
"inputs": {
"nixpkgs": [
"nixpkgs-fmt",
"nixpkgs"
]
},
"locked": {
"lastModified": 1631004250,
"narHash": "sha256-LGh0CjAZwh13AVkTi9w9lITEC7x6bwSQyFViOZ6HyNo=",
"owner": "nmattia",
"repo": "naersk",
"rev": "08afb3d1dbfe016108b72e05b02ba0f6ecb3c8e1",
"type": "github"
},
"original": {
"owner": "nmattia",
"repo": "naersk",
"type": "github"
}
},
"nix-straight": { "nix-straight": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -319,6 +377,29 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-fmt": {
"inputs": {
"fenix": "fenix",
"flake-utils": "flake-utils_2",
"naersk": "naersk",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1631557044,
"narHash": "sha256-5VPeqRvNhRxTv07NSvxQSXvtuGnrjWmmwss0PGhFzTI=",
"owner": "nix-community",
"repo": "nixpkgs-fmt",
"rev": "c7f66ec1b969ed118231fdf7f596c5ed2c2cfe49",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs-fmt",
"type": "github"
}
},
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1634782485, "lastModified": 1634782485,
@ -463,7 +544,7 @@
}, },
"polygon-art": { "polygon-art": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_2" "nixpkgs": "nixpkgs_2"
}, },
"locked": { "locked": {
@ -505,6 +586,7 @@
"home-manager-utils": "home-manager-utils", "home-manager-utils": "home-manager-utils",
"krops-lib": "krops-lib", "krops-lib": "krops-lib",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-fmt": "nixpkgs-fmt",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"polygon-art": "polygon-art", "polygon-art": "polygon-art",
"sops-nix": "sops-nix" "sops-nix": "sops-nix"
@ -526,6 +608,23 @@
"type": "github" "type": "github"
} }
}, },
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1630943734,
"narHash": "sha256-jqgAKhvrVDEkv8HB56hVIgvMDuuQ7X4D2zE9ATV+baI=",
"owner": "rust-analyzer",
"repo": "rust-analyzer",
"rev": "3dae94bf2b3e496adb049da589c7efef272a39b8",
"type": "github"
},
"original": {
"owner": "rust-analyzer",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"sops-nix": { "sops-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs_3"

View file

@ -33,11 +33,27 @@
"git+https://git.ingolf-wagner.de/nix-modules/cluster.git?rev=ef621797a30f8a57de16bf33672abdd411cbcece"; "git+https://git.ingolf-wagner.de/nix-modules/cluster.git?rev=ef621797a30f8a57de16bf33672abdd411cbcece";
flake = false; flake = false;
}; };
nixpkgs-fmt = {
url = "github:nix-community/nixpkgs-fmt";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, sops-nix, nixpkgs, home-manager, home-manager-utils outputs =
, doom-emacs-nix, backup-module, nixpkgs-unstable, krops-lib, cluster-module { self
, polygon-art, ... }: , sops-nix
, nixpkgs
, home-manager
, home-manager-utils
, doom-emacs-nix
, backup-module
, nixpkgs-unstable
, krops-lib
, cluster-module
, polygon-art
, nixpkgs-fmt
, ...
}:
let let
nixosSystem = nixpkgs.lib.nixosSystem; nixosSystem = nixpkgs.lib.nixosSystem;
@ -70,13 +86,13 @@
} }
]; ];
desktopModules = [ desktopModules = [
home-manager.nixosModules.home-manager
{ {
home-manager.users.mainUser = { home-manager.users.mainUser = {
imports = [ doom-emacs-nix.hmModule home-manager-utils.hmModule ]; imports = [ doom-emacs-nix.hmModule home-manager-utils.hmModule ];
}; };
home-manager.useGlobalPkgs = true; environment.systemPackages = [
home-manager.useUserPackages = true; nixpkgs-fmt.defaultPackage."x86_64-linux"
];
} }
]; ];
desktopConfiguration = initPath: desktopConfiguration = initPath:
@ -89,7 +105,8 @@
system = "x86_64-linux"; system = "x86_64-linux";
modules = defaultModules ++ [ initPath ]; modules = defaultModules ++ [ initPath ];
}; };
in { in
{
nixosConfigurations = { nixosConfigurations = {
sterni = desktopConfiguration ./configs/sterni/configuration.nix; sterni = desktopConfiguration ./configs/sterni/configuration.nix;
sternchen = desktopConfiguration ./configs/sternchien/configuration.nix; sternchen = desktopConfiguration ./configs/sternchien/configuration.nix;

View file

@ -5,8 +5,9 @@ let
command = targetPath: command = targetPath:
let let
commandLine = commandLine =
"TMPDIR=/tmp nixos-rebuild build --flake ${targetPath} -L --keep-going"; "TMPDIR=/tmp nixos-rebuild test --flake ${targetPath} -L --keep-going";
in '' in
''
echo '${commandLine}' echo '${commandLine}'
nix-shell \ nix-shell \
-E "with import <nixpkgs> {}; mkShell { buildInputs = [ git (nixos { nix.package = nixFlakes; }).nixos-rebuild ]; }" \ -E "with import <nixpkgs> {}; mkShell { buildInputs = [ git (nixos { nix.package = nixFlakes; }).nixos-rebuild ]; }" \
@ -64,7 +65,8 @@ let
target = lib.mkTarget "root@${host}/var/krops"; target = lib.mkTarget "root@${host}/var/krops";
inherit command; inherit command;
}; };
in { in
{
"${name}" = pkgs.writers.writeBashBin name '' "${name}" = pkgs.writers.writeBashBin name ''
echo "deploy system" echo "deploy system"
${system}/bin/system ${system}/bin/system
@ -89,7 +91,8 @@ let
force = true; force = true;
target = lib.mkTarget "root@${host}/etc/NetworkManager"; target = lib.mkTarget "root@${host}/etc/NetworkManager";
}; };
in { in
{
"${name}" = pkgs.writers.writeBashBin "${name}-all" '' "${name}" = pkgs.writers.writeBashBin "${name}-all" ''
echo "deploy network secerts" echo "deploy network secerts"
${network}/bin/secrets ${network}/bin/secrets
@ -98,7 +101,8 @@ let
''; '';
}; };
in (desktop { in
(desktop {
name = "sterni"; name = "sterni";
host = "sterni.private"; host = "sterni.private";
}) // (desktop { }) // (desktop {

View file

@ -1,7 +1,10 @@
{ pkgs, lib, ... }: { { pkgs, lib, ... }: {
desktopFile = bin: desktopFile = bin:
{ comment ? "No Comment", longName ? "Script" { comment ? "No Comment"
, command ? "${bin}/bin/${bin.name}", ... }: , longName ? "Script"
, command ? "${bin}/bin/${bin.name}"
, ...
}:
pkgs.writeTextFile { pkgs.writeTextFile {
name = "${bin.name}.desktop"; name = "${bin.name}.desktop";
destination = "/share/applications/${bin.name}.desktop"; destination = "/share/applications/${bin.name}.desktop";

View file

@ -7,79 +7,90 @@ with builtins;
{ {
# source container url and credentialsId # source container url and credentialsId
job = name: job = name:
{ url, credentialsId, branch ? "master", { url
# https://docs.openstack.org/infra/jenkins-job-builder/triggers.html , credentialsId
triggers ? [{ , branch ? "master"
pollscm = { , # https://docs.openstack.org/infra/jenkins-job-builder/triggers.html
cron = "H/30 * * * *"; triggers ? [{
ignore-post-commit-hooks = true; pollscm = {
}; cron = "H/30 * * * *";
}], ... }: ignore-post-commit-hooks = true;
};
}]
, ...
}:
config: { config: {
job = { job = {
inherit name triggers; inherit name triggers;
sandbox = true; sandbox = true;
project-type = "pipeline"; project-type = "pipeline";
dsl = let dsl =
stage = elem: let
let stage = elem:
stageName = head (attrNames elem); let
stateScripts = map (stage: stageName = head (attrNames elem);
lib.getAttr (typeOf stage) { stateScripts = map
string = '' (stage:
withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) { lib.getAttr (typeOf stage) {
sh '${toString stage}' string = ''
}''; withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) {
set = let sh '${toString stage}'
script = '' }'';
withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) { set =
sh '${toString stage.script}' let
} script = ''
''; withEnv(['PATH=/run/current-system/sw/bin/','NIX_PATH=/var/src/']) {
in if (stage.credentialsId != null) then '' sh '${toString stage.script}'
sshagent(['${stage.credentialsId}']) { ${script} } }
'' else '';
script; in
}) (getAttr stageName elem); if (stage.credentialsId != null) then ''
in '' sshagent(['${stage.credentialsId}']) { ${script} }
stage('${stageName}') { '' else
steps { script;
${concatStringsSep "\n" stateScripts} })
(getAttr stageName elem);
in
''
stage('${stageName}') {
steps {
${concatStringsSep "\n" stateScripts}
}
}
'';
stages = map stage config;
in
''
pipeline {
agent any
post {
failure {
mattermostSend channel: 'notification', color: '#FF0000', message: "Failed to build : [''${env.JOB_NAME}-''${env.BUILD_NUMBER}](''${env.BUILD_URL})"
}
success {
mattermostSend channel: 'jenkins', color: '#00FF00', message: "Successfully build : [''${env.JOB_NAME}-''${env.BUILD_NUMBER}](''${env.JOB_URL})"
} }
} }
''; stages{
stages = map stage config; stage('Pull') {
in '' steps {
pipeline { checkout(
agent any [$class: 'GitSCM'
post { , branches: [[name: '*/${branch}']]
failure { , doGenerateSubmoduleConfigurations: false
mattermostSend channel: 'notification', color: '#FF0000', message: "Failed to build : [''${env.JOB_NAME}-''${env.BUILD_NUMBER}](''${env.BUILD_URL})" , extensions: [[$class: 'LocalBranch', localBranch: 'master']]
} , submoduleCfg: []
success { , userRemoteConfigs:
mattermostSend channel: 'jenkins', color: '#00FF00', message: "Successfully build : [''${env.JOB_NAME}-''${env.BUILD_NUMBER}](''${env.JOB_URL})" [[ credentialsId: '${credentialsId}'
} , url: '${url}']]
} ]
stages{ )
stage('Pull') { }
steps {
checkout(
[$class: 'GitSCM'
, branches: [[name: '*/${branch}']]
, doGenerateSubmoduleConfigurations: false
, extensions: [[$class: 'LocalBranch', localBranch: 'master']]
, submoduleCfg: []
, userRemoteConfigs:
[[ credentialsId: '${credentialsId}'
, url: '${url}']]
]
)
} }
${concatStringsSep "\n" stages}
} }
${concatStringsSep "\n" stages}
} }
} '';
'';
}; };
}; };

View file

@ -45,92 +45,104 @@ let
backupFile = "${homeBackup}.tar.lzma"; backupFile = "${homeBackup}.tar.lzma";
rolloutFile = "${home}.tar.lzma"; rolloutFile = "${home}.tar.lzma";
lockFile = "${home}-lock"; lockFile = "${home}-lock";
in pkgs.writeShellScriptBin "${name}-clean" # sh in
'' pkgs.writeShellScriptBin "${name}-clean" # sh
sudo killall -9 -u ${name} ''
sudo rm -f ${lockFile} sudo killall -9 -u ${name}
sudo rm -rf ${home} sudo rm -f ${lockFile}
''; sudo rm -rf ${home}
'';
createBrowser = name: user: browser: home: homeBackup: createBrowser = name: user: browser: home: homeBackup:
let let
backupFile = "${homeBackup}.tar.lzma"; backupFile = "${homeBackup}.tar.lzma";
rolloutFile = "${home}.tar.lzma"; rolloutFile = "${home}.tar.lzma";
lockFile = "${home}-lock"; lockFile = "${home}-lock";
in pkgs.writeShellScriptBin "${name}" # sh in
'' pkgs.writeShellScriptBin "${name}" # sh
# set -x ''
if [[ ! -e ${lockFile} ]] # set -x
then if [[ ! -e ${lockFile} ]]
# rollout backup then
if [[ -e ${backupFile} ]] # rollout backup
then if [[ -e ${backupFile} ]]
if [[ ! -d ${home} ]] then
then if [[ ! -d ${home} ]]
# todo : use make user then
sudo mkdir -p ${home} # todo : use make user
sudo chown -R ${user}:users ${home} sudo mkdir -p ${home}
fi sudo chown -R ${user}:users ${home}
cp ${backupFile} ${rolloutFile} fi
sudo -u ${user} ${tarBin} xf ${rolloutFile} --directory ${home} cp ${backupFile} ${rolloutFile}
rm ${rolloutFile} sudo -u ${user} ${tarBin} xf ${rolloutFile} --directory ${home}
touch ${lockFile} rm ${rolloutFile}
fi touch ${lockFile}
fi fi
fi
sudo -u ${user} ${browser} sudo -u ${user} ${browser}
''; '';
browserExecutableList = let browserExecutableList =
allBrowser = flip mapAttrsToList cfg.configList (name: config: let
let allBrowser = flip mapAttrsToList cfg.configList (name: config:
browser = if config.browserType == "chrome" then let
''${chromiumBin} "$@"'' browser =
else if config.browserType == "google" then if config.browserType == "chrome" then
''${chromeBin} "$@"'' ''${chromiumBin} "$@"''
else else if config.browserType == "google" then
''${firefoxBin} "$@"''; ''${chromeBin} "$@"''
in createBrowser name config.user browser config.home config.homeBackup); else
xclipBrowser = [ ''${firefoxBin} "$@"'';
(pkgs.writeShellScriptBin "copy-to-xclip" # sh in
'' createBrowser name config.user browser config.home config.homeBackup);
echo "$*" | ${pkgs.xclip}/bin/xclip xclipBrowser = [
'') (pkgs.writeShellScriptBin "copy-to-xclip" # sh
]; ''
in allBrowser ++ xclipBrowser; echo "$*" | ${pkgs.xclip}/bin/xclip
'')
];
in
allBrowser ++ xclipBrowser;
createBackupScript = name: home: backupHome: createBackupScript = name: home: backupHome:
pkgs.writeShellScriptBin "${name}-backup" # sh pkgs.writeShellScriptBin "${name}-backup" # sh
'' ''
sudo -u ${name} \ sudo -u ${name} \
${tarBin} \ ${tarBin} \
--exclude=.cache \ --exclude=.cache \
--exclude=Downloads \ --exclude=Downloads \
--create \ --create \
--verbos \ --verbos \
--lzma \ --lzma \
--file ${home}.tar.lzma \ --file ${home}.tar.lzma \
--directory ${home} \ --directory ${home} \
. .
cp ${home}.tar.lzma ${backupHome}.tar.lzma cp ${home}.tar.lzma ${backupHome}.tar.lzma
''; '';
allBackupScripts = let allBackupScripts =
filteredConfigs = let
filterAttrs (name: browserConfig: browserConfig.homeBackup != null) filteredConfigs =
cfg.configList; filterAttrs (name: browserConfig: browserConfig.homeBackup != null)
in mapAttrsToList (name: browserConfig: cfg.configList;
createBackupScript name browserConfig.home browserConfig.homeBackup) in
filteredConfigs; mapAttrsToList
(name: browserConfig:
createBackupScript name browserConfig.home browserConfig.homeBackup)
filteredConfigs;
allCleanScripts = let allCleanScripts =
filteredConfigs = let
filterAttrs (name: browserConfig: browserConfig.homeBackup != null) filteredConfigs =
cfg.configList; filterAttrs (name: browserConfig: browserConfig.homeBackup != null)
in mapAttrsToList (name: browserConfig: cfg.configList;
cleanBrowser name name browserConfig.home browserConfig.homeBackup) in
filteredConfigs; mapAttrsToList
(name: browserConfig:
cleanBrowser name name browserConfig.home browserConfig.homeBackup)
filteredConfigs;
allKillScripts = mapAttrsToList (name: _: killBrowser name) cfg.configList; allKillScripts = mapAttrsToList (name: _: killBrowser name) cfg.configList;
@ -153,7 +165,8 @@ let
$BIN "$@" $BIN "$@"
''; '';
in { in
{
options.programs.custom.browser = { options.programs.custom.browser = {
enable = mkEnableOption "enable browsers"; enable = mkEnableOption "enable browsers";
@ -214,18 +227,22 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
# add sudo rights # add sudo rights
security.sudo.extraConfig = let security.sudo.extraConfig =
extraRules = flip mapAttrsToList cfg.configList (name: values: let
concatStringsSep "" (map (sudoUser: '' extraRules = flip mapAttrsToList cfg.configList (name: values:
# sudo configuration to control browser concatStringsSep "" (map
${sudoUser} ALL=(${values.user}) NOPASSWD: ALL (sudoUser: ''
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/mkdir -p ${values.home} # sudo configuration to control browser
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/chown -R ${values.user}\:users ${values.home} ${sudoUser} ALL=(${values.user}) NOPASSWD: ALL
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/killall -9 -u ${name} ${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/mkdir -p ${values.home}
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -rf ${values.home} ${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/chown -R ${values.user}\:users ${values.home}
${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -f ${values.home}-lock ${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/killall -9 -u ${name}
'') values.sudoUsers)); ${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -rf ${values.home}
in lib.concatStringsSep "\n" extraRules; ${sudoUser} ALL=(root) NOPASSWD: /run/current-system/sw/bin/rm -f ${values.home}-lock
'')
values.sudoUsers));
in
lib.concatStringsSep "\n" extraRules;
# create users # create users
users.users = flip mapAttrs cfg.configList (name: config: { users.users = flip mapAttrs cfg.configList (name: config: {

View file

@ -19,7 +19,8 @@ let
scriptAxel = citateScript (toString ../../assets/sprueche-axel) "axel"; scriptAxel = citateScript (toString ../../assets/sprueche-axel) "axel";
scriptSiw = citateScript (toString ../../assets/sprueche-siw) "siw"; scriptSiw = citateScript (toString ../../assets/sprueche-siw) "siw";
in { in
{
options.programs.custom.citate = { options.programs.custom.citate = {
enable = mkEnableOption "enable programs.custom.citate"; enable = mkEnableOption "enable programs.custom.citate";

View file

@ -18,7 +18,8 @@ let
cfg = config.programs.custom.curlScripts; cfg = config.programs.custom.curlScripts;
in { in
{
options.programs.custom.curlScripts.enable = options.programs.custom.curlScripts.enable =
mkEnableOption "enable curl scripts"; mkEnableOption "enable curl scripts";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.easytag; cfg = config.programs.custom.easytag;
in { in
{
options.programs.custom.easytag.enable = options.programs.custom.easytag.enable =
mkEnableOption "install easytag with dependencies"; mkEnableOption "install easytag with dependencies";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.elm; cfg = config.programs.custom.elm;
in { in
{
options.programs.custom.elm.enable = mkEnableOption "enable elm stack"; options.programs.custom.elm.enable = mkEnableOption "enable elm stack";

View file

@ -36,7 +36,8 @@ let
cfg = config.programs.custom.espeak; cfg = config.programs.custom.espeak;
in { in
{
options.programs.custom.espeak.enable = options.programs.custom.espeak.enable =
mkEnableOption "enable espeak scripts"; mkEnableOption "enable espeak scripts";

View file

@ -5,8 +5,13 @@ let
cfg = config.programs.custom.ffmpeg; cfg = config.programs.custom.ffmpeg;
ffmpegTemplate = name: ffmpegTemplate = name:
{ profile, preset, tune ? null, width ? 1280, height ? 720 { profile
, resolution ? "720p" }: , preset
, tune ? null
, width ? 1280
, height ? 720
, resolution ? "720p"
}:
pkgs.writeShellScriptBin "ffmpeg-${name}" '' pkgs.writeShellScriptBin "ffmpeg-${name}" ''
if [ $# -eq 0 ] if [ $# -eq 0 ]
@ -99,48 +104,53 @@ let
]; ];
tunes = [ "film" "animation" "grain" "stillimage" "fastdecode" ]; tunes = [ "film" "animation" "grain" "stillimage" "fastdecode" ];
ffmpegs = let ffmpegs =
let
configurations = lib.cartesianProductOfSets { configurations = lib.cartesianProductOfSets {
profile = profiles; profile = profiles;
preset = presets; preset = presets;
};
p720 = { profile, preset }:
ffmpegTemplate "${profile}-${preset}-720p" { inherit profile preset; };
p1080 = { profile, preset }:
ffmpegTemplate "${profile}-${preset}-1080p" {
inherit profile preset;
height = 1080;
width = 1920;
resolution = "1080p";
};
in (map p720 configurations) ++ (map p1080 configurations);
ffmpegsTune = let
configurations = lib.cartesianProductOfSets {
profile = profiles;
preset = presets;
tune = tunes;
};
p720 = { profile, preset, tune }:
ffmpegTemplate "${profile}-${preset}-${tune}-720p" {
inherit profile preset tune;
}; };
p1080 = { profile, preset, tune }: p720 = { profile, preset }:
ffmpegTemplate "${profile}-${preset}-${tune}-1080p" { ffmpegTemplate "${profile}-${preset}-720p" { inherit profile preset; };
inherit profile preset tune;
height = 1080; p1080 = { profile, preset }:
width = 1920; ffmpegTemplate "${profile}-${preset}-1080p" {
resolution = "1080p"; inherit profile preset;
height = 1080;
width = 1920;
resolution = "1080p";
};
in
(map p720 configurations) ++ (map p1080 configurations);
ffmpegsTune =
let
configurations = lib.cartesianProductOfSets {
profile = profiles;
preset = presets;
tune = tunes;
}; };
in (map p720 configurations) ++ (map p1080 configurations); p720 = { profile, preset, tune }:
ffmpegTemplate "${profile}-${preset}-${tune}-720p" {
inherit profile preset tune;
};
in { p1080 = { profile, preset, tune }:
ffmpegTemplate "${profile}-${preset}-${tune}-1080p" {
inherit profile preset tune;
height = 1080;
width = 1920;
resolution = "1080p";
};
in
(map p720 configurations) ++ (map p1080 configurations);
in
{
options.programs.custom.ffmpeg = { options.programs.custom.ffmpeg = {
enable = mkEnableOption "enable programs.custom.ffmpeg"; enable = mkEnableOption "enable programs.custom.ffmpeg";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.git; cfg = config.programs.custom.git;
in { in
{
options.programs.custom.git.enable = options.programs.custom.git.enable =
mkEnableOption "install git and all its tools"; mkEnableOption "install git and all its tools";

View file

@ -29,7 +29,8 @@ let
cfg = config.programs.custom.shellTools; cfg = config.programs.custom.shellTools;
in { in
{
options.programs.custom.shellTools.enable = options.programs.custom.shellTools.enable =
mkEnableOption "enable shell tools"; mkEnableOption "enable shell tools";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.zsh; cfg = config.programs.custom.zsh;
in { in
{
options.programs.custom.zsh = { options.programs.custom.zsh = {
enable = mkEnableOption "enable zsh"; enable = mkEnableOption "enable zsh";

View file

@ -14,47 +14,51 @@ let
# --------------------------- # ---------------------------
command = "${pkgs.slack}/bin/slack"; command = "${pkgs.slack}/bin/slack";
desktopFile = let desktopFile =
name = program; let
comment = "Chat Programm"; name = program;
in pkgs.writeTextFile { comment = "Chat Programm";
name = "${name}.desktop"; in
destination = "/share/applications/${name}.desktop"; pkgs.writeTextFile {
text = '' name = "${name}.desktop";
[Desktop Entry] destination = "/share/applications/${name}.desktop";
Categories=Application;Utility; text = ''
Comment=${comment} [Desktop Entry]
Encoding=UTF-8 Categories=Application;Utility;
Exec=${bin}/bin/${name} Comment=${comment}
Icon=gnome-lockscreen Encoding=UTF-8
Name=${name} Exec=${bin}/bin/${name}
Terminal=false Icon=gnome-lockscreen
Type=Application Name=${name}
''; Terminal=false
}; Type=Application
'';
};
# the script # the script
# ---------- # ----------
bin = let bin =
backupFile = "${cfg.homeBackup}.tar.lzma"; let
rolloutFile = "${cfg.home}.tar.lzma"; backupFile = "${cfg.homeBackup}.tar.lzma";
lockFile = "${cfg.home}-lock"; rolloutFile = "${cfg.home}.tar.lzma";
in pkgs.writeShellScriptBin "${program}" '' lockFile = "${cfg.home}-lock";
# set -x in
if [[ ! -e ${lockFile} ]] pkgs.writeShellScriptBin "${program}" ''
then # set -x
# rollout backup if [[ ! -e ${lockFile} ]]
if [[ -e ${backupFile} ]]
then then
cp ${backupFile} ${rolloutFile} # rollout backup
sudo -u ${program} ${tarBin} xf ${rolloutFile} --directory ${cfg.home} if [[ -e ${backupFile} ]]
rm ${rolloutFile} then
touch ${lockFile} cp ${backupFile} ${rolloutFile}
sudo -u ${program} ${tarBin} xf ${rolloutFile} --directory ${cfg.home}
rm ${rolloutFile}
touch ${lockFile}
fi
fi fi
fi
sudo -u ${program} ${command} sudo -u ${program} ${command}
''; '';
backupScript = pkgs.writeShellScriptBin "${program}-backup" '' backupScript = pkgs.writeShellScriptBin "${program}-backup" ''
sudo -u ${program} \ sudo -u ${program} \
@ -75,7 +79,8 @@ let
cfg = config.programs.custom.slack; cfg = config.programs.custom.slack;
in { in
{
options.programs.custom.slack = { options.programs.custom.slack = {
enable = mkEnableOption "install slack"; enable = mkEnableOption "install slack";

View file

@ -14,7 +14,8 @@ let
cfg = config.programs.custom.steam; cfg = config.programs.custom.steam;
in { in
{
options.programs.custom.steam.enable = mkEnableOption "enable steam"; options.programs.custom.steam.enable = mkEnableOption "enable steam";

View file

@ -34,7 +34,8 @@ let
}); });
#vit = pkgs.vit; #vit = pkgs.vit;
in { in
{
options.programs.custom.taskwarrior.enable = options.programs.custom.taskwarrior.enable =
mkEnableOption "Enable Taskwarrior services"; mkEnableOption "Enable Taskwarrior services";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.urxvt; cfg = config.programs.custom.urxvt;
in { in
{
options.programs.custom.urxvt = { options.programs.custom.urxvt = {
@ -63,24 +64,26 @@ in {
URxvt.fading: 0 URxvt.fading: 0
''; '';
"X11/Xresource.d/urxvt-font".source = let "X11/Xresource.d/urxvt-font".source =
fontFamily = "terminus"; let
normalFont = fontSize: fontFamily = "terminus";
"-*-${fontFamily}-medium-*-*-*-${toString fontSize}-*-*-*-*-*-*-*"; normalFont = fontSize:
boldFont = fontSize: "-*-${fontFamily}-medium-*-*-*-${toString fontSize}-*-*-*-*-*-*-*";
"-*-${fontFamily}-bold-*-*-*-${toString fontSize}-*-*-*-*-*-*-*"; boldFont = fontSize:
italicFont = normalFont; "-*-${fontFamily}-bold-*-*-*-${toString fontSize}-*-*-*-*-*-*-*";
itallicBoldFont = boldFont; italicFont = normalFont;
backupFont = fontSize: itallicBoldFont = boldFont;
"xft:TerminessTTF Nerd Font:pixelsize=${toString fontSize}"; backupFont = fontSize:
"xft:TerminessTTF Nerd Font:pixelsize=${toString fontSize}";
fontCommand = key: fontSize: '' fontCommand = key: fontSize: ''
URxvt.keysym.M-${key}: command:\033]710;${normalFont fontSize},${ URxvt.keysym.M-${key}: command:\033]710;${normalFont fontSize},${
backupFont fontSize backupFont fontSize
}\007\033]711;${boldFont fontSize},${backupFont fontSize}\007 }\007\033]711;${boldFont fontSize},${backupFont fontSize}\007
''; '';
in pkgs.writeText "Xresource-urxvt-font" '' in
pkgs.writeText "Xresource-urxvt-font" ''
URxvt.allow_bold: true URxvt.allow_bold: true
URxvt.xftAntialias: true URxvt.xftAntialias: true
@ -110,28 +113,31 @@ in {
${fontCommand "F4" (cfg.fontSize + 20)} ${fontCommand "F4" (cfg.fontSize + 20)}
''; '';
"X11/Xresource.d/urxvt-colors".source = let "X11/Xresource.d/urxvt-colors".source =
colorTheme = if (cfg.colorTheme == "dark") then '' let
#define S_base03 #002b36 colorTheme =
#define S_base02 #073642 if (cfg.colorTheme == "dark") then ''
#define S_base01 #586e75 #define S_base03 #002b36
#define S_base00 #657b83 #define S_base02 #073642
#define S_base0 #839496 #define S_base01 #586e75
#define S_base1 #93a1a1 #define S_base00 #657b83
#define S_base2 #eee8d5 #define S_base0 #839496
#define S_base3 #fdf6e3 #define S_base1 #93a1a1
'' else '' #define S_base2 #eee8d5
#define S_base03 #fdf6e3 #define S_base3 #fdf6e3
#define S_base02 #eee8d5 '' else ''
#define S_base01 #93a1a1 #define S_base03 #fdf6e3
#define S_base00 #839496 #define S_base02 #eee8d5
#define S_base0 #657b83 #define S_base01 #93a1a1
#define S_base1 #586e75 #define S_base00 #839496
#define S_base2 #073642 #define S_base0 #657b83
#define S_base3 #002b36 #define S_base1 #586e75
''; #define S_base2 #073642
#define S_base3 #002b36
'';
in pkgs.writeText "Xresource-urxvt-colors" '' in
pkgs.writeText "Xresource-urxvt-colors" ''
!! Common !! Common
!! ------ !! ------

View file

@ -9,24 +9,27 @@ let
# show keyboard input on desktop for screencasts # show keyboard input on desktop for screencasts
screenKey = pkgs.symlinkJoin { screenKey = pkgs.symlinkJoin {
name = "screen-keys"; name = "screen-keys";
paths = let paths =
screenKeyScript = { position ? "bottom", size ? "small", ... }: let
pkgs.writeShellScriptBin "screenkeys-${position}-${size}" # sh screenKeyScript = { position ? "bottom", size ? "small", ... }:
'' pkgs.writeShellScriptBin "screenkeys-${position}-${size}" # sh
${pkgs.screenkey}/bin/screenkey \ ''
--no-detach \ ${pkgs.screenkey}/bin/screenkey \
--bg-color '#fdf6e3' \ --no-detach \
--font-color '#073642' \ --bg-color '#fdf6e3' \
-p ${position} \ --font-color '#073642' \
-s ${size} \ -p ${position} \
"$@" -s ${size} \
''; "$@"
in lib.flatten (lib.flip map [ "large" "small" "medium" ] (size: '';
lib.flip map [ "top" "center" "bottom" ] in
(position: screenKeyScript { inherit size position; }))); lib.flatten (lib.flip map [ "large" "small" "medium" ] (size:
lib.flip map [ "top" "center" "bottom" ]
(position: screenKeyScript { inherit size position; })));
}; };
in { in
{
options.programs.custom.video.enable = mkEnableOption "enable video tools"; options.programs.custom.video.enable = mkEnableOption "enable video tools";

View file

@ -125,7 +125,7 @@ let
}).env }).env
''; '';
}; };
# active plugins # active plugins
@ -200,7 +200,8 @@ let
''; '';
in { in
{
# no options # no options
options.programs.custom.vim.enable = lib.mkEnableOption "vim"; options.programs.custom.vim.enable = lib.mkEnableOption "vim";

View file

@ -6,7 +6,8 @@ let
cfg = config.programs.custom.xterm; cfg = config.programs.custom.xterm;
in { in
{
options.programs.custom.xterm = { options.programs.custom.xterm = {
enable = mkEnableOption "configure and enable urxvt"; enable = mkEnableOption "configure and enable urxvt";
@ -41,17 +42,19 @@ in {
''; '';
"X11/Xresource.d/xterm-font".source = let "X11/Xresource.d/xterm-font".source =
fontFamily = "terminus"; let
normalFont = fontSize: fontFamily = "terminus";
"-*-${fontFamily}-medium-*-*-*-${toString fontSize}-*-*-*-*-*-*-*"; normalFont = fontSize:
boldFont = fontSize: "-*-${fontFamily}-medium-*-*-*-${toString fontSize}-*-*-*-*-*-*-*";
"-*-${fontFamily}-bold-*-*-*-${toString fontSize}-*-*-*-*-*-*-*"; boldFont = fontSize:
italicFont = normalFont; "-*-${fontFamily}-bold-*-*-*-${toString fontSize}-*-*-*-*-*-*-*";
itallicBoldFont = boldFont; italicFont = normalFont;
backupFont = fontSize: itallicBoldFont = boldFont;
"xft:TerminessTTF Nerd Font:pixelsize=${toString fontSize}"; backupFont = fontSize:
in pkgs.writeText "Xresource-xterm-font" '' "xft:TerminessTTF Nerd Font:pixelsize=${toString fontSize}";
in
pkgs.writeText "Xresource-xterm-font" ''
XTerm.allow_bold: true XTerm.allow_bold: true
XTerm.xftAntialias: true XTerm.xftAntialias: true
@ -76,29 +79,32 @@ in {
XTerm.*.bolditalicFont: ${itallicBoldFont cfg.fontSize} XTerm.*.bolditalicFont: ${itallicBoldFont cfg.fontSize}
''; '';
"X11/Xresource.d/xterm-colors".source = let "X11/Xresource.d/xterm-colors".source =
colorTheme = if (cfg.colorTheme == "dark") then '' let
#define S_base03 #002b36 colorTheme =
#define S_base02 #073642 if (cfg.colorTheme == "dark") then ''
#define S_base01 #586e75 #define S_base03 #002b36
#define S_base00 #657b83 #define S_base02 #073642
#define S_base0 #839496 #define S_base01 #586e75
#define S_base1 #93a1a1 #define S_base00 #657b83
#define S_base2 #eee8d5 #define S_base0 #839496
#define S_base3 #fdf6e3 #define S_base1 #93a1a1
#define S_base2 #eee8d5
#define S_base3 #fdf6e3
'' else '' '' else ''
#define S_base03 #fdf6e3 #define S_base03 #fdf6e3
#define S_base02 #eee8d5 #define S_base02 #eee8d5
#define S_base01 #93a1a1 #define S_base01 #93a1a1
#define S_base00 #839496 #define S_base00 #839496
#define S_base0 #657b83 #define S_base0 #657b83
#define S_base1 #586e75 #define S_base1 #586e75
#define S_base2 #073642 #define S_base2 #073642
#define S_base3 #002b36 #define S_base3 #002b36
''; '';
in pkgs.writeText "Xresource-xterm-colors" '' in
pkgs.writeText "Xresource-xterm-colors" ''
!! Color Configuration !! Color Configuration
!! ------------------- !! -------------------

View file

@ -6,7 +6,8 @@ let
cfg = config.custom.services.castget; cfg = config.custom.services.castget;
in { in
{
options.custom.services.castget = { options.custom.services.castget = {
enable = mkEnableOption "enable custom.services.castget"; enable = mkEnableOption "enable custom.services.castget";
@ -67,25 +68,33 @@ in {
restartIfChanged = false; restartIfChanged = false;
serviceConfig.User = cfg.user; serviceConfig.User = cfg.user;
preStart = let preStart =
mkSpools = let
mapAttrsToList (ignore: value: "mkdir -p ${value.spool}") cfg.feeds; mkSpools =
in concatStringsSep "\n" mkSpools; mapAttrsToList (ignore: value: "mkdir -p ${value.spool}") cfg.feeds;
script = let in
channels = mapAttrsToList (key: ignore: key) cfg.feeds; concatStringsSep "\n" mkSpools;
castget = "${pkgs.castget}/bin/castget"; script =
let
channels = mapAttrsToList (key: ignore: key) cfg.feeds;
castget = "${pkgs.castget}/bin/castget";
configurationFile = let configurationFile =
configurations = mapAttrsToList (key: value: '' let
[${key}] configurations = mapAttrsToList
url=${value.url} (key: value: ''
spool=${value.spool} [${key}]
'') cfg.feeds; url=${value.url}
in (pkgs.writeText "castget-configuration" spool=${value.spool}
(concatStringsSep "" configurations)); '')
in (concatMapStringsSep "\n" cfg.feeds;
(channel: "${castget} --rcfile ${configurationFile} ${channel}") in
channels); (pkgs.writeText "castget-configuration"
(concatStringsSep "" configurations));
in
(concatMapStringsSep "\n"
(channel: "${castget} --rcfile ${configurationFile} ${channel}")
channels);
}; };
systemd.timers."${cfg.serviceName}" = { systemd.timers."${cfg.serviceName}" = {

View file

@ -11,21 +11,24 @@ let
inherit example description default; inherit example description default;
type = with lib.types; type = with lib.types;
let let
valueType = nullOr (oneOf [ valueType = nullOr
bool (oneOf [
int bool
float int
str float
(attrsOf valueType) str
(listOf valueType) (attrsOf valueType)
]) // { (listOf valueType)
]) // {
description = ""; description = "";
emptyValue.value = { }; emptyValue.value = { };
}; };
in valueType; in
valueType;
}; };
in { in
{
options.services.homeAssistantConfig = mkMagicMergeOption { options.services.homeAssistantConfig = mkMagicMergeOption {
description = '' description = ''

View file

@ -6,7 +6,8 @@ let
cfg = config.services.lektor; cfg = config.services.lektor;
in { in
{
options.services.lektor = { options.services.lektor = {
enable = mkEnableOption "enable services.lektor"; enable = mkEnableOption "enable services.lektor";
@ -107,57 +108,59 @@ in {
TimeoutStartSec = TimeoutStartSec =
"infinity"; # it might take some time will this thing is up "infinity"; # it might take some time will this thing is up
ExecStartPre = let ExecStartPre =
let
sshKeyTarget = "/run/keys.lektor/id_rsa"; sshKeyTarget = "/run/keys.lektor/id_rsa";
sshConfig = pkgs.writeText "sshconfig" '' sshConfig = pkgs.writeText "sshconfig" ''
Host ${cfg.host} Host ${cfg.host}
IdentityFile ${sshKeyTarget} IdentityFile ${sshKeyTarget}
Host * Host *
ForwardAgent no ForwardAgent no
Compression no Compression no
ServerAliveInterval 0 ServerAliveInterval 0
HashKnownHosts no HashKnownHosts no
UserKnownHostsFile ~/.ssh/known_hosts UserKnownHostsFile ~/.ssh/known_hosts
ControlMaster no ControlMaster no
ControlPath ~/.ssh/master-%r@%n:%p ControlPath ~/.ssh/master-%r@%n:%p
ControlPersist no ControlPersist no
'';
sshKeyScript = pkgs.writers.writeDash "keyfile-gen" # sh
''
set -x
# setup ~/.ssh
mkdir -p ${cfg.home}/.ssh
chown ${cfg.user} ${cfg.home}/.ssh
chmod 700 ${cfg.home}/.ssh
cp ${sshConfig} ${cfg.home}/.ssh/config
chown ${cfg.user} ${cfg.home}/.ssh/config
chmod 500 ${cfg.home}/.ssh/config
mkdir -p ${dirOf sshKeyTarget}
chmod 700 ${dirOf sshKeyTarget}
chown ${cfg.user} ${dirOf sshKeyTarget}
cp ${toString cfg.sshKey} ${sshKeyTarget}
chown ${cfg.user} ${sshKeyTarget}
chmod 500 ${sshKeyTarget}
''; '';
cloneScript = pkgs.writers.writeDash "clone" # sh sshKeyScript = pkgs.writers.writeDash "keyfile-gen" # sh
'' ''
set -x set -x
if [[ `ls ~/${cfg.user} | wc -l` == 0 ]]
then
rm ~/${cfg.user}
fi
${pkgs.git}/bin/git clone ${cfg.repository} ~/${cfg.user}
'';
in [ "+${sshKeyScript}" "-${cloneScript}" ]; # setup ~/.ssh
mkdir -p ${cfg.home}/.ssh
chown ${cfg.user} ${cfg.home}/.ssh
chmod 700 ${cfg.home}/.ssh
cp ${sshConfig} ${cfg.home}/.ssh/config
chown ${cfg.user} ${cfg.home}/.ssh/config
chmod 500 ${cfg.home}/.ssh/config
mkdir -p ${dirOf sshKeyTarget}
chmod 700 ${dirOf sshKeyTarget}
chown ${cfg.user} ${dirOf sshKeyTarget}
cp ${toString cfg.sshKey} ${sshKeyTarget}
chown ${cfg.user} ${sshKeyTarget}
chmod 500 ${sshKeyTarget}
'';
cloneScript = pkgs.writers.writeDash "clone" # sh
''
set -x
if [[ `ls ~/${cfg.user} | wc -l` == 0 ]]
then
rm ~/${cfg.user}
fi
${pkgs.git}/bin/git clone ${cfg.repository} ~/${cfg.user}
'';
in
[ "+${sshKeyScript}" "-${cloneScript}" ];
}; };
# todo : add restart ruling # todo : add restart ruling

View file

@ -11,24 +11,27 @@ let
inherit example description default; inherit example description default;
type = with lib.types; type = with lib.types;
let let
valueType = nullOr (oneOf [ valueType = nullOr
bool (oneOf [
int bool
float int
str float
(attrsOf valueType) str
(listOf valueType) (attrsOf valueType)
]) // { (listOf valueType)
]) // {
description = ""; description = "";
emptyValue.value = { }; emptyValue.value = { };
}; };
in valueType; in
valueType;
}; };
lightControlConfig = lightControlConfig =
pkgs.writeText "light-control.json" (builtins.toJSON cfg.config); pkgs.writeText "light-control.json" (builtins.toJSON cfg.config);
in { in
{
options.services.mqtt.light-control = { options.services.mqtt.light-control = {
enable = mkEnableOption "enable mqtt.light-control"; enable = mkEnableOption "enable mqtt.light-control";

View file

@ -6,7 +6,8 @@ let
cfg = config.custom.samba-share; cfg = config.custom.samba-share;
in { in
{
options.custom.samba-share = { options.custom.samba-share = {
enable = mkEnableOption "enable custom.samba-share"; enable = mkEnableOption "enable custom.samba-share";
@ -61,27 +62,31 @@ in {
disable spoolss = yes disable spoolss = yes
''; '';
shares = mapAttrs' (name: path: { shares = mapAttrs'
name = name; (name: path: {
value = {
browsable = "yes";
comment = "read only share ${name}";
path = path;
"read only" = "yes";
"guest ok" = "yes";
};
}) cfg.folders // (mapAttrs' (name:
{ users, folder, ... }: {
name = name; name = name;
value = { value = {
browsable = "yes"; browsable = "yes";
comment = "read only share ${name}"; comment = "read only share ${name}";
path = folder; path = path;
"read only" = "no"; "read only" = "yes";
"valid users" = users; "guest ok" = "yes";
"guest ok" = "false";
}; };
}) cfg.private); })
cfg.folders // (mapAttrs'
(name:
{ users, folder, ... }: {
name = name;
value = {
browsable = "yes";
comment = "read only share ${name}";
path = folder;
"read only" = "no";
"valid users" = users;
"guest ok" = "false";
};
})
cfg.private);
}; };
users.users.smbguest = { users.users.smbguest = {

View file

@ -6,7 +6,8 @@ let
cfg = config.services.custom.ssh; cfg = config.services.custom.ssh;
in { in
{
options.services.custom.ssh = { options.services.custom.ssh = {
tools.enable = mkEnableOption "Add ssh tools"; tools.enable = mkEnableOption "Add ssh tools";
@ -44,14 +45,16 @@ in {
Banner /etc/sshd/banner-line Banner /etc/sshd/banner-line
''; '';
environment.etc."sshd/banner-line".text = let environment.etc."sshd/banner-line".text =
text = config.networking.hostName; let
size = 80 - (lib.stringLength text); text = config.networking.hostName;
space = lib.fixedWidthString size " " ""; size = 80 - (lib.stringLength text);
in '' space = lib.fixedWidthString size " " "";
in
${space}${text} ''
'';
${space}${text}
'';
}) })

View file

@ -14,7 +14,7 @@ in
default = "4:00:00"; default = "4:00:00";
}; };
recurrence = mkOption { recurrence = mkOption {
type = enum["on" "off"]; type = enum [ "on" "off" ];
default = "off"; default = "off";
}; };
pushoverApiTokenFile = mkOption { pushoverApiTokenFile = mkOption {
@ -37,7 +37,7 @@ in
certificateFile = mkOption { certificateFile = mkOption {
type = path; type = path;
}; };
credentials= mkOption { credentials = mkOption {
type = str; type = str;
}; };
keyFile = mkOption { keyFile = mkOption {
@ -55,43 +55,44 @@ in
DynamicUser = true; DynamicUser = true;
StateDirectory = name; StateDirectory = name;
}; };
script = let script =
taskwarriorCommand = pkgs.writers.writeDash "taskwarrior-push" '' let
${pkgs.taskwarrior}/bin/task \ taskwarriorCommand = pkgs.writers.writeDash "taskwarrior-push" ''
rc.recurrence=${cfg.recurrence} \ ${pkgs.taskwarrior}/bin/task \
rc:/var/lib/${name}/.taskrc \ rc.recurrence=${cfg.recurrence} \
rc.data.location=/var/lib/${name}/${cfg.dataDir} \ rc:/var/lib/${name}/.taskrc \
rc.taskd.ca=${cfg.caFile} \ rc.data.location=/var/lib/${name}/${cfg.dataDir} \
rc.taskd.certificate=${cfg.certificateFile} \ rc.taskd.ca=${cfg.caFile} \
rc.taskd.credentials="${cfg.credentials}" \ rc.taskd.certificate=${cfg.certificateFile} \
rc.taskd.key=${cfg.keyFile} \ rc.taskd.credentials="${cfg.credentials}" \
rc.taskd.server=${cfg.server} \ rc.taskd.key=${cfg.keyFile} \
"$@" rc.taskd.server=${cfg.server} \
''; "$@"
in '';
in
'' ''
if [ -d /var/lib/${name}/${cfg.dataDir} ] if [ -d /var/lib/${name}/${cfg.dataDir} ]
then then
echo "synchronize {cfg.dataDir}" echo "synchronize {cfg.dataDir}"
${taskwarriorCommand} sync ${taskwarriorCommand} sync
else else
echo "initialize ${cfg.dataDir}" echo "initialize ${cfg.dataDir}"
${pkgs.coreutils}/bin/yes | ${taskwarriorCommand} sync init ${pkgs.coreutils}/bin/yes | ${taskwarriorCommand} sync init
fi fi
${taskwarriorCommand} '${cfg.query}' export \ ${taskwarriorCommand} '${cfg.query}' export \
| ${pkgs.jq}/bin/jq -r '.[] | @base64' | while read entry | ${pkgs.jq}/bin/jq -r '.[] | @base64' | while read entry
do do
echo $entry | base64 --decode | \ echo $entry | base64 --decode | \
${pkgs.jq}/bin/jq '{ ${pkgs.jq}/bin/jq '{
"token": "'`cat ${cfg.pushoverApiTokenFile}`'", "token": "'`cat ${cfg.pushoverApiTokenFile}`'",
"user": "'`cat ${cfg.pushoverUserKeyFile}`'", "user": "'`cat ${cfg.pushoverUserKeyFile}`'",
"titel": "taskwarrior", "titel": "taskwarrior",
message: .description message: .description
}' \ }' \
| ${pkgs.curl}/bin/curl -sS -X POST -H 'Content-Type: application/json' -d @- \ | ${pkgs.curl}/bin/curl -sS -X POST -H 'Content-Type: application/json' -d @- \
"https://api.pushover.net/1/messages.json" "https://api.pushover.net/1/messages.json"
done done
''; '';
}; };
systemd.timers.taskwarrior-pushover = { systemd.timers.taskwarrior-pushover = {

View file

@ -30,7 +30,8 @@ let
fi fi
''; '';
in { in
{
options.service.videoencoder = { options.service.videoencoder = {
enable = mkEnableOption "enable service.videoencoder"; enable = mkEnableOption "enable service.videoencoder";
@ -91,14 +92,17 @@ in {
systemd.services."videoEncoding" = { systemd.services."videoEncoding" = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
enable = true; enable = true;
script = let script =
myList = map (value: let
createEncoder "/tmp/videoencoder" value.inputFile value.outputFile) myList = map
cfg.fileConfig; (value:
in '' createEncoder "/tmp/videoencoder" value.inputFile value.outputFile)
set -x cfg.fileConfig;
${concatStringsSep "\n" myList} in
''; ''
set -x
${concatStringsSep "\n" myList}
'';
}; };

View file

@ -41,7 +41,8 @@ let
cfg = config.system.custom.audio; cfg = config.system.custom.audio;
in { in
{
options.system.custom.audio = { options.system.custom.audio = {
enable = mkEnableOption "use PluseAudio"; enable = mkEnableOption "use PluseAudio";

View file

@ -4,7 +4,8 @@ let
cfg = config.system.custom.bluetooth; cfg = config.system.custom.bluetooth;
in { in
{
options.system.custom.bluetooth.enable = options.system.custom.bluetooth.enable =
lib.mkEnableOption "enable bluetooth support"; lib.mkEnableOption "enable bluetooth support";

View file

@ -6,7 +6,8 @@ let
cfg = config.system.custom.fonts; cfg = config.system.custom.fonts;
in { in
{
options.system.custom.fonts = { options.system.custom.fonts = {
enable = mkEnableOption "enable fonts"; enable = mkEnableOption "enable fonts";

View file

@ -9,12 +9,14 @@ let
dockerGroup = dockerGroup =
if (config.virtualisation.docker.enable) then [ "docker" ] else [ ]; if (config.virtualisation.docker.enable) then [ "docker" ] else [ ];
vboxGroup = if (config.virtualisation.virtualbox.host.enable) then vboxGroup =
[ "vboxusers" ] if (config.virtualisation.virtualbox.host.enable) then
else [ "vboxusers" ]
[ ]; else
[ ];
in { in
{
options.system.custom.mainUser = { options.system.custom.mainUser = {

View file

@ -55,7 +55,8 @@ let
${cfg.url} ${cfg.url}
''; '';
in { in
{
options.on-failure = api; options.on-failure = api;

View file

@ -6,7 +6,8 @@ let
cfg = config.system.permown; cfg = config.system.permown;
nameGenerator = path: "permown.${replaceStrings [ "/" ] [ "_" ] path}"; nameGenerator = path: "permown.${replaceStrings [ "/" ] [ "_" ] path}";
in { in
{
options.system.permown = mkOption { options.system.permown = mkOption {
default = { }; default = { };
@ -45,51 +46,54 @@ in {
})); }));
}; };
config = let plans = lib.attrValues cfg; config =
let plans = lib.attrValues cfg;
in mkIf (plans != [ ]) { in mkIf (plans != [ ]) {
system.activationScripts.permown = let system.activationScripts.permown =
mkdir = { path, ... }: '' let
${pkgs.coreutils}/bin/mkdir -p ${path} mkdir = { path, ... }: ''
''; ${pkgs.coreutils}/bin/mkdir -p ${path}
in concatMapStrings mkdir plans; '';
in
concatMapStrings mkdir plans;
systemd.services = listToAttrs (flip map plans systemd.services = listToAttrs (flip map plans
({ path, directory-mode, file-mode, owner, group, umask, ... }: { ({ path, directory-mode, file-mode, owner, group, umask, ... }: {
name = nameGenerator path;
value = {
environment = {
DIR_MODE = directory-mode;
FILE_MODE = file-mode;
OWNER_GROUP = "${owner}:${group}";
ROOT_PATH = path;
};
path = [ pkgs.coreutils pkgs.findutils pkgs.inotifyTools ];
serviceConfig = {
ExecStart = pkgs.writers.writeDash "permown" ''
set -efu
find "$ROOT_PATH" -exec chown -h "$OWNER_GROUP" {} +
find "$ROOT_PATH" -type d -exec chmod "$DIR_MODE" {} +
find "$ROOT_PATH" -type f -exec chmod "$FILE_MODE" {} +
'';
PrivateTmp = true;
Restart = "always";
RestartSec = 10;
UMask = umask;
};
wantedBy = [ "multi-user.target" ];
};
}));
systemd.timers = listToAttrs (flip map plans ({ path, timer, ... }: {
name = nameGenerator path; name = nameGenerator path;
value = { value = {
environment = {
DIR_MODE = directory-mode;
FILE_MODE = file-mode;
OWNER_GROUP = "${owner}:${group}";
ROOT_PATH = path;
};
path = [ pkgs.coreutils pkgs.findutils pkgs.inotifyTools ];
serviceConfig = {
ExecStart = pkgs.writers.writeDash "permown" ''
set -efu
find "$ROOT_PATH" -exec chown -h "$OWNER_GROUP" {} +
find "$ROOT_PATH" -type d -exec chmod "$DIR_MODE" {} +
find "$ROOT_PATH" -type f -exec chmod "$FILE_MODE" {} +
'';
PrivateTmp = true;
Restart = "always";
RestartSec = 10;
UMask = umask;
};
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
timerConfig.OnCalendar = timer;
}; };
})); }));
systemd.timers = listToAttrs (flip map plans ({ path, timer, ... }: { };
name = nameGenerator path;
value = {
wantedBy = [ "multi-user.target" ];
timerConfig.OnCalendar = timer;
};
}));
};
} }

View file

@ -6,7 +6,8 @@ let
cfg = config.system.custom.wifi; cfg = config.system.custom.wifi;
in { in
{
options.system.custom.wifi = { options.system.custom.wifi = {
enable = mkEnableOption "enable wifi"; enable = mkEnableOption "enable wifi";

View file

@ -6,7 +6,8 @@ let
cfg = config.system.custom.x11; cfg = config.system.custom.x11;
in { in
{
options.system.custom.x11 = { options.system.custom.x11 = {
enable = mkEnableOption "enable x11"; enable = mkEnableOption "enable x11";

View file

@ -12,7 +12,8 @@ let
# function call # function call
# ------------- # -------------
in (pkgs.buildFHSUserEnv { in
(pkgs.buildFHSUserEnv {
# name of the programm # name of the programm
# -------------------- # --------------------

View file

@ -1,6 +1,27 @@
{ stdenv, fetchurl, alsaLib, bzip2, cairo, dpkg, freetype, gdk_pixbuf, glib { stdenv
, gtk2, harfbuzz, jdk, lib, xorg, libbsd, libjack2, libpng, libxkbcommon , fetchurl
, makeWrapper, pixman, xdg_utils, zenity, zlib }: , alsaLib
, bzip2
, cairo
, dpkg
, freetype
, gdk_pixbuf
, glib
, gtk2
, harfbuzz
, jdk
, lib
, xorg
, libbsd
, libjack2
, libpng
, libxkbcommon
, makeWrapper
, pixman
, xdg_utils
, zenity
, zlib
}:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "bitwig-studio-${version}"; name = "bitwig-studio-${version}";

View file

@ -40,9 +40,10 @@ let
Y Oˡʸ L O | yolo Y Oˡʸ L O | yolo
(ʟ) | zen (ʟ) | zen
@}-,-`- | rose @}-,-`- | rose
''; '';
in writeShellScriptBin "emoticons" '' in
writeShellScriptBin "emoticons" ''
set -efu set -efu
data=$(${coreutils}/bin/cat ${emoticons}) data=$(${coreutils}/bin/cat ${emoticons})

View file

@ -1,9 +1,11 @@
{ pkgs, lib, ... }: { pkgs, lib, ... }:
pkgs.writers.writePython3Bin "gitlog2json" { pkgs.writers.writePython3Bin "gitlog2json"
{
libraries = [ libraries = [
pkgs.python3Packages.GitPython pkgs.python3Packages.GitPython
pkgs.python3Packages.click pkgs.python3Packages.click
pkgs.python3Packages.elasticsearch pkgs.python3Packages.elasticsearch
]; ];
} (lib.fileContents ./gitlog2json.py) }
(lib.fileContents ./gitlog2json.py)

View file

@ -1,5 +1,10 @@
{ lib, writeTextFile, jsonConfig ? { }, title ? "Landing Page" { lib
, destination ? "/index.html", ... }: , writeTextFile
, jsonConfig ? { }
, title ? "Landing Page"
, destination ? "/index.html"
, ...
}:
with lib; with lib;

View file

@ -1,5 +1,12 @@
{ lib, symlinkJoin, rofi, gnused, pass-otp, writeTextFile, writeShellScriptBin { lib
, xdotool }: , symlinkJoin
, rofi
, gnused
, pass-otp
, writeTextFile
, writeShellScriptBin
, xdotool
}:
let let
@ -36,7 +43,8 @@ let
printf %s "$otp" | ${xdotool}/bin/xdotool type -f - printf %s "$otp" | ${xdotool}/bin/xdotool type -f -
''; '';
in symlinkJoin rec { in
symlinkJoin rec {
version = "1.0.0"; version = "1.0.0";
name = "otpMenu-${version}"; name = "otpMenu-${version}";
paths = [ bin desktopFile ]; paths = [ bin desktopFile ];

View file

@ -1,82 +1,93 @@
{ pkgs, lib { pkgs
# tzselect is your frind do find timezones , lib
, timeZones ? [ ], timeColor ? 9, timeZoneColor ? 10, calBackgroundColor ? 10 # tzselect is your frind do find timezones
, calWeekColor ? 13, calDayColor ? 9, enableIntelBacklight ? true , timeZones ? [ ]
, userHighlight ? [ "palo" ], enableBattery ? true, ... }: , timeColor ? 9
, timeZoneColor ? 10
, calBackgroundColor ? 10
, calWeekColor ? 13
, calDayColor ? 9
, enableIntelBacklight ? true
, userHighlight ? [ "palo" ]
, enableBattery ? true
, ...
}:
let let
hrule = "${pkgs.terminal-tools}/bin/hrule"; hrule = "${pkgs.terminal-tools}/bin/hrule";
q-cal = let q-cal =
let
# Maximum width of cal's output. # Maximum width of cal's output.
calwidth = 23; calwidth = 23;
# Number of space characters between two calendars. # Number of space characters between two calendars.
hspace = 2; hspace = 2;
# Return number of columns required to print n calenders side by side. # Return number of columns required to print n calenders side by side.
need_width = n: assert n >= 1; n * calwidth + (n - 1) * hspace; need_width = n: assert n >= 1; n * calwidth + (n - 1) * hspace;
lpad = n: c: s: if lib.stringLength s < n then lpad n c (c + s) else s; lpad = n: c: s: if lib.stringLength s < n then lpad n c (c + s) else s;
pad = '' pad = ''
{ {
${pkgs.gnused}/bin/sed ' ${pkgs.gnused}/bin/sed '
# rtrim # rtrim
s/ *$// s/ *$//
# delete last empty line # delete last empty line
''${/^$/d} ''${/^$/d}
' \
| ${pkgs.gawk}/bin/awk '{printf "%-${
toString calwidth
}s\n", $0}' \
| ${pkgs.gnused}/bin/sed "
# colorize header
1,2s/.*/[38;5;${toString calBackgroundColor}m&/
# highlight current week
s/^$(${pkgs.coreutils}/bin/date +%W)/[38;5;${
toString calWeekColor
}m&/
# colorize week number
s/^[ 1-9][0-9]/[38;5;${
toString calBackgroundColor
}m&/
"
}'';
in
''
cols=$(${pkgs.ncurses}/bin/tput cols)
${pkgs.coreutils}/bin/paste \
<(if test $cols -ge ${toString (need_width 3)}; then
${pkgs.utillinux}/bin/cal -mw \
$(${pkgs.coreutils}/bin/date +'%m %Y' -d 'last month') \
| ${pad}
fi) \
<(if test $cols -ge ${toString (need_width 1)}; then
${pkgs.utillinux}/bin/cal -mw \
| ${pkgs.gnused}/bin/sed '
# colorize day of month
s/\(^\| \)'"$(${pkgs.coreutils}/bin/date +%e)"'\>/[38;5;${
toString calDayColor
}m&/
' \ ' \
| ${pkgs.gawk}/bin/awk '{printf "%-${ | ${pad}
toString calwidth fi) \
}s\n", $0}' \ <(if test $cols -ge ${toString (need_width 2)}; then
| ${pkgs.gnused}/bin/sed " ${pkgs.utillinux}/bin/cal -mw \
# colorize header $(${pkgs.coreutils}/bin/date +'%m %Y' -d 'next month') \
1,2s/.*/[38;5;${toString calBackgroundColor}m&/ | ${pad}
fi) \
# highlight current week | ${pkgs.gnused}/bin/sed '
s/^$(${pkgs.coreutils}/bin/date +%W)/[38;5;${ s/^\t//
toString calWeekColor s/\t$//
}m&/ s/\t/${lpad hspace " " ""}/g
'
# colorize week number '';
s/^[ 1-9][0-9]/[38;5;${
toString calBackgroundColor
}m&/
"
}'';
in ''
cols=$(${pkgs.ncurses}/bin/tput cols)
${pkgs.coreutils}/bin/paste \
<(if test $cols -ge ${toString (need_width 3)}; then
${pkgs.utillinux}/bin/cal -mw \
$(${pkgs.coreutils}/bin/date +'%m %Y' -d 'last month') \
| ${pad}
fi) \
<(if test $cols -ge ${toString (need_width 1)}; then
${pkgs.utillinux}/bin/cal -mw \
| ${pkgs.gnused}/bin/sed '
# colorize day of month
s/\(^\| \)'"$(${pkgs.coreutils}/bin/date +%e)"'\>/[38;5;${
toString calDayColor
}m&/
' \
| ${pad}
fi) \
<(if test $cols -ge ${toString (need_width 2)}; then
${pkgs.utillinux}/bin/cal -mw \
$(${pkgs.coreutils}/bin/date +'%m %Y' -d 'next month') \
| ${pad}
fi) \
| ${pkgs.gnused}/bin/sed '
s/^\t//
s/\t$//
s/\t/${lpad hspace " " ""}/g
'
'';
q-timeZoneDate = size: zone: q-timeZoneDate = size: zone:
let let
@ -88,17 +99,19 @@ let
comment = lib.optionalString (zone != null) comment = lib.optionalString (zone != null)
" : ${lib.fixedWidthString size " " zone}"; " : ${lib.fixedWidthString size " " zone}";
# sh # sh
in '' in
''
${timeZoneVariable} ${pkgs.coreutils}/bin/date ${ ${timeZoneVariable} ${pkgs.coreutils}/bin/date ${
dateString comment dateString comment
} | ${pkgs.terminal-tools}/bin/center } | ${pkgs.terminal-tools}/bin/center
''; '';
q-timeZoneDates = if timeZones == [ ] then q-timeZoneDates =
q-timeZoneDate 0 null if timeZones == [ ] then
else q-timeZoneDate 0 null
let size = lib.foldr lib.max 0 (map builtins.stringLength timeZones); else
in lib.concatMapStringsSep "\n" (q-timeZoneDate size) timeZones; let size = lib.foldr lib.max 0 (map builtins.stringLength timeZones);
in lib.concatMapStringsSep "\n" (q-timeZoneDate size) timeZones;
q-intel_backlight = '' q-intel_backlight = ''
cd /sys/class/backlight/intel_backlight cd /sys/class/backlight/intel_backlight
@ -116,144 +129,146 @@ let
' '
''; '';
q-power_supply = let q-power_supply =
power_supply = pkgs.writers.writeBash "power_supply" '' let
set -efu power_supply = pkgs.writers.writeBash "power_supply" ''
uevent=$1 set -efu
eval "$(${pkgs.gnused}/bin/sed -n ' uevent=$1
s/^\([A-Z_]\+=[0-9A-Za-z_-]*\)$/export \1/p eval "$(${pkgs.gnused}/bin/sed -n '
' $uevent)" s/^\([A-Z_]\+=[0-9A-Za-z_-]*\)$/export \1/p
case $POWER_SUPPLY_NAME in ' $uevent)"
AC) case $POWER_SUPPLY_NAME in
exit # not battery AC)
;; exit # not battery
esac ;;
exec </dev/null esac
exec ${pkgs.gawk}/bin/awk ' exec </dev/null
function die(s) { exec ${pkgs.gawk}/bin/awk '
printf "%20s %s\n", name, s function die(s) {
exit 1 printf "%20s %s\n", name, s
} exit 1
function print_hm(h, m) {
m = (h - int(h)) * 60
return sprintf("%dh%dm", h, m)
}
function print_bar(bar_size, charge, full_bars, empty_bars, full_color) {
full_bars = int(charge * bar_size)
empty_bars = bar_size - full_bars
if (charge >= .42) full_color = "2"
else if (charge >= .23) full_color = "3"
else full_color = "1"
left_arrow = 1
middle_arrow = 1
right_arrow = 1
if (full_bars == 0) {
left_arrow = 0
middle_arrow = 0
}
if (empty_bars == 0) {
middle_arrow = 0
right_arrow = 0
} }
empty_color = "0"; function print_hm(h, m) {
return sgr("38;5;" 8) sgr("48;5;" full_color) strdup("",left_arrow) strdup(" ", full_bars) sgr("48;5;" empty_color) sgr("38;5;" full_color) strdup("",middle_arrow) strdup(" ", empty_bars) sgr() sgr("38;5;" empty_color) strdup("",right_arrow) sgr() m = (h - int(h)) * 60
} return sprintf("%dh%dm", h, m)
function sgr(p) {
return "\x1b[" p "m"
}
function strdup(s,n,t) {
t = sprintf("%"n"s","")
gsub(/ /,s,t)
return t
}
END {
name = ENVIRON["POWER_SUPPLY_NAME"]
charge_unit = "Ah"
charge_now = ENVIRON["POWER_SUPPLY_CHARGE_NOW"] / 10^6
charge_full = ENVIRON["POWER_SUPPLY_CHARGE_FULL"] / 10^6
current_unit = "A"
current_now = ENVIRON["POWER_SUPPLY_CURRENT_NOW"] / 10^6
energy_unit = "Wh"
energy_now = ENVIRON["POWER_SUPPLY_ENERGY_NOW"] / 10^6
energy_full = ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
power_unit = "W"
power_now = ENVIRON["POWER_SUPPLY_POWER_NOW"] / 10^6
voltage_unit = "V"
voltage_now = ENVIRON["POWER_SUPPLY_VOLTAGE_NOW"] / 10^6
voltage_min_design = ENVIRON["POWER_SUPPLY_VOLTAGE_MIN_DESIGN"] / 10^6
#printf "charge_now: %s\n", charge_now
#printf "charge_full: %s\n", charge_full
#printf "current_now: %s\n", current_now
#printf "energy_now: %s\n", energy_now
#printf "energy_full: %s\n", energy_full
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"]
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
#printf "power_now: %s\n", power_now
#printf "voltage_now: %s\n", voltage_now
if (current_now == 0 && voltage_now != 0) {
current_now = power_now / voltage_now
}
if (power_now == 0) {
power_now = current_now * voltage_now
}
if (charge_now == 0 && voltage_min_design != 0) {
charge_now = energy_now / voltage_min_design
}
if (energy_now == 0) {
energy_now = charge_now * voltage_min_design
}
if (charge_full == 0 && voltage_min_design != 0) {
charge_full = energy_full / voltage_min_design
}
if (energy_full == 0) {
energy_full = charge_full * voltage_min_design
} }
if (charge_now == 0 || charge_full == 0) { function print_bar(bar_size, charge, full_bars, empty_bars, full_color) {
die("unknown charge") full_bars = int(charge * bar_size)
empty_bars = bar_size - full_bars
if (charge >= .42) full_color = "2"
else if (charge >= .23) full_color = "3"
else full_color = "1"
left_arrow = 1
middle_arrow = 1
right_arrow = 1
if (full_bars == 0) {
left_arrow = 0
middle_arrow = 0
}
if (empty_bars == 0) {
middle_arrow = 0
right_arrow = 0
}
empty_color = "0";
return sgr("38;5;" 8) sgr("48;5;" full_color) strdup("",left_arrow) strdup(" ", full_bars) sgr("48;5;" empty_color) sgr("38;5;" full_color) strdup("",middle_arrow) strdup(" ", empty_bars) sgr() sgr("38;5;" empty_color) strdup("",right_arrow) sgr()
} }
charge_ratio = charge_now / charge_full function sgr(p) {
return "\x1b[" p "m"
out = out sprintf("%20s ", name)
out = out sprintf(" %s", print_bar(10, charge_ratio))
out = out sprintf(" %d%", charge_ratio * 100)
out = out sprintf(" %.2f%s", charge_now, charge_unit)
if (current_now != 0) {
out = out sprintf("/%.1f%s", current_now, current_unit)
}
out = out sprintf(" %d%s", energy_full, energy_unit)
if (power_now != 0) {
out = out sprintf("/%.1f%s", power_now, power_unit)
}
if (current_now != 0) {
out = out sprintf(" %s", print_hm(charge_now / current_now))
} }
print out function strdup(s,n,t) {
} t = sprintf("%"n"s","")
' gsub(/ /,s,t)
return t
}
END {
name = ENVIRON["POWER_SUPPLY_NAME"]
charge_unit = "Ah"
charge_now = ENVIRON["POWER_SUPPLY_CHARGE_NOW"] / 10^6
charge_full = ENVIRON["POWER_SUPPLY_CHARGE_FULL"] / 10^6
current_unit = "A"
current_now = ENVIRON["POWER_SUPPLY_CURRENT_NOW"] / 10^6
energy_unit = "Wh"
energy_now = ENVIRON["POWER_SUPPLY_ENERGY_NOW"] / 10^6
energy_full = ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
power_unit = "W"
power_now = ENVIRON["POWER_SUPPLY_POWER_NOW"] / 10^6
voltage_unit = "V"
voltage_now = ENVIRON["POWER_SUPPLY_VOLTAGE_NOW"] / 10^6
voltage_min_design = ENVIRON["POWER_SUPPLY_VOLTAGE_MIN_DESIGN"] / 10^6
#printf "charge_now: %s\n", charge_now
#printf "charge_full: %s\n", charge_full
#printf "current_now: %s\n", current_now
#printf "energy_now: %s\n", energy_now
#printf "energy_full: %s\n", energy_full
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"]
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
#printf "power_now: %s\n", power_now
#printf "voltage_now: %s\n", voltage_now
if (current_now == 0 && voltage_now != 0) {
current_now = power_now / voltage_now
}
if (power_now == 0) {
power_now = current_now * voltage_now
}
if (charge_now == 0 && voltage_min_design != 0) {
charge_now = energy_now / voltage_min_design
}
if (energy_now == 0) {
energy_now = charge_now * voltage_min_design
}
if (charge_full == 0 && voltage_min_design != 0) {
charge_full = energy_full / voltage_min_design
}
if (energy_full == 0) {
energy_full = charge_full * voltage_min_design
}
if (charge_now == 0 || charge_full == 0) {
die("unknown charge")
}
charge_ratio = charge_now / charge_full
out = out sprintf("%20s ", name)
out = out sprintf(" %s", print_bar(10, charge_ratio))
out = out sprintf(" %d%", charge_ratio * 100)
out = out sprintf(" %.2f%s", charge_now, charge_unit)
if (current_now != 0) {
out = out sprintf("/%.1f%s", current_now, current_unit)
}
out = out sprintf(" %d%s", energy_full, energy_unit)
if (power_now != 0) {
out = out sprintf("/%.1f%s", power_now, power_unit)
}
if (current_now != 0) {
out = out sprintf(" %s", print_hm(charge_now / current_now))
}
print out
}
'
'';
in
''
for uevent in /sys/class/power_supply/*/uevent; do
${power_supply} "$uevent" || :
done
''; '';
in ''
for uevent in /sys/class/power_supply/*/uevent; do
${power_supply} "$uevent" || :
done
'';
q-virtualization = '' q-virtualization = ''
printf '%20s %s\n' "VT" \ printf '%20s %s\n' "VT" \
@ -323,7 +338,8 @@ let
''; '';
# bash needed for <(...) # bash needed for <(...)
in pkgs.writers.writeBashBin "q" '' in
pkgs.writers.writeBashBin "q" ''
set -eu set -eu
export PATH=/var/empty export PATH=/var/empty
${hrule} ${hrule}

View file

@ -32,7 +32,8 @@ let
}; };
in (pkgs.buildFHSUserEnv { in
(pkgs.buildFHSUserEnv {
# name it # name it
# ------- # -------

View file

@ -32,7 +32,8 @@ let
}; };
in (pkgs.buildFHSUserEnv { in
(pkgs.buildFHSUserEnv {
# name it # name it
# ------- # -------

View file

@ -20,58 +20,62 @@
}; };
}; };
config = let config =
let
servers = [ servers = [
{ {
name = "workhorse"; name = "workhorse";
host = "workhorse.private"; host = "workhorse.private";
} }
{ {
name = "pepe"; name = "pepe";
host = "pepe.private"; host = "pepe.private";
} }
]; ];
dirs = config.backup.dirs; dirs = config.backup.dirs;
myHostname = config.networking.hostName; myHostname = config.networking.hostName;
setup = server: {
paths = config.backup.dirs;
exclude = config.backup.exclude;
doInit = true;
repo = "borg@${server}:./${myHostname}";
encryption = {
mode = "repokey-blake2";
passCommand =
"cat ${config.sops.secrets.backup_repository_passphrase.path}";
};
environment.BORG_RSH =
"ssh -i ${toString config.sops.secrets.backup_ssh_rsa_private.path}";
compression = "auto,lzma";
startAt = "daily";
prune.keep = {
within = "10d"; # Keep all backups in the last 10 days.
weekly = 8; # Keep 8 additional end of week archives.
monthly = -1; # Keep end of month archive for every month
};
setup = server: {
paths = config.backup.dirs;
exclude = config.backup.exclude;
doInit = true;
repo = "borg@${server}:./${myHostname}";
encryption = {
mode = "repokey-blake2";
passCommand =
"cat ${config.sops.secrets.backup_repository_passphrase.path}";
};
environment.BORG_RSH =
"ssh -i ${toString config.sops.secrets.backup_ssh_rsa_private.path}";
compression = "auto,lzma";
startAt = "daily";
prune.keep = {
within = "10d"; # Keep all backups in the last 10 days.
weekly = 8; # Keep 8 additional end of week archives.
monthly = -1; # Keep end of month archive for every month
}; };
in
{
sops.secrets.backup_repository_passphrase = { };
sops.secrets.backup_ssh_rsa_private = { };
services.borgbackup.jobs =
let
setups = map ({ name, host }: { "${name}" = setup host; }) servers;
setupAttrs = lib.zipAttrsWith (_: vals: lib.head vals) setups;
nonEmptySetups =
lib.filterAttrs (_: { paths, ... }: builtins.length paths != 0)
setupAttrs;
in
nonEmptySetups;
}; };
in {
sops.secrets.backup_repository_passphrase = { };
sops.secrets.backup_ssh_rsa_private = { };
services.borgbackup.jobs = let
setups = map ({ name, host }: { "${name}" = setup host; }) servers;
setupAttrs = lib.zipAttrsWith (_: vals: lib.head vals) setups;
nonEmptySetups =
lib.filterAttrs (_: { paths, ... }: builtins.length paths != 0)
setupAttrs;
in nonEmptySetups;
};
} }

View file

@ -1,20 +1,24 @@
{ pkgs, lib, ... }: { { pkgs, lib, ... }: {
environment.systemPackages = let environment.systemPackages =
createScript = command: host: repository: let
pkgs.writers.writeBashBin createScript = command: host: repository:
"borg-${command}-on-${host}-for-${repository}" '' pkgs.writers.writeBashBin
${pkgs.borgbackup}/bin/borg \ "borg-${command}-on-${host}-for-${repository}" ''
${command} \ ${pkgs.borgbackup}/bin/borg \
--rsh='ssh -i ~/.ssh/card_rsa.pub' borg@${host}.private:${repository}/. \ ${command} \
"$@" --rsh='ssh -i ~/.ssh/card_rsa.pub' borg@${host}.private:${repository}/. \
''; "$@"
hosts = [ "workhorse" "pepe" ]; '';
repositories = [ "workhorse" "pepe" "sterni" "workout" ]; hosts = [ "workhorse" "pepe" ];
commands = [ "list" ]; repositories = [ "workhorse" "pepe" "sterni" "workout" ];
in lib.flatten (map (command: commands = [ "list" ];
map in
(host: map (repository: createScript command host repository) repositories) lib.flatten (map
hosts) commands); (command:
map
(host: map (repository: createScript command host repository) repositories)
hosts)
commands);
} }

View file

@ -5,7 +5,8 @@ let
rev = "fe27cbc99e994d50bb4269a9388e3f7d60492ffa"; rev = "fe27cbc99e994d50bb4269a9388e3f7d60492ffa";
sha256 = "1z8zc4k2mh8d56ipql8vfljvdjczrrna5ckgzjsdyrndfkwv8ghw"; sha256 = "1z8zc4k2mh8d56ipql8vfljvdjczrrna5ckgzjsdyrndfkwv8ghw";
}; };
in { in
{
boot.loader.grub.extraConfig = '' boot.loader.grub.extraConfig = ''
set theme=($drive1)//themes/fallout-grub-theme/theme.txt set theme=($drive1)//themes/fallout-grub-theme/theme.txt

View file

@ -26,28 +26,30 @@
}; };
}; };
config = let config =
kbits = number: let
import (pkgs.runCommand "round-${toString number}" { } kbits = number:
''awk 'BEGIN{printf "\"%ikbit\"", ${toString number}}' > $out''); import (pkgs.runCommand "round-${toString number}" { }
''awk 'BEGIN{printf "\"%ikbit\"", ${toString number}}' > $out'');
interface = config.configuration.fireqos.interface; interface = config.configuration.fireqos.interface;
input = "${toString config.configuration.fireqos.input}kbit"; input = "${toString config.configuration.fireqos.input}kbit";
output = "${toString config.configuration.fireqos.output}kbit"; output = "${toString config.configuration.fireqos.output}kbit";
tincInput = kbits (config.configuration.fireqos.input * 0.7); tincInput = kbits (config.configuration.fireqos.input * 0.7);
tincOutput = kbits (config.configuration.fireqos.output * 0.7); tincOutput = kbits (config.configuration.fireqos.output * 0.7);
useBalancedForExperimenting = false; useBalancedForExperimenting = false;
tincPorts = tincPorts =
lib.mapAttrsToList (name: configuration: toString configuration.port) lib.mapAttrsToList (name: configuration: toString configuration.port)
config.module.cluster.services.tinc; config.module.cluster.services.tinc;
in { in
{
# https://firehol.org/tutorial/fireqos-new-user/ # https://firehol.org/tutorial/fireqos-new-user/
services.fireqos.enable = config.configuration.fireqos.enable; services.fireqos.enable = config.configuration.fireqos.enable;
systemd.services.fireqos.wantedBy = [ "multi-user.target" ]; systemd.services.fireqos.wantedBy = [ "multi-user.target" ];
services.fireqos.config = '' services.fireqos.config = ''
# ------------------- world # ------------------- world
@ -121,6 +123,6 @@
''; '';
}; };
} }

View file

@ -228,28 +228,32 @@
} }
{ {
text = "Syncthings"; text = "Syncthings";
items = map ({ name, host ? "${name}.private", ... }: { items = map
label = name; ({ name, host ? "${name}.private", ... }: {
href = "http://${host}:8384/"; label = name;
image = href = "http://${host}:8384/";
"https://media.giphy.com/media/JoyU4vuzwj6ZA7Ging/giphy.gif"; image =
}) (map (name: { inherit name; }) (lib.attrNames "https://media.giphy.com/media/JoyU4vuzwj6ZA7Ging/giphy.gif";
config.module.cluster.services.tinc."private".hosts)); })
(map (name: { inherit name; }) (lib.attrNames
config.module.cluster.services.tinc."private".hosts));
} }
{ {
text = "netdata"; text = "netdata";
items = map ({ name, host ? "${name}.private", ... }: { items = map
label = name; ({ name, host ? "${name}.private", ... }: {
href = "http://${host}:19999/"; label = name;
image = "https://media.giphy.com/media/BkjdN6MQCDPaw/giphy.gif"; href = "http://${host}:19999/";
}) (map (name: { inherit name; }) [ image = "https://media.giphy.com/media/BkjdN6MQCDPaw/giphy.gif";
"workhorse" })
"porani" (map (name: { inherit name; }) [
"pepe" "workhorse"
"sputnik" "porani"
] "pepe"
#(lib.attrNames config.module.cluster.services.tinc."private".hosts) "sputnik"
); ]
#(lib.attrNames config.module.cluster.services.tinc."private".hosts)
);
} }
]; ];
}; };

View file

@ -2,7 +2,8 @@
let let
access_log_sink = "workhorse.private:12304"; access_log_sink = "workhorse.private:12304";
error_log_sink = "workhorse.private:12305"; error_log_sink = "workhorse.private:12305";
in { in
{
security.acme.email = "contact@ingolf-wagner.de"; security.acme.email = "contact@ingolf-wagner.de";
security.acme.acceptTerms = true; security.acme.acceptTerms = true;

View file

@ -29,14 +29,17 @@ let
EOF EOF
''; '';
storepath = let storepath =
dirname = "${pkgs.coreutils-full}/bin/dirname"; let
readlink = "${pkgs.coreutils-full}/bin/readlink"; dirname = "${pkgs.coreutils-full}/bin/dirname";
in pkgs.writers.writeBashBin "storepath" '' readlink = "${pkgs.coreutils-full}/bin/readlink";
${dirname} $( ${readlink} $( type -p "$1" ) ) in
''; pkgs.writers.writeBashBin "storepath" ''
${dirname} $( ${readlink} $( type -p "$1" ) )
'';
in { in
{
#imports = [ ./packages/llvm-config-dummy.nix ]; #imports = [ ./packages/llvm-config-dummy.nix ];

View file

@ -1,41 +1,43 @@
{ pkgs, config, lib, ... }: { pkgs, config, lib, ... }:
with pkgs.lib; { with pkgs.lib; {
environment.systemPackages = let environment.systemPackages =
llvm = pkgs.llvm; let
llvm-config = pkgs.writers.writeBashBin "llvm-config" '' llvm = pkgs.llvm;
while [[ $# -gt 0 ]]; do llvm-config = pkgs.writers.writeBashBin "llvm-config" ''
arg="$1" while [[ $# -gt 0 ]]; do
case $arg in arg="$1"
--assertion-mode) case $arg in
echo "OFF" --assertion-mode)
;; echo "OFF"
--bindir) ;;
echo "${getBin llvm}/bin" --bindir)
;; echo "${getBin llvm}/bin"
--libdir) ;;
echo "${getLib llvm}/lib" --libdir)
;; echo "${getLib llvm}/lib"
--includedir) ;;
echo "${getDev llvm}/include" --includedir)
;; echo "${getDev llvm}/include"
--prefix) ;;
echo "${llvm.out}" --prefix)
;; echo "${llvm.out}"
--src-root) ;;
echo "/build/llvm"; --src-root)
;; echo "/build/llvm";
--obj-root) ;;
echo "/build/llvm/build"; --obj-root)
;; echo "/build/llvm/build";
--cmakedir) ;;
echo "${getDev llvm}/lib/cmake/llvm" --cmakedir)
;; echo "${getDev llvm}/lib/cmake/llvm"
*) ;;
echo "Unhandled argument '$arg' passed to dummy llvm-config!" *)
exit 1 echo "Unhandled argument '$arg' passed to dummy llvm-config!"
esac exit 1
shift esac
done shift
''; done
in [ llvm-config ]; '';
in
[ llvm-config ];
} }

View file

@ -1,4 +1,2 @@
{ config, lib, ... }: { config, lib, ... }:
{ { }
}

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