implement ifwait trigger service and use in bridge

should we convert all ifwait uses to this trigger too? seems
reasonable
This commit is contained in:
Daniel Barlow 2024-03-16 20:41:13 +00:00
parent fad0a47b75
commit 28a5dec7dd
5 changed files with 91 additions and 14 deletions

View file

@ -14,6 +14,8 @@ let
inherit (pkgs) liminix; inherit (pkgs) liminix;
in in
{ {
imports = [ ../ifwait ];
options = { options = {
system.service.bridge = { system.service.bridge = {
primary = mkOption { type = liminix.lib.types.serviceDefn; }; primary = mkOption { type = liminix.lib.types.serviceDefn; };
@ -27,7 +29,7 @@ in
description = "bridge interface name to create"; description = "bridge interface name to create";
}; };
}; };
members = liminix.callService ./members.nix { members = config.system.callService ./members.nix {
primary = mkOption { primary = mkOption {
type = liminix.lib.types.interface; type = liminix.lib.types.interface;
description = "primary bridge interface"; description = "primary bridge interface";

View file

@ -2,6 +2,7 @@
liminix liminix
, ifwait , ifwait
, lib , lib
, svc
}: }:
{ members, primary } : { members, primary } :
@ -10,14 +11,20 @@ let
inherit (liminix.services) bundle oneshot; inherit (liminix.services) bundle oneshot;
inherit (lib) mkOption types; inherit (lib) mkOption types;
addif = member : addif = member :
oneshot { # how do we get sight of services from here? maybe we need to
# implement ifwait as a regualr derivation instead of a
# servicedefinition
svc.ifwait.build {
state = "running";
interface = member;
dependencies = [ primary member ];
service = oneshot {
name = "${primary.name}.member.${member.name}"; name = "${primary.name}.member.${member.name}";
up = '' up = ''
dev=$(output ${member} ifname) ip link set dev $(output ${member} ifname) master $(output ${primary} ifname)
${ifwait}/bin/ifwait $dev running && ip link set dev $dev master $(output ${primary} ifname)
''; '';
down = "ip link set dev $(output ${member} ifname) nomaster"; down = "ip link set dev $(output ${member} ifname) nomaster";
dependencies = [ primary member ]; };
}; };
in bundle { in bundle {
name = "${primary.name}.members"; name = "${primary.name}.members";

View file

@ -0,0 +1,18 @@
{ config, pkgs, lib, ... } :
let
inherit (pkgs) liminix;
inherit (lib) mkOption types;
in {
options.system.service.ifwait =
mkOption { type = liminix.lib.types.serviceDefn; };
config.system.service.ifwait = config.system.callService ./ifwait.nix {
state = mkOption { type = types.str; };
interface = mkOption {
type = liminix.lib.types.interface;
};
service = mkOption {
type = liminix.lib.types.service;
};
};
}

15
modules/ifwait/ifwait.nix Normal file
View file

@ -0,0 +1,15 @@
{ ifwait, liminix } :
{
state
, interface
, service
}:
let
inherit (liminix.services) longrun;
in longrun {
name = "ifwait.${interface.name}";
buildInputs = [ service ];
run = ''
${ifwait}/bin/ifwait -s ${service.name} $(output ${interface} ifname) ${state}
'';
}

View file

@ -13,9 +13,14 @@ spawn socat unix-connect:vm/console -
set console_id $spawn_id set console_id $spawn_id
expect "BusyBox" expect "BusyBox"
expect "#" { send "PS1=RE\\ADY_\\ \r" } expect "#" { send "PS1=RE\\ADY_\\ ; stty -echo \r" }
expect "READY_" { send "sleep 3\r" } expect "READY_" { send "s6-rc -b -a list\r" } ; # -b waits for s6-rc lock
expect "READY_" { send "ip link\r" } expect "READY_" { send "ls /sys/class/net/lan/master\r" }
expect {
"No such file or directory" { }
timeout { exit 1 }
}
expect "READY_" { send "cat /sys/class/net/lan/operstate\r" } expect "READY_" { send "cat /sys/class/net/lan/operstate\r" }
expect { expect {
"down" { } "down" { }
@ -24,6 +29,36 @@ expect {
expect "READY_" { send "s6-rc -a -u change\r" } expect "READY_" { send "s6-rc -a -u change\r" }
expect { expect {
"unable to take locks" { exit 1 } "unable to take locks" { exit 1 }
"READY_" { send "hostname\r" } "READY_" { send "\r" }
} }
expect "updown"
set spawn_id $monitor_id
send "\r"
expect "(qemu)"
send "set_link virtio-net-pci.1 on\n"
expect "(qemu)"
send "set_link virtio-net-pci.0 on\n"
expect "(qemu)"
set spawn_id $console_id
expect "entered forwarding state"
send "\r"
expect "READY_" { send "cat /sys/class/net/lan/operstate\r" }
expect {
"down" { exit 1 }
"up" { }
}
expect "READY_" { send "cat /sys/class/net/lan/master/uevent\r" }
expect {
"INTERFACE=int" { }
timeout { exit 1 }
}
expect "READY_" { send "s6-rc listall int.link.a.10.8.0.1.member.lan.link ; hostname\r" }
expect {
"updown" {}
timeout { exit 1 }
}