Merge remote-tracking branch 'ni/master'
This commit is contained in:
commit
5b29d7a435
|
@ -3,6 +3,14 @@ with import <stockholm/lib>;
|
||||||
cfg = config.krebs.secret;
|
cfg = config.krebs.secret;
|
||||||
in {
|
in {
|
||||||
options.krebs.secret = {
|
options.krebs.secret = {
|
||||||
|
directory = mkOption {
|
||||||
|
default = toString <secrets>;
|
||||||
|
type = types.absolute-pathname;
|
||||||
|
};
|
||||||
|
file = mkOption {
|
||||||
|
default = relpath: "${cfg.directory}/${relpath}";
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
files = mkOption {
|
files = mkOption {
|
||||||
type = with types; attrsOf secret-file;
|
type = with types; attrsOf secret-file;
|
||||||
default = {};
|
default = {};
|
||||||
|
|
|
@ -52,7 +52,7 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ssh.privkey.path = <secrets/ssh.id_rsa>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_rsa";
|
||||||
ssh.pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDP9JS2Nyjx4Pn+/4MrFi1EvBBYVKkGm2Q4lhgaAiSuiGLol53OSsL2KIo01mbcSSBWow9QpQpn8KDoRnT2aMLDrdTFqL20ztDLOXmtrSsz3flgCjmW4f6uOaoZF0RNjAybd1coqwSJ7EINugwoqOsg1zzN2qeIGKYFvqFIKibYFAnQ8hcksmkvPdIO5O8CbdIiP9sZSrSDp0ZyLK2T0PML2jensVZOeqSPulQDFqLsbmavpVLkpDjdzzPRwbZWNB4++YeipbYNOkX4GR1EB4wMZ93IbBV7kpJtib2Zb2AnUf7UW37hxWBjILdstj9ClwNOQggn8kD9ub7YxBzH1dz0Xd8a0mPOAWIDJz9MypXgFRc3vdvPB/W1I4Se0CLbgOkORun9CkgijKr9oEY8JNt8HFd6viZcAaQxOyIm6PNHZTnHfdSc7bIBS2n3e3IZBv0fTd77knGLXg402aTuu2bm/kxsKivxsILXIaGbeXe4ceN3Fynr3FzSM2bUkzHb0mAHu1BQ9YaX0xzCwjVueA5nzGls7ODSFkXsiBfg2FvMN/sTLFca6tnwyqcnD6nujoiS5+BxjDWPgnZYqCaW3B/IkpTsRMsX6QrfhOFcsP8qlJ2Cp82orWoDK/D0vZ9pdzAc6PFGga0RofuJKY2yiq+SRZ7/e9E6VncIVCYZ1OfN0Q==";
|
ssh.pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDP9JS2Nyjx4Pn+/4MrFi1EvBBYVKkGm2Q4lhgaAiSuiGLol53OSsL2KIo01mbcSSBWow9QpQpn8KDoRnT2aMLDrdTFqL20ztDLOXmtrSsz3flgCjmW4f6uOaoZF0RNjAybd1coqwSJ7EINugwoqOsg1zzN2qeIGKYFvqFIKibYFAnQ8hcksmkvPdIO5O8CbdIiP9sZSrSDp0ZyLK2T0PML2jensVZOeqSPulQDFqLsbmavpVLkpDjdzzPRwbZWNB4++YeipbYNOkX4GR1EB4wMZ93IbBV7kpJtib2Zb2AnUf7UW37hxWBjILdstj9ClwNOQggn8kD9ub7YxBzH1dz0Xd8a0mPOAWIDJz9MypXgFRc3vdvPB/W1I4Se0CLbgOkORun9CkgijKr9oEY8JNt8HFd6viZcAaQxOyIm6PNHZTnHfdSc7bIBS2n3e3IZBv0fTd77knGLXg402aTuu2bm/kxsKivxsILXIaGbeXe4ceN3Fynr3FzSM2bUkzHb0mAHu1BQ9YaX0xzCwjVueA5nzGls7ODSFkXsiBfg2FvMN/sTLFca6tnwyqcnD6nujoiS5+BxjDWPgnZYqCaW3B/IkpTsRMsX6QrfhOFcsP8qlJ2Cp82orWoDK/D0vZ9pdzAc6PFGga0RofuJKY2yiq+SRZ7/e9E6VncIVCYZ1OfN0Q==";
|
||||||
};
|
};
|
||||||
au = {
|
au = {
|
||||||
|
@ -79,7 +79,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
secure = true;
|
secure = true;
|
||||||
ssh.privkey.path = <secrets/ssh.id_ed25519>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_ed25519";
|
||||||
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsqDuhGJpjpqNv4QmjoOhcODObrPyY3GHLvtVkgXV0g root@au";
|
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsqDuhGJpjpqNv4QmjoOhcODObrPyY3GHLvtVkgXV0g root@au";
|
||||||
};
|
};
|
||||||
mu = {
|
mu = {
|
||||||
|
@ -103,7 +103,7 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
ssh.privkey.path = <secrets/ssh.id_ed25519>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_ed25519";
|
||||||
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1vJsAddvxMA84u9iJEOrIkKn7pQiemMbfW5cfK1d7g root@mu";
|
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1vJsAddvxMA84u9iJEOrIkKn7pQiemMbfW5cfK1d7g root@mu";
|
||||||
};
|
};
|
||||||
ni = {
|
ni = {
|
||||||
|
@ -177,7 +177,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
secure = true;
|
secure = true;
|
||||||
ssh.privkey.path = <secrets/ssh.id_ed25519>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_ed25519";
|
||||||
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIHmwXHV7E9UGuk4voVCADjlLkyygqNw054jvrsPn5t root@nomic";
|
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIHmwXHV7E9UGuk4voVCADjlLkyygqNw054jvrsPn5t root@nomic";
|
||||||
};
|
};
|
||||||
wu = {
|
wu = {
|
||||||
|
@ -203,7 +203,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
secure = true;
|
secure = true;
|
||||||
ssh.privkey.path = <secrets/ssh.id_ed25519>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_ed25519";
|
||||||
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIcJvu8JDVzObLUtlAQg9qVugthKSfitwCljuJ5liyHa";
|
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIcJvu8JDVzObLUtlAQg9qVugthKSfitwCljuJ5liyHa";
|
||||||
};
|
};
|
||||||
querel = {
|
querel = {
|
||||||
|
@ -262,7 +262,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
secure = true;
|
secure = true;
|
||||||
ssh.privkey.path = <secrets/ssh.id_ed25519>;
|
ssh.privkey.path = config.krebs.secret.file "ssh.id_ed25519";
|
||||||
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPnjfceKuHNQu7S4eYFN1FqgzMqiL7haNZMh2ZLhvuhK root@xu";
|
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPnjfceKuHNQu7S4eYFN1FqgzMqiL7haNZMh2ZLhvuhK root@xu";
|
||||||
};
|
};
|
||||||
zu = {
|
zu = {
|
||||||
|
|
|
@ -60,13 +60,17 @@ let
|
||||||
}.${typeOf x};
|
}.${typeOf x};
|
||||||
|
|
||||||
mapNixDir1 = f: dirPath:
|
mapNixDir1 = f: dirPath:
|
||||||
|
let
|
||||||
|
toPackageName = name:
|
||||||
|
if test "^[0-9].*" name then "_${name}" else name;
|
||||||
|
in
|
||||||
listToAttrs
|
listToAttrs
|
||||||
(map
|
(map
|
||||||
(relPath: let
|
(relPath: let
|
||||||
name = removeSuffix ".nix" relPath;
|
name = removeSuffix ".nix" relPath;
|
||||||
path = dirPath + "/${relPath}";
|
path = dirPath + "/${relPath}";
|
||||||
in
|
in
|
||||||
nameValuePair name (f path))
|
nameValuePair (toPackageName name) (f path))
|
||||||
(filter
|
(filter
|
||||||
(name: name != "default.nix" && !hasPrefix "." name)
|
(name: name != "default.nix" && !hasPrefix "." name)
|
||||||
(attrNames (readDir dirPath))));
|
(attrNames (readDir dirPath))));
|
||||||
|
|
|
@ -116,6 +116,10 @@ rec {
|
||||||
type = listOf hostname;
|
type = listOf hostname;
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
mac = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
ip4 = mkOption {
|
ip4 = mkOption {
|
||||||
type = nullOr (submodule {
|
type = nullOr (submodule {
|
||||||
options = {
|
options = {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
./disks.nix
|
./disks.nix
|
||||||
<stockholm/tv>
|
<stockholm/tv>
|
||||||
<stockholm/tv/2configs/hw/x220.nix>
|
<stockholm/tv/2configs/hw/x220.nix>
|
||||||
|
<stockholm/tv/2configs/ppp.nix>
|
||||||
<stockholm/tv/2configs/retiolum.nix>
|
<stockholm/tv/2configs/retiolum.nix>
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
with import <stockholm/lib>;
|
with import <stockholm/lib>;
|
||||||
{ config, pkgs, ... }: {
|
{ config, pkgs, ... }: {
|
||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
boot.kernelPackages = mkDefault pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
boot.tmpOnTmpfs = true;
|
boot.tmpOnTmpfs = true;
|
||||||
|
|
||||||
|
@ -68,18 +68,13 @@ with import <stockholm/lib>;
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.shellAliases = mkForce {
|
environment.shellAliases = mkForce {
|
||||||
# alias cal='cal -m3'
|
|
||||||
gp = "${pkgs.pari}/bin/gp -q";
|
gp = "${pkgs.pari}/bin/gp -q";
|
||||||
df = "df -h";
|
df = "df -h";
|
||||||
du = "du -h";
|
du = "du -h";
|
||||||
# alias grep='grep --color=auto'
|
|
||||||
|
|
||||||
# TODO alias cannot contain #\'
|
# TODO alias cannot contain #\'
|
||||||
# "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep";
|
# "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep";
|
||||||
|
|
||||||
# alias la='ls -lA'
|
|
||||||
lAtr = "ls -lAtr";
|
|
||||||
# alias ll='ls -l'
|
|
||||||
ls = "ls -h --color=auto --group-directories-first";
|
ls = "ls -h --color=auto --group-directories-first";
|
||||||
dmesg = "dmesg -L --reltime";
|
dmesg = "dmesg -L --reltime";
|
||||||
view = "vim -R";
|
view = "vim -R";
|
||||||
|
|
|
@ -1,9 +1,25 @@
|
||||||
{ pkgs, ... }: {
|
{ config, pkgs, ... }: let
|
||||||
|
lib = import <stockholm/lib>;
|
||||||
# usage: pppd call default
|
cfg = {
|
||||||
|
pin = "@${toString <secrets/o2.pin>}";
|
||||||
environment.etc."ppp/peers/default".text = ''
|
ttys.ppp = "/dev/ttyACM0";
|
||||||
/dev/ttyACM2
|
ttys.com = "/dev/ttyACM1";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = config.networking.resolvconf.enable;
|
||||||
|
message = "ppp configuration needs resolvconf";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
environment.etc."ppp/ip-up".source = pkgs.writeDash "ppp.ip-up" ''
|
||||||
|
${pkgs.openresolv}/bin/resolvconf -a "$IFNAME" < /etc/ppp/resolv.conf
|
||||||
|
'';
|
||||||
|
environment.etc."ppp/ip-down".source = pkgs.writeDash "ppp.ip-down" ''
|
||||||
|
${pkgs.openresolv}/bin/resolvconf -fd "$IFNAME"
|
||||||
|
'';
|
||||||
|
environment.etc."ppp/peers/o2".text = /* sh */ ''
|
||||||
|
${cfg.ttys.ppp}
|
||||||
921600
|
921600
|
||||||
crtscts
|
crtscts
|
||||||
defaultroute
|
defaultroute
|
||||||
|
@ -16,17 +32,53 @@
|
||||||
passive
|
passive
|
||||||
persist
|
persist
|
||||||
usepeerdns
|
usepeerdns
|
||||||
connect "${pkgs.ppp}/bin/chat -f ${pkgs.writeText "default.chat" ''
|
connect "${pkgs.ppp}/bin/chat ''${DEBUG+-v} -Ss -f ${pkgs.writeText "o2.chat" /* sh */ ''
|
||||||
ABORT "BUSY"
|
ABORT "BUSY"
|
||||||
ABORT "NO CARRIER"
|
ABORT "NO CARRIER"
|
||||||
REPORT CONNECT
|
REPORT CONNECT
|
||||||
"" "ATDT*99#"
|
"*EMRDY: 1"
|
||||||
CONNECT
|
ATZ OK
|
||||||
|
AT+CFUN=1 OK
|
||||||
|
${cfg.pin} TIMEOUT 2 ERROR-AT-OK
|
||||||
|
AT+CGDCONT=1,\042IP\042,\042internet\042 OK
|
||||||
|
ATDT*99***1# CONNECT
|
||||||
''}"
|
''}"
|
||||||
'';
|
'';
|
||||||
|
users.users.root.packages = [
|
||||||
environment.systemPackages = [
|
(pkgs.writeDashBin "connect" ''
|
||||||
pkgs.ppp
|
# usage:
|
||||||
|
# connect wlan
|
||||||
|
# connect wwan [PEERNAME]
|
||||||
|
set -efu
|
||||||
|
rfkill_wlan=/sys/class/rfkill/rfkill2
|
||||||
|
rfkill_wwan=/sys/class/rfkill/rfkill1
|
||||||
|
case $1 in
|
||||||
|
wlan)
|
||||||
|
${pkgs.procps}/bin/pkill pppd || :
|
||||||
|
echo 0 > "$rfkill_wwan"/state
|
||||||
|
echo 1 > "$rfkill_wlan"/state
|
||||||
|
;;
|
||||||
|
wwan)
|
||||||
|
name=''${2-o2}
|
||||||
|
echo 0 > "$rfkill_wlan"/state
|
||||||
|
echo 1 > "$rfkill_wwan"/state
|
||||||
|
${pkgs.ppp}/bin/pppd call "$name" updetach
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$0: error: bad arguments: $*" >&2
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
'')
|
||||||
|
(pkgs.writeDashBin "modem-send" ''
|
||||||
|
# usage: modem-send ATCOMMAND
|
||||||
|
set -efu
|
||||||
|
tty=${lib.shell.escape cfg.ttys.com}
|
||||||
|
exec <"$tty"
|
||||||
|
printf '%s\r\n' "$1" >"$tty"
|
||||||
|
${pkgs.gnused}/bin/sed -E '
|
||||||
|
/^OK\r?$/q
|
||||||
|
/^ERROR\r?$/q
|
||||||
|
'
|
||||||
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,22 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with import <stockholm/lib>;
|
with import <stockholm/lib>;
|
||||||
|
{ config, ... }: let
|
||||||
{
|
cfg.host = config.krebs.build.host;
|
||||||
|
in {
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
tv.iptables.input-internet-accept-tcp = singleton "ssh";
|
tv.iptables.input-internet-accept-tcp = singleton "ssh";
|
||||||
|
tv.iptables.extra.nat.OUTPUT = [
|
||||||
|
"-o lo -p tcp --dport 11423 -j REDIRECT --to-ports 22"
|
||||||
|
];
|
||||||
|
tv.iptables.extra4.nat.PREROUTING = [
|
||||||
|
"-d ${cfg.host.nets.retiolum.ip4.addr} -p tcp --dport 22 -j ACCEPT"
|
||||||
|
];
|
||||||
|
tv.iptables.extra6.nat.PREROUTING = [
|
||||||
|
"-d ${cfg.host.nets.retiolum.ip6.addr} -p tcp --dport 22 -j ACCEPT"
|
||||||
|
];
|
||||||
|
tv.iptables.extra.nat.PREROUTING = [
|
||||||
|
"-p tcp --dport 22 -j REDIRECT --to-ports 0"
|
||||||
|
"-p tcp --dport 11423 -j REDIRECT --to-ports 22"
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,19 @@ let
|
||||||
configDir = "/var/empty";
|
configDir = "/var/empty";
|
||||||
dataDir = "/run/xdg/${cfg.user.name}/xmonad";
|
dataDir = "/run/xdg/${cfg.user.name}/xmonad";
|
||||||
user = config.krebs.build.user;
|
user = config.krebs.build.user;
|
||||||
|
xmonad.pkg = pkgs.haskellPackages.xmonad-tv.overrideAttrs (_: {
|
||||||
|
au = {
|
||||||
|
XMONAD_BUILD_SCREEN_WIDTH = 1920;
|
||||||
|
XMONAD_BUILD_TERM_FONT_WIDTH = 10;
|
||||||
|
XMONAD_BUILD_TERM_FONT = "xft:Input Mono:size=12:style=Regular";
|
||||||
|
XMONAD_BUILD_TERM_PADDING = 2;
|
||||||
|
};
|
||||||
|
}.${config.krebs.build.host.name} or {
|
||||||
|
XMONAD_BUILD_SCREEN_WIDTH = 1366;
|
||||||
|
XMONAD_BUILD_TERM_FONT_WIDTH = 6;
|
||||||
|
XMONAD_BUILD_TERM_FONT = "-*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1";
|
||||||
|
XMONAD_BUILD_TERM_PADDING = 2;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|
||||||
|
@ -51,7 +64,7 @@ in {
|
||||||
systemd.services.display-manager.enable = false;
|
systemd.services.display-manager.enable = false;
|
||||||
|
|
||||||
systemd.services.xmonad = let
|
systemd.services.xmonad = let
|
||||||
xmonad = "${pkgs.haskellPackages.xmonad-tv}/bin/xmonad";
|
xmonad = "${cfg.xmonad.pkg}/bin/xmonad";
|
||||||
xmonad-start = pkgs.writeDash "xmonad-start" ''
|
xmonad-start = pkgs.writeDash "xmonad-start" ''
|
||||||
${pkgs.coreutils}/bin/mkdir -p "$XMONAD_CACHE_DIR"
|
${pkgs.coreutils}/bin/mkdir -p "$XMONAD_CACHE_DIR"
|
||||||
${pkgs.coreutils}/bin/mkdir -p "$XMONAD_CONFIG_DIR"
|
${pkgs.coreutils}/bin/mkdir -p "$XMONAD_CONFIG_DIR"
|
||||||
|
|
|
@ -135,15 +135,8 @@ let {
|
||||||
:INPUT ACCEPT [0:0]
|
:INPUT ACCEPT [0:0]
|
||||||
:OUTPUT ACCEPT [0:0]
|
:OUTPUT ACCEPT [0:0]
|
||||||
:POSTROUTING ACCEPT [0:0]
|
:POSTROUTING ACCEPT [0:0]
|
||||||
${concatMapStringsSep "\n" (rule: "-A PREROUTING ${rule}") [
|
|
||||||
"! -i retiolum -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 0"
|
|
||||||
"-p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
|
|
||||||
]}
|
|
||||||
${concatMapStringsSep "\n" (rule: "-A OUTPUT ${rule}") [
|
|
||||||
"-o lo -p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
|
|
||||||
]}
|
|
||||||
${formatTable cfg.extra.nat}
|
|
||||||
${formatTable cfg."extra${toString iptables-version}".nat}
|
${formatTable cfg."extra${toString iptables-version}".nat}
|
||||||
|
${formatTable cfg.extra.nat}
|
||||||
COMMIT
|
COMMIT
|
||||||
*filter
|
*filter
|
||||||
:INPUT DROP [0:0]
|
:INPUT DROP [0:0]
|
||||||
|
|
10
tv/5pkgs/haskell/th-env/default.nix
Normal file
10
tv/5pkgs/haskell/th-env/default.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ mkDerivation, base, stdenv, template-haskell, text }:
|
||||||
|
mkDerivation {
|
||||||
|
pname = "th-env";
|
||||||
|
version = "1.0.0";
|
||||||
|
src = ./.;
|
||||||
|
libraryHaskellDepends = [ base template-haskell text ];
|
||||||
|
homepage = "https://stackoverflow.com/q/57635686";
|
||||||
|
license = "unknown";
|
||||||
|
hydraPlatforms = stdenv.lib.platforms.none;
|
||||||
|
}
|
49
tv/5pkgs/haskell/th-env/src/THEnv.hs
Normal file
49
tv/5pkgs/haskell/th-env/src/THEnv.hs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
module THEnv
|
||||||
|
(
|
||||||
|
-- * Compile-time configuration
|
||||||
|
lookupCompileEnv
|
||||||
|
, lookupCompileEnvExp
|
||||||
|
, getCompileEnv
|
||||||
|
, getCompileEnvExp
|
||||||
|
, fileAsString
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.IO as T
|
||||||
|
import Language.Haskell.TH
|
||||||
|
import Language.Haskell.TH.Syntax (Lift(..))
|
||||||
|
import System.Environment (getEnvironment)
|
||||||
|
|
||||||
|
-- Functions that work with compile-time configuration
|
||||||
|
|
||||||
|
-- | Looks up a compile-time environment variable.
|
||||||
|
lookupCompileEnv :: String -> Q (Maybe String)
|
||||||
|
lookupCompileEnv key = lookup key `liftM` runIO getEnvironment
|
||||||
|
|
||||||
|
-- | Looks up a compile-time environment variable. The result is a TH
|
||||||
|
-- expression of type @Maybe String@.
|
||||||
|
lookupCompileEnvExp :: String -> Q Exp
|
||||||
|
lookupCompileEnvExp = (`sigE` [t| Maybe String |]) . lift <=< lookupCompileEnv
|
||||||
|
-- We need to explicly type the result so that things like `print Nothing`
|
||||||
|
-- work.
|
||||||
|
|
||||||
|
-- | Looks up an compile-time environment variable and fail, if it's not
|
||||||
|
-- present.
|
||||||
|
getCompileEnv :: String -> Q String
|
||||||
|
getCompileEnv key =
|
||||||
|
lookupCompileEnv key >>=
|
||||||
|
maybe (fail $ "Environment variable " ++ key ++ " not defined") return
|
||||||
|
|
||||||
|
-- | Looks up an compile-time environment variable and fail, if it's not
|
||||||
|
-- present. The result is a TH expression of type @String@.
|
||||||
|
getCompileEnvExp :: String -> Q Exp
|
||||||
|
getCompileEnvExp = lift <=< getCompileEnv
|
||||||
|
|
||||||
|
-- | Loads the content of a file as a string constant expression.
|
||||||
|
-- The given path is relative to the source directory.
|
||||||
|
fileAsString :: FilePath -> Q Exp
|
||||||
|
fileAsString = do
|
||||||
|
-- addDependentFile path -- works only with template-haskell >= 2.7
|
||||||
|
stringE . T.unpack . T.strip <=< runIO . T.readFile
|
20
tv/5pkgs/haskell/th-env/th-env.cabal
Normal file
20
tv/5pkgs/haskell/th-env/th-env.cabal
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
name: th-env
|
||||||
|
version: 1.0.0
|
||||||
|
-- license: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
license: OtherLicense
|
||||||
|
author: https://stackoverflow.com/users/9348482
|
||||||
|
homepage: https://stackoverflow.com/q/57635686
|
||||||
|
maintainer: tv <tv@krebsco.de>
|
||||||
|
build-type: Simple
|
||||||
|
cabal-version: >=1.10
|
||||||
|
|
||||||
|
library
|
||||||
|
hs-source-dirs: src
|
||||||
|
build-depends:
|
||||||
|
base,
|
||||||
|
template-haskell,
|
||||||
|
text
|
||||||
|
exposed-modules:
|
||||||
|
THEnv
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -O2 -Wall
|
|
@ -1,5 +1,6 @@
|
||||||
{ mkDerivation, base, containers, directory, extra, stdenv, unix
|
{ mkDerivation, aeson, base, bytestring, containers, directory
|
||||||
, X11, xmonad, xmonad-contrib, xmonad-stockholm
|
, extra, stdenv, template-haskell, th-env, unix, X11, xmonad
|
||||||
|
, xmonad-contrib, xmonad-stockholm
|
||||||
}:
|
}:
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
pname = "xmonad-tv";
|
pname = "xmonad-tv";
|
||||||
|
@ -8,8 +9,8 @@ mkDerivation {
|
||||||
isLibrary = false;
|
isLibrary = false;
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
executableHaskellDepends = [
|
executableHaskellDepends = [
|
||||||
base containers directory extra unix X11 xmonad xmonad-contrib
|
aeson base bytestring containers directory extra template-haskell
|
||||||
xmonad-stockholm
|
th-env unix X11 xmonad xmonad-contrib xmonad-stockholm
|
||||||
];
|
];
|
||||||
license = stdenv.lib.licenses.mit;
|
license = stdenv.lib.licenses.mit;
|
||||||
}
|
}
|
||||||
|
|
18
tv/5pkgs/haskell/xmonad-tv/src/THEnv/JSON.hs
Normal file
18
tv/5pkgs/haskell/xmonad-tv/src/THEnv/JSON.hs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
|
||||||
|
module THEnv.JSON where
|
||||||
|
|
||||||
|
import Data.Aeson (eitherDecode,FromJSON)
|
||||||
|
import Data.ByteString.Lazy.Char8 (pack)
|
||||||
|
import Language.Haskell.TH.Syntax (Exp,Lift(lift),Q)
|
||||||
|
import THEnv (getCompileEnv)
|
||||||
|
import Control.Monad
|
||||||
|
|
||||||
|
getCompileEnvJSON :: (FromJSON a) => String -> Q a
|
||||||
|
getCompileEnvJSON name =
|
||||||
|
either error (id :: a -> a) . eitherDecode . pack <$> getCompileEnv name
|
||||||
|
|
||||||
|
getCompileEnvJSONExp ::
|
||||||
|
forall proxy a. (FromJSON a, Lift a) => proxy a -> String -> Q Exp
|
||||||
|
getCompileEnvJSONExp _ =
|
||||||
|
(lift :: a -> Q Exp) <=< getCompileEnvJSON
|
|
@ -1,4 +1,6 @@
|
||||||
{-# LANGUAGE LambdaCase #-}
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
|
@ -32,10 +34,23 @@ import XMonad.Stockholm.Pager
|
||||||
import XMonad.Stockholm.Shutdown
|
import XMonad.Stockholm.Shutdown
|
||||||
import qualified Paths
|
import qualified Paths
|
||||||
|
|
||||||
|
import THEnv.JSON (getCompileEnvJSONExp)
|
||||||
|
|
||||||
|
|
||||||
myFont :: String
|
myFont :: String
|
||||||
myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
|
myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
|
||||||
|
|
||||||
|
myScreenWidth :: Dimension
|
||||||
|
myScreenWidth =
|
||||||
|
$(getCompileEnvJSONExp (id @Dimension) "XMONAD_BUILD_SCREEN_WIDTH")
|
||||||
|
|
||||||
|
myTermFontWidth :: Dimension
|
||||||
|
myTermFontWidth =
|
||||||
|
$(getCompileEnvJSONExp (id @Dimension) "XMONAD_BUILD_TERM_FONT_WIDTH")
|
||||||
|
|
||||||
|
myTermPadding :: Dimension
|
||||||
|
myTermPadding = 2
|
||||||
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = getArgs >>= \case
|
main = getArgs >>= \case
|
||||||
|
@ -46,7 +61,6 @@ main = getArgs >>= \case
|
||||||
|
|
||||||
mainNoArgs :: IO ()
|
mainNoArgs :: IO ()
|
||||||
mainNoArgs = do
|
mainNoArgs = do
|
||||||
let width = 1366
|
|
||||||
workspaces0 <- getWorkspaces0
|
workspaces0 <- getWorkspaces0
|
||||||
handleShutdownEvent <- newShutdownEventHandler
|
handleShutdownEvent <- newShutdownEventHandler
|
||||||
launch
|
launch
|
||||||
|
@ -60,8 +74,9 @@ mainNoArgs = do
|
||||||
smartBorders $
|
smartBorders $
|
||||||
ResizableTall
|
ResizableTall
|
||||||
1
|
1
|
||||||
(10 * 6 / width)
|
(fromIntegral (10 * myTermFontWidth) / fromIntegral myScreenWidth)
|
||||||
((80 * 6 + 2 * (1+1+1))/width) []
|
(fromIntegral (80 * myTermFontWidth + 2 * (myTermPadding + borderWidth def)) / fromIntegral myScreenWidth)
|
||||||
|
[]
|
||||||
|||
|
|||
|
||||||
Full
|
Full
|
||||||
, manageHook =
|
, manageHook =
|
||||||
|
|
|
@ -9,10 +9,14 @@ cabal-version: >=1.10
|
||||||
executable xmonad
|
executable xmonad
|
||||||
main-is: main.hs
|
main-is: main.hs
|
||||||
build-depends:
|
build-depends:
|
||||||
|
aeson,
|
||||||
base,
|
base,
|
||||||
|
bytestring,
|
||||||
containers,
|
containers,
|
||||||
directory,
|
directory,
|
||||||
extra,
|
extra,
|
||||||
|
template-haskell,
|
||||||
|
th-env,
|
||||||
unix,
|
unix,
|
||||||
X11,
|
X11,
|
||||||
xmonad,
|
xmonad,
|
||||||
|
@ -20,6 +24,7 @@ executable xmonad
|
||||||
xmonad-stockholm
|
xmonad-stockholm
|
||||||
other-modules:
|
other-modules:
|
||||||
Helpers.Path,
|
Helpers.Path,
|
||||||
Paths
|
Paths,
|
||||||
|
THEnv.JSON
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options: -O2 -Wall -threaded
|
ghc-options: -O2 -Wall -threaded
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
with import <stockholm/lib>;
|
with import <stockholm/lib>;
|
||||||
self: super: {
|
self: super: {
|
||||||
|
input-fonts = super.input-fonts.overrideAttrs (old: rec {
|
||||||
|
src = self.fetchurl {
|
||||||
|
url = "http://xu.r/~tv/mirrors/input-fonts/Input-Font-2.zip";
|
||||||
|
sha256 = "1vvipqcflz4ximy7xpqy9idrdpq3a0c490hp5137r2dq03h865y0";
|
||||||
|
};
|
||||||
|
outputHash = null;
|
||||||
|
outputHashAlgo = null;
|
||||||
|
outputHashMode = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
nix-prefetch-github =
|
||||||
|
self.python3Packages.callPackage ./nix-prefetch-github.nix {};
|
||||||
|
|
||||||
rxvt_unicode = self.callPackage ./rxvt_unicode.nix {
|
rxvt_unicode = self.callPackage ./rxvt_unicode.nix {
|
||||||
rxvt_unicode = super.rxvt_unicode;
|
rxvt_unicode = super.rxvt_unicode;
|
||||||
};
|
};
|
||||||
|
|
47
tv/5pkgs/override/nix-prefetch-github.nix
Normal file
47
tv/5pkgs/override/nix-prefetch-github.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{ fetchPypi
|
||||||
|
, lib
|
||||||
|
, buildPythonPackage
|
||||||
|
, pythonOlder
|
||||||
|
, attrs
|
||||||
|
, click
|
||||||
|
, effect
|
||||||
|
, jinja2
|
||||||
|
, git
|
||||||
|
, pytestCheckHook
|
||||||
|
, pytest-black
|
||||||
|
, pytestcov
|
||||||
|
, pytest-isort
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "nix-prefetch-github";
|
||||||
|
version = "3.0";
|
||||||
|
|
||||||
|
src = fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-EN+EbVXUaf+id5UsK4EBm/9k9FYaH79g08kblvW60XA=";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
attrs
|
||||||
|
click
|
||||||
|
effect
|
||||||
|
jinja2
|
||||||
|
];
|
||||||
|
|
||||||
|
checkInputs = [ pytestCheckHook pytest-black pytestcov pytest-isort git ];
|
||||||
|
checkPhase = ''
|
||||||
|
pytest -m 'not network'
|
||||||
|
'';
|
||||||
|
|
||||||
|
# latest version of isort will cause tests to fail
|
||||||
|
# ignore tests which are impure
|
||||||
|
disabledTests = [ "isort" "life" "outputs" "fetch_submodules" ];
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Prefetch sources from github";
|
||||||
|
homepage = "https://github.com/seppeljordan/nix-prefetch-github";
|
||||||
|
license = licenses.gpl3;
|
||||||
|
maintainers = with maintainers; [ seppeljordan ];
|
||||||
|
};
|
||||||
|
}
|
24
tv/5pkgs/rpi/433Utils/RPi_utils.codesend.codestring.patch
Normal file
24
tv/5pkgs/rpi/433Utils/RPi_utils.codesend.codestring.patch
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
--- a/RPi_utils/codesend.cpp
|
||||||
|
+++ b/RPi_utils/codesend.cpp
|
||||||
|
@@ -40,18 +40,18 @@ int main(int argc, char *argv[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change protocol and pulse length accroding to parameters
|
||||||
|
- int code = atoi(argv[1]);
|
||||||
|
+ const char *code = argv[1];
|
||||||
|
if (argc >= 3) protocol = atoi(argv[2]);
|
||||||
|
if (argc >= 4) pulseLength = atoi(argv[3]);
|
||||||
|
|
||||||
|
if (wiringPiSetup () == -1) return 1;
|
||||||
|
- printf("sending code[%i]\n", code);
|
||||||
|
+ printf("sending code[%s]\n", code);
|
||||||
|
RCSwitch mySwitch = RCSwitch();
|
||||||
|
if (protocol != 0) mySwitch.setProtocol(protocol);
|
||||||
|
if (pulseLength != 0) mySwitch.setPulseLength(pulseLength);
|
||||||
|
mySwitch.enableTransmit(PIN);
|
||||||
|
|
||||||
|
- mySwitch.send(code, 24);
|
||||||
|
+ mySwitch.send(code);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
42
tv/5pkgs/rpi/433Utils/default.nix
Normal file
42
tv/5pkgs/rpi/433Utils/default.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{ fetchFromGitHub, stdenv
|
||||||
|
, wiringPi ? WiringPi.wiringPi
|
||||||
|
, wiringPiDev ? WiringPi.wiringPiDev
|
||||||
|
, WiringPi ? rpiPackages.WiringPi
|
||||||
|
, rpiPackages
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "433Utils-RPi_utils";
|
||||||
|
version = "2018-06-07";
|
||||||
|
|
||||||
|
src = fetchFromGitHub (stdenv.lib.importJSON ./src.json);
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./rc-switch.protocols.patch
|
||||||
|
./RPi_utils.codesend.codestring.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook postBuild
|
||||||
|
|
||||||
|
make -C RPi_utils
|
||||||
|
|
||||||
|
runHook preBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
wiringPi
|
||||||
|
wiringPiDev
|
||||||
|
];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
for name in send codesend RFSniffer; do
|
||||||
|
cp RPi_utils/$name $out/bin/
|
||||||
|
done
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
}
|
10
tv/5pkgs/rpi/433Utils/rc-switch.protocols.patch
Normal file
10
tv/5pkgs/rpi/433Utils/rc-switch.protocols.patch
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
--- a/rc-switch/RCSwitch.cpp
|
||||||
|
+++ b/rc-switch/RCSwitch.cpp
|
||||||
|
@@ -78,6 +78,7 @@ static const RCSwitch::Protocol PROGMEM proto[] = {
|
||||||
|
{ 100, { 30, 71 }, { 4, 11 }, { 9, 6 } }, // protocol 3
|
||||||
|
{ 380, { 1, 6 }, { 1, 3 }, { 3, 1 } }, // protocol 4
|
||||||
|
{ 500, { 6, 14 }, { 1, 2 }, { 2, 1 } }, // protocol 5
|
||||||
|
+ { 136, { 1, 31 }, { 1, 3 }, { 3, 1 } }, // protocol 6
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
7
tv/5pkgs/rpi/433Utils/src.json
Normal file
7
tv/5pkgs/rpi/433Utils/src.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"owner": "ninjablocks",
|
||||||
|
"repo": "433Utils",
|
||||||
|
"rev": "31c0ea4e158287595a6f6116b6151e72691e1839",
|
||||||
|
"sha256": "04r2qlkdsz46qgpnbizrfccz1i0qlkb1iqz0jzyq4fzvksqp9dg1",
|
||||||
|
"fetchSubmodules": true
|
||||||
|
}
|
61
tv/5pkgs/rpi/WiringPi/default.nix
Normal file
61
tv/5pkgs/rpi/WiringPi/default.nix
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{ fetchFromGitHub, runCommand, stdenv }:
|
||||||
|
|
||||||
|
let
|
||||||
|
generic = name: extraAttrs:
|
||||||
|
stdenv.mkDerivation ({
|
||||||
|
pname = "WiringPi-${name}";
|
||||||
|
version = "2020-09-14";
|
||||||
|
|
||||||
|
src = fetchFromGitHub (stdenv.lib.importJSON ./src.json);
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook postBuild
|
||||||
|
|
||||||
|
make -C ${name} all
|
||||||
|
|
||||||
|
runHook preBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
export DESTDIR=$out
|
||||||
|
export PREFIX=
|
||||||
|
export LDCONFIG=true
|
||||||
|
|
||||||
|
make -C ${name} install
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
} // extraAttrs);
|
||||||
|
|
||||||
|
fakeutils = runCommand "fakeutils-1.0" {} /* sh */ ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
for name in chown chmod; do
|
||||||
|
touch $out/bin/$name
|
||||||
|
chmod +x $out/bin/$name
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
rec {
|
||||||
|
wiringPi = generic "wiringPi" {};
|
||||||
|
wiringPiDev = generic "devLib" {
|
||||||
|
buildInputs = [
|
||||||
|
wiringPi
|
||||||
|
];
|
||||||
|
};
|
||||||
|
gpio = generic "gpio" {
|
||||||
|
preInstall = ''
|
||||||
|
# fakeutils cannot be buildInputs because they have to override existing
|
||||||
|
# executables and therefore need to be prepended to the search path.
|
||||||
|
PATH=${fakeutils}/bin:$PATH
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
'';
|
||||||
|
buildInputs = [
|
||||||
|
wiringPi
|
||||||
|
wiringPiDev
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
6
tv/5pkgs/rpi/WiringPi/src.json
Normal file
6
tv/5pkgs/rpi/WiringPi/src.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"owner": "WiringPi",
|
||||||
|
"repo": "WiringPi",
|
||||||
|
"rev": "5c6bab7d4279e8c0cc890984eaa1a69ff3af1c99",
|
||||||
|
"sha256": "1jlx7lb3ybwv06b2dpmsr718d0xj85awl1dgdqc607k50kk25mjb"
|
||||||
|
}
|
9
tv/5pkgs/rpi/default.nix
Normal file
9
tv/5pkgs/rpi/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
let
|
||||||
|
lib = import <stockholm/lib>;
|
||||||
|
in
|
||||||
|
|
||||||
|
self: super:
|
||||||
|
|
||||||
|
{
|
||||||
|
rpiPackages = lib.mapNixDir (path: self.callPackage path {}) ./.;
|
||||||
|
}
|
16
tv/5pkgs/simple/rxvt-unicode-256color-terminfo/default.nix
Normal file
16
tv/5pkgs/simple/rxvt-unicode-256color-terminfo/default.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# This package is mainly intended for cross-built systems for which we cannot
|
||||||
|
# or don't want to build pkgs.rxvt_unicode for some reason.
|
||||||
|
#
|
||||||
|
# ${./rxvt-unicode-256color.terminfo} was copied from a previously built
|
||||||
|
# /run/current-system/sw/share/terminfo/r/rxvt-unicode-256color
|
||||||
|
{ runCommand }:
|
||||||
|
|
||||||
|
runCommand "rxvt-unicode-256color-terminfo" {} /* sh */ ''
|
||||||
|
mkdir -p $out/nix-support
|
||||||
|
mkdir -p $out/share/terminfo/r
|
||||||
|
|
||||||
|
ln -s ${./rxvt-unicode-256color.terminfo} \
|
||||||
|
$out/share/terminfo/r/rxvt-unicode-256color
|
||||||
|
|
||||||
|
echo "$out" >> $out/nix-support/propagated-user-env-packages
|
||||||
|
''
|
Binary file not shown.
|
@ -11,6 +11,7 @@ stdenv.mkDerivation {
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${./index.html} $out/index.html
|
cp ${./index.html} $out/index.html
|
||||||
|
convert ${./logo.xpm} $out/favicon.ico
|
||||||
convert ${./logo.xpm} $out/favicon2.png
|
convert ${./logo.xpm} $out/favicon2.png
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,8 +133,9 @@ with import <stockholm/lib>;
|
||||||
(writer "Jq")
|
(writer "Jq")
|
||||||
(writerExt "jq")
|
(writerExt "jq")
|
||||||
];
|
];
|
||||||
javascript.extraStart = comment "jq";
|
javascript.extraStart = comment "js";
|
||||||
lua = {};
|
lua = {};
|
||||||
|
markdown.extraStart = writerExt "md";
|
||||||
#nginx = {};
|
#nginx = {};
|
||||||
python.extraStart = alts [
|
python.extraStart = alts [
|
||||||
(comment "py")
|
(comment "py")
|
||||||
|
|
1
tv/dummy_secrets/o2.pin
Normal file
1
tv/dummy_secrets/o2.pin
Normal file
|
@ -0,0 +1 @@
|
||||||
|
AT
|
Loading…
Reference in a new issue