WIP: ap01: towards our VLAN model #181
8 changed files with 143 additions and 54 deletions
|
@ -116,6 +116,13 @@ in
|
|||
pkgs.freeradius
|
||||
pkgs.picocom # for serial access
|
||||
|
||||
# Daemon-less copy closure for Liminix systems.
|
||||
(pkgs.callPackage (sources.liminix + "/pkgs/min-copy-closure") { nix = pkgs.lix; })
|
||||
# Daemon-less garbage collection for Liminix systems.
|
||||
(pkgs.callPackage (sources.liminix + "/pkgs/min-collect-garbage") { nix = pkgs.lix; })
|
||||
# TFTP server, friendly for Nix builds.
|
||||
(pkgs.callPackage (sources.liminix + "/pkgs/tufted") { })
|
||||
|
||||
(pkgs.callPackage ./lib/colmena {
|
||||
colmena = pkgs.callPackage "${sources.colmena}/package.nix" { };
|
||||
})
|
||||
|
|
|
@ -3,16 +3,18 @@ let
|
|||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
services.dhcpv4 = svc.network.dhcp.client.build {
|
||||
services.init-dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = config.services.int;
|
||||
dependencies = [
|
||||
config.services.bridge.components.lan
|
||||
];
|
||||
};
|
||||
|
||||
services.defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
services.init-defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.init-dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
dependencies = [ config.services.init-dhcpv4 ];
|
||||
};
|
||||
|
||||
# TODO: ensure SLAAC for admin-vlan.
|
||||
}
|
||||
|
|
|
@ -8,17 +8,18 @@ in
|
|||
# TODO: support dynamic reconfiguration once we are in the target VLAN?
|
||||
services.resolvconf = oneshot rec {
|
||||
name = "resolvconf";
|
||||
# TODO: imho, DNS should be static and provided by the router?
|
||||
up = ''
|
||||
. ${serviceFns}
|
||||
( in_outputs ${name}
|
||||
for i in $(output ${config.services.dhcpv4} dns); do
|
||||
for i in $(output ${config.services.init-dhcpv4} dns); do
|
||||
echo "nameserver $i" >> resolv.conf
|
||||
done
|
||||
)
|
||||
'';
|
||||
|
||||
dependencies = [
|
||||
config.services.dhcpv4
|
||||
config.services.init-dhcpv4
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -3,37 +3,41 @@ let
|
|||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
services.int = svc.bridge.primary.build {
|
||||
ifname = "int";
|
||||
macAddressFromInterface = config.hardware.networkInterfaces.lan;
|
||||
};
|
||||
# Our bridging is a bit complicated, therefore, we need iproute2.
|
||||
programs.iproute2.enable = true;
|
||||
|
||||
services.bridge = svc.bridge.members.build {
|
||||
primary = config.services.int;
|
||||
members = {
|
||||
lan.member = config.hardware.networkInterfaces.lan;
|
||||
wlan0 = {
|
||||
member = config.hardware.networkInterfaces.wlan0;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-1-ready ];
|
||||
};
|
||||
wlan1 = {
|
||||
member = config.hardware.networkInterfaces.wlan1;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-2-ready ];
|
||||
services = {
|
||||
int = svc.bridge.primary.build {
|
||||
ifname = "int";
|
||||
macAddressFromInterface = config.hardware.networkInterfaces.lan;
|
||||
untagged = {
|
||||
enable = true;
|
||||
pvid = 1;
|
||||
default-pvid = 1;
|
||||
};
|
||||
};
|
||||
|
||||
bridge = svc.bridge.members.build {
|
||||
primary = config.services.int;
|
||||
members = {
|
||||
lan.member = config.hardware.networkInterfaces.lan;
|
||||
wlan0 = {
|
||||
member = config.hardware.networkInterfaces.wlan0;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-1-ready ];
|
||||
};
|
||||
wlan1 = {
|
||||
member = config.hardware.networkInterfaces.wlan1;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-2-ready ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
admin-vlan = svc.vlan.build {
|
||||
ifname = "admin";
|
||||
primary = config.services.int;
|
||||
vid = "3001";
|
||||
};
|
||||
};
|
||||
|
||||
# Default VLAN
|
||||
# services.vlan-apro = svc.vlan.build {
|
||||
# vlanId = 0;
|
||||
# interface = config.services.int;
|
||||
# };
|
||||
|
||||
# # Administration VLAN
|
||||
# services.vlan-admin = svc.vlan.build {
|
||||
# vlan = 3001;
|
||||
# interface = config.services.int;
|
||||
# };
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
}:
|
||||
let
|
||||
svc = config.system.service;
|
||||
parentConfig = config;
|
||||
in
|
||||
{
|
||||
defaultProfile.packages = with pkgs; [
|
||||
defaultProfile.packages = [
|
||||
# Levitate enable us to mass-reinstall the system on the fly.
|
||||
(levitate.override {
|
||||
(pkgs.levitate.override {
|
||||
config = {
|
||||
imports = [
|
||||
"${modulesPath}/network"
|
||||
|
@ -19,24 +20,33 @@ in
|
|||
"${modulesPath}/kernel"
|
||||
"${modulesPath}/outputs/tftpboot.nix"
|
||||
"${modulesPath}/outputs.nix"
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
services = {
|
||||
# In this situation, we fallback to the appro VLAN.
|
||||
# TODO: add support for the admin VLAN.
|
||||
# Simplest DHCPv4 we can find.
|
||||
dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = parentConfig.hardware.networkInterfaces.lan;
|
||||
};
|
||||
inherit (parentConfig.services) sshd;
|
||||
defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
hostname = "${parentConfig.hostname}-live";
|
||||
nixpkgs.buildPlatform = builtins.currentSystem;
|
||||
services = {
|
||||
# In this situation, we fallback to the appro VLAN.
|
||||
# TODO: add support for the admin VLAN.
|
||||
# Simplest DHCPv4 we can find.
|
||||
dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = config.hardware.networkInterfaces.lan;
|
||||
};
|
||||
inherit (config.services) sshd;
|
||||
defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
};
|
||||
};
|
||||
|
||||
defaultProfile.packages = [ mtdutils ];
|
||||
defaultProfile.packages = with pkgs; [
|
||||
mtdutils
|
||||
zyxel-bootconfig
|
||||
];
|
||||
# Only keep root, which should inherit from DGN access control's root permissions.
|
||||
users.root = config.users.root;
|
||||
};
|
||||
|
|
|
@ -131,9 +131,9 @@
|
|||
"url": "https://git.dgnum.eu/DGNum/liminix"
|
||||
},
|
||||
"branch": "main",
|
||||
"revision": "473d6acc3de70bd6dbbb4a77af54f508f25c3c9c",
|
||||
"revision": "1322de1ee0cdb19fead79e12ab279ee0b575019a",
|
||||
"url": null,
|
||||
"hash": "00slsh0yqd8n8jcx3sbxgcmw1z28bnszy87pfs0ynfkl3bldzs3d"
|
||||
"hash": "07nk6nik97k8a57cf17dcj3gn2lbhw1myymrxpqc2aqa3haj754k"
|
||||
},
|
||||
"linkal": {
|
||||
"type": "Git",
|
||||
|
|
12
scripts/extract-firmware-from-zyxel-nwa-fit.sh
Executable file
12
scripts/extract-firmware-from-zyxel-nwa-fit.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p ubootTools
|
||||
|
||||
usage() {
|
||||
echo "extract the firmware part to write it manually from a Zyxel NWA FIT image"
|
||||
echo "$0 <zyxel_nwa_fit_image_path> <firmware_output_file>"
|
||||
}
|
||||
|
||||
ZYXEL_NWA_FIT="$1"
|
||||
FIRMWARE_OUTPUT="$2"
|
||||
|
||||
dumpimage -T flat_dt -p 0 $ZYXEL_NWA_FIT -o $FIRMWARE_OUTPUT
|
53
scripts/liminix-rebuild.sh
Executable file
53
scripts/liminix-rebuild.sh
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env bash
|
||||
# TODO: support automatic levitation when the rebuild counts does not fit in the target.
|
||||
# TODO: support preflight checks where we detect the environment we are booted in (this requires the levitation to write a special file).
|
||||
# TODO: use colmena to know the target host and focus on the node name.
|
||||
set -Eeuo pipefail
|
||||
|
||||
ssh_command=${SSH_COMMAND-ssh}
|
||||
root_prefix=${ROOT_PREFIX-/}
|
||||
|
||||
reboot="reboot"
|
||||
|
||||
case "$1" in
|
||||
"--no-reboot")
|
||||
unset reboot
|
||||
shift
|
||||
;;
|
||||
"--fast")
|
||||
reboot="soft"
|
||||
shift
|
||||
;;
|
||||
"--live")
|
||||
echo "Root prefix changed from $root_prefix to /mnt"
|
||||
root_prefix="/mnt"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
target_host=$1
|
||||
shift
|
||||
|
||||
if [ -z "$target_host" ] ; then
|
||||
echo Usage: liminix-rebuild \[--no-reboot\] target-host params
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if toplevel="$(nom-build $(colmena eval -E "{ nodes, ... }: nodes.$@.config.system.outputs.systemConfiguration" --instantiate))"; then
|
||||
echo systemConfiguration $toplevel aimed at $root_prefix
|
||||
sleep 3
|
||||
min-copy-closure --root "$root_prefix" $target_host $toplevel
|
||||
$ssh_command $target_host "$root_prefix/$toplevel/bin/install" "$root_prefix"
|
||||
case "$reboot" in
|
||||
reboot)
|
||||
$ssh_command $target_host "sync; source /etc/profile; reboot"
|
||||
;;
|
||||
soft)
|
||||
$ssh_command $target_host $toplevel/bin/restart-services
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo Rebuild failed
|
||||
fi
|
Loading…
Reference in a new issue