TIL! Using the existence of obscure member sys._MEIPASS, I can detect if
we're running from a bundled PyInstaller binary, versus running from Python
directly.
Add schema.yaml to the datas of the PyInstaller spec. Then, if the
-/--schema flag is given, use it, and if it's not given, default to the
built-in one if we're running from a bundled binary, or fall-through to
./schema.yaml in other cases.
This avoids the need for config/schema.py as a carbon-copy of the schema,
slick!
The handling of BVI is awkward, with the autoderived interface name
"bviXX" based on the bridgedomain bd_id. Lots of special casing happens
on account of this decision, and to make matters worse there is poor
interaction (leading to VPP crashes) when BVIs and Loopbacks are used
at the same time: https://lists.fd.io/g/vpp-dev/message/21116
This is step one of a refactor of the logic. In this commit, I'm
removing all of the BVI logic from the codebase, rendering bridgedomains
unable to have IP interfaces. In the next commit, I will introduce new
behavior in the schema, allowing for 'bvi' to be a loopback
interfacename which will be used as BVI for a bridgedomain, restoring
the ability to use bridgedomains with IP interfaces (using a loop).
This is rather straight forward: for each object (in correct order),
if the object exists in VPP, we can skip it. We know that it will exist
only if it was valid (ie correct encapsulation, tc). If it does not
exist in VPP, issue the correct creation request to VPP.
Implement the creation of all types, in the following order:
- create_loopbacks() and create_bvis()
- create_bondethernets()
- create_vxlan_tunnels()
- create_sub_interfaces() first 1-tag, then 2-tag
- create_bridgedomains()
- create_lcps() bottomsup: first 0-tag, then 1-tag, then 2-tag names.
Add a placeholder TODO to fix a bug with prune_sub_interfaces() which
should allow for TAPs belonging to LCPs; will fix in followup commit.
- Prune bridgedomains before pruning BVIs. The reason for this is that
prune_bridgedomains() will set the BVI to L3 mode, and if the BVI is
removed before the bridge is pruned, this is an error.
- When pruning bridge members, use the VPP configuration as the member
may not exist in the config, upon which the call to interface.is_sub()
will return False even if it is actually a VPP sub-int.
Update README.md, also take into account the previous change which calls
prune_addresses() before object deletion.
1. sub-ints have to be removed before their parent, particularly
bondethernets, because destroying BondEthernet0 will cascade
destruction of all of its sub-ints. So:
- first prune_sub_interfaces()
- then prune_bondethernets()
- finally prune_phys()
2. for any interface (loop, bvi, sub, phy, bond), prune_addresses()
before destroying the interface
Update the README with this new flow.