Compare commits

..

1 commit
main ... usteer

Author SHA1 Message Date
Raito Bezarius
605055deea usteer: init at unstable-04-09-2024
Some checks failed
build liminix / build_vm_qemu_mips (pull_request) Failing after 26s
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-04 15:58:27 +02:00
66 changed files with 183 additions and 771 deletions

View file

@ -17,34 +17,4 @@ jobs:
- name: Build VM QEMU MIPS - name: Build VM QEMU MIPS
run: | run: |
# Enter the shell # Enter the shell
nix-build ci.nix -A qemu nix-build -I liminix-config=./examples/hello-from-qemu.nix --arg device "import ./devices/qemu" -A outputs.default
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,15 +1,21 @@
{ {
sources ? import ./lon.nix nixpkgs
, nixpkgs ? sources.nixpkgs , unstable
, unstable ? nixpkgs , liminix
, liminix ? ./.
, ... }: , ... }:
let let
pkgs = (import nixpkgs { }); inherit (builtins) map;
pkgs = (import nixpkgs {});
borderVmConf = ./bordervm.conf-example.nix; borderVmConf = ./bordervm.conf-example.nix;
inherit (pkgs.lib.attrsets) genAttrs mapAttrs; inherit (pkgs.lib.attrsets) genAttrs;
devices = [ devices = [
"gl-ar750"
"gl-mt300a"
"gl-mt300n-v2"
"qemu" "qemu"
"qemu-aarch64"
"qemu-armv7l"
"tp-archer-ax23"
"zyxel-nwa50ax" "zyxel-nwa50ax"
]; ];
vanilla = ./vanilla-configuration.nix; vanilla = ./vanilla-configuration.nix;
@ -19,7 +25,7 @@ let
device = import (liminix + "/devices/${name}"); device = import (liminix + "/devices/${name}");
liminix-config = vanilla; liminix-config = vanilla;
}).outputs.default; }).outputs.default;
tests = mapAttrs (_: v: v { inherit liminix nixpkgs; }) (import ./tests/ci.nix); tests = import ./tests/ci.nix;
jobs = jobs =
(genAttrs devices for-device) // (genAttrs devices for-device) //
tests // tests //
@ -38,6 +44,12 @@ let
imports = [ ./modules/all-modules.nix ]; imports = [ ./modules/all-modules.nix ];
}; };
}).outputs.optionsJson; }).outputs.optionsJson;
installers = map (f: "system.outputs.${f}") [
"vmroot"
"mtdimage"
"ubimage"
];
inherit (pkgs.lib) concatStringsSep;
in pkgs.stdenv.mkDerivation { in pkgs.stdenv.mkDerivation {
name = "liminix-doc"; name = "liminix-doc";
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [

View file

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

View file

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

View file

@ -1,4 +1,4 @@
rec { {
system = { system = {
crossSystem = { crossSystem = {
config = "mipsel-unknown-linux-musl"; config = "mipsel-unknown-linux-musl";
@ -135,8 +135,6 @@ rec {
../../modules/zyxel-dual-image ../../modules/zyxel-dual-image
]; ];
nixpkgs.hostPlatform = system.crossSystem;
filesystem = dir { filesystem = dir {
lib = dir { lib = dir {
firmware = dir { firmware = dir {
@ -224,8 +222,8 @@ rec {
imageFormat = "fit"; imageFormat = "fit";
tftp = { tftp = {
# 20MB is pretty good on this device as we have plenty of RAM. # 5MB is nice.
freeSpaceBytes = 20 * 1024 * 1024; freeSpaceBytes = 5 * 1024 * 1024;
appendDTB = true; appendDTB = true;
loadAddress = lim.parseInt "0x2000000"; 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: args:
let let
modulesPath = builtins.toString ../modules; modulesPath = builtins.toString ../modules;
@ -12,7 +12,6 @@ in
"${modulesPath}/hardware.nix" "${modulesPath}/hardware.nix"
"${modulesPath}/base.nix" "${modulesPath}/base.nix"
"${modulesPath}/busybox.nix" "${modulesPath}/busybox.nix"
"${modulesPath}/iproute2.nix"
"${modulesPath}/hostname.nix" "${modulesPath}/hostname.nix"
"${modulesPath}/kernel" "${modulesPath}/kernel"
"${modulesPath}/s6" "${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 = [ imports = [
./base.nix ./base.nix
./bridge ./bridge
./busybox.nix ./busybox.nix
./iproute2.nix
./dhcp6c ./dhcp6c
./jitter-rng ./jitter-rng
./dnsmasq ./dnsmasq

View file

@ -4,13 +4,11 @@
{ lib, pkgs, config, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr concatStringsSep mapAttrsToList; inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ;
inherit (pkgs.pseudofile) dir symlink; inherit (pkgs.pseudofile) dir symlink;
inherit (pkgs.liminix.networking) address interface; inherit (pkgs.liminix.networking) address interface;
inherit (pkgs.liminix.services) bundle; inherit (pkgs.liminix.services) bundle;
# TODO: escape shell argument.
exportVar = name: value: "export ${name}=\"${value}\"";
type_service = pkgs.liminix.lib.types.service; type_service = pkgs.liminix.lib.types.service;
in { in {
@ -24,24 +22,6 @@ in {
/run/current-system, we just add the paths in /etc/profile /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 { services = mkOption {
type = types.attrsOf type_service; type = types.attrsOf type_service;
@ -89,14 +69,6 @@ in {
default = "uimage"; default = "uimage";
}; };
tftp = { 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 { loadAddress = mkOption {
type = types.ints.unsigned; type = types.ints.unsigned;
description = '' description = ''
@ -126,13 +98,8 @@ in {
}; };
}; };
config = { config = {
# By default, we enable cross-compilation support.
nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem;
defaultProfile.packages = with pkgs; defaultProfile.packages = with pkgs;
[ s6 s6-init-bin execline s6-linux-init s6-rc iproute2 ]; [ s6 s6-init-bin execline s6-linux-init s6-rc ];
# Set the useful PS1 prompt by default.
defaultProfile.environmentVariables.PS1 = lib.mkDefault config.defaultProfile.prompt;
boot.commandLine = [ boot.commandLine = [
"panic=10 oops=panic init=/bin/init loglevel=8" "panic=10 oops=panic init=/bin/init loglevel=8"
@ -203,10 +170,9 @@ in {
etc = let etc = let
profile = symlink profile = symlink
(pkgs.writeScript ".profile" '' (pkgs.writeScript ".profile" ''
PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin PATH=${lib.makeBinPath config.defaultProfile.packages}:/bin
export PATH export PATH
${concatStringsSep "\n" (mapAttrsToList exportVar config.defaultProfile.environmentVariables)} '');
'');
in dir { in dir {
inherit profile; inherit profile;
ashrc = profile; ashrc = profile;

View file

@ -9,7 +9,8 @@
{ lib, pkgs, config, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkOption types mkEnableOption; inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs) liminix; inherit (pkgs) liminix;
in in
{ {
@ -34,20 +35,6 @@ in
default = null; default = null;
description = "reuse mac address from an existing interface service"; 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 { members = config.system.callService ./members.nix {
primary = mkOption { primary = mkOption {
@ -56,20 +43,8 @@ in
}; };
members = mkOption { members = mkOption {
type = types.attrsOf (types.submodule ({ ... }: { options = { type = types.listOf liminix.lib.types.interface;
member = mkOption { description = "interfaces to add to the bridge";
type = liminix.lib.types.interface;
description = "interface to add";
};
dependencies = mkOption {
type = types.listOf liminix.lib.types.service;
default = [];
description = "extra dependencies before attaching this interface to the bridge";
};
}; }));
description = "set of bridge members";
}; };
}; };

View file

@ -7,10 +7,11 @@
{ members, primary } : { members, primary } :
let let
inherit (liminix.services) structuredBundle oneshot; inherit (liminix.networking) interface;
inherit (lib) mapAttrs; inherit (liminix.services) bundle oneshot;
addif = name: { dependencies ? [ ], member }: oneshot { inherit (lib) mkOption types;
name = "${primary.name}.member.${name}"; addif = member : oneshot {
name = "${primary.name}.member.${member.name}";
up = '' up = ''
echo "attaching $(output ${member} ifname) to $(output ${primary} ifname) bridge" echo "attaching $(output ${member} ifname) to $(output ${primary} ifname) bridge"
ip link set dev $(output ${member} ifname) master $(output ${primary} ifname) ip link set dev $(output ${member} ifname) master $(output ${primary} ifname)
@ -20,9 +21,9 @@ let
ip link set dev $(output ${member} ifname) nomaster ip link set dev $(output ${member} ifname) nomaster
''; '';
dependencies = [ primary member ] ++ dependencies; dependencies = [ primary member ];
}; };
in structuredBundle { in bundle {
name = "${primary.name}.members"; name = "${primary.name}.members";
contents = mapAttrs addif members; contents = map addif members;
} }

View file

@ -3,22 +3,17 @@
, ifwait , ifwait
, lib , lib
}: }:
{ ifname, macAddressFromInterface ? null, untagged } : { ifname, macAddressFromInterface ? null } :
let let
inherit (liminix.services) oneshot; inherit (liminix.services) bundle oneshot;
inherit (lib) optional optionalString; inherit (lib) mkOption types optional;
# 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 { in oneshot rec {
name = "${ifname}.link"; name = "${ifname}.link";
up = '' up = ''
${if macAddressFromInterface == null then ${if macAddressFromInterface == null then
"ip link add name ${ifname} type bridge${extra}" "ip link add name ${ifname} type bridge"
else else
"ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge${extra}"} "ip link add name ${ifname} address $(output ${macAddressFromInterface} ether) type bridge"}
${optionalString untagged.enable
"bridge vlan add vid ${toString untagged.pvid} dev ${ifname} pvid untagged self"}
(in_outputs ${name} (in_outputs ${name}
echo ${ifname} > ifname echo ${ifname} > ifname

View file

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

View file

@ -20,10 +20,6 @@ in {
system.service.hostapd = mkOption { system.service.hostapd = mkOption {
type = liminix.lib.types.serviceDefn; type = liminix.lib.types.serviceDefn;
}; };
system.service.hostapd-ready = mkOption {
type = liminix.lib.types.serviceDefn;
};
}; };
config = { config = {
system.service.hostapd = liminix.callService ./service.nix { system.service.hostapd = liminix.callService ./service.nix {
@ -38,12 +34,5 @@ in {
type = types.attrs; 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, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
inherit (pkgs.liminix.services) oneshot;
in { in {
options = { options = {
hostname = mkOption { hostname = mkOption {
@ -11,21 +12,12 @@ in {
default = "liminix"; default = "liminix";
type = types.nonEmptyStr; type = types.nonEmptyStr;
}; };
hostname-script = mkOption { };
description = '' config = {
Script that outputs the system hostname on stdin. services.hostname = oneshot {
''; name = "hostname";
default = pkgs.writeScript "hostname-gen" '' up = "echo ${config.hostname} > /proc/sys/kernel/hostname";
#!/bin/sh down = "true";
echo ${config.hostname}
'';
defaultText = ''
pkgs.writeScript "hostname-gen" '''
#!/bin/sh
echo ''${config.hostname}
'''
'';
type = types.package;
}; };
}; };
} }

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

View file

@ -36,43 +36,22 @@ in
kernel.config = { kernel.config = {
BLK_DEV_INITRD = "y"; BLK_DEV_INITRD = "y";
INITRAMFS_SOURCE = builtins.toJSON "${config.system.outputs.initramfs}"; INITRAMFS_SOURCE = builtins.toJSON "${config.system.outputs.initramfs}";
INITRAMFS_COMPRESSION_ZSTD = "y"; # INITRAMFS_COMPRESSION_LZO = "y";
}; };
system.outputs = { system.outputs = {
initramfs = initramfs =
let let inherit (pkgs.pkgsBuildBuild) gen_init_cpio;
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" {} '' 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 /proc 0755 0 0
dir /dev 0755 0 0 dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1 nod /dev/console 0600 0 0 c 5 1
dir /target 0755 0 0 dir /target 0755 0 0
dir /target/persist 0755 0 0 dir /target/persist 0755 0 0
dir /target/nix 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 /init ${pkgs.preinit}/bin/preinit 0755 0 0
file /failsafe-init ${failsafe-init} 0755 0 0
SPECIALS SPECIALS
find $(cat ${refs}) | ${cpio}/bin/cpio -H newc -o -A -v -O out
mv out $out
''; '';
systemConfiguration = systemConfiguration =
pkgs.systemconfig config.filesystem.contents; pkgs.systemconfig config.filesystem.contents;

View file

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

View file

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

View file

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

View file

@ -1,24 +0,0 @@
## ubus
## ====
##
## ubus is a micro-bus à la D-Bus for all your needs.
{ lib, pkgs, config, ...}:
let
inherit (lib) mkOption types;
inherit (pkgs) liminix;
in {
options = {
system.service.ubus = mkOption {
type = liminix.lib.types.serviceDefn;
};
};
config = {
system.service.ubus = liminix.callService ./service.nix {
package = mkOption {
type = types.package;
default = pkgs.ubus;
};
};
};
}

View file

@ -1,16 +0,0 @@
{
liminix
, writeText
, lib
}:
{ package } :
let
inherit (liminix.services) longrun;
in longrun {
# Long term: make it unique so that user can spawn multiple buses if they want.
name = "ubus";
run = ''
mkdir -p /run/ubus
${package}/bin/ubusd -s /run/ubus/ubus.sock
'';
}

View file

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

View file

@ -2,15 +2,13 @@
liminix liminix
, lib , lib
}: }:
{ ifname, primary, vid, untagged } : { ifname, primary, vid } :
let let
inherit (lib) optionalString;
inherit (liminix.services) oneshot; inherit (liminix.services) oneshot;
in oneshot rec { in oneshot rec {
name = "${ifname}.link"; name = "${ifname}.link";
up = '' up = ''
ip link add link $(output ${primary} ifname) name ${ifname} type vlan id ${vid} 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} ${liminix.networking.ifup name ifname}
(in_outputs ${name} (in_outputs ${name}
echo ${ifname} > ifname echo ${ifname} > ifname

View file

@ -1,24 +1,23 @@
final: prev: final: prev:
let let
isCross = final.stdenv.buildPlatform != final.stdenv.hostPlatform;
crossOnly = pkg : amendFn : if isCross then (amendFn pkg) else pkg;
extraPkgs = import ./pkgs/default.nix { extraPkgs = import ./pkgs/default.nix {
inherit (final) lib callPackage; inherit (final) lib callPackage;
}; };
inherit (final) fetchpatch; inherit (final) fetchpatch;
luaHost = prev.lua5_3.overrideAttrs(o: { lua_no_readline = prev.lua5_3;
name = "lua-tty"; # lua_no_readline = prev.lua5_3.overrideAttrs(o: {
preBuild = '' # name = "lua-tty";
makeFlagsArray+=(PLAT="posix" SYSLIBS="-Wl,-E -ldl" CFLAGS="-O2 -fPIC -DLUA_USE_POSIX -DLUA_USE_DLOPEN") # 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 # # lua in nixpkgs has a postInstall stanza that assumes only
# convert to multi-output # # one output, we need to override that if we're going to
# outputs = ["bin" "man" "out"]; # # convert to multi-output
makeFlags = # # outputs = ["bin" "man" "out"];
builtins.filter (x: (builtins.match "(PLAT|MYLIBS).*" x) == null) # makeFlags =
o.makeFlags; # builtins.filter (x: (builtins.match "(PLAT|MYLIBS).*" x) == null)
}); # o.makeFlags;
# });
s6 = prev.s6.overrideAttrs(o: s6 = prev.s6.overrideAttrs(o:
let let
@ -43,6 +42,7 @@ let
(if o ? patches then o.patches else []) ++ (if o ? patches then o.patches else []) ++
(if patch_needed then [ patch ] else []); (if patch_needed then [ patch ] else []);
}); });
lua = let s = lua_no_readline.override { self = s; }; in s;
in in
extraPkgs // { extraPkgs // {
# liminix library functions # liminix library functions
@ -130,20 +130,9 @@ extraPkgs // {
"CONFIG_LIBNL32=y" "CONFIG_LIBNL32=y"
"CONFIG_PKCS12=y" "CONFIG_PKCS12=y"
"CONFIG_RSN_PREAUTH=y" "CONFIG_RSN_PREAUTH=y"
"CONFIG_UBUS=y"
"CONFIG_TLS=internal" "CONFIG_TLS=internal"
]; ];
h = prev.hostapd.overrideAttrs(o: { h = prev.hostapd.overrideAttrs(o: {
buildInputs = o.buildInputs ++ [ final.libubox final.ubus ];
src = final.fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "hostapd";
rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
# Do not take any patch.
patches = [];
extraConfig = ""; extraConfig = "";
configurePhase = '' configurePhase = ''
cat > hostapd/defconfig <<EOF cat > hostapd/defconfig <<EOF
@ -174,19 +163,10 @@ extraPkgs // {
"CONFIG_LIBNL32=y" "CONFIG_LIBNL32=y"
"CONFIG_PKCS12=y" "CONFIG_PKCS12=y"
"CONFIG_RSN_PREAUTH=y" "CONFIG_RSN_PREAUTH=y"
"CONFIG_UBUS=y" # Required to read the key material for RADIUS.
"CONFIG_TLS=internal" "CONFIG_TLS=openssl"
]; ];
h = prev.hostapd.overrideAttrs(o: { h = prev.hostapd.overrideAttrs(o: {
buildInputs = o.buildInputs ++ [ final.libubox final.ubus ];
src = final.fetchFromGitea {
domain = "git.dgnum.eu";
owner = "DGNum";
repo = "hostapd";
rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
};
patches = [];
extraConfig = ""; extraConfig = "";
configurePhase = '' configurePhase = ''
cat > hostapd/defconfig <<EOF cat > hostapd/defconfig <<EOF
@ -195,37 +175,9 @@ extraPkgs // {
${o.configurePhase} ${o.configurePhase}
''; '';
}); });
in h.override { openssl = null; sqlite = null; }; in h.override { 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: { kexec-tools-static = prev.kexec-tools.overrideAttrs(o: {
# For kexecboot we copy kexec into a ramdisk on the system being # For kexecboot we copy kexec into a ramdisk on the system being
@ -245,7 +197,8 @@ extraPkgs // {
]; ];
}); });
lua = crossOnly prev.lua5_3 (_: luaHost); luaFull = prev.lua;
inherit lua;
mtdutils = prev.mtdutils.overrideAttrs(o: { mtdutils = prev.mtdutils.overrideAttrs(o: {
patches = (if o ? patches then o.patches else []) ++ [ 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: test:
ln -s . anoia ln -s . anoia

View file

@ -4,7 +4,6 @@
, linotify , linotify
, lua , lua
, lualinux , lualinux
, iwinfo
, cpio , cpio
}: }:
let pname = "anoia"; let pname = "anoia";
@ -13,7 +12,7 @@ in stdenv.mkDerivation {
version = "0.1"; version = "0.1";
src = ./.; src = ./.;
nativeBuildInputs = [ fennel cpio ]; nativeBuildInputs = [ fennel cpio ];
buildInputs = with lua.pkgs; [ linotify lualinux iwinfo ]; buildInputs = with lua.pkgs; [ linotify lualinux ];
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
doCheck = true; 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,7 @@ in {
tufted = callPackage ./tufted {}; tufted = callPackage ./tufted {};
libubox = callPackage ./libubox {}; libubox = callPackage ./libubox {};
ubus = callPackage ./ubus {}; ubus = callPackage ./ubus {};
iwinfo = callPackage ./iwinfo {}; usteer = callPackage ./usteer {};
uevent-watch = callPackage ./uevent-watch {}; uevent-watch = callPackage ./uevent-watch {};
usb-modeswitch = callPackage ./usb-modeswitch {}; usb-modeswitch = callPackage ./usb-modeswitch {};
writeAshScript = callPackage ./write-ash-script {}; writeAshScript = callPackage ./write-ash-script {};

View file

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

View file

@ -1,14 +1,11 @@
{ {
lua lua
, netlink-lua , netlink-lua
, lualinux
, iwinfo
, writeFennelScript , writeFennelScript
, runCommand , runCommand
, anoia , anoia
}: }:
runCommand "ifwait" {} '' runCommand "ifwait" {} ''
mkdir -p $out/bin 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

@ -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 , pkgsBuildBuild
, runCommand , runCommand
, cpio , cpio
, writeClosure , writeReferencesToFile
, writeScript , writeScript
} : } :
let let
@ -18,7 +18,7 @@ let
mount -t sysfs none /sys mount -t sysfs none /sys
${busybox}/bin/sh ${busybox}/bin/sh
''; '';
refs = writeClosure [ busybox ]; refs = writeReferencesToFile busybox;
in runCommand "initramfs.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 /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] ++ nativeBuildInputs = [buildPackages.stdenv.cc] ++
(with buildPackages.pkgs; [ (with buildPackages.pkgs; [
rsync bc bison flex pkg-config rsync bc bison flex pkg-config
openssl ncurses.all perl zstd openssl ncurses.all perl
]); ]);
CC = "${stdenv.cc.bintools.targetPrefix}gcc"; CC = "${stdenv.cc.bintools.targetPrefix}gcc";
HOSTCC = with buildPackages.pkgs; HOSTCC = with buildPackages.pkgs;

View file

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

View file

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

View file

@ -39,7 +39,6 @@ let
, contents ? [] , contents ? []
, buildInputs ? [] , buildInputs ? []
, isTrigger ? false , isTrigger ? false
, passthru ? {}
} @ args: } @ args:
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
# we use stdenvNoCC to avoid generating derivations with names # we use stdenvNoCC to avoid generating derivations with names
@ -51,8 +50,6 @@ let
dependencies = builtins.map (d: d.name) dependencies; dependencies = builtins.map (d: d.name) dependencies;
contents = builtins.map (d: d.name) contents; contents = builtins.map (d: d.name) contents;
builder = ./builder.sh; builder = ./builder.sh;
inherit passthru;
}; };
longrun = { longrun = {
@ -103,18 +100,7 @@ let
serviceType = "bundle"; serviceType = "bundle";
inherit contents dependencies; inherit contents dependencies;
}); });
structuredBundle = {
name
, contents ? {}
, dependencies ? []
, ...
} @ args: service (args // {
serviceType = "bundle";
contents = builtins.attrValues contents;
inherit dependencies;
passthru.components = contents;
});
target = bundle; target = bundle;
in { in {
inherit target bundle oneshot longrun output structuredBundle; inherit target bundle oneshot longrun output;
} }

View file

@ -1,5 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -Eeuo pipefail
ssh_command=${SSH_COMMAND-ssh} ssh_command=${SSH_COMMAND-ssh}
@ -14,24 +13,19 @@ case "$1" in
reboot="soft" reboot="soft"
shift shift
;; ;;
"--root")
root_prefix="$2"
shift
shift
;;
esac esac
target_host=$1 target_host=$1
shift shift
if [ -z "$target_host" ] ; then 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 exit 1
fi fi
if toplevel=$(nix-build "$@" -A outputs.systemConfiguration --no-out-link); then if toplevel=$(nix-build "$@" -A outputs.systemConfiguration --no-out-link); then
echo systemConfiguration $toplevel 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 $ssh_command $target_host $toplevel/bin/install
case "$reboot" in case "$reboot" in
reboot) reboot)

View file

@ -4,13 +4,9 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/stat.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <dirent.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ #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); 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 banner[] = "Running pre-init...\n";
char buf[COMMAND_LINE_SIZE]; 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)); AVER(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts));
} else { } else {
if(mount(opts.device, "/target/persist", opts.fstype, 0, opts.mount_opts) < 0) { 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)); 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)); "bind", MS_BIND, NULL));
char *exec_args[] = { "activate", "/target", NULL }; char *exec_args[] = { "activate", "/target", NULL };
if (fork_exec("/target/persist/activate", exec_args) < 0) { AVER(fork_exec("/target/persist/activate", exec_args));
ERR("failed to activate the system\n");
pr_u32(errno); ERR ( " - "); ERR(strerror(errno)); ERR("\n");
goto failsafe;
}
AVER(chdir("/target")); AVER(chdir("/target"));
AVER(mount("/target", "/", "bind", MS_BIND | MS_REC, NULL)); 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)); 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(); die();
} }

View file

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

View file

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

36
pkgs/usteer/default.nix Normal file
View file

@ -0,0 +1,36 @@
{
lib,
stdenv,
fetchFromGitHub,
cmake,
json_c,
libpcap,
libubox,
ubus,
}:
stdenv.mkDerivation rec {
pname = "usteer";
version = "unstable-04-09-2024";
src = fetchFromGitHub {
owner = "openwrt";
repo = "usteer";
rev = "e218150979b40a1b3c59ad0aaa3bbb943814db1e";
hash = "sha256-shbN5Wp7m/olr0OcckcPk11yXnJxpnllXqi/bw+X7gM=";
};
nativeBuildInputs = [
cmake
];
buildInputs = [ ubus libpcap libubox json_c ];
meta = {
description = "";
homepage = "https://github.com/openwrt/usteer";
maintainers = with lib.maintainers; [ raitobezarius ];
mainProgram = "usteer";
platforms = lib.platforms.all;
};
}

View file

@ -27,7 +27,7 @@ name :
echo "#!${lua}/bin/lua ${luaFlags}" echo "#!${lua}/bin/lua ${luaFlags}"
echo "package.path = ${lib.strings.escapeShellArg (builtins.concatStringsSep "" luapath)} .. package.path" echo "package.path = ${lib.strings.escapeShellArg (builtins.concatStringsSep "" luapath)} .. package.path"
echo "package.cpath = ${lib.strings.escapeShellArg (builtins.concatStringsSep "" luacpath)} .. package.cpath" 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} fennel ${if correlate then "--correlate" else ""} --compile ${source}
) > ${name}.lua ) > ${name}.lua
''; '';

View file

@ -10,5 +10,4 @@
tftpboot = import ./tftpboot/test.nix; tftpboot = import ./tftpboot/test.nix;
updown = import ./updown/test.nix; updown = import ./updown/test.nix;
inout = import ./inout/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/"; device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix; liminix-config = ./configuration.nix;
}).outputs.vmroot; }).outputs.vmroot;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; }; pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" { in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
expect expect

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,7 +7,6 @@ in rec {
../../modules/wlan.nix ../../modules/wlan.nix
../../modules/hostapd ../../modules/hostapd
../../modules/network ../../modules/network
./wpa_supplicant.nix
]; ];
services.hostap = config.system.service.hostapd.build { services.hostap = config.system.service.hostapd.build {
@ -28,21 +27,5 @@ in rec {
}; };
}; };
services.wpa_supplicant = config.system.service.wpa_supplicant.build { defaultProfile.packages = with pkgs; [ tcpdump ] ;
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,11 +3,10 @@
, nixpkgs , nixpkgs
}: }:
let img = (import liminix { let img = (import liminix {
inherit nixpkgs; device = import "${liminix}/devices/qemu-armv7l/";
device = import "${liminix}/devices/qemu/";
liminix-config = ./configuration.nix; liminix-config = ./configuration.nix;
}).outputs.default; }).outputs.default;
pkgs = import nixpkgs { overlays = [(import ../../overlay.nix)]; }; pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
in pkgs.runCommand "check" { in pkgs.runCommand "check" {
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
expect socat expect socat

View file

@ -14,10 +14,10 @@ expect {
} }
expect "#" expect "#"
while { $FINISHED < 10 } { 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 { 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 } "not_present" { send_user "waiting ...\n" ; sleep 5 }
} }
set FINISHED [ expr $FINISHED + 1 ] 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;
};
};
}