Suggestion: Atomic validation and load of a config file #164

Closed
toreanderson opened this Issue Jul 29, 2015 · 5 comments

Projects

None yet

3 participants

@toreanderson
Contributor

We're using Puppet as our config management/automation system. I wanted to integrate Jool into it, and found that it would be somewhat complex. Puppet will know what Jool's complete configuration should look like, the challenge is to actually synchronise that with the actual running configuration. In order to manipulate any of the pools or the EAMT, for example, I need first dump the current contents (parsing the output from the jool or jool_siit utilites, which would be somewhat fragile), look for entries there that are no longer defined in Puppet and remove them, then add any missing entries. It's far from impossible, but it would take a bit of scripting. Also, in order to ensure I don't end up in a half-committed state I need to validate that the entire new config is correct from the start, otherwise I might end up failing to add a pool/eamt entry half-way through. The global settings are easier as I assume I can just set them every time, and if they're already set correctly that should be a no-op, I guess.

So what I think would be nice is to be able to write out Jool's entire configuration in configuration file, and then run, e.g., jool --load jool.cfg. If the config is valid, it gets loaded (preferably in an atomic manner), or if invalid, the entire load will be aborted and Jool continues to operate using the old config. Compare iptables-restore, which does something very similar.

I'll probably end up writing a Perl script that does something like this, and would be happy to contribute it in case you're interested. Just thought I'd mention in case this is an idea you'd be interested in integrating directly into the jool/jool_siit utilities.

@ydahhrk
Member
ydahhrk commented Jul 29, 2015

So I guess the best way to implement this is to create the databases in temporal placeholders, and once everything is tidy, swap pointers. It can be a little expensive memory-wise, but there really isn't any other way to ensure a revert will never fail, I think.

All right, it doesn't look too hard, but my sidekick candidate rejected the job in the end, so I don't much see this (or the namespace gimmic) happening in the next release :/

I need first dump the current contents (parsing the output from the jool or jool_siit utilites, which would be somewhat fragile), look for entries there that are no longer defined in Puppet and remove them, then add any missing entries

Why don't you just --flush and --add everything back again? It'd be easier, but less atomic, but your solution isn't atomic in the first place anyway.

parsing the output from the jool or jool_siit utilites, which would be somewhat fragile

If you mean you'd be tying your script to Jool's output format, and you don't like that, you can use the --csv flag and read something fairly standard.

The global settings are easier as I assume I can just set them every time, and if they're already set correctly that should be a no-op, I guess.

Hmmm... well, yes, but each configuration value is still a separate command. Which means if one fails (for something like invalid syntax), you still have to revert the other ones, do you not?

@toreanderson
Contributor

Why don't you just --flush and --add everything back again? It'd be easier, but less atomic, but your solution isn't atomic in the first place anyway.

Because after the --flush I'll be dropping packets. It could get worse: If I then run into some problems while adding everything back again, I fear I'll be blackholing traffic until an operator can intervene. Therefore I consider it better/safer to apply only the changes between the target configuration and the running configuration.

Thanks for the tip about the --csv flag, I had missed that. It's very helpful, but it doesn't seem like it is available for all output modes (can't dump the global parameters that way, for example).

Hmmm... well, yes, but each configuration value is still a separate command. Which means if one fails (for something like invalid syntax), you still have to revert the other ones, do you not?

I'm less concerned about failing to toggle one of the global parameters, as those are mostly autonomous. I'm more worried about e.g. the contents of the EAMT. In any case, I probably won't attempt to implement rollback logic in my wrapper script, but rather try to make very certain that I don't try to apply invalid config.

@ydahhrk
Member
ydahhrk commented Jul 29, 2015

Still thinking about the milestone this should be in.

I've actually never seen a table in a typical .cfg file. Failing that, does JSON sound comfortable?

@toreanderson
Contributor

JSON or maybe YAML sounds fine. Regarding the milestone, don't give it much priority, there's no rush - just wanted to make sure the suggestion was made.

@rolivasnic rolivasnic was assigned by ydahhrk Nov 12, 2015
@ydahhrk ydahhrk added this to the 3.5.0 milestone Nov 23, 2015
@rolivasnic rolivasnic was unassigned by ydahhrk Sep 26, 2016
@ydahhrk ydahhrk closed this Sep 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment