-
Notifications
You must be signed in to change notification settings - Fork 1
Upgrading to 0.8
A topology written for 0.7.x meets several changes at once. This page is what to read before upgrading one, and it covers the whole 0.8 line: the sections marked (0.8.1) arrived in that release, and the rest in 0.8.0. Coming from 0.7.x you want all of them; the CHANGELOG describes each in full.
A file declared with path: /etc/frr/frr.conf is written to
r1/etc/frr/frr.conf, not r1/frr.conf. A node's files are laid out by the
path they take inside the container.
What to do: nothing in the topology. Anything reading generated files by path has to follow — a script of your own, or a downstream tool such as netroub, which reads a lab's generated files to replay failures on it. See File Output.
The default interface prefix is eth, where it used to be net.
What to do: update any template that names an interface literally. eth is
what a Linux container calls its interfaces and the only prefix Kathara accepts,
so this is the one name every platform agrees on.
Generated nodes carry network-mode: none, so a lab has only the links its
topology describes. The management network is now opt-in rather than gone.
What to do: if the lab relied on clab exec, the clab-* container names,
or reachability through the management network, put it back:
module_config:
containerlab:
management_network: trueand name the data interfaces something other than eth0, which containerlab
keeps for itself.
A multi-host topology that drew a segment spanning machines now gets one bridge per machine, linked to each other, instead of one link leaving a machine per member on the far side.
What to do: nothing, unless the old shape was wanted:
global.aggregate_crossing_links: false.
One flag used to answer two questions — is this object there? and does dot2net write its configuration? — and a topology could not answer them separately. In 0.8.0 they are two settings (though see the note at the end: one combination is still out of reach):
-
deploysays what the object is materialised as. On a node,container(the default) ·platform·none. On an interface or a connection,link·logical·none. -
virtual: truesays only that this object's own configuration is not written. It means the same thing on every kind of class, and it no longer has any bearing on whether the object is deployed.
What to do: replace virtual: true with deploy: none wherever it meant
"this is not deployed" — which is what it meant on a node, and what it usually
meant on an interface or a connection.
# 0.7.x # 0.8.0
nodeclass: nodeclass:
- name: vrouter - name: vrouter
virtual: true deploy: none
connectionclass: connectionclass:
- name: v - name: v
virtual: true deploy: logical # a tunnel the configuration buildsYou do not have to find them by reading. A class that sets virtual: true
without also naming a deploy is an error, so a topology written for 0.7.x
stops on the first one and tells you what to write instead. The error is a
migration aid and is removed in 0.9.0; until then, saying which
one you mean is required.
Choose deploy: logical rather than none for a connection that is not wired by
the platform but is built by the configuration running on the nodes — a VXLAN
overlay or a GRE tunnel. Its endpoints are real devices and still get their
configuration; only the wiring is absent.
deploy and virtual can now also be combined, which the single flag
could not express: deploy: container with virtual: true is a node that starts
like any other and that dot2net writes no configuration into.
One combination is still out of reach. deploy: none withholds the
configuration as well, so deployed by nobody, configured by us — writing a
configuration file for a real router that dot2net does not start — cannot be
said in 0.8.0. It needs a form meaning "it exists, we just do not put it there",
and the values above do not have one.
{{ .segments_<name> }} becomes {{ .segments_<layer>_<name> }}. The layer was
missing from the name, so two layers that used one config name were merged
without a word.
What to do: add the layer to the name.
# 0.7.x 0.8.0
- "{{ .segments_network_entry }}" - "{{ .segments_ip_network_entry }}"A template that still names the old parameter fails with map has no entry for key "segments_<name>". That happens while the templates are being rendered —
late enough that the message can look unrelated to the upgrade — so it is worth
searching your templates for segments_ before you start.
| What | Why |
|---|---|
| An unknown or duplicate key in the config file | A key the config did not know was dropped without a word, which looks exactly like a setting that had no effect |
| Two file definitions writing the same file | Whichever was written last won, and the other's content was gone |
A config entry naming both template and sourcefile
|
Which came first was decided in the code and written down nowhere |
What to do: run dot2net build and fix what it names. Each message says
what is wrong and how to write it instead.
Two things share the word startup, and it matters which one you have:
- the file
<device>.startup, which Kathara runs inside the device - the hook group
startup, whose blocks fill that file
0.7.0 documented declaring the file yourself — a file: entry with
name_suffix: .startup and output: root. The Kathara module declares it now,
so a topology that still does gets two definitions writing one file, which is an
error.
What to do: delete the file: entry. Keep the commands, in a config entry
written into the startup group (see
A hook is a group below for what that is):
nodeclass:
- name: router
config:
- group: startup
template:
- "ip link set lo up"Those are the commands containerlab puts in exec: and TiNET in cmds:, so they
are written once and run on all three. A topology that never loads the Kathara
module keeps working either way; the collision appears when the module is added,
and dot2net names both definitions.
startup, teardown and the four worker_ hooks are written with group::
config:
- group: startup # was: - name: startup
template:
- "ip link set lo up"The old form still works, with a warning, so nothing breaks on upgrade. Two things become possible that were not: two classes of your own may both write into one hook, and a class of any kind may, an interface class included.
A block that has to run after the platform's own command says so by naming it, rather than by picking a number above zero:
- group: worker_deploy
placed:
after: [worker_deploy]A block left at priority 0 in a worker_ hook is now refused, because it
sits exactly where the platform's command does and nothing says which runs
first. If you wrote a worker_ block with no priority, give it placed:.
A template that embeds {{ .self_x }}, or merges self_x with blocks:, has
already said it needs x rendered first. Writing depends: [x] as well says it
twice; the key still works and is still checked, so nothing breaks, but it can
go.
A classmembers: entry iterates the members of the classes it names, and the
object doing the referring is one of them. The flag that excludes it has not
been read since 0.7, so the referrer has been included whatever you wrote.
The default is false — the referrer is not among its own members. If your
topology worked around the old behaviour, take the workaround out. If you want
the referrer included, say include_self: true.
The wiki said the default was
true. No version has done that.
- Blank first and last lines of a gathered block are dropped. They used to become empty lines between blocks — an empty command in a script.
-
platform:on a config entry is gone. It selected which output a config belonged to, from a list that never learned about Kathara, and nothing has read it since modules arrived in 0.7. - Writing into a group nothing sorts is an error, where the block used to be generated and dropped.
- Blocks of equal priority come out in the order their classes are declared. Past ten config templates on one object they did not.
-
File Output -
path,provide, and how files reach a container - Module System - which names cross between a module and a topology
- Module: Kathara