commit | e950cf7aa2d9309c23380bf76606871ca5c3b56d | [log] [tgz] |
---|---|---|
author | Jan Kundrát <jan.kundrat@cesnet.cz> | Fri Sep 06 17:46:11 2024 +0200 |
committer | Jan Kundrát <jan.kundrat@cesnet.cz> | Tue Sep 17 14:44:08 2024 +0200 |
tree | 147cb636789aec3ec150719582ebe725b27bc7a0 | |
parent | febc9991a13351300356103ab70cb2d7a1f5e6ca [diff] |
libyang v3 This is a huge commit which changes a lot of things in the system, including the boot process and configuration handling. There are also massive updates all over the stack which have accumulated in the upstream projects. In no particular order: - The configuration schema has changed in an incompatible way. That's due to an update of some drafts related to the ietf-netconf-server YANG model and its dependencies; as a result, the way how SSH keys and SSH listening configuration is managed in YANG data is incompatible with the previous approach, and that means that we *cannot* import the previous config into sysrepo which already has new YANG modules. "Solve" that by simply dropping the entire YANG config (!) because we decided that it's sometimes better to start from scratch. Yay. - Config migrations now work at the JSON level, not through sysrepo. There is currently no real "migration" apart from the initial one (the one that brings the config schema from the implicit/empty "v0" to "v9"). The TL;DR version is that future migrations will work on an JSON input, producing some new JSON output, and only after the migration is done, we push stuff into sysrepo. Also, the migrations will (likely) not be performed in a sequence, on a cumulative basis, but it is now a one-shot process with no intermediate steps. This should hopefully simplify the launching/wrapping code. From the developer's standpoint, any migration should focus on bringing the system to the "final state" (v_new), not to v_old + 1. These migrations will use `jq` heavily. So far, we only have some "simple" code which merges objects (and arrays!) recursively, courtesy of Peter Koppstein (https://stackoverflow.com/a/53666584/2245623). - Some Buildroot options which should have been hardcoded (e.g., persisting of OpenSSH server keys) are now unconditional. Once the czechlight-cfg-fs package is selected, these cannot be disabled. - We no longer nuke the entire sysrepo SW stack upon a failure. If, e.g., cla-sysrepo fails, this does not bring the NETCONF server down anymore, for example. (We might restore the PartOf=... if this proves to be a problem.) - There's a bunch of YANG rules which try to make sure that the NETCONF server is reasonably configured. Previously, we would simply reprovision the server config at the next boot, now we have nice error messages at the YANG level already. - The RESTCONF server has been vastly improved, and some changes all over that SW stack were made. Also, cleaned up the packaging a bit (especially those parts which would be a PITA to split into extra commits due to conflicts everywhere -- sorry). - Use `jq` patterns for JSON filtering (to make sure that we can provide an exclusion filter for the crypto material). Also, since we drop anything but v9 configs now, let's drop the existing migration tests (there's nothing to test, really). Change-Id: Id1bb5b9ee66c6deb7a886289e4d768ce3ff7c9b2 Depends-on: https://gerrit.cesnet.cz/plugins/gitiles/github/buildroot/buildroot/+/refs/heads/cesnet/2024-09-06 Depends-on: https://gerrit.cesnet.cz/c/CzechLight/gammarus/+/7570
This repository contains CzechLight-specific bits for Buildroot. Buildroot is a tool which produces system images for flashing to embedded devices. They have a nice documentation which explains everything that one might need.
The system architecture is described in another document. This is a quick build HOWTO.
Everything is in Gerrit. One should not need to clone anything from anywhere else. The build will download source tarballs of various open source components, though.
By default, each change of this repo uploaded to Gerrit causes the CI system to produce a firmware update. On Gerrit, the change will get a comment from Zuul with a link to the CI log server. Next to the logs, a file named artifacts/update.raucb
can be used for updating devices.
Behind the scenes, the system uses Zuul with a configuration tracked in git.
Here's how to reproduce the build on a developer's workstation:
git clone ssh://$YOUR_LOGIN@cesnet.cz@gerrit.cesnet.cz:29418/CzechLight/br2-external czechlight pushd czechlight git submodule update --init --recursive popd mkdir build-clearfog cd build-clearfog ../czechlight/dev-setup-git.sh make czechlight_clearfog_defconfig make -j8
A full rebuild takes about half an hour on a modern laptop.
WARNING: Buildroot is fragile. It is not safe to perform incremental builds after changing an "important" setting. Please check their manual for details.
Apart from the traditional way of re-flashing the SD card or the eMMC from scratch, it's also possible to use RAUC to update. This method preserves the U-Boot version and the U-Boot's environment. Apart from that, everything starting with the kernel and the DTB file and including the root FS is updated. Configuration stored in /cfg
is brought along and preserved as well.
To install an update:
# build node make rsync -avP images/update.raucb somewhere.example.org:path/to/web/root # target, perhaps via an USB console or over SSH rauc install http://somewhere.example.org/update.raucb reboot
Once the updated FW slot boots, the configuration in /cfg
will be automatically upgraded ("migrated") to the newest layout. A downgrade to an incompatible OS version might therefore fail during the next reboot. Completely removing all data in the newly updated slot's cfg
partition will restore functionality, but it is effectively a factory reset.
On a regular Clearfog Base with an eMMC, one has to bootstrap the device first. If recovering a totally bricked board (or one that is fresh from factory), use the kwboot
command to upload the initial, new enough U-Boot via the console. Ensure that the jumpers are set to 0 1 0 0 1
(default for eMMC boot is 0 0 1 1 1
), and then use U-Boot's kwboot
tool:
./host/bin/kwboot -b ./u-boot-spl.kwb -t -p /dev/ttyUSB0
Prepare a USB flash disk with a raw bootable image, images/usb-flash.img
. Use a tool such as dd
to overwrite the raw block device, do not copy the image file. Once in U-Boot, plug the USB flash disk and execute:
usb start; fatload usb 0:1 00800000 boot.scr; source 00800000
The system will boot and flash the eMMC from the USB drive. Once the status LED starts blinking in yellow, data are being transferred to the eMMC. The light changes to solid yellow in later phases of the flashing process. Once everything is done, the status LED shows a solid white light and the system reboots automatically.
Turn off power, remove the USB flash, re-jumper the board (0 0 1 1 1
), power-cycle, and configure MAC addresses at the U-Boot prompt. The MAC addresses are found on the label at the front panel.
=> setenv eth1addr 00:11:17:01:XX:XX => setenv eth2addr 00:11:17:01:XX:YY => setenv eth3addr 00:11:17:01:XX:ZZ
Also set up the system type:
Model | czechlight variable value |
---|---|
ROADM Line Degree | sdn-roadm-line-g2 |
WSS Add/Drop | sdn-roadm-add-drop-g2 |
Hi-resolution Add/Drop | sdn-roadm-hires-add-drop-g2 |
Coherent Add/Drop | sdn-roadm-coherent-a-d-g2 |
Inline EDFA Amplifier | sdn-inline-g2 |
Some prototypes have deprecated PCBs (blue). On these, skip the -g2
suffix. All red PCBs are -g2
.
=> setenv czechlight sdn-roadm-line-g2 => saveenv Saving Environment to MMC... Writing to redundant MMC(0)... OK => boot
Once the system boots (which currently requires a reboot for some unknown reason -- fsck, perhaps?), configure hostname, plug in the network cable, and update SW:
# hostnamectl set-hostname line-XYZSERIALNO # cp /etc/hostname /cfg/etc/ # rauc install http://somewhere.example.org/update.raucb # reboot
Obtain a reasonable Linux distro image for BBB and flash it to a µSD card. Unlock eMMC boot partitions (echo 0 > /sys/class/block/mmcblk1boot0/force_ro; echo 0 > /sys/class/block/mmcblk1boot1/force_ro
). Clean the eMMC data (blkdiscard /dev/mmcblk1
). Flash the content of images/emmc.img
to device's /dev/mmcblk1
. Flash what fits into /dev/mmcblk1boot0
and /dev/mmcblk1boot1
. Fetching the image over web (python3 -m http.server
and wget http://...:8000/emmc.img -O - | dd of=/dev/mmcblk1 conv=sparse
) works well.