Compare commits

..

1 commit

Author SHA1 Message Date
Raito Bezarius
37a355b901 overlay: update hostapd with readiness support
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 18:09:34 +02:00
61 changed files with 134 additions and 668 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

26
ci.nix
View file

@ -1,15 +1,21 @@
{
sources ? import ./lon.nix
, nixpkgs ? sources.nixpkgs
, unstable ? nixpkgs
, liminix ? ./.
nixpkgs
, unstable
, liminix
, ... }:
let
pkgs = (import nixpkgs { });
inherit (builtins) map;
pkgs = (import nixpkgs {});
borderVmConf = ./bordervm.conf-example.nix;
inherit (pkgs.lib.attrsets) genAttrs mapAttrs;
inherit (pkgs.lib.attrsets) genAttrs;
devices = [
"gl-ar750"
"gl-mt300a"
"gl-mt300n-v2"
"qemu"
"qemu-aarch64"
"qemu-armv7l"
"tp-archer-ax23"
"zyxel-nwa50ax"
];
vanilla = ./vanilla-configuration.nix;
@ -19,7 +25,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 //
@ -38,6 +44,12 @@ 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,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

@ -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,9 +41,6 @@ rec {
../../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,8 +135,6 @@ rec {
../../modules/zyxel-dual-image
];
nixpkgs.hostPlatform = system.crossSystem;
filesystem = dir {
lib = dir {
firmware = dir {
@ -224,8 +222,8 @@ rec {
imageFormat = "fit";
tftp = {
# 20MB is pretty good on this device as we have plenty of RAM.
freeSpaceBytes = 20 * 1024 * 1024;
# 5MB is nice.
freeSpaceBytes = 5 * 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,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

@ -1,15 +0,0 @@
{
"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
View file

@ -1,41 +0,0 @@
# 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,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;
@ -89,14 +69,6 @@ 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 = ''
@ -126,13 +98,8 @@ 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 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 +170,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

@ -20,10 +20,6 @@ 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 {
@ -38,12 +34,5 @@ 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.";
};
};
};
}

View file

@ -1,16 +0,0 @@
{
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,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";
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

@ -83,11 +83,11 @@ let
localSystem = cfg.hostPlatform;
};
in
import cfg.source ({
import <nixpkgs> ({
inherit (cfg) config overlays;
} // systemArgs)
else
import cfg.source {
import <nixpkgs> {
inherit (cfg) config overlays localSystem crossSystem;
};
@ -97,14 +97,6 @@ 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,43 +36,22 @@ in
kernel.config = {
BLK_DEV_INITRD = "y";
INITRAMFS_SOURCE = builtins.toJSON "${config.system.outputs.initramfs}";
INITRAMFS_COMPRESSION_ZSTD = "y";
# INITRAMFS_COMPRESSION_LZO = "y";
};
system.outputs = {
initramfs =
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 ];
let inherit (pkgs.pkgsBuildBuild) gen_init_cpio;
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,15 +12,10 @@ let
arch = pkgs.stdenv.hostPlatform.linuxArch;
# UBI cannot run on the top of phram.
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;
}
needsSquashfs = config.rootfsType == "ubifs";
rootfstype = if needsSquashfs then "squashfs" else config.rootfsType;
rootfs = if needsSquashfs then
liminix.builders.squashfs config.filesystem.contents
else config.system.outputs.rootfs;
in {
imports = [ ../ramdisk.nix ];
@ -41,6 +36,14 @@ 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 {
@ -79,13 +82,9 @@ in {
config = {
boot.ramdisk.enable = true;
kernel.config = mkIf needsJffs2 {
JFFS2_FS = "y";
JFFS2_LZO = "y";
JFFS2_RTIME = "y";
JFFS2_COMPRESSION_OPTIONS = "y";
JFFS2_ZLIB = "y";
JFFS2_CMODE_SIZE = "y";
kernel.config = mkIf needsSquashfs {
SQUASHFS = "y";
SQUASHFS_XZ = "y";
};
system.outputs = rec {

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

@ -1,24 +1,23 @@
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;
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;
});
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;
# });
s6 = prev.s6.overrideAttrs(o:
let
@ -43,6 +42,7 @@ 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
@ -141,9 +141,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 +184,6 @@ extraPkgs // {
rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
patches = [];
extraConfig = "";
configurePhase = ''
cat > hostapd/defconfig <<EOF
@ -197,35 +194,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
@ -245,7 +214,8 @@ extraPkgs // {
];
});
lua = crossOnly prev.lua5_3 (_: luaHost);
luaFull = prev.lua;
inherit lua;
mtdutils = prev.mtdutils.overrideAttrs(o: {
patches = (if o ? patches then o.patches else []) ++ [

View file

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

View file

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

View file

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

View file

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

View file

@ -1,14 +1,11 @@
{
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 "ifbridgeable" [ anoia lualinux iwinfo ] ./ifbridgeable.fnl} $out/bin/ifbridgeable
cp -p ${writeFennelScript "ifwait" [anoia netlink-lua] ./ifwait.fnl} $out/bin/ifwait
''

View file

@ -1,30 +0,0 @@
(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
, 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

@ -1,59 +0,0 @@
{
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 zstd
openssl ncurses.all perl
]);
CC = "${stdenv.cc.bintools.targetPrefix}gcc";
HOSTCC = with buildPackages.pkgs;

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

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

View file

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

View file

@ -4,13 +4,9 @@
#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 */
@ -48,25 +44,6 @@ 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];
@ -121,7 +98,6 @@ 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));
}
}
@ -131,12 +107,7 @@ int main(int argc, char *argv[], char *envp[])
"bind", MS_BIND, NULL));
char *exec_args[] = { "activate", "/target", NULL };
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(fork_exec("/target/persist/activate", exec_args));
AVER(chdir("/target"));
AVER(mount("/target", "/", "bind", MS_BIND | MS_REC, NULL));
@ -147,23 +118,5 @@ 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,15 +2,14 @@
qemuLim
, socat
, writeShellScript
, writeFennel
, runCommand
, fennel
, lib
, lua
, pkgsBuildBuild
}: let
writeFennel = pkgsBuildBuild.writeFennel.override { inherit lua; };
run-liminix-vm = writeFennel "run-liminix-vm" {
packages = [ qemuLim lua.pkgs.luaposix fennel ];
run-liminix-vm = pkgsBuildBuild.writeFennel "run-liminix-vm" {
packages = [ qemuLim pkgsBuildBuild.lua.pkgs.luaposix pkgsBuildBuild.lua.pkgs.fennel ];
} ./run-liminix-vm.fnl;
connect = writeShellScript "connect-vm" ''
export PATH="${lib.makeBinPath [socat]}:$PATH"

View file

@ -1,14 +1,13 @@
{ stdenv, fetchFromGitea, lib, cmake, libubox, json_c, lua, defaultSocketLocation ? "/run/ubus/ubus.sock" }:
{ stdenv, fetchFromGitHub, cmake, libubox, json_c, lua5_1, defaultSocketLocation ? "/run/ubus/ubus.sock" }:
stdenv.mkDerivation {
pname = "ubus";
version = "unstable-04-09-2024";
src = fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
src = fetchFromGitHub {
owner = "openwrt";
repo = "ubus";
rev = "ebb1dc92e4985538a8e18b7e926264118138f281";
hash = "sha256-fo4zleC9R6uzlcOJ/jQ0t0nSBHUAq/uqPVd9xJdkAM0=";
rev = "65bb027054def3b94a977229fd6ad62ddd32345b";
hash = "sha256-n82Ub0IiuvWbnlDCoN+0hjo/1PbplEbc56kuOYMrHxQ=";
};
# We don't use /var/run/ in Liminix by default.
@ -22,14 +21,14 @@ stdenv.mkDerivation {
];
buildInputs = [
lua
lua5_1
libubox
json_c
];
cmakeFlags = [
"-DBUILD_LUA=on"
"-DLUAPATH=${placeholder "out"}/lib/lua/${lua.luaversion}"
"-DLUAPATH=${placeholder "out"}/lib/lua"
"-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.makeBinPath packages}\" .. \":\" .. os.getenv('PATH')) end"
echo "local ok, stdlib = pcall(require,'posix.stdlib'); if ok then stdlib.setenv('PATH',${lib.escapeShellArg (lib.makeBinPath packages)} .. \":\" .. os.getenv('PATH')) end"
fennel ${if correlate then "--correlate" else ""} --compile ${source}
) > ${name}.lua
'';

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;
};
};
}