Compare commits

...

24 commits
CI ... main

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
All checks were successful
build liminix / build_zyxel-nwa50ax_mips (pull_request) Successful in 20s
build liminix / build_vm_qemu_mips (pull_request) Successful in 20s
build liminix / test_shell_customization (pull_request) Successful in 22s
build liminix / test_hostapd (pull_request) Successful in 22s
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
21 changed files with 203 additions and 26 deletions

View file

@ -38,3 +38,13 @@ jobs:
run: | run: |
# Enter the shell # Enter the shell
nix-build ci.nix -A wlan 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

View file

@ -12,6 +12,7 @@ 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

@ -4,9 +4,10 @@
{ {
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,11 +4,13 @@
{ lib, pkgs, config, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkEnableOption mkOption types isDerivation hasAttr ; inherit (lib) mkEnableOption mkOption types isDerivation hasAttr concatStringsSep mapAttrsToList;
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 {
@ -22,6 +24,24 @@ 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;
@ -110,7 +130,9 @@ in {
nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem; nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem;
defaultProfile.packages = with pkgs; 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 = [ boot.commandLine = [
"panic=10 oops=panic init=/bin/init loglevel=8" "panic=10 oops=panic init=/bin/init loglevel=8"
@ -181,9 +203,10 @@ 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,8 +9,7 @@
{ lib, pkgs, config, ...}: { lib, pkgs, config, ...}:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types mkEnableOption;
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs) liminix; inherit (pkgs) liminix;
in in
{ {
@ -35,6 +34,20 @@ 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 {

View file

@ -3,17 +3,22 @@
, ifwait , ifwait
, lib , lib
}: }:
{ ifname, macAddressFromInterface ? null } : { ifname, macAddressFromInterface ? null, untagged } :
let let
inherit (liminix.services) bundle oneshot; inherit (liminix.services) oneshot;
inherit (lib) mkOption types optional; 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 { 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" "ip link add name ${ifname} type bridge${extra}"
else 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} (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" "ip" "ipaddr" "iplink" "ipneigh" "iproute" "iprule" "kill" "ifconfig" "ipneigh" "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

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

@ -54,7 +54,7 @@ in
mount -t sysfs none /sys mount -t sysfs none /sys
${busybox}/bin/sh ${busybox}/bin/sh
''; '';
refs = pkgs.writeReferencesToFile busybox; 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

View file

@ -30,6 +30,8 @@ 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,6 +36,7 @@ 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

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

@ -141,7 +141,9 @@ extraPkgs // {
repo = "hostapd"; repo = "hostapd";
rev = "hostap-liminix-integration"; rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI="; hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
}; };
# Do not take any patch.
patches = [];
extraConfig = ""; extraConfig = "";
configurePhase = '' configurePhase = ''
cat > hostapd/defconfig <<EOF cat > hostapd/defconfig <<EOF
@ -184,6 +186,7 @@ extraPkgs // {
rev = "hostap-liminix-integration"; rev = "hostap-liminix-integration";
hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI="; hash = "sha256-5Xi90keCHxvuKR5Q7STuZDzuM9h9ac6aWoXVQYvqkQI=";
}; };
patches = [];
extraConfig = ""; extraConfig = "";
configurePhase = '' configurePhase = ''
cat > hostapd/defconfig <<EOF cat > hostapd/defconfig <<EOF
@ -194,6 +197,30 @@ extraPkgs // {
}); });
in h.override { openssl = null; sqlite = null; }; 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 { wpa_supplicant = prev.wpa_supplicant.override {
dbusSupport = false; dbusSupport = false;
withPcsclite = false; withPcsclite = false;

View file

@ -3,7 +3,7 @@
, pkgsBuildBuild , pkgsBuildBuild
, runCommand , runCommand
, cpio , cpio
, writeReferencesToFile , writeClosure
, 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 = writeReferencesToFile busybox; refs = 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

View file

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

@ -10,4 +10,5 @@
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

@ -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
''