Dewclaw: semi-declarative openwrt configurations

ever wanted to have declarative openwrt configs? are you also not quite willing to wait until liminix is ready for any device that currently runs openwrt? have you looked at other solutions for this problem but found them lacking in some respect, like not having rollback mechanisms in place to not accidentally temp-brick a device by deploying a broken config to it?

then maybe dewclaw, a nix framework for generating openwrt configuration scripts, is for you.

at this point it’s functional but incomplete in many ways: all UCI configs can be represented but aren’t checked before deployment, user management and /etc management are very much limited in their capabilities, the scripts doing the deployment don’t natively support parallel deployment to many devices unless you’re happy to wrap them in a parallel command line, the list goes on. but it’s functional enough to deploy at least small hackerspace infra.

happy to hear thoughts. can’t provide any support, but figured other folks may be interested.

28 Likes

Love this! Will have a play when I get a chance!

Have you explored integrating this with @astro’s image builder? GitHub - astro/nix-openwrt-imagebuilder: Build OpenWRT images in Nix derivations

1 Like

no. for running a system we’ve actively decided against using images because that makes trial booting a new configuration hard to impossible. extracting the UCI bits to make the image builder more comfortable should be reasonably easy though, the necessary configs are already exposed and could “just” be used in a image builder invocation.

(on a side note, we’re not very fond of the openwrt build process in general, regardless of the method used. we’ve tried to nixify it properly for a while and eventually just gave up, astro’s version seems to be the best nixified image builder setup that’s viable for now)

1 Like

I too would love to see that. Could you share the unfinished bits?

no, we deleted it all in anger. :frowning:

Thanks! I think updating a running system is important, but can also see value in building an image with an initial configuration. e.g. bootstrap a device with credentials and network settings.

1 Like

I’m loving this so far, but I think I’ve found an obscure race condition:

                log 'applying config'
                if $RELOAD_ONLY; then
                  ssh 'logread -l9999 -f' &
                  ssh '/etc/init.d/config_generation prepare_reload'
                  ssh '/etc/init.d/config_generation start' &
                  ssh '/etc/init.d/config_generation apply_reload 2>&1 | logger -t '"$TAG"
                  ssh -O exit

I think the logread and the prepare_reload ssh invocations are racing with each other to establish the ControlMaster master socket because the first one is backgrounded, not sure exactly what happens but the attempt to close down the socket hangs, which seems to ultimately cause the router to rollback and reboot. This only seems to happen on the second or subsequent deploy_xxx --reload invocation - the first always seems to succeed on my machine, not sure why.

Anyway, chucking a sleep 3 after the logread ssh invocation works here as a horrible hack. A proper fix might be to explicitly establish the ControlMaster connection first?

I’m in the process of rebuilding my router so I forked the code in my personal GitHub account. Right now just added a build CI and GitHub Pages. Gonna see how I can actually migrate my configs tomorrow.

2 Likes

Now wondering if just using -f on the logread invocation would be enough?

Just did a basic configuration and I’m also having issue with applying config stage:

> applying config
root@192.168.31.163's password: 
        <The output stopped here, so I pressed enter again.>

Permission denied, please try again.
root@192.168.31.163's password: 
cp: can't create '/overlay/upper.prev/': No such file or directory
>> failed to snapshot old config
        <Script is stuck again.>

Not sure if this is the same issue you were talking about.

Edit: I see the ControlSocket /tmp/tmp.AjK2mynzrh/cm already exists, disabling multiplexing when I added RootPasswordAuth = "on";. I guess this is required for 23.05 since I did not see this on uci show with 21.02 that I’m working to replace.

Edit 2: error with /overlay/upper.prev/ is due to I’m targeting x64 VM deployment, which does not use squashfs.

I see there is already -f there?

Oh, I meant -f as an ssh option (background after establishing connection), sorry for lack of clarity!

Fixed in fix: set up control socket before running commands · MakiseKurisu/dewclaw@260e0c1 · GitHub

1 Like