Compare commits

...

49 commits

Author SHA1 Message Date
Raito Bezarius
1322de1ee0 feat: add support for untagged frames
Should cover egress & ingress.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 01:25:52 +01:00
Raito Bezarius
9490822c1a feat: introduce iproute2 module for linkage
In the future, we will make it possible to choose between iproute2 and
busybox more properly.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:43:45 +01:00
Raito Bezarius
0c6d26b4fc feat: remove db from iproute2 as well
Too big already… !

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:22:30 +01:00
Raito Bezarius
c5c82a5391 fix: i do not know how to do makefiles ok?
it's in sbin/ not in bin/, nix moves it to bin/ later on.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:16:40 +01:00
Raito Bezarius
92594b3b64 fix: i do not know how to do nix ok?
it's in bin/, not in $out/ simply.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:15:07 +01:00
Raito Bezarius
9f9ade29f4 fix: i do not know how to do bash ok?
fix the quoting for the array iteration

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:14:22 +01:00
Raito Bezarius
d6c976f8a1 feat: remove iptables from iproute2
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:13:18 +01:00
Raito Bezarius
1598d59ca7 feat: remove elfutils from iproute2
Shaves a lot of the compile time.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:11:48 +01:00
Raito Bezarius
4dabd970f0 feat: use iproute2 by default instead of busybox
iproute2 brings so much on the table, it's worth it.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-09 00:09:21 +01:00
Raito Bezarius
473d6acc3d Revert "fix: chrony does not have readline, nspr, nss anymore"
This reverts commit 24443628a1 because we
fell back to NixOS 24.05.
2024-12-08 20:40:53 +01:00
Raito Bezarius
b8caddae08 fix: do not take any hostapd patches from nixpkgs
We have our own hostapd fork, hence patches may be wrong.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-08 20:32:57 +01:00
Raito Bezarius
d02397cd65 fix: do not pass graphviz as a dependency
On mipsel, we do not have… graphviz.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-08 13:14:19 +01:00
Raito Bezarius
24443628a1 fix: chrony does not have readline, nspr, nss anymore
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-07 16:19:17 +01:00
Raito Bezarius
c515e4354b fix: do not redefine pkgs and lim for levitated system
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-07 16:15:12 +01:00
Raito Bezarius
1a607ef8ed fix: propagate host platform to levitated systems
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-07 16:15:12 +01:00
Raito Bezarius
9b03b4355b fix: add forgotten modules for levitation
Otherwise, this won't eval properly.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-07 16:15:12 +01:00
Raito Bezarius
752ff19e21 fix: switch to writeClosure
writeReferencesToFile has been removed from nixpkgs…

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-12-07 16:00:57 +01:00
6dd34b97a9 Merge pull request 'feat(ci): shell-customization' (#32) from lbailly/liminix:shell-customization into main
Reviewed-on: DGNum/liminix#32
2024-10-04 11:22:43 +02:00
7eff028b02
fix: hostname at early boot 2024-10-04 11:21:46 +02:00
89d2d34ad7
feat(ci): prompt checking 2024-10-04 11:21:46 +02:00
eec7a6e985
fix PS1 2024-10-04 11:21:46 +02:00
a56936f1d3 Merge pull request 'feat: add environment variables and prompt customization in login shells' (#29) from shell-customization into main
Reviewed-on: DGNum/liminix#29
2024-10-04 11:12:05 +02:00
Raito Bezarius
562b050341 feat: add environment variables and prompt customization in login shells
This way, we can configure a bit our prompt.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-10-04 11:12:05 +02:00
dbe6b1b135 Merge pull request 'feat(ci): test with wpa_supplicant' (#24) from lbailly/liminix:CI into main
Reviewed-on: DGNum/liminix#24
Reviewed-by: Ryan Lahfa <ryan@dgnum.eu>
2024-10-04 11:11:47 +02:00
c5e48f5c9f
feat(ci-wlan): use wpa_supplicant 2024-09-30 13:16:57 +02:00
0dd72b31f4
feat(ci): use ci.nix 2024-09-30 13:16:57 +02:00
Raito Bezarius
013e4c396c feat: repair CI and cleanup cross-compilation mechanism
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-16 18:14:39 +02:00
Raito Bezarius
036f91d2f0 feat(ubus): support for Lua 5.3
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-08 01:08:59 +02:00
Raito Bezarius
54db2ad006 feat(libubox): support for Lua 5.3
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-08 01:08:54 +02:00
Raito Bezarius
8ac3e32b8b fix(modules/hostname): hash the hostname to avoid duplicate services in the db
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-08 00:31:15 +02:00
Raito Bezarius
6970d811e8 chore(min-copy-closure): improve liminix-rebuild for maintenance
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 23:59:29 +02:00
Raito Bezarius
b468275f53 fix(tftpboot): revert squashfs use and go back to JFFS2
squashfs doesn't copy all the files we need.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 23:48:13 +02:00
Raito Bezarius
3ed1564235 feat(recovery): bump to 20MB the TFTP phram size
Otherwise, this will fail to boot on a modern closure.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 23:39:22 +02:00
Raito Bezarius
9fcfae3eae feat(recovery): strengthen debugging capabilities of preinit
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 23:30:05 +02:00
Raito Bezarius
73ea02b982 feat(modules/nixpkgs): introduce source parameter
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 23:05:03 +02:00
Raito Bezarius
c942b2be09 feat(initramfs): enable zstd compression
Busybox is still 3MB.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 22:49:25 +02:00
Raito Bezarius
95850a44c2 feat(recovery): implement failsafe boot
for TFTP or anything, really.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 22:49:25 +02:00
Raito Bezarius
bc1f54e701 Merge branch 'bridgeability' into 'main' 2024-09-07 21:53:20 +02:00
Raito Bezarius
0ee2ce4183 fix(overlay): adopt upstream fix for Lua readline
9f58e7b926
("maybe fix nixpkgs-unstable lua")

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 21:52:48 +02:00
Raito Bezarius
94a5b19c77 fix(evalConfig): fix pkgs relation with nixpkgs
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 21:52:48 +02:00
Raito Bezarius
13069415fd feat(modules/hostapd): offer readiness oneshot
WLAN oper wait until the WLAN interface is ready.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 21:15:31 +02:00
Raito Bezarius
5590fea16e feat(ifwait): add ifbridgeable script
This enable to wait for bridgeability of a WLAN interface via
`iwinfo`.

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 21:09:17 +02:00
Raito Bezarius
c39bfc2bb5 fix(write-fennel): escape binary path for PATH
otherwise, escapeShellArg might just do nothing!

Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 21:03:57 +02:00
Raito Bezarius
0c363be423 fennelrepl: add iwinfo to it
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 20:03:02 +02:00
Raito Bezarius
26d2812aa4 fennerepl: remove readline
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 20:03:02 +02:00
Raito Bezarius
b57df3f288 iwinfo: use Lua 5.3 port
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 20:03:02 +02:00
Raito Bezarius
4cf10c2e75 iwinfo: init at unstable-07-09-2024
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 19:26:14 +02:00
Raito Bezarius
0d36000d9f overlay: update hostapd with readiness support
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 18:31:57 +02:00
ce17fea337 Merge pull request 'feat(hostapd): ubus support' (#16) from hostapd-ubus into main
Reviewed-on: DGNum/liminix#16
2024-09-07 17:53:21 +02:00
61 changed files with 670 additions and 136 deletions

View file

@ -17,4 +17,34 @@ jobs:
- name: Build VM QEMU MIPS
run: |
# Enter the shell
nix-build -I liminix-config=./examples/hello-from-qemu.nix --arg device "import ./devices/qemu" -A outputs.default
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

26
ci.nix
View file

@ -1,21 +1,15 @@
{
nixpkgs
, unstable
, liminix
sources ? import ./lon.nix
, nixpkgs ? sources.nixpkgs
, unstable ? nixpkgs
, liminix ? ./.
, ... }:
let
inherit (builtins) map;
pkgs = (import nixpkgs {});
pkgs = (import nixpkgs { });
borderVmConf = ./bordervm.conf-example.nix;
inherit (pkgs.lib.attrsets) genAttrs;
inherit (pkgs.lib.attrsets) genAttrs mapAttrs;
devices = [
"gl-ar750"
"gl-mt300a"
"gl-mt300n-v2"
"qemu"
"qemu-aarch64"
"qemu-armv7l"
"tp-archer-ax23"
"zyxel-nwa50ax"
];
vanilla = ./vanilla-configuration.nix;
@ -25,7 +19,7 @@ let
device = import (liminix + "/devices/${name}");
liminix-config = vanilla;
}).outputs.default;
tests = import ./tests/ci.nix;
tests = mapAttrs (_: v: v { inherit liminix nixpkgs; }) (import ./tests/ci.nix);
jobs =
(genAttrs devices for-device) //
tests //
@ -44,12 +38,6 @@ let
imports = [ ./modules/all-modules.nix ];
};
}).outputs.optionsJson;
installers = map (f: "system.outputs.${f}") [
"vmroot"
"mtdimage"
"ubimage"
];
inherit (pkgs.lib) concatStringsSep;
in pkgs.stdenv.mkDerivation {
name = "liminix-doc";
nativeBuildInputs = with pkgs; [

View file

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

View file

@ -1,7 +1,7 @@
# This "device" generates images that can be used with the QEMU
# emulator. The default output is a directory containing separate
# kernel (uncompressed vmlinux) and initrd (squashfs) images
{
rec {
system = {
crossSystem = {
config = "mips-unknown-linux-musl";
@ -41,6 +41,9 @@
../../modules/arch/mipseb.nix
../families/qemu.nix
];
nixpkgs.hostPlatform = system.crossSystem;
kernel = {
config = {
MIPS_MALTA= "y";

View file

@ -1,4 +1,4 @@
{
rec {
system = {
crossSystem = {
config = "mipsel-unknown-linux-musl";
@ -135,6 +135,8 @@
../../modules/zyxel-dual-image
];
nixpkgs.hostPlatform = system.crossSystem;
filesystem = dir {
lib = dir {
firmware = dir {
@ -222,8 +224,8 @@
imageFormat = "fit";
tftp = {
# 5MB is nice.
freeSpaceBytes = 5 * 1024 * 1024;
# 20MB is pretty good on this device as we have plenty of RAM.
freeSpaceBytes = 20 * 1024 * 1024;
appendDTB = true;
loadAddress = lim.parseInt "0x2000000";
};

View file

@ -1,4 +1,4 @@
{ nixpkgs ? <nixpkgs>, pkgs ? (import <nixpkgs> {}), lib ? pkgs.lib }:
{ nixpkgs ? <nixpkgs>, pkgs ? (import nixpkgs {}), lib ? pkgs.lib }:
args:
let
modulesPath = builtins.toString ../modules;
@ -12,6 +12,7 @@ in
"${modulesPath}/hardware.nix"
"${modulesPath}/base.nix"
"${modulesPath}/busybox.nix"
"${modulesPath}/iproute2.nix"
"${modulesPath}/hostname.nix"
"${modulesPath}/kernel"
"${modulesPath}/s6"

15
lon.lock Normal file
View file

@ -0,0 +1,15 @@
{
"version": "1",
"sources": {
"nixpkgs": {
"type": "GitHub",
"fetchType": "tarball",
"owner": "nixos",
"repo": "nixpkgs",
"branch": "nixos-unstable-small",
"revision": "b6227cadb5123c7e4cb159bf6f9f5705ae081a47",
"url": "https://github.com/nixos/nixpkgs/archive/b6227cadb5123c7e4cb159bf6f9f5705ae081a47.tar.gz",
"hash": "sha256-KFR30GNFhjzXl0kVEn+KK4xrFr0gggb1NBroP8ukbxY="
}
}
}

41
lon.nix Normal file
View file

@ -0,0 +1,41 @@
# Generated by lon. Do not modify!
let
lock = builtins.fromJSON (builtins.readFile ./lon.lock);
# Override with a path defined in an environment variable. If no variable is
# set, the original path is used.
overrideFromEnv =
name: path:
let
replacement = builtins.getEnv "LON_OVERRIDE_${name}";
in
if replacement == "" then
path
else
# this turns the string into an actual Nix path (for both absolute and
# relative paths)
if builtins.substring 0 1 replacement == "/" then
/. + replacement
else
/. + builtins.getEnv "PWD" + "/${replacement}";
fetchSource =
args@{ fetchType, ... }:
if fetchType == "git" then
builtins.fetchGit {
url = args.url;
ref = args.branch;
rev = args.revision;
narHash = args.hash;
}
else if fetchType == "tarball" then
builtins.fetchTarball {
url = args.url;
sha256 = args.hash;
}
else
builtins.throw "Unsupported source type ${fetchType}";
in
builtins.mapAttrs (name: args: overrideFromEnv name (fetchSource args)) lock.sources

View file

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

View file

@ -4,11 +4,13 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr concatStringsSep mapAttrsToList;
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 {
@ -22,6 +24,24 @@ 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;
@ -69,6 +89,14 @@ in {
default = "uimage";
};
tftp = {
commandLine = mkOption {
type = types.listOf types.str;
default = config.boot.commandLine;
description = ''
TFTP-specific command line.
Defaults to the classical one if unset.
'';
};
loadAddress = mkOption {
type = types.ints.unsigned;
description = ''
@ -98,8 +126,13 @@ in {
};
};
config = {
# By default, we enable cross-compilation support.
nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem;
defaultProfile.packages = with pkgs;
[ s6 s6-init-bin execline s6-linux-init s6-rc ];
[ 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;
boot.commandLine = [
"panic=10 oops=panic init=/bin/init loglevel=8"
@ -170,9 +203,10 @@ 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,8 +9,7 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
inherit (lib) mkOption types mkEnableOption;
inherit (pkgs) liminix;
in
{
@ -35,6 +34,20 @@ 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,17 +3,22 @@
, ifwait
, lib
}:
{ ifname, macAddressFromInterface ? null } :
{ ifname, macAddressFromInterface ? null, untagged } :
let
inherit (liminix.services) bundle oneshot;
inherit (lib) mkOption types optional;
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 "";
in oneshot rec {
name = "${ifname}.link";
up = ''
${if macAddressFromInterface == null then
"ip link add name ${ifname} type bridge"
"ip link add name ${ifname} type bridge${extra}"
else
"ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge"}
"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"}
(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" "ip" "ipaddr" "iplink" "ipneigh" "iproute" "iprule" "kill"
"ifconfig" "ipneigh" "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

@ -20,6 +20,10 @@ in {
system.service.hostapd = mkOption {
type = liminix.lib.types.serviceDefn;
};
system.service.hostapd-ready = mkOption {
type = liminix.lib.types.serviceDefn;
};
};
config = {
system.service.hostapd = liminix.callService ./service.nix {
@ -34,5 +38,12 @@ in {
type = types.attrs;
};
};
system.service.hostapd-ready = liminix.callService ./ready.nix {
interface = mkOption {
type = liminix.lib.types.interface;
description = "Interface for which to wait that the oper state Master or Master (VLAN) has been reached.";
};
};
};
}

16
modules/hostapd/ready.nix Normal file
View file

@ -0,0 +1,16 @@
{
liminix
, ifwait
, lib
}:
{ interface } :
let
inherit (liminix.services) oneshot;
in oneshot {
name = "${interface.name}.wlan-oper";
up = ''
${ifwait}/bin/ifbridgeable -v $(output ${interface} ifname)
'';
dependencies = [ interface ];
}

View file

@ -1,7 +1,6 @@
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
in {
options = {
hostname = mkOption {
@ -12,12 +11,21 @@ in {
default = "liminix";
type = types.nonEmptyStr;
};
};
config = {
services.hostname = oneshot {
name = "hostname";
up = "echo ${config.hostname} > /proc/sys/kernel/hostname";
down = "true";
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;
};
};
}

28
modules/iproute2.nix Normal file
View file

@ -0,0 +1,28 @@
{ 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

@ -83,11 +83,11 @@ let
localSystem = cfg.hostPlatform;
};
in
import <nixpkgs> ({
import cfg.source ({
inherit (cfg) config overlays;
} // systemArgs)
else
import <nixpkgs> {
import cfg.source {
inherit (cfg) config overlays localSystem crossSystem;
};
@ -97,6 +97,14 @@ in
{
options.nixpkgs = {
source = mkOption {
type = types.package // {
description = "Source of a nixpkgs repository";
};
default = <nixpkgs>;
defaultText = "<nixpkgs>";
};
pkgs = mkOption {
defaultText = literalExpression ''

View file

@ -36,22 +36,43 @@ in
kernel.config = {
BLK_DEV_INITRD = "y";
INITRAMFS_SOURCE = builtins.toJSON "${config.system.outputs.initramfs}";
# INITRAMFS_COMPRESSION_LZO = "y";
INITRAMFS_COMPRESSION_ZSTD = "y";
};
system.outputs = {
initramfs =
let inherit (pkgs.pkgsBuildBuild) gen_init_cpio;
let
inherit (pkgs.pkgsBuildBuild) gen_init_cpio cpio writeScript;
inherit (pkgs) busybox;
failsafe-init = writeScript "init" ''
#!/bin/sh
exec >/dev/console
echo Running in initramfs
PATH=${busybox}/bin:$PATH
export PATH
mount -t proc none /proc
mount -t sysfs none /sys
${busybox}/bin/sh
'';
refs = pkgs.writeClosure [ busybox ];
in runCommand "initramfs.cpio" {} ''
cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > $out
cat << SPECIALS | ${gen_init_cpio}/bin/gen_init_cpio /dev/stdin > out
dir /proc 0755 0 0
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /target 0755 0 0
dir /target/persist 0755 0 0
dir /target/nix 0755 0 0
dir /nix 0755 0 0
dir /nix/store 0755 0 0
dir /bin 0755 0 0
file /bin/sh ${busybox}/bin/sh 0755 0 0
file /init ${pkgs.preinit}/bin/preinit 0755 0 0
file /failsafe-init ${failsafe-init} 0755 0 0
SPECIALS
find $(cat ${refs}) | ${cpio}/bin/cpio -H newc -o -A -v -O out
mv out $out
'';
systemConfiguration =
pkgs.systemconfig config.filesystem.contents;

View file

@ -12,10 +12,15 @@ let
arch = pkgs.stdenv.hostPlatform.linuxArch;
# UBI cannot run on the top of phram.
needsSquashfs = config.rootfsType == "ubifs";
rootfstype = if needsSquashfs then "squashfs" else config.rootfsType;
rootfs = if needsSquashfs then
liminix.builders.squashfs config.filesystem.contents
needsJffs2 = config.rootfsType == "ubifs";
# squashfs doesn't work out for us because only `bootablerootdir`
# contain what we need to boot, not `config.filesystem.contents` alas.
rootfstype = if needsJffs2 then "jffs2" else config.rootfsType;
rootfs = if needsJffs2 then
liminix.builders.jffs2 {
bootableRootDirectory = config.system.outputs.bootablerootdir;
inherit (config.hardware.flash) eraseBlockSize;
}
else config.system.outputs.rootfs;
in {
imports = [ ../ramdisk.nix ];
@ -36,14 +41,6 @@ in {
type = types.bool;
default = false;
};
commandLine = mkOption {
type = types.listOf types.str;
default = config.boot.commandLine;
description = ''
TFTP-specific command line.
Defaults to the classical one if unset.
'';
};
};
options.system.outputs = {
tftpboot = mkOption {
@ -82,9 +79,13 @@ in {
config = {
boot.ramdisk.enable = true;
kernel.config = mkIf needsSquashfs {
SQUASHFS = "y";
SQUASHFS_XZ = "y";
kernel.config = mkIf needsJffs2 {
JFFS2_FS = "y";
JFFS2_LZO = "y";
JFFS2_RTIME = "y";
JFFS2_COMPRESSION_OPTIONS = "y";
JFFS2_ZLIB = "y";
JFFS2_CMODE_SIZE = "y";
};
system.outputs = rec {

View file

@ -30,6 +30,8 @@ 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,6 +36,7 @@ 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,6 +33,11 @@ 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,13 +2,15 @@
liminix
, lib
}:
{ ifname, primary, vid } :
{ ifname, primary, vid, untagged } :
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

@ -1,23 +1,24 @@
final: prev:
let
isCross = final.stdenv.buildPlatform != final.stdenv.hostPlatform;
crossOnly = pkg : amendFn : if isCross then (amendFn pkg) else pkg;
extraPkgs = import ./pkgs/default.nix {
inherit (final) lib callPackage;
};
inherit (final) fetchpatch;
lua_no_readline = prev.lua5_3;
# lua_no_readline = prev.lua5_3.overrideAttrs(o: {
# name = "lua-tty";
# preBuild = ''
# makeFlagsArray+=(PLAT="posix" SYSLIBS="-Wl,-E -ldl" CFLAGS="-O2 -fPIC -DLUA_USE_POSIX -DLUA_USE_DLOPEN")
# '';
# # lua in nixpkgs has a postInstall stanza that assumes only
# # one output, we need to override that if we're going to
# # convert to multi-output
# # outputs = ["bin" "man" "out"];
# makeFlags =
# builtins.filter (x: (builtins.match "(PLAT|MYLIBS).*" x) == null)
# o.makeFlags;
# });
luaHost = prev.lua5_3.overrideAttrs(o: {
name = "lua-tty";
preBuild = ''
makeFlagsArray+=(PLAT="posix" SYSLIBS="-Wl,-E -ldl" CFLAGS="-O2 -fPIC -DLUA_USE_POSIX -DLUA_USE_DLOPEN")
'';
# lua in nixpkgs has a postInstall stanza that assumes only
# one output, we need to override that if we're going to
# convert to multi-output
# outputs = ["bin" "man" "out"];
makeFlags =
builtins.filter (x: (builtins.match "(PLAT|MYLIBS).*" x) == null)
o.makeFlags;
});
s6 = prev.s6.overrideAttrs(o:
let
@ -42,7 +43,6 @@ let
(if o ? patches then o.patches else []) ++
(if patch_needed then [ patch ] else []);
});
lua = let s = lua_no_readline.override { self = s; }; in s;
in
extraPkgs // {
# liminix library functions
@ -140,8 +140,10 @@ extraPkgs // {
owner = "DGNum";
repo = "hostapd";
rev = "hostap-liminix-integration";
hash = "sha256-qoCXx3raXCD51YX5izj30VG/HMgr6lv/288Yg9I4S7M=";
};
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
# Do not take any patch.
patches = [];
extraConfig = "";
configurePhase = ''
cat > hostapd/defconfig <<EOF
@ -182,8 +184,9 @@ extraPkgs // {
owner = "DGNum";
repo = "hostapd";
rev = "hostap-liminix-integration";
hash = "sha256-qoCXx3raXCD51YX5izj30VG/HMgr6lv/288Yg9I4S7M=";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
patches = [];
extraConfig = "";
configurePhase = ''
cat > hostapd/defconfig <<EOF
@ -194,7 +197,35 @@ 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
@ -214,8 +245,7 @@ extraPkgs // {
];
});
luaFull = prev.lua;
inherit lua;
lua = crossOnly prev.lua5_3 (_: luaHost);
mtdutils = prev.mtdutils.overrideAttrs(o: {
patches = (if o ? patches then o.patches else []) ++ [

View file

@ -1,5 +1,5 @@
default: fs.lua init.lua nl.lua svc.lua net/constants.lua
default: wlan.lua fs.lua init.lua nl.lua svc.lua net/constants.lua
test:
ln -s . anoia

View file

@ -4,6 +4,7 @@
, linotify
, lua
, lualinux
, iwinfo
, cpio
}:
let pname = "anoia";
@ -12,7 +13,7 @@ in stdenv.mkDerivation {
version = "0.1";
src = ./.;
nativeBuildInputs = [ fennel cpio ];
buildInputs = with lua.pkgs; [ linotify lualinux ];
buildInputs = with lua.pkgs; [ linotify lualinux iwinfo ];
outputs = [ "out" "dev" ];
doCheck = true;

8
pkgs/anoia/wlan.fnl Normal file
View file

@ -0,0 +1,8 @@
(local { : nl80211 } (require :iwinfo))
(fn is-bridgeable [ifname]
(let [mode (nl80211.mode ifname)]
(or (= mode "Master") (= mode "Master (VLAN)"))
))
{ : is-bridgeable }

View file

@ -112,6 +112,7 @@ in {
tufted = callPackage ./tufted {};
libubox = callPackage ./libubox {};
ubus = callPackage ./ubus {};
iwinfo = callPackage ./iwinfo {};
uevent-watch = callPackage ./uevent-watch {};
usb-modeswitch = callPackage ./usb-modeswitch {};
writeAshScript = callPackage ./write-ash-script {};

View file

@ -10,6 +10,7 @@
, linotify
, anoia
, netlink-lua
, iwinfo
, fennel
}:
let packages = [
@ -18,7 +19,7 @@ let packages = [
fennel
lualinux
netlink-lua
lua.pkgs.readline
iwinfo
];
join = ps: builtins.concatStringsSep ";" ps;
luapath = join (builtins.map (f:

View file

@ -1,11 +1,14 @@
{
lua
, netlink-lua
, lualinux
, iwinfo
, writeFennelScript
, runCommand
, anoia
}:
runCommand "ifwait" {} ''
mkdir -p $out/bin
cp -p ${writeFennelScript "ifwait" [anoia netlink-lua] ./ifwait.fnl} $out/bin/ifwait
cp -p ${writeFennelScript "ifwait" [ anoia netlink-lua ] ./ifwait.fnl} $out/bin/ifwait
cp -p ${writeFennelScript "ifbridgeable" [ anoia lualinux iwinfo ] ./ifbridgeable.fnl} $out/bin/ifbridgeable
''

View file

@ -0,0 +1,30 @@
(local wlan (require :anoia.wlan))
(local { : assoc } (require :anoia))
(local { : msleep } (require :lualinux))
(fn parse-args [args]
(match args
["-v" & rest] (assoc (parse-args rest) :verbose true)
[linkname] {:link linkname}
_ nil))
(fn run [args poll-fn]
(let [parameters
(assert (parse-args args)
(.. "Usage: ifbridgeable [-v] ifname"))]
(when parameters.verbose
(print (.. "ifbridgeable: waiting for "
parameters.link " to be bridgeable")))
(while (not (poll-fn parameters.link))
(when parameters.verbose
(print (.. "ifbridgeable: waiting for " parameters.link " to be bridgeable")))
(msleep 500)
)
)
)
(when (not (= (. arg 0) "test"))
(run arg wlan.is-bridgeable))
{ : run }

View file

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

59
pkgs/iwinfo/default.nix Normal file
View file

@ -0,0 +1,59 @@
{
lib,
stdenv,
fetchFromGitea,
ubus,
libubox,
lua5_3,
libnl-tiny,
backend ? "nl80211"
}:
let
lua = lua5_3;
in
stdenv.mkDerivation rec {
pname = "iwinfo";
version = "unstable-07-09-2024";
src = fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "iwinfo";
rev = "14685a26805155aa5c137993b9a4861a0bc585d5";
hash = "sha256-lg4sBoYcFFLhcUv+wKR6u1OCartjtnAoF9M5FdfO6JE=";
};
BACKENDS = backend;
buildInputs = [
ubus
libubox
lua
libnl-tiny
];
CFLAGS = "-I${libnl-tiny}/include/libnl-tiny -D_GNU_SOURCE";
installPhase = ''
runHook preInstall
install -Dm755 iwinfo $out/bin/iwinfo
install -Dm755 iwinfo.so $out/lib/lua/${lua.luaversion}/iwinfo.so
install -Dm755 libiwinfo.so $out/lib/libiwinfo.so
install -Dm755 libiwinfo.so.0 $out/lib/libiwinfo.so.0
mkdir -p $out/include
cp -r include/* $out/include
runHook postInstall
'';
meta = {
description = "Library to access wireless devices";
homepage = "https://github.com/openwrt/iwinfo";
license = lib.licenses.gpl2Only;
maintainers = with lib.maintainers; [ raitobezarius ];
mainProgram = "iwinfo";
platforms = lib.platforms.all;
};
}

View file

@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
nativeBuildInputs = [buildPackages.stdenv.cc] ++
(with buildPackages.pkgs; [
rsync bc bison flex pkg-config
openssl ncurses.all perl
openssl ncurses.all perl zstd
]);
CC = "${stdenv.cc.bintools.targetPrefix}gcc";
HOSTCC = with buildPackages.pkgs;

View file

@ -2,6 +2,7 @@
writeScriptBin
, writeScript
, systemconfig
, stdenv
, execline
, lib
, config ? {}
@ -56,11 +57,19 @@ 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

@ -1,9 +1,9 @@
{
lib,
stdenv,
fetchgit,
fetchFromGitea,
cmake,
lua5_1,
lua,
json_c
}:
@ -11,30 +11,32 @@ stdenv.mkDerivation rec {
pname = "libubox";
version = "unstable-2024-04-09";
src = fetchgit {
url = "https://git.openwrt.org/project/libubox.git";
rev = "eb9bcb64185ac155c02cc1a604692c4b00368324";
hash = "sha256-5KO2E+4pcDp/pe2+vjoQDmyMwCc0yKm847U4J6HjxyA=";
src = fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "libubox";
rev = "1c4b2dc4c12848e1b70b11e1cb2139ca8f19c860";
hash = "sha256-aPhGJ7viXQmnoQRY8DuRvtwtxSy+S4qPj1fBsK066Yc=";
};
nativeBuildInputs = [
cmake
lua5_1
lua
];
buildInputs = [
lua5_1
lua
json_c
];
# Otherwise, CMake cannot find jsoncpp?
env.NIX_CFLAGS_COMPILE = toString [ "-I${json_c.dev}/include/json-c" "-D JSONC" ];
env.NIX_CFLAGS_COMPILE = toString [ "-I${json_c.dev}/include/json-c" "-D JSONC" "-D LUA_COMPAT_MODULE" ];
cmakeFlags = [
"-DBUILD_EXAMPLES=off"
# TODO: it explode at install phase.
"-DBUILD_LUA=on"
"-DLUAPATH=${placeholder "out"}/lib/lua"
"-DLUAPATH=${placeholder "out"}/lib/lua/${lua.luaversion}/"
];
meta = {

View file

@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -Eeuo pipefail
ssh_command=${SSH_COMMAND-ssh}
@ -13,19 +14,24 @@ case "$1" in
reboot="soft"
shift
;;
"--root")
root_prefix="$2"
shift
shift
;;
esac
target_host=$1
shift
if [ -z "$target_host" ] ; then
echo Usage: liminix-rebuild \[--no-reboot\] target-host params
echo Usage: liminix-rebuild \[--no-reboot\] \[--fast\] target-host params
exit 1
fi
if toplevel=$(nix-build "$@" -A outputs.systemConfiguration --no-out-link); then
echo systemConfiguration $toplevel
min-copy-closure $target_host $toplevel
min-copy-closure --root "$root_prefix" $target_host $toplevel
$ssh_command $target_host $toplevel/bin/install
case "$reboot" in
reboot)

View file

@ -4,9 +4,13 @@
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
#include <dirent.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
@ -44,6 +48,25 @@ static int fork_exec(char * command, char *args[])
return execve(command, args, NULL);
}
static void debug_listdir(const char * path)
{
DIR *mydir;
struct dirent *myfile;
struct stat mystat;
char buf[512];
mydir = opendir(path);
while((myfile = readdir(mydir)) != NULL)
{
sprintf(buf, "%s/%s", path, myfile->d_name);
stat(buf, &mystat);
printf("%llu", mystat.st_size);
printf(" %s\n", myfile->d_name);
}
closedir(mydir);
}
char banner[] = "Running pre-init...\n";
char buf[COMMAND_LINE_SIZE];
@ -98,6 +121,7 @@ int main(int argc, char *argv[], char *envp[])
AVER(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts));
} else {
if(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts) < 0) {
ERR("failed to mount primary device, mount the alternative device\n");
AVER(mount(opts.altdevice, "/target/persist", opts.fstype, 0, opts.mount_opts));
}
}
@ -107,7 +131,12 @@ int main(int argc, char *argv[], char *envp[])
"bind", MS_BIND, NULL));
char *exec_args[] = { "activate", "/target", NULL };
AVER(fork_exec("/target/persist/activate", exec_args));
if (fork_exec("/target/persist/activate", exec_args) < 0) {
ERR("failed to activate the system\n");
pr_u32(errno); ERR ( " - "); ERR(strerror(errno)); ERR("\n");
goto failsafe;
}
AVER(chdir("/target"));
AVER(mount("/target", "/", "bind", MS_BIND | MS_REC, NULL));
@ -118,5 +147,23 @@ int main(int argc, char *argv[], char *envp[])
AVER(execve("/persist/init", argv, envp));
}
failsafe:
debug_listdir("/");
debug_listdir("/target");
ERR("failed to mount the rootfs\n");
ERR("final stand using the failsafe initialization method\n");
ERR("the boot process is manual from now on\n");
argv[0] = "init";
argv[1] = NULL;
// Attempt to unmount the /target mount-bind.
AVER(umount("/target"));
AVER(execve("/failsafe-init", argv, envp));
debug_listdir("/");
debug_listdir("/target");
die();
}

View file

@ -2,14 +2,15 @@
qemuLim
, socat
, writeShellScript
, writeFennel
, runCommand
, fennel
, lib
, lua
, pkgsBuildBuild
}: let
run-liminix-vm = pkgsBuildBuild.writeFennel "run-liminix-vm" {
packages = [ qemuLim pkgsBuildBuild.lua.pkgs.luaposix pkgsBuildBuild.lua.pkgs.fennel ];
writeFennel = pkgsBuildBuild.writeFennel.override { inherit lua; };
run-liminix-vm = writeFennel "run-liminix-vm" {
packages = [ qemuLim lua.pkgs.luaposix fennel ];
} ./run-liminix-vm.fnl;
connect = writeShellScript "connect-vm" ''
export PATH="${lib.makeBinPath [socat]}:$PATH"

View file

@ -1,13 +1,14 @@
{ stdenv, fetchFromGitHub, cmake, libubox, json_c, lua5_1, defaultSocketLocation ? "/run/ubus/ubus.sock" }:
{ stdenv, fetchFromGitea, lib, cmake, libubox, json_c, lua, defaultSocketLocation ? "/run/ubus/ubus.sock" }:
stdenv.mkDerivation {
pname = "ubus";
version = "unstable-04-09-2024";
src = fetchFromGitHub {
owner = "openwrt";
src = fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "ubus";
rev = "65bb027054def3b94a977229fd6ad62ddd32345b";
hash = "sha256-n82Ub0IiuvWbnlDCoN+0hjo/1PbplEbc56kuOYMrHxQ=";
rev = "ebb1dc92e4985538a8e18b7e926264118138f281";
hash = "sha256-fo4zleC9R6uzlcOJ/jQ0t0nSBHUAq/uqPVd9xJdkAM0=";
};
# We don't use /var/run/ in Liminix by default.
@ -21,14 +22,14 @@ stdenv.mkDerivation {
];
buildInputs = [
lua5_1
lua
libubox
json_c
];
cmakeFlags = [
"-DBUILD_LUA=on"
"-DLUAPATH=${placeholder "out"}/lib/lua"
"-DLUAPATH=${placeholder "out"}/lib/lua/${lua.luaversion}"
"-DBUILD_EXAMPLES=off"
];
}

View file

@ -27,7 +27,7 @@ name :
echo "#!${lua}/bin/lua ${luaFlags}"
echo "package.path = ${lib.strings.escapeShellArg (builtins.concatStringsSep "" luapath)} .. package.path"
echo "package.cpath = ${lib.strings.escapeShellArg (builtins.concatStringsSep "" luacpath)} .. package.cpath"
echo "local ok, stdlib = pcall(require,'posix.stdlib'); if ok then stdlib.setenv('PATH',${lib.escapeShellArg (lib.makeBinPath packages)} .. \":\" .. os.getenv('PATH')) end"
echo "local ok, stdlib = pcall(require,'posix.stdlib'); if ok then stdlib.setenv('PATH', \"${lib.makeBinPath packages}\" .. \":\" .. os.getenv('PATH')) end"
fennel ${if correlate then "--correlate" else ""} --compile ${source}
) > ${name}.lua
'';

View file

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

View file

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

View file

@ -0,0 +1,13 @@
{ 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

@ -0,0 +1,21 @@
{
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,7 +5,6 @@ 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,7 +13,6 @@ 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,5 +1,6 @@
{
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,6 +7,7 @@ in rec {
../../modules/wlan.nix
../../modules/hostapd
../../modules/network
./wpa_supplicant.nix
];
services.hostap = config.system.service.hostapd.build {
@ -27,5 +28,21 @@ in rec {
};
};
defaultProfile.packages = with pkgs; [ tcpdump ] ;
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 ];
}

View file

@ -3,10 +3,11 @@
, nixpkgs
}:
let img = (import liminix {
device = import "${liminix}/devices/qemu-armv7l/";
inherit nixpkgs;
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)]; };
in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [
expect socat

View file

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

View file

@ -0,0 +1,21 @@
{
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

@ -0,0 +1,15 @@
{ 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;
};
};
}