Compare commits

..

4 commits

Author SHA1 Message Date
Daniel Barlow
1896d9d70c pass service to output fn in output-template
All checks were successful
build liminix / build_vm_qemu_mips (pull_request) Successful in 33s
instead of on command line
2024-09-17 15:26:25 +02:00
Daniel Barlow
87e1fa128a support json quoting in output-template 2024-09-17 15:26:25 +02:00
Daniel Barlow
7b5b930984 new: output-template interpolates output values into config file 2024-09-17 15:25:07 +02:00
Daniel Barlow
6b36215d61 add health check service and example that uses it 2024-09-17 15:23:14 +02:00
56 changed files with 318 additions and 307 deletions

View file

@ -17,34 +17,4 @@ jobs:
- name: Build VM QEMU MIPS
run: |
# Enter the shell
nix-build ci.nix -A qemu
build_zyxel-nwa50ax_mips:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build VM QEMU MIPS
run: |
# Enter the shell
nix-build ci.nix -A qemu
test_hostapd:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build VM QEMU MIPS
run: |
# Enter the shell
nix-build ci.nix -A wlan
test_shell_customization:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build VM QEMU MIPS
run: |
# Enter the shell
nix-build ci.nix -A custom-shell
nix-build -I liminix-config=./examples/hello-from-qemu.nix --arg device "import ./devices/qemu" -A outputs.default

4
ci.nix
View file

@ -7,7 +7,7 @@
let
pkgs = (import nixpkgs { });
borderVmConf = ./bordervm.conf-example.nix;
inherit (pkgs.lib.attrsets) genAttrs mapAttrs;
inherit (pkgs.lib.attrsets) genAttrs;
devices = [
"qemu"
"zyxel-nwa50ax"
@ -19,7 +19,7 @@ let
device = import (liminix + "/devices/${name}");
liminix-config = vanilla;
}).outputs.default;
tests = mapAttrs (_: v: v { inherit liminix nixpkgs; }) (import ./tests/ci.nix);
tests = import ./tests/ci.nix;
jobs =
(genAttrs devices for-device) //
tests //

View file

@ -26,13 +26,9 @@ let
eval = evalModules {
modules = [
{
nixpkgs = {
source = nixpkgs;
overlays = [ overlay ];
config.permittedInsecurePackages = [
"python-2.7.18.8"
];
};
nixpkgs.overlays = [
overlay
];
}
device.module
liminix-config

View file

@ -28,6 +28,9 @@ in rec {
../modules/watchdog
../modules/mount
../modules/ppp
../modules/round-robin
../modules/health-check
../modules/profiles/gateway.nix
];
hostname = "thing";
@ -38,7 +41,95 @@ in rec {
authType = "chap";
};
services.dhcpc = svc.network.dhcp.client.build {
profile.gateway = {
lan = {
interfaces = with config.hardware.networkInterfaces;
[
# EDIT: these are the interfaces exposed by the gl.inet gl-ar750:
# if your device has more or differently named lan interfaces,
# specify them here
wlan wlan5
lan
];
inherit (rsecrets.lan) prefix;
address = {
family = "inet"; address ="${rsecrets.lan.prefix}.1"; prefixLength = 24;
};
dhcp = {
start = 10;
end = 240;
hosts = { } // lib.optionalAttrs (builtins.pathExists ./static-leases.nix) (import ./static-leases.nix);
localDomain = "lan";
};
};
wan = {
interface = let
pppoe = svc.pppoe.build {
interface = config.hardware.networkInterfaces.wan;
debug = true;
username = rsecrets.l2tp.name;
password = rsecrets.l2tp.password;
};
l2tp =
let
check-address = oneshot rec {
name = "check-lns-address";
up = "grep -Fx ${lns.address} $(output_path ${services.lns-address} addresses)";
dependencies = [ services.lns-address ];
};
route = svc.network.route.build {
via = "$(output ${services.bootstrap-dhcpc} router)";
target = lns.address;
dependencies = [services.bootstrap-dhcpc check-address];
};
l2tpd= svc.l2tp.build {
lns = lns.address;
ppp-options = [
"debug" "+ipv6" "noauth"
"name" rsecrets.l2tp.name
"password" rsecrets.l2tp.password
];
dependencies = [config.services.lns-address route check-address];
};
in
svc.health-check.build {
service = l2tpd;
threshold = 3;
interval = 2;
healthCheck = pkgs.writeAshScript "ping-check" {} "ping 1.1.1.1";
};
in svc.round-robin.build {
name = "wan";
services = [
pppoe
l2tp
];
};
dhcp6.enable = true;
};
wireless.networks = {
"${rsecrets.ssid}" = {
interface = config.hardware.networkInterfaces.wlan;
hw_mode = "g";
channel = "6";
ieee80211n = 1;
} // wirelessConfig;
"${rsecrets.ssid}5" = rec {
interface = config.hardware.networkInterfaces.wlan5;
hw_mode = "a";
channel = 36;
ht_capab = "[HT40+]";
vht_oper_chwidth = 1;
vht_oper_centr_freq_seg0_idx = channel + 6;
ieee80211n = 1;
ieee80211ac = 1;
} // wirelessConfig;
};
};
services.bootstrap-dhcpc = svc.network.dhcp.client.build {
interface = config.services.wwan;
dependencies = [ config.services.hostname ];
};

View file

@ -12,7 +12,6 @@ in
"${modulesPath}/hardware.nix"
"${modulesPath}/base.nix"
"${modulesPath}/busybox.nix"
"${modulesPath}/iproute2.nix"
"${modulesPath}/hostname.nix"
"${modulesPath}/kernel"
"${modulesPath}/s6"

View file

@ -4,10 +4,9 @@
{
imports = [
./base.nix
./base.nix
./bridge
./busybox.nix
./iproute2.nix
./dhcp6c
./jitter-rng
./dnsmasq

View file

@ -4,13 +4,11 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr concatStringsSep mapAttrsToList;
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
inherit (pkgs.pseudofile) dir symlink;
inherit (pkgs.liminix.networking) address interface;
inherit (pkgs.liminix.services) bundle;
# TODO: escape shell argument.
exportVar = name: value: "export ${name}=\"${value}\"";
type_service = pkgs.liminix.lib.types.service;
in {
@ -24,24 +22,6 @@ in {
/run/current-system, we just add the paths in /etc/profile
'';
};
environmentVariables = mkOption {
type = types.attrsOf types.str;
description = ''
Attribute set of environment variables to make available
in a login shell.
The value is assumed to be escaped and the name to be valid.
'';
};
prompt = mkOption {
type = types.str;
default = "$(whoami)@$(hostname) # ";
description = ''
Prompt string (PS1) for the shell.
'';
};
};
services = mkOption {
type = types.attrsOf type_service;
@ -130,9 +110,7 @@ in {
nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem;
defaultProfile.packages = with pkgs;
[ s6 s6-init-bin execline s6-linux-init s6-rc iproute2 ];
# Set the useful PS1 prompt by default.
defaultProfile.environmentVariables.PS1 = lib.mkDefault config.defaultProfile.prompt;
[ s6 s6-init-bin execline s6-linux-init s6-rc ];
boot.commandLine = [
"panic=10 oops=panic init=/bin/init loglevel=8"
@ -203,10 +181,9 @@ in {
etc = let
profile = symlink
(pkgs.writeScript ".profile" ''
PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
export PATH
${concatStringsSep "\n" (mapAttrsToList exportVar config.defaultProfile.environmentVariables)}
'');
'');
in dir {
inherit profile;
ashrc = profile;

View file

@ -9,7 +9,8 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types mkEnableOption;
inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs) liminix;
in
{
@ -34,20 +35,6 @@ in
default = null;
description = "reuse mac address from an existing interface service";
};
untagged = {
enable = mkEnableOption "untagged frames on port VID";
pvid = mkOption {
type = types.nullOr types.int;
default = null;
description = "Port VLAN ID for egress untagged frames";
};
default-pvid = mkOption {
type = types.int;
default = 0;
description = "Default PVID for ingress untagged frames, defaults to 0, which disable untagged frames for ingress";
};
};
};
members = config.system.callService ./members.nix {
primary = mkOption {

View file

@ -3,22 +3,17 @@
, ifwait
, lib
}:
{ ifname, macAddressFromInterface ? null, untagged } :
{ ifname, macAddressFromInterface ? null } :
let
inherit (liminix.services) oneshot;
inherit (lib) optional optionalString;
# This enables vlan_filtering if we do make use of it.
extra = if untagged.enable then " vlan_filtering 1 vlan_default_pvid ${toString untagged.default-pvid}" else "";
inherit (liminix.services) bundle oneshot;
inherit (lib) mkOption types optional;
in oneshot rec {
name = "${ifname}.link";
up = ''
${if macAddressFromInterface == null then
"ip link add name ${ifname} type bridge${extra}"
"ip link add name ${ifname} type bridge"
else
"ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge${extra}"}
${optionalString untagged.enable
"bridge vlan add vid ${toString untagged.pvid} dev ${ifname} pvid untagged self"}
"ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge"}
(in_outputs ${name}
echo ${ifname} > ifname

View file

@ -37,7 +37,7 @@ let
"comm" "cp" "cpio" "cut" "date" "dhcprelay" "dd" "df" "dirname" "dmesg"
"du" "echo" "egrep" "env" "expand" "expr" "false" "fdisk" "fgrep" "find"
"free" "fuser" "grep" "gunzip" "gzip" "head" "hexdump" "hostname" "hwclock"
"ifconfig" "ipneigh" "kill"
"ifconfig" "ip" "ipaddr" "iplink" "ipneigh" "iproute" "iprule" "kill"
"killall" "killall5" "less" "ln" "ls" "lsattr" "lsof" "md5sum" "mkdir"
"mknod" "mktemp" "mount" "mv" "nc" "netstat" "nohup" "od" "pgrep" "pidof"
"ping" "ping6" "pkill" "pmap" "printenv" "printf" "ps" "pwd" "readlink"

View file

@ -0,0 +1,43 @@
## Health check
##
## Runs a service and a separate periodic health process. When the
## health check starts failing over a period of time, kill the service.
## (Usually that means the supervisor will restart it, but you can
## have other behaviours by e.g. combining this service with a round-robin
## for failover)
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs) liminix;
# inherit (pkgs.liminix.services) longrun;
in {
options = {
system.service.health-check = mkOption {
description = "run a service while periodically checking it is healthy";
type = liminix.lib.types.serviceDefn;
};
};
config.system.service.health-check = config.system.callService ./service.nix {
service = mkOption {
type = liminix.lib.types.service;
};
interval = mkOption {
description = "interval between checks, in seconds";
type = types.int;
default = 10;
example = 10;
};
threshold = mkOption {
description = "number of consecutive failures required for the service to be kicked";
type = types.int;
example = 3;
};
healthCheck = mkOption {
description = "health check command or script. Expected to exit 0 if the service is healthy or any other exit status otherwise";
type = types.path;
};
};
config.programs.busybox.applets = ["expr"];
}

View file

@ -0,0 +1,37 @@
{
liminix, lib, lim, s6
}:
{ service, interval, threshold, healthCheck } :
let
inherit (liminix.services) oneshot longrun;
inherit (builtins) toString;
inherit (service) name;
checker = let name' = "check-${name}"; in longrun {
name = name';
run = ''
fails=0
echo waiting for /run/service/${name}
${s6}/bin/s6-svwait -U /run/service/${name} || exit
while sleep ${toString interval} ; do
${healthCheck}
if test $? -gt 0; then
fails=$(expr $fails + 1)
else
fails=0
fi
echo fails $fails/${toString threshold} for ${name}
if test "$fails" -gt "${toString threshold}" ; then
echo time to die
${s6}/bin/s6-svc -r /run/service/${name}
echo bounced
fails=0
echo waiting for /run/service/${name}
${s6}/bin/s6-svwait -U /run/service/${name}
fi
done
'';
};
in service.overrideAttrs(o: {
buildInputs = (lim.orEmpty o.buildInputs) ++ [ checker ];
dependencies = (lim.orEmpty o.dependencies) ++ [ checker ];
})

View file

@ -1,6 +1,7 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
in {
options = {
hostname = mkOption {
@ -11,21 +12,12 @@ in {
default = "liminix";
type = types.nonEmptyStr;
};
hostname-script = mkOption {
description = ''
Script that outputs the system hostname on stdin.
'';
default = pkgs.writeScript "hostname-gen" ''
#!/bin/sh
echo ${config.hostname}
'';
defaultText = ''
pkgs.writeScript "hostname-gen" '''
#!/bin/sh
echo ''${config.hostname}
'''
'';
type = types.package;
};
config = {
services.hostname = oneshot {
name = "hostname-${builtins.substring 0 12 (builtins.hashString "sha256" config.hostname)}";
up = "echo ${config.hostname} > /proc/sys/kernel/hostname";
down = "true";
};
};
}

View file

@ -1,28 +0,0 @@
{ config, pkgs, lib, ... }:
let
inherit (lib) mkEnableOption mkPackageOption mkIf genAttrs;
inherit (pkgs.pseudofile) dir symlink;
cfg = config.programs.iproute2;
minimalPrograms = [
"ip"
"devlink"
"ss"
"bridge"
"genl"
"ifstat"
"nstat"
];
links = genAttrs minimalPrograms (p: symlink "${cfg.package}/bin/${p}");
in
{
options.programs.iproute2 = {
enable = mkEnableOption "the iproute2 programs instead of busybox variants";
package = mkPackageOption pkgs "iproute2" { };
};
config = mkIf cfg.enable {
filesystem = dir {
bin = dir links;
};
};
}

View file

@ -54,7 +54,7 @@ in
mount -t sysfs none /sys
${busybox}/bin/sh
'';
refs = pkgs.writeClosure [ busybox ];
refs = pkgs.writeReferencesToFile busybox;
in runCommand "initramfs.cpio" {} ''
cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > out
dir /proc 0755 0 0

View file

@ -30,8 +30,6 @@ let
installPhase = ''
mkdir $out
cp -r $src $out/scripts
substituteInPlace $out/scripts/rc.init \
--replace-fail 'config.hostname' "${config.hostname-script}"
chmod -R +w $out
'';
};

View file

@ -36,7 +36,6 @@ fi
### (replace /run/service with your scandir)
s6-rc-init -d -c /etc/s6-rc/compiled /run/service
config.hostname > /proc/sys/kernel/hostname
### 2. Starting the wanted set of services
### This is also called every time you change runlevels with telinit.

View file

@ -33,11 +33,6 @@ in
description = "VLAN identifier (VID) in range 1-4094";
type = types.str;
};
untagged.egress = mkOption {
description = "Whether packets from this interface will go out *untagged*";
type = types.bool;
default = false;
};
};
config.kernel.config = {
VLAN_8021Q = "y";

View file

@ -2,15 +2,13 @@
liminix
, lib
}:
{ ifname, primary, vid, untagged } :
{ ifname, primary, vid } :
let
inherit (lib) optionalString;
inherit (liminix.services) oneshot;
in oneshot rec {
name = "${ifname}.link";
up = ''
ip link add link $(output ${primary} ifname) name ${ifname} type vlan id ${vid}
${optionalString untagged.egress "bridge vlan add dev ${ifname} vid ${toString untagged.vid} pvid untagged master"}
${liminix.networking.ifup name ifname}
(in_outputs ${name}
echo ${ifname} > ifname

View file

@ -47,7 +47,8 @@ in
extraPkgs // {
# liminix library functions
lim = {
parseInt = s : (builtins.fromTOML "r=${s}").r;
parseInt = s: (builtins.fromTOML "r=${s}").r;
orEmpty = x: if x != null then x else [];
};
# keep these alphabetical
@ -141,9 +142,7 @@ extraPkgs // {
repo = "hostapd";
rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
# Do not take any patch.
patches = [];
};
extraConfig = "";
configurePhase = ''
cat > hostapd/defconfig <<EOF
@ -186,7 +185,6 @@ extraPkgs // {
rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
patches = [];
extraConfig = "";
configurePhase = ''
cat > hostapd/defconfig <<EOF
@ -197,35 +195,7 @@ extraPkgs // {
});
in h.override { openssl = null; sqlite = null; };
libnl = prev.libnl.override {
graphviz = null;
};
iproute2 =
let i = prev.iproute2.overrideAttrs (old: {
postInstall = ''
${(old.postInstall or "")}
non_necessary_binaries=("tc" "rdma" "dcb" "tipc" "vdpa")
for needless_binary in "''${non_necessary_binaries[@]}"; do
echo "Removing unnecessary binary $out/sbin/$needless_binary"
rm "$out/sbin/$needless_binary"
done
# No man
rm -rf "$out/share"
# Remove all the data about distributions for tc.
rm -rf "$out/lib"
'';
});
# Don't bring ebpf stuff to the table.
# We also remove tc so we can drop iptables as well.
# Let's try to kill `db` as well.
in i.override { elfutils = null; iptables = null; db = null; };
wpa_supplicant = prev.wpa_supplicant.override {
dbusSupport = false;
withPcsclite = false;
wpa_supplicant_gui = null;
};
kexec-tools-static = prev.kexec-tools.overrideAttrs(o: {
# For kexecboot we copy kexec into a ramdisk on the system being

View file

@ -91,6 +91,7 @@ in {
odhcp-script = callPackage ./odhcp-script {};
odhcp6c = callPackage ./odhcp6c {};
openwrt = callPackage ./openwrt {};
output-template = callPackage ./output-template { };
ppp = callPackage ./ppp {};
pppoe = callPackage ./pppoe {};
preinit = callPackage ./preinit {};

View file

@ -3,7 +3,7 @@
, pkgsBuildBuild
, runCommand
, cpio
, writeClosure
, writeReferencesToFile
, writeScript
} :
let
@ -18,7 +18,7 @@ let
mount -t sysfs none /sys
${busybox}/bin/sh
'';
refs = writeClosure [ busybox ];
refs = writeReferencesToFile busybox;
in runCommand "initramfs.cpio" { } ''
cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > out
dir /proc 0755 0 0

View file

@ -2,7 +2,6 @@
writeScriptBin
, writeScript
, systemconfig
, stdenv
, execline
, lib
, config ? {}
@ -57,19 +56,11 @@ let
};
eval = lib.evalModules {
modules = [
{ _module.args = { inherit pkgs; inherit (pkgs) lim; }; }
../../modules/base.nix
../../modules/users.nix
../../modules/busybox.nix
../../modules/hostname.nix
../../modules/misc/assertions.nix
../../modules/nixpkgs.nix
base
{
# Inherit from that target system host platform.
nixpkgs.hostPlatform = stdenv.hostPlatform;
# Force our own package set.
nixpkgs.pkgs = lib.mkForce pkgs;
}
({ ... } : paramConfig)
../../modules/s6
];

View file

@ -0,0 +1,3 @@
check:
./output-template '{{' '}}' < example.ini > output
diff -u output example.ini.expected

View file

@ -0,0 +1,34 @@
{
fetchurl,
writeFennel,
fennel,
runCommand,
lua,
anoia,
linotify,
lualinux,
stdenv
}:
let name = "output-template";
in stdenv.mkDerivation {
inherit name;
src = ./.;
buildInputs = [lua];
doCheck = true;
buildPhase = ''
cp -p ${writeFennel name {
packages = [
anoia
lualinux
linotify
] ;
mainFunction = "run";
} ./output-template.fnl } ${name}
'';
checkPhase = "make check";
installPhase = ''
install -D ${name} $out/bin/${name}
'';
}

View file

@ -0,0 +1 @@
000000

View file

@ -0,0 +1 @@
0000ff

View file

@ -0,0 +1 @@
00ff00

View file

@ -0,0 +1 @@
ff0000

View file

@ -0,0 +1 @@
eth1

View file

@ -0,0 +1,3 @@
wpa_passphrase={{ output("./example-service","colours/black") }}
think = {{ string.format("%q", output("./example-service","colours/blue")) }}
argonaut = {{ json_quote "hello\ngoodbye\tnext\027" }}

View file

@ -0,0 +1,3 @@
wpa_passphrase=000000
think = "0000ff"
argonaut = "hello\ngoodbye\tnext\u001B"

View file

@ -0,0 +1,44 @@
(local svc (require :anoia.svc))
(fn json-escape [s]
;; All Unicode characters may be placed within the quotation marks,
;; except for the characters that MUST be escaped:
;; quotation mark, reverse solidus, and the control characters (U+0000
;; through U+001F). (RFC 8259)
(-> s
(string.gsub
"[\"\b\f\n\r\t]" {
"\b" "\\b"
"\"" "\\\""
"\f" "\\f"
"\n" "\\n"
"\r" "\\r"
"\t" "\\t"
})
(string.gsub
"([\x00-\x1b])"
(fn [x] (string.format "\\u%04X" (string.byte x))))))
(fn substitute [text opening closing]
(let [delim (.. opening "(.-)" closing)
myenv {
: string
:output
(fn [service-path path]
(let [s (assert (svc.open (.. service-path "/.outputs")))]
(s:output path)))
:lua_quote #(string.format "%q" %1)
:json_quote (fn [x] (.. "\"" (json-escape x) "\""))
}]
(string.gsub text delim
(fn [x]
(assert ((load (.. "return " x) x :t myenv))
(string.format "missing value for %q" x))))))
(fn run []
(let [[opening closing] arg
out (substitute (: (io.input) :read "*a") opening closing)]
(io.write out)))
{ : run }

View file

@ -10,5 +10,4 @@
tftpboot = import ./tftpboot/test.nix;
updown = import ./updown/test.nix;
inout = import ./inout/test.nix;
custom-shell = import ./custom-shell/test.nix;
}

View file

@ -1,7 +0,0 @@
set timeout 60
spawn socat unix-connect:vm/console -
expect {
"root@liminix blah blah > " { exit 0 }
timeout { exit 1 }
}

View file

@ -1,13 +0,0 @@
{ config, pkgs, lib, ... } :
let
inherit (pkgs.liminix.networking) interface address hostapd route dnsmasq;
inherit (pkgs.liminix.services) oneshot longrun bundle target;
in rec {
imports = [
../../modules/network
];
defaultProfile.prompt = "$(whoami)@$(hostname) blah blah > ";
defaultProfile.packages = with pkgs; [ ];
}

View file

@ -1,21 +0,0 @@
{
liminix
, nixpkgs
}:
let img = (import liminix {
inherit nixpkgs;
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix;
}).outputs.default;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect socat
] ;
} ''
. ${../test-helpers.sh}
mkdir vm
${img}/run.sh --background ./vm
expect ${./check-prompt.expect} |tee output && mv output $out
''

View file

@ -6,7 +6,7 @@ let img = (import liminix {
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix;
}).outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect

View file

@ -4,7 +4,7 @@
}:
let
overlay = import "${liminix}/overlay.nix";
pkgs = import nixpkgs { overlays = [overlay]; };
pkgs = import <nixpkgs> { overlays = [overlay]; };
script = pkgs.writeFennelScript "foo" [] ./hello.fnl;
inherit (pkgs.lua.pkgs) fifo;
netlink = pkgs.netlink-lua;

View file

@ -6,7 +6,7 @@ let img = (import liminix {
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix;
}).outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect

View file

@ -5,6 +5,7 @@ in {
imports = [
../../vanilla-configuration.nix
../../modules/squashfs.nix
../../modules/outputs/jffs2.nix
];
config.rootfsType = "jffs2";
config.filesystem = dir {

View file

@ -6,7 +6,7 @@ let img = (import liminix {
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix;
}).outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect

View file

@ -13,6 +13,7 @@ let
in {
imports = [
../../vanilla-configuration.nix
../../modules/outputs/jffs2.nix
];
config = {
services.sshd = longrun {

View file

@ -8,7 +8,7 @@ let lmx = (import liminix {
});
rogue = lmx.pkgs.rogue;
img = lmx.outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect

View file

@ -6,7 +6,7 @@ let img = (import liminix {
device = import "${liminix}/devices/qemu";
liminix-config = ./configuration.nix;
}).outputs.default;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
inherit (pkgs.pkgsBuildBuild) routeros;
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [

View file

@ -1,6 +1,5 @@
{
liminix,
...
liminix
}:
let check = deviceName : config :
let derivation = (import liminix {

View file

@ -6,7 +6,7 @@ let img = (import liminix {
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix;
}).outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect

View file

@ -7,7 +7,6 @@ in rec {
../../modules/wlan.nix
../../modules/hostapd
../../modules/network
./wpa_supplicant.nix
];
services.hostap = config.system.service.hostapd.build {
@ -28,21 +27,5 @@ in rec {
};
};
services.wpa_supplicant = config.system.service.wpa_supplicant.build {
interface = "wlan1";
driver = "nl80211";
config-file = pkgs.writeText "wpa_supplicant.conf" ''
country=us
update_config=1
ctrl_interface=/run/wpa_supplicant
network={
scan_ssid=1
ssid="liminix"
psk="colourless green ideas"
}
'';
};
defaultProfile.packages = with pkgs; [ tcpdump wpa_supplicant ];
defaultProfile.packages = with pkgs; [ tcpdump ] ;
}

View file

@ -3,11 +3,10 @@
, nixpkgs
}:
let img = (import liminix {
inherit nixpkgs;
device = import "${liminix}/devices/qemu/";
device = import "${liminix}/devices/qemu-armv7l/";
liminix-config = ./configuration.nix;
}).outputs.default;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; };
pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect socat

View file

@ -14,10 +14,10 @@ expect {
}
expect "#"
while { $FINISHED < 10 } {
send "date && grep CTRL-EVENT-CONNECTED /run/uncaught-logs/* || echo \$NOT\r\n"
send "date && grep AP-ENABLED /run/uncaught-logs/* || echo \$NOT\r\n"
expect {
"wlan1: CTRL-EVENT-CONNECTED" { set FINISHED 999; set EXIT 0; }
"wlan0: AP-ENABLED" { set FINISHED 999; set EXIT 0; }
"not_present" { send_user "waiting ...\n" ; sleep 5 }
}
set FINISHED [ expr $FINISHED + 1 ]

View file

@ -1,21 +0,0 @@
{
liminix,
wpa_supplicant,
lib,
}:
{
interface,
driver,
config-file,
}:
let
inherit (liminix.services) longrun;
inherit (lib.strings) escapeShellArg;
in
longrun {
name = "wpa_supplicant";
run =
''
${wpa_supplicant}/bin/wpa_supplicant -D${driver} -i${interface} -c ${config-file}
'';
}

View file

@ -1,15 +0,0 @@
{ config, lib, pkgs, ... }:
with lib; {
options.system.service.wpa_supplicant = mkOption { type = pkgs.liminix.lib.types.serviceDefn; };
config.system.service.wpa_supplicant = config.system.callService ./wpa_service.nix {
interface = mkOption {
type = types.str;
};
driver = mkOption {
type = types.str;
};
config-file = mkOption {
type = types.package;
};
};
}