Compare commits

..

1 commit

Author SHA1 Message Date
Raito Bezarius
54bcc78a96 limiswitch: init
All checks were successful
build liminix / build_vm_qemu_mips (pull_request) Successful in 29s
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-17 13:48:38 +02:00
49 changed files with 1302 additions and 305 deletions

View file

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

4
ci.nix
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

1
pkgs/limiswitch/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target/

539
pkgs/limiswitch/Cargo.lock generated Normal file
View file

@ -0,0 +1,539 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "console"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indicatif"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
dependencies = [
"console",
"instant",
"number_prefix",
"portable-atomic",
"unicode-width",
"vt100",
]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "limiswitch"
version = "0.1.0"
dependencies = [
"clap",
"thiserror",
"tracing",
"tracing-indicatif",
]
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "portable-atomic"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265"
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-indicatif"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "069580424efe11d97c3fef4197fa98c004fa26672cc71ad8770d224e23b1951d"
dependencies = [
"indicatif",
"tracing",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vt100"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274de"
dependencies = [
"itoa",
"log",
"unicode-width",
"vte",
]
[[package]]
name = "vte"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197"
dependencies = [
"arrayvec",
"utf8parse",
"vte_generate_state_changes",
]
[[package]]
name = "vte_generate_state_changes"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

View file

@ -0,0 +1,10 @@
[package]
name = "limiswitch"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.5.17", features = ["derive"] }
thiserror = "1.0.63"
tracing = { version = "0.1.40", features = ["max_level_debug", "release_max_level_info"] }
tracing-indicatif = "0.3.6"

View file

@ -0,0 +1,28 @@
use std::path::Path;
use super::state::OSOperState;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ChannelError {
}
pub type Result<V> = std::result::Result<V, ChannelError>;
/// An interaction channel enable the program to communicate with the target device
/// and perform side-effects, e.g. gather information, write bytes to some flash, etc.
pub trait InteractionChannel {
fn execute(&self, cmd: &str) -> String;
fn read_file(&self, path: &Path) -> String;
fn has_executable_in_path(&self, executable: &str) -> bool;
fn has_directory(&self, path: &Path) -> bool;
fn infer_operational_state(&self) -> Result<Option<OSOperState>>;
fn get_kernel_log(&self) -> String;
}
// struct SSH;
// impl InteractionChannel for SSH {}
//
// struct Serial;
// impl InteractionChannel for Serial {}
//
// struct Agent;
// impl InteractionChannel for Agent {}

View file

@ -0,0 +1,184 @@
use super::channels::InteractionChannel;
use super::state::{OSOperState, DistributionType};
use thiserror::Error;
pub struct Device {
channel: Box<dyn InteractionChannel>,
operational_state: Option<OSOperState>,
}
#[derive(Debug, Error)]
pub enum DeviceError {
#[error("The device is in an unknown operational state at the operating system level")]
UnknownOperationalState,
#[error("The device is in an unsupported operational state at the operating system level: {0:?}")]
UnsupportedOperationalState(OSOperState),
#[error("The device type could not be inferred: unsupported device?")]
UnknownDeviceType,
#[error("This device does not have a MTD-based partition layout: this is unsupported")]
UnsupportedPartitionLayout,
#[error("This device has an unexpected partition layout with respect to its device type")]
UnexpectedPartitionLayout,
}
pub type Result<V> = std::result::Result<V, DeviceError>;
impl Device {
pub fn open_uri(uri: String) -> Self {
}
pub fn new(channel: Box<dyn InteractionChannel>) -> Self {
Device {
channel,
operational_state: None
}
}
fn gather_os_operational_state(&self) -> Result<OSOperState> {
// 1. Ask the underlying layer if it can know what is the current operational state.
// Returns it.
let inferred_oper_state = self.channel.infer_operational_state()?;
// 2. If it cannot guess, it means it's either a recovery or a userspace.
// 3. Run a command to determine if we have a busybox.
let has_busybox: bool = self.channel.has_executable_in_path("busybox");
// 4. If we have no busybox, fail by explaining that we have unknown OS oper state.
if !has_busybox {
return Err(DeviceError::UnknownOperationalState);
}
// 5. If we have a busybox,
// (1) check for the existence of /nix/store → Liminix.
let has_nix_store: bool = self.channel.has_directory("/nix/store");
if has_nix_store {
return Ok(OSOperState::Userspace(DistributionType::Liminix {
revision: self.channel.read_file("/etc/liminix-version".into()),
nixpkgs_revision: self.channel.read_file("/etc/nixpkgs-version".into()),
}))
}
// TODO: (2) check for the existence of OpenWrt specific → ...
// (3) return unknown.
Ok(OSOperState::Userspace(DistributionType::Unknown))
}
fn gather_device_type(&self) -> Result<crate::state::DeviceType> {
// Assert we are in Liminix or OpenWRT.
if !matches!(self.operational_state, Some(OSOperState::Userspace(DistributionType::Liminix { .. })) | Some(OSOperState::Userspace(DistributionType::OpenWrt { .. }))) {
if self.operational_state.is_some() {
return Err(DeviceError::UnsupportedOperationalState(self.operational_state.unwrap()));
} else {
return Err(DeviceError::UnknownOperationalState);
}
}
// Read the kernel log and find "Machine is XYZ".
let kernel_log = self.channel.get_kernel_log();
// Use a regex to find "Machine is ..."
let machine_name: String = "";
match machine_name.as_str() {
"Zyxel NWA50AX" => Ok(crate::state::DeviceType::NWA50AX),
_ => Ok(crate::state::DeviceType::Custom(machine_name))
}
}
fn gather_partition_layout(&self) -> Result<super::state::PartitionLayout> {
let mtd_data = self.channel.execute("cat /proc/mtd");
// Assert this is a MTD-based system.
// Parse: cat /proc/mtd
}
fn gather_running_image_type(&self) -> Result<super::state::ImageType> {
// Assert we know at least one ABSchemeConfiguration partition.
// If not, warn about this.
//
// Assume primary.
//
// If we have an ABSchemeConfiguration partition, look for it.
// Perform static dispatch for every device, parse the result.
}
pub fn gather_runtime_state(&mut self) -> Result<super::state::RuntimeState> {
// 1. Determine OS operational state
// If it's in any of the wrong state, report error.
let os_oper_state = self.gather_os_operational_state()?;
match os_oper_state {
OSOperState::UBoot | OSOperState::Recovery | OSOperState::KernelPanicked(_) => return Err(DeviceError::UnsupportedOperationalState(os_oper_state)),
_ => {}
}
self.operational_state = Some(os_oper_state);
// 2. Determine device type.
let dtype = self.gather_device_type()?;
// 3. Determine partition layout
let playout = self.gather_partition_layout()?;
// and match it with one of the known partition layouts for that device type.
if !dtype.is_compatible_with(playout) {
return Err(DeviceError::UnexpectedPartitionLayout);
}
// 4. Determine running image type given the device type.
let running_itype = self.gather_running_image_type()?;
Ok(crate::state::RuntimeState::new(dtype, playout, running_itype))
}
}
#[cfg(test)]
mod tests {
use std::collections::{HashMap, HashSet};
use crate::{channels::InteractionChannel, state::OSOperState};
use super::Device;
#[derive(Default)]
struct FakeChannel {
pub oper_state: Option<OSOperState>,
pub file_contents: HashMap<std::path::PathBuf, String>,
pub kernel_log: Option<String>,
pub available_executables: HashSet<String>,
pub available_directories: HashSet<std::path::PathBuf>
}
impl InteractionChannel for FakeChannel {
fn infer_operational_state(&self) -> Result<Option<crate::state::OSOperState>, crate::channels::ChannelError> {
Ok(self.oper_state.clone())
}
fn execute(&self, cmd: &str) -> String {
""
}
fn has_executable_in_path(&self, executable: &str) -> bool {
self.available_executables.contains(executable)
}
fn get_kernel_log(&self) -> String {
self.kernel_log
}
fn read_file(&self, path: &std::path::Path) -> String {
self.file_contents.get(path).unwrap().to_string()
}
fn has_directory(&self, path: &std::path::Path) -> bool {
self.available_directories.contains(path)
}
}
// Create a fake interaction channel that can mock things.
fn test_parse_kernel_log_for_machine_type() {
let channel = Box::new(FakeChannel {
oper_state: None,
kernel_log: include_str!("tests/kernel.log"),
..Default::default()
});
let device = Device::new(channel);
let dtype = device.gather_device_type()?;
}
fn test_parse_mtd_partition_layout() {
}
fn test_parse_disk_state() {
}
fn test_parse_memory_state() {
}
}

View file

@ -0,0 +1,83 @@
use thiserror::Error;
use clap::Parser;
mod channels;
mod interaction;
mod state;
#[derive(Debug, Error)]
enum DeploymentError {
#[error("During information gathering error, we encountered a device-specific error: {0}")]
InformationGatheringError(
#[source]
interaction::DeviceError
),
#[error("Delta closure does not fit on the target partition, levitation is needed but cannot be enabled automatically yet")]
LevitationRequired,
}
struct Toplevel {
made_for: state::DeviceType,
path: String
}
#[derive(Parser, Debug)]
#[command(version, about)]
struct Args {
/// Top-level path for the deployment
toplevel_path: String,
/// Connection URI to the target
/// e.g. `serial:///dev/ttyUSB0`
/// e.g. `ssh://root@...`
connection_uri: String,
#[arg(long, default_value_t = false)]
dry_run: bool,
}
fn main() {
let args = Args::parse();
// 1. Open the toplevel_path
// Obtain the theoretical target information, e.g. what device is it.
// Populate a `Toplevel` structure.
// 2. Connect to the connection URI
let device = Device::open_uri(args.connection_uri)?;
// Run information gathering procedure.
let runtime_state = device.gather_runtime_state()?;
// Compare theoretical target information with actual target information.
// toplevel.is_compatible_with(runtime_state);
// Fail if it's wrong.
// 3. Compute the delta closure to send.
// let store_paths = device.get_store_paths_for(ImageState::Secondary);
// let delta = toplevel.delta(store_paths);
// 4. Compute the size of the delta closure
// let size = delta.size();
// Verify if it fits in the RAM, if not, fail.
// Verify if it fits in the target disk, if not, warn.
//
// 5. If it doesn't fit in the target disk, verify if levitation is available.
// If not, fail.
//
// 6. If it doesn't fit and levitation is available, propose levitation as a deployment method
// and go back to 2 with a levitation parameter, i.e. `?actual-system=/mnt` or something
// like that.
//
// 7. If it fits in the target disk, copy the contents of the store in the target.
// Under A/B:
// - Identify which image are we running, whether there's a success image and are we on it, if
// not, propose to reboot in the success image and wait for the device to be available again.
//
// - Instead of writing the contents of the store in the target, propose to mount the B store,
// write the contents over there, there's no need for levitation anymore.
//
// - Write the kernel image to the B partition as well and verify that its size fits the MTD
// sizes.
//
// - Put the new image under test, reboot into it, let the bootloader handle it. Wait for
// successful boot to the new image, if not, signal that deployment failed to pass A/B checks.
tracing::info!("Test {}", args.toplevel_path);
}

View file

@ -0,0 +1,91 @@
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub enum DistributionType {
Liminix {
revision: String,
nixpkgs_revision: String
},
OpenWrt {
version: String
},
Unknown
}
#[derive(Debug, Clone)]
pub enum OSOperState {
UBoot,
Recovery,
Userspace(DistributionType),
KernelPanicked(String),
}
pub enum ImageType {
Primary,
Secondary
}
pub enum DeviceType {
NWA50AX,
Custom(String)
}
pub enum FilesystemType {
UBI,
JFFS2,
}
pub enum ABSchemeType {
Zyxel
}
pub enum PartitionType {
UBootFirmware,
UBootConfig,
/// kernel + rootfs concatenated.
Image {
variant: ImageType
},
Kernel {
variant: ImageType
},
RootFs {
fs_type: FilesystemType,
variant: ImageType
},
UserData,
Logs,
Vendor,
ABSchemeConfiguration {
variant: ABSchemeType
},
DeviceSpecificData
}
pub struct Partition {
size: u64,
offset: u64,
name: String,
r#type: PartitionType
}
pub type PartitionLayout = HashMap<String, Partition>;
pub struct RuntimeState {
device_type: DeviceType,
partition_layout: PartitionLayout,
running_image: ImageType,
memory_state: MemoryState,
disk_state: DiskState
}
impl RuntimeState {
pub fn new(device_type: DeviceType, partition_layout: PartitionLayout, running_image: ImageType) -> Self {
Self {
device_type,
partition_layout,
running_image
}
}
}

View file

@ -0,0 +1,3 @@
total used free shared buff/cache available
Mem: 250920 36056 201556 1452 13308 205368
Swap: 0 0 0

View file

@ -0,0 +1,295 @@
<5>[ 0.000000] Linux version 5.15.137 (nixbld@liminix.builder) (mipsel-unknown-linux-musl-gcc (GCC) 13.3.0, GNU ld (GNU Binutils) 2.42) #1 SMP Mon Aug 26 18:09:43 UTC 2024
<6>[ 0.000000] SoC Type: MediaTek MT7621 ver:1 eco:3
<6>[ 0.000000] printk: bootconsole [early0] enabled
<6>[ 0.000000] CPU0 revision is: 0001992f (MIPS 1004Kc)
<6>[ 0.000000] MIPS: machine is ZyXEL NWA50AX
<6>[ 0.000000] Initrd not found or empty - disabling initrd
<6>[ 0.000000] Detected 1 available secondary CPU(s)
<6>[ 0.000000] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.
<6>[ 0.000000] Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
<4>[ 0.000000] MIPS secondary cache 256kB, 8-way, linesize 32 bytes.
<6>[ 0.000000] Zone ranges:
<6>[ 0.000000] Normal [mem 0x0000000000000000-0x000000000fffffff]
<6>[ 0.000000] Movable zone start for each node
<6>[ 0.000000] Early memory node ranges
<6>[ 0.000000] node 0: [mem 0x0000000000000000-0x000000000fffffff]
<6>[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x000000000fffffff]
<6>[ 0.000000] percpu: Embedded 10 pages/cpu s11184 r8192 d21584 u40960
<7>[ 0.000000] pcpu-alloc: s11184 r8192 d21584 u40960 alloc=10*4096
<7>[ 0.000000] pcpu-alloc: [0] 0 [0] 1
<6>[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 65024
<5>[ 0.000000] Kernel command line: console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=ubi0:rootfs rootfstype=ubifs fw_devlink=off ubi.mtd=ubi_a ubi.mtd=ubi_b rootalt=ubi1:rootfs
<5>[ 0.000000] Unknown kernel command line parameters "rootalt=ubi1:rootfs", will be passed to user space.
<6>[ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes, linear)
<6>[ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes, linear)
<6>[ 0.000000] Writing ErrCtl register=000307c0
<6>[ 0.000000] Readback ErrCtl register=000307c0
<6>[ 0.000000] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
<6>[ 0.000000] Memory: 249660K/262144K available (6690K kernel code, 620K rwdata, 1272K rodata, 1260K init, 215K bss, 12484K reserved, 0K cma-reserved)
<6>[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
<6>[ 0.000000] rcu: Hierarchical RCU implementation.
<6>[ 0.000000] rcu: RCU event tracing is enabled.
<6>[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
<6>[ 0.000000] NR_IRQS: 256
<6>[ 0.000000] clocksource: GIC: mask: 0xffffffffffffffff max_cycles: 0xcaf478abb4, max_idle_ns: 440795247997 ns
<6>[ 0.000004] sched_clock: 64 bits at 880MHz, resolution 1ns, wraps every 4398046511103ns
<6>[ 0.008218] Console: colour dummy device 80x25
<6>[ 0.012632] Calibrating delay loop... 583.68 BogoMIPS (lpj=1167360)
<6>[ 0.046814] pid_max: default: 32768 minimum: 301
<6>[ 0.051583] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
<6>[ 0.058813] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
<6>[ 0.068777] rcu: Hierarchical SRCU implementation.
<6>[ 0.074116] smp: Bringing up secondary CPUs ...
<6>[ 0.079353] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.
<6>[ 0.079374] Primary data cache 32kB, 4-way, PIPT, no aliases, linesize 32 bytes
<4>[ 0.079388] MIPS secondary cache 256kB, 8-way, linesize 32 bytes.
<6>[ 0.079433] CPU1 revision is: 0001992f (MIPS 1004Kc)
<6>[ 0.106815] Synchronize counters for CPU 1: done.
<6>[ 0.137415] smp: Brought up 1 node, 2 CPUs
<6>[ 0.142174] devtmpfs: initialized
<6>[ 0.149141] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
<6>[ 0.158851] futex hash table entries: 512 (order: 2, 16384 bytes, linear)
<6>[ 0.165686] pinctrl core: initialized pinctrl subsystem
<6>[ 0.172363] NET: Registered PF_NETLINK/PF_ROUTE protocol family
<7>[ 0.195326] FPU Affinity set after 4688 emulations
<6>[ 0.210941] vgaarb: loaded
<6>[ 0.213833] pps_core: LinuxPPS API ver. 1 registered
<6>[ 0.218718] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
<6>[ 0.227852] PTP clock support registered
<6>[ 0.232996] clocksource: Switched to clocksource GIC
<6>[ 0.247916] NET: Registered PF_INET protocol family
<6>[ 0.253106] IP idents hash table entries: 4096 (order: 3, 32768 bytes, linear)
<6>[ 0.261109] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 6144 bytes, linear)
<6>[ 0.269438] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
<6>[ 0.277109] TCP established hash table entries: 2048 (order: 1, 8192 bytes, linear)
<6>[ 0.284734] TCP bind hash table entries: 2048 (order: 2, 16384 bytes, linear)
<6>[ 0.291833] TCP: Hash tables configured (established 2048 bind 2048)
<6>[ 0.298233] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
<6>[ 0.304728] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
<6>[ 0.311863] NET: Registered PF_UNIX/PF_LOCAL protocol family
<6>[ 0.317488] PCI: CLS 0 bytes, default 32
<5>[ 0.322010] Initialise system trusted keyrings
<6>[ 0.326848] workingset: timestamp_bits=30 max_order=16 bucket_order=0
<6>[ 0.338689] squashfs: version 4.0 (2009/01/31) Phillip Lougher
<6>[ 0.344647] NET: Registered PF_ALG protocol family
<5>[ 0.349383] Key type asymmetric registered
<5>[ 0.353437] Asymmetric key parser 'x509' registered
<6>[ 0.358339] io scheduler mq-deadline registered
<6>[ 0.362797] io scheduler kyber registered
<6>[ 0.368367] mt7621_gpio 1e000600.gpio: registering 32 gpios
<6>[ 0.374144] mt7621_gpio 1e000600.gpio: registering 32 gpios
<6>[ 0.379906] mt7621_gpio 1e000600.gpio: registering 32 gpios
<6>[ 0.385758] mt7621-pci 1e140000.pcie: host bridge /pcie@1e140000 ranges:
<6>[ 0.392397] mt7621-pci 1e140000.pcie: No bus range found for /pcie@1e140000, using [bus 00-ff]
<6>[ 0.401153] mt7621-pci 1e140000.pcie: MEM 0x0060000000..0x006fffffff -> 0x0060000000
<6>[ 0.409262] mt7621-pci 1e140000.pcie: IO 0x001e160000..0x001e16ffff -> 0x0000000000
<6>[ 0.740953] mt7621-pci 1e140000.pcie: pcie2 no card, disable it (RST & CLK)
<6>[ 0.747846] mt7621-pci 1e140000.pcie: PCIE0 enabled
<6>[ 0.752676] mt7621-pci 1e140000.pcie: PCIE1 enabled
<6>[ 0.757535] PCI coherence region base: 0x60000000, mask/settings: 0xf0000002
<6>[ 0.764608] mt7621-pci 1e140000.pcie: PCI host bridge to bus 0000:00
<6>[ 0.770890] pci_bus 0000:00: root bus resource [bus 00-ff]
<6>[ 0.776323] pci_bus 0000:00: root bus resource [mem 0x60000000-0x6fffffff]
<6>[ 0.783159] pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
<6>[ 0.789337] pci 0000:00:00.0: [0e8d:0801] type 01 class 0x060400
<6>[ 0.795285] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x7fffffff]
<6>[ 0.801504] pci 0000:00:00.0: reg 0x14: [mem 0x60600000-0x6060ffff]
<6>[ 0.807784] pci 0000:00:00.0: supports D1
<6>[ 0.811724] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
<6>[ 0.817750] pci 0000:00:01.0: [0e8d:0801] type 01 class 0x060400
<6>[ 0.823698] pci 0000:00:01.0: reg 0x10: [mem 0x00000000-0x7fffffff]
<6>[ 0.829912] pci 0000:00:01.0: reg 0x14: [mem 0x60610000-0x6061ffff]
<6>[ 0.836183] pci 0000:00:01.0: supports D1
<6>[ 0.840122] pci 0000:00:01.0: PME# supported from D0 D1 D3hot
<6>[ 0.847184] pci 0000:01:00.0: [14c3:7916] type 00 class 0x000280
<6>[ 0.853151] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x000fffff 64bit pref]
<6>[ 0.860308] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x00003fff 64bit pref]
<6>[ 0.867491] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x00000fff 64bit pref]
<6>[ 0.874765] pci 0000:01:00.0: supports D1 D2
<6>[ 0.878963] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[ 0.885579] pci 0000:01:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0000:00:00.0 (capable of 4.000 Gb/s with 5.0 GT/s PCIe x1 link)
<6>[ 0.900515] pci 0000:00:00.0: ASPM: current common clock configuration is inconsistent, reconfiguring
<6>[ 0.922057] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
<6>[ 0.927222] pci 0000:00:00.0: bridge window [io 0x0000-0x0fff]
<6>[ 0.933266] pci 0000:00:00.0: bridge window [mem 0x60000000-0x600fffff]
<6>[ 0.940002] pci 0000:00:00.0: bridge window [mem 0x60100000-0x602fffff pref]
<6>[ 0.947179] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
<6>[ 0.953911] pci 0000:02:00.0: [14c3:7915] type 00 class 0x000280
<6>[ 0.959871] pci 0000:02:00.0: reg 0x10: [mem 0x00000000-0x000fffff 64bit pref]
<6>[ 0.967032] pci 0000:02:00.0: reg 0x18: [mem 0x00000000-0x00003fff 64bit pref]
<6>[ 0.974204] pci 0000:02:00.0: reg 0x20: [mem 0x00000000-0x00000fff 64bit pref]
<6>[ 0.981494] pci 0000:02:00.0: supports D1 D2
<6>[ 0.985692] pci 0000:02:00.0: PME# supported from D0 D1 D2 D3hot D3cold
<6>[ 0.992301] pci 0000:02:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0000:00:01.0 (capable of 4.000 Gb/s with 5.0 GT/s PCIe x1 link)
<6>[ 1.007240] pci 0000:00:01.0: ASPM: current common clock configuration is inconsistent, reconfiguring
<6>[ 1.026047] pci 0000:00:01.0: PCI bridge to [bus 02-ff]
<6>[ 1.031209] pci 0000:00:01.0: bridge window [io 0x0000-0x0fff]
<6>[ 1.037254] pci 0000:00:01.0: bridge window [mem 0x60300000-0x603fffff]
<6>[ 1.043989] pci 0000:00:01.0: bridge window [mem 0x60400000-0x605fffff pref]
<6>[ 1.051164] pci_bus 0000:02: busn_res: [bus 02-ff] end is updated to 02
<6>[ 1.057780] pci 0000:00:00.0: BAR 0: no space for [mem size 0x80000000]
<6>[ 1.064319] pci 0000:00:00.0: BAR 0: failed to assign [mem size 0x80000000]
<6>[ 1.071234] pci 0000:00:01.0: BAR 0: no space for [mem size 0x80000000]
<6>[ 1.077796] pci 0000:00:01.0: BAR 0: failed to assign [mem size 0x80000000]
<6>[ 1.084709] pci 0000:00:00.0: BAR 8: assigned [mem 0x60000000-0x600fffff]
<6>[ 1.091459] pci 0000:00:00.0: BAR 9: assigned [mem 0x60100000-0x602fffff pref]
<6>[ 1.098629] pci 0000:00:01.0: BAR 8: assigned [mem 0x60300000-0x603fffff]
<6>[ 1.105363] pci 0000:00:01.0: BAR 9: assigned [mem 0x60400000-0x605fffff pref]
<6>[ 1.112529] pci 0000:00:00.0: BAR 1: assigned [mem 0x60600000-0x6060ffff]
<6>[ 1.119276] pci 0000:00:01.0: BAR 1: assigned [mem 0x60610000-0x6061ffff]
<6>[ 1.126014] pci 0000:00:00.0: BAR 7: assigned [io 0x0000-0x0fff]
<6>[ 1.132055] pci 0000:00:01.0: BAR 7: assigned [io 0x1000-0x1fff]
<6>[ 1.138119] pci 0000:01:00.0: BAR 0: assigned [mem 0x60100000-0x601fffff 64bit pref]
<6>[ 1.145810] pci 0000:01:00.0: BAR 2: assigned [mem 0x60200000-0x60203fff 64bit pref]
<6>[ 1.153506] pci 0000:01:00.0: BAR 4: assigned [mem 0x60204000-0x60204fff 64bit pref]
<6>[ 1.161188] pci 0000:00:00.0: PCI bridge to [bus 01]
<6>[ 1.166096] pci 0000:00:00.0: bridge window [io 0x0000-0x0fff]
<6>[ 1.172144] pci 0000:00:00.0: bridge window [mem 0x60000000-0x600fffff]
<6>[ 1.178887] pci 0000:00:00.0: bridge window [mem 0x60100000-0x602fffff pref]
<6>[ 1.186066] pci 0000:02:00.0: BAR 0: assigned [mem 0x60400000-0x604fffff 64bit pref]
<6>[ 1.193762] pci 0000:02:00.0: BAR 2: assigned [mem 0x60500000-0x60503fff 64bit pref]
<6>[ 1.201457] pci 0000:02:00.0: BAR 4: assigned [mem 0x60504000-0x60504fff 64bit pref]
<6>[ 1.209139] pci 0000:00:01.0: PCI bridge to [bus 02]
<6>[ 1.214053] pci 0000:00:01.0: bridge window [io 0x1000-0x1fff]
<6>[ 1.220095] pci 0000:00:01.0: bridge window [mem 0x60300000-0x603fffff]
<6>[ 1.226838] pci 0000:00:01.0: bridge window [mem 0x60400000-0x605fffff pref]
<6>[ 1.293553] Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
<6>[ 1.301659] printk: console [ttyS0] disabled
<6>[ 1.305989] 1e000c00.uartlite: ttyS0 at MMIO 0x1e000c00 (irq = 15, base_baud = 3125000) is a 16550A
<6>[ 1.315005] printk: console [ttyS0] enabled
<6>[ 1.323276] printk: bootconsole [early0] disabled
<6>[ 1.334191] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
<6>[ 1.340589] nand: Macronix MX30LF1G28AD
<6>[ 1.344427] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 128
<6>[ 1.352085] mt7621-nand 1e003000.nand: ECC strength adjusted to 12 bits
<6>[ 1.361726] Signature found at block 1023 [0x07fe0000]
<6>[ 1.366867] NMBM management region starts at block 960 [0x07800000]
<6>[ 1.378961] First info table with writecount 23 found in block 960
<6>[ 1.402451] Second info table with writecount 23 found in block 963
<6>[ 1.408777] NMBM has been successfully attached
<5>[ 1.413459] 10 fixed-partitions partitions found on MTD device mt7621-nand
<5>[ 1.420736] Creating 10 MTD partitions on "mt7621-nand":
<5>[ 1.426060] 0x000000000000-0x000000080000 : "u-boot"
<5>[ 1.439414] 0x000000080000-0x000000100000 : "u-boot-env"
<5>[ 1.453035] 0x000000100000-0x000000180000 : "factory"
<5>[ 1.466309] 0x000000180000-0x000002980000 : "firmware_a"
<5>[ 2.085213] 2 fixed-partitions partitions found on MTD device firmware_a
<5>[ 2.091937] Creating 2 MTD partitions on "firmware_a":
<5>[ 2.097081] 0x000000000000-0x000000800000 : "kernel_a"
<5>[ 2.225386] 0x000000800000-0x000002800000 : "ubi_a"
<5>[ 2.721495] 0x000002980000-0x000005180000 : "firmware_b"
<5>[ 3.340246] 2 fixed-partitions partitions found on MTD device firmware_b
<5>[ 3.346968] Creating 2 MTD partitions on "firmware_b":
<5>[ 3.352107] 0x000000000000-0x000000800000 : "kernel_b"
<5>[ 3.480263] 0x000000800000-0x000002800000 : "ubi_b"
<5>[ 3.975666] 0x000005180000-0x000006580000 : "rootfs_data"
<5>[ 4.287830] 0x000006580000-0x000007280000 : "logs"
<5>[ 4.492219] 0x000007280000-0x000007700000 : "vendor-myzyxel"
<5>[ 4.567305] 0x000007700000-0x000007780000 : "bootconfig"
<5>[ 4.580784] 0x000007780000-0x000007800000 : "mrd"
<6>[ 4.728861] mt7530-mdio mdio-bus:1f: MT7530 adapts as multi-chip module
<6>[ 4.739452] mtk_soc_eth 1e100000.ethernet eth0: mediatek frame engine at 0xbe100000, irq 17
<6>[ 4.749780] NET: Registered PF_INET6 protocol family
<6>[ 4.756356] Segment Routing with IPv6
<6>[ 4.760155] In-situ OAM (IOAM) with IPv6
<6>[ 4.764191] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
<6>[ 4.770812] NET: Registered PF_PACKET protocol family
<6>[ 4.776330] 8021q: 802.1Q VLAN Support v1.8
<5>[ 4.781230] Loading compiled-in X.509 certificates
<5>[ 4.797729] Loaded X.509 cert 'Build time autogenerated kernel key: 3cb1578c6bb232a0582cf98f15a4972f913c1af3'
<3>[ 4.807668] Problem parsing in-kernel X.509 certificate list
<5>[ 4.817397] Key type encrypted registered
<6>[ 4.824007] mt7530-mdio mdio-bus:1f: MT7530 adapts as multi-chip module
<6>[ 4.846395] mt7530-mdio mdio-bus:1f: configuring for fixed/rgmii link mode
<6>[ 4.854154] mt7530-mdio mdio-bus:1f: Link is Up - 1Gbps/Full - flow control rx/tx
<6>[ 4.859149] mt7530-mdio mdio-bus:1f lan (uninitialized): PHY [mt7530-0:04] driver [MediaTek MT7530 PHY] (irq=19)
<6>[ 4.873461] DSA: tree 0 setup
<5>[ 4.876884] ubi0: attaching mtd5
<5>[ 5.863729] ubi0: scanning is finished
<5>[ 5.890726] ubi0: attached mtd5 (name "ubi_a", size 32 MiB)
<5>[ 5.896336] ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
<5>[ 5.903205] ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
<5>[ 5.909985] ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
<5>[ 5.916945] ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
<5>[ 5.922942] ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
<5>[ 5.930154] ubi0: max/mean erase counter: 126998/126988, WL threshold: 4096, image sequence number: 315532800
<5>[ 5.940050] ubi0: available PEBs: 0, total reserved PEBs: 256, PEBs reserved for bad PEB handling: 19
<5>[ 5.949276] ubi0: background thread "ubi_bgt0d" started, PID 68
<5>[ 5.953015] ubi1: attaching mtd8
<5>[ 6.941903] ubi1: scanning is finished
<5>[ 6.968852] ubi1: attached mtd8 (name "ubi_b", size 32 MiB)
<5>[ 6.974477] ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
<5>[ 6.981349] ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
<5>[ 6.988131] ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096
<5>[ 6.995089] ubi1: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
<5>[ 7.001103] ubi1: user volume: 1, internal volumes: 1, max. volumes count: 128
<5>[ 7.008317] ubi1: max/mean erase counter: 126977/126976, WL threshold: 4096, image sequence number: 315532800
<5>[ 7.018222] ubi1: available PEBs: 0, total reserved PEBs: 256, PEBs reserved for bad PEB handling: 19
<5>[ 7.027455] ubi1: background thread "ubi_bgt1d" started, PID 69
<6>[ 7.038626] Freeing unused kernel image (initmem) memory: 1260K
<4>[ 7.044612] This architecture does not have kernel memory protection.
<6>[ 7.051070] Run /init as init process
<7>[ 7.054740] with arguments:
<7>[ 7.057711] /init
<7>[ 7.059974] with environment:
<7>[ 7.063118] HOME=/
<7>[ 7.065486] TERM=linux
<7>[ 7.068180] rootalt=ubi1:rootfs
<5>[ 7.075382] UBIFS (ubi0:0): Mounting in unauthenticated mode
<5>[ 7.082662] UBIFS (ubi0:0): background thread "ubifs_bgt0_0" started, PID 70
<5>[ 7.204958] UBIFS (ubi0:0): recovery needed
<5>[ 7.601923] UBIFS (ubi0:0): recovery completed
<5>[ 7.606622] UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs"
<5>[ 7.614056] UBIFS (ubi0:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
<5>[ 7.623958] UBIFS (ubi0:0): FS size: 28315648 bytes (27 MiB, 223 LEBs), max 256 LEBs, journal size 4444160 bytes (4 MiB, 35 LEBs)
<5>[ 7.635596] UBIFS (ubi0:0): reserved for root: 0 bytes (0 KiB)
<5>[ 7.641430] UBIFS (ubi0:0): media format: w4/r0 (latest is w5/r0), UUID A68EAB38-9D1E-4184-AEFB-63A0740A6A2D, small LPT model
<4>[ 9.842286] compat: loading out-of-tree module taints kernel.
<5>[ 9.857452] compat: module verification failed: signature and/or required key missing - tainting kernel
<6>[ 9.967488] Loading modules backported from Linux version e2c1a934fd8
<6>[ 9.974025] Backport generated by backports.git dfe0f60ca8a
<5>[ 11.676238] random: chronyd: uninitialized urandom read (1027 bytes read)
<6>[ 11.685221] mtk_soc_eth 1e100000.ethernet eth0: configuring for fixed/rgmii link mode
<6>[ 11.695046] mtk_soc_eth 1e100000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
<6>[ 11.723238] mt7530-mdio mdio-bus:1f lan: configuring for phy/gmii link mode
<6>[ 11.747231] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
<6>[ 12.360030] int: port 1(lan) entered blocking state
<6>[ 12.364996] int: port 1(lan) entered disabled state
<6>[ 12.371531] device lan entered promiscuous mode
<6>[ 12.376119] device eth0 entered promiscuous mode
<6>[ 12.509793] pci 0000:00:00.0: enabling device (0006 -> 0007)
<6>[ 12.515560] mt7915e_hif 0000:01:00.0: enabling device (0000 -> 0002)
<6>[ 12.522443] pci 0000:00:01.0: enabling device (0006 -> 0007)
<6>[ 12.528197] mt7915e 0000:02:00.0: enabling device (0000 -> 0002)
<6>[ 12.630121] mt7915e 0000:02:00.0: HW/SW Version: 0x8a108a10, Build Time: 20220929104113a
<6>[ 12.630121]
<6>[ 13.117498] mt7915e 0000:02:00.0: WM Firmware Version: ____000000, Build Time: 20220929104145
<6>[ 13.225464] mt7915e 0000:02:00.0: WA Firmware Version: DEV_000000, Build Time: 20220929104205
<6>[ 14.924294] mt7530-mdio mdio-bus:1f lan: Link is Up - 1Gbps/Full - flow control off
<5>[ 15.854162] random: crng init done
<6>[ 18.497431] IPv6: ADDRCONF(NETDEV_CHANGE): lan: link becomes ready
<6>[ 18.503953] int: port 1(lan) entered blocking state
<6>[ 18.508961] int: port 1(lan) entered forwarding state
<6>[ 18.520882] IPv6: ADDRCONF(NETDEV_CHANGE): int: link becomes ready
<6>[ 19.726486] int: port 2(wlan0) entered blocking state
<6>[ 19.731712] int: port 2(wlan0) entered disabled state
<6>[ 19.737934] device wlan0 entered promiscuous mode
<6>[ 19.750519] int: port 3(wlan1) entered blocking state
<6>[ 19.755784] int: port 3(wlan1) entered disabled state
<6>[ 19.762121] device wlan1 entered promiscuous mode
<6>[ 19.860627] IPv6: ADDRCONF(NETDEV_CHANGE): wlan1: link becomes ready
<6>[ 19.867243] int: port 3(wlan1) entered blocking state
<6>[ 19.872311] int: port 3(wlan1) entered forwarding state
<6>[ 21.167370] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
<6>[ 21.174100] int: port 2(wlan0) entered blocking state
<6>[ 21.179211] int: port 2(wlan0) entered forwarding state
<6>[319860.057754] mt7530-mdio mdio-bus:1f lan: Link is Down
<6>[319860.071078] int: port 1(lan) entered disabled state
<6>[332932.024408] mt7530-mdio mdio-bus:1f lan: Link is Up - 1Gbps/Full - flow control off
<6>[332932.032293] int: port 1(lan) entered blocking state
<6>[332932.037277] int: port 1(lan) entered forwarding state
<6>[658890.171767] mt7530-mdio mdio-bus:1f lan: Link is Down
<6>[658890.177373] int: port 1(lan) entered disabled state
<6>[751678.748021] mt7530-mdio mdio-bus:1f lan: Link is Up - 1Gbps/Full - flow control off
<6>[751678.755994] int: port 1(lan) entered blocking state
<6>[751678.760989] int: port 1(lan) entered forwarding state

View file

@ -0,0 +1,6 @@
Filesystem 1024-blocks Used Available Use% Mounted on
ubi0:rootfs 24884 20216 4668 81% /persist
ubi0:rootfs 24884 20216 4668 81% /nix
dev 124828 0 124828 0% /dev
tmpfs 125460 1452 124008 1% /run
none 125460 0 125460 0% /tmp

View file

@ -0,0 +1,15 @@
dev: size erasesize name
mtd0: 00080000 00020000 "u-boot"
mtd1: 00080000 00020000 "u-boot-env"
mtd2: 00080000 00020000 "factory"
mtd3: 02800000 00020000 "firmware_a"
mtd4: 00800000 00020000 "kernel_a"
mtd5: 02000000 00020000 "ubi_a"
mtd6: 02800000 00020000 "firmware_b"
mtd7: 00800000 00020000 "kernel_b"
mtd8: 02000000 00020000 "ubi_b"
mtd9: 01400000 00020000 "rootfs_data"
mtd10: 00d00000 00020000 "logs"
mtd11: 00480000 00020000 "vendor-myzyxel"
mtd12: 00080000 00020000 "bootconfig"
mtd13: 00080000 00020000 "mrd"

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