public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <thomas@lamprecht.org>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
	Gabriel Goller <g.goller@proxmox.com>
Cc: Lukas Wagner <l.wagner@proxmox.com>
Subject: Re: [pve-devel] [RFC network/ve-rs 0/8] Template-based FRR config generation
Date: Sat, 4 Oct 2025 13:58:15 +0200	[thread overview]
Message-ID: <f2728fd6-91fd-4fc0-9e75-886c77f03f90@lamprecht.org> (raw)
In-Reply-To: <20250919094122.73373-1-g.goller@proxmox.com>

Am 19.09.25 um 11:41 schrieb Gabriel Goller:
> Currently we generate the frr config by having a few rust-structs that look
> very similar to the literal frr config -- these structs then implement a custom
> trait similar to Display, which serializes the config into a String. This is
> not optimal due to multiple reasons, the main one being it's quite verbose and
> and the fact that we often mixed Display and FrrDump implementations. This
> means that sometimes structs are serialized using Display and sometimes using
> FrrDump. There is also the question of granularity, so does a single line
> correspond to a single FrrDump implementation? Or does every frr word
> correspond to an FrrDump implementation and a random one just adds a '
> '?
> 
> In order to clean this up a bit, there was an attempt at writing a full-fledged
> serde serializer, which takes structs and converts them into blocks and using
> nested enums as the options on every line. This turned out to be quite
> difficult and involved a lot of magic when creating the config in rust.
> Especially the ending statements (e.g. 'exit-address-family' when exiting an
> address-family block, but 'exit' when exiting a router block) turned out to be
> quite tricky.
> 
> The third and probably most popular way (Vyos and Sonic both use jinja
> templates as well) to generate frr config is to use templates. So you basically
> have rust-structs that look similar to the frr config and implement derive or
> implemennt serialize. Then we can use template files, which contain the whole
> configuration with every option wrapped in a `if` block and lists/blocks
> wrapped in `for` loops. Finally, we can use the rust structs to insert them into
> the templates and get the full frr config. The major downside of this approach
> is that the frr template files get quite complicated and can be a major source
> of config generation errors. A positive thing though, is that we don't need to
> model the whole frr config with every option and every property, we can easily
> wrap a few options into a single (e.g.) bool, and then maybe split it out later
> when we add a ui option for each property.

I mean, that should be possible in any representation, just needs separation of
types for the API and types to generate the (dumped) FRR config from.
One drawback is. that you loose type checks with templates, but that can be
made up by a regression test system (which is a necessity either way), so your
approach can be OK to me in general, but this needs to be Ack'ed also by Stefan.

> Here I made the decision to split every protocol into its own template file.
> These template files then import some common structs, such as the interfaces and
> route-maps, which are used in every protocol. To accommodate for this, I also had
> to change the structure of the FrrConfig:
> So we no longer have:
> 
> config/
> ├─ interfaces/
> │  ├─ openfabric
> │  ├─ ospf
> ├─ routers/
> │  ├─ openfabric
> │  ├─ ospf
> 
> but:
> 
> config/
> ├─ openfabric/
> │  ├─ interfaces
> │  ├─ routers
> ├─ ospf/
> │  ├─ interfaces
> │  ├─ routers
> 
> Which plays much nicer with the templates, and IMO still makes sense logically.

Sounds OK.

> I used minijinja for this series, as that seems to be the most used template
> engine in the rust ecosystem, even though we mostly seem to use handlebars. I
> discussed this we Lukas and Thomas, and we'll decide in the next few weeks if
> this is fine, or it's better if we use the same templating engine
> everywhere.

I took a (not so deep) look, and saw already that minijinja had two major
releases during the last two years, while that's the same amount as handlebars,
it's also a big turn-off there. Using one templating project where some
maintainers live out their refactoring hobby is already pain enough for us,
using two of them is IMO a no-go, at least for mid/long term. So if we really
want to choose minijinja here, I'd need an actionable plan–at least a draft–for
switching everything to it; which naturally makes me question why we shouldn't
go the route that do not need us to do some migrations for all notification
templates we now got in multiple projects. Is there a strong technical reason,
to favor minijinja that really is worth the cost of us migrating all handlebar
templates over? As from a quick look at the dependency tree the "mini" in the
name seems rather relative, or at least it's not orders of magnitude leaner
compared to handlebars-rust; and given that it also had as many major breaking
releases since 2023 it's not signalling a much stronger stability to me either,
which is naturally hard to predict for the future though.
Because just migrating due to you not checking upfront for the templating
engines in use in our projects, and some subjective "minijinja might be better"
opinion is IMO not enough; if there's a broader front and some technical arguments
that make it quite likely that the cost of the switch will be compensated due
to lower maintenance or whatever, I can be fine with going for this; but otherwise
I'd at least like you to investigate if this would be really that much worse/harder
with handlebars.

The third option of using two template engines is naturally also one, but actively
and knowingly planing a schism is not something I'd promote much either tbh.

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

      parent reply	other threads:[~2025-10-04 12:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-19  9:41 Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH ve-rs 1/4] frr: add templates and structs to represent the frr config Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH ve-rs 2/4] sdn-types: forward serialize to display for NET Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH ve-rs 3/4] ve-config: fabrics: use new proxmox-frr structs to generate frr config Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH ve-rs 4/4] tests: always prepend the frr delimiter/comment "!" to the block Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH network 1/4] sdn: remove duplicate comment line '!' in frr config Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH network 2/4] sdn: add trailing newline " Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH network 3/4] sdn: tests: add missing comment '!' " Gabriel Goller
2025-09-19  9:41 ` [pve-devel] [PATCH network 4/4] tests: use Test::Differences to make test assertions Gabriel Goller
2025-10-03 15:46 ` [pve-devel] [RFC network/ve-rs 0/8] Template-based FRR config generation Gabriel Goller
2025-10-04 11:58 ` Thomas Lamprecht [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f2728fd6-91fd-4fc0-9e75-886c77f03f90@lamprecht.org \
    --to=thomas@lamprecht.org \
    --cc=g.goller@proxmox.com \
    --cc=l.wagner@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal