[PATCH] Gate boolean protocol options on filename.
Toggling session parameters currently requires editing the configuration file and reloading BIRD. Doing so programatically requires keeping up with the syntax and layout of a particular configuration. This commit introduces an alternative method for gating configuration of boolean protocol properties. In addition to the keywords on/off and yes/no, a user can instead provide a filename on which to predicate whether the flag is set. In particular, this makes toggling protocols programatically much simpler, since we can decouple state from configuration more cleanly, i.e: protocol kernel { disabled filename "/etc/disable-kernel"; } --- conf/cf-lex.l | 23 +++++++++++++++++++++++ conf/conf.h | 1 + conf/confbase.Y | 3 ++- doc/bird.sgml | 5 +++-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 5a2a4d6..af85291 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -693,6 +693,29 @@ cf_symbol_class_name(struct symbol *sym) } } +/** + * cf_file_exists - check if expanded filename exists + * @arg: filename + * + * This function expands relative filenames and returns + * whether file is present. + */ +int +cf_file_exists(char *arg) +{ + char *patt = arg; + + if (*arg != '/') + { + int dlen = strlen(ifs->file_name); + char *dir = alloca(dlen + 1); + patt = alloca(dlen + strlen(arg) + 2); + memcpy(dir, ifs->file_name, dlen + 1); + sprintf(patt, "%s/%s", dirname(dir), arg); + } + + return access(patt, F_OK) != -1; +} /** * DOC: Parser diff --git a/conf/conf.h b/conf/conf.h index 89a2c5b..6f6a33d 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -160,6 +160,7 @@ char *cf_symbol_class_name(struct symbol *sym); static inline int cf_symbol_is_constant(struct symbol *sym) { return (sym->class & 0xff00) == SYM_CONSTANT; } +int cf_file_exists(char *arg); /* Parser */ diff --git a/conf/confbase.Y b/conf/confbase.Y index 5f487c1..7ee26f3 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -88,7 +88,7 @@ CF_DECLS %left '!' %nonassoc '.' -CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT) +CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, FILENAME) CF_GRAMMAR @@ -143,6 +143,7 @@ bool: | YES { $$ = 1; } | OFF { $$ = 0; } | NO { $$ = 0; } + | FILENAME text { $$ = cf_file_exists($2); } | /* Silence means agreement */ { $$ = 1; } ; diff --git a/doc/bird.sgml b/doc/bird.sgml index a0b45f4..03682cb 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -493,8 +493,9 @@ protocol (see sections talking about the protocols). <p>Several options use a <m/switch/ argument. It can be either <cf/on/, <cf/yes/ or a numeric expression with a non-zero value for the option to be enabled or <cf/off/, <cf/no/ or a numeric expression evaluating to zero to -disable it. An empty <m/switch/ is equivalent to <cf/on/ ("silence means -agreement"). +disable it. Alternatively you can gate the value of <m/switch/ on the presence +of a file through the <cf/filename/ "<m/name/" directive. An empty <m/switch/ +is equivalent to <cf/on/ ("silence means agreement"). <descrip> <tag>preference <m/expr/</tag> -- 2.8.1
Hi, On Sun, May 22, 2016 at 04:50:12PM -0700, João Taveira Araújo wrote:
Toggling session parameters currently requires editing the configuration file and reloading BIRD. Doing so programatically requires keeping up with the syntax and layout of a particular configuration.
This commit introduces an alternative method for gating configuration of boolean protocol properties. In addition to the keywords on/off and yes/no, a user can instead provide a filename on which to predicate whether the flag is set.
In particular, this makes toggling protocols programatically much simpler, since we can decouple state from configuration more cleanly, i.e:
protocol kernel { disabled filename "/etc/disable-kernel"; }
Can't you achieve the same effect with an include? The included file would just need to contain either nothing, or "disabled yes".
--- conf/cf-lex.l | 23 +++++++++++++++++++++++ conf/conf.h | 1 + conf/confbase.Y | 3 ++- doc/bird.sgml | 5 +++-- 4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 5a2a4d6..af85291 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -693,6 +693,29 @@ cf_symbol_class_name(struct symbol *sym) } }
+/** + * cf_file_exists - check if expanded filename exists + * @arg: filename + * + * This function expands relative filenames and returns + * whether file is present. + */ +int +cf_file_exists(char *arg) +{ + char *patt = arg; + + if (*arg != '/') + { + int dlen = strlen(ifs->file_name); + char *dir = alloca(dlen + 1); + patt = alloca(dlen + strlen(arg) + 2); + memcpy(dir, ifs->file_name, dlen + 1); + sprintf(patt, "%s/%s", dirname(dir), arg); + } + + return access(patt, F_OK) != -1; +}
/** * DOC: Parser diff --git a/conf/conf.h b/conf/conf.h index 89a2c5b..6f6a33d 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -160,6 +160,7 @@ char *cf_symbol_class_name(struct symbol *sym); static inline int cf_symbol_is_constant(struct symbol *sym) { return (sym->class & 0xff00) == SYM_CONSTANT; }
+int cf_file_exists(char *arg);
/* Parser */
diff --git a/conf/confbase.Y b/conf/confbase.Y index 5f487c1..7ee26f3 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -88,7 +88,7 @@ CF_DECLS %left '!' %nonassoc '.'
-CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT) +CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, FILENAME)
CF_GRAMMAR
@@ -143,6 +143,7 @@ bool: | YES { $$ = 1; } | OFF { $$ = 0; } | NO { $$ = 0; } + | FILENAME text { $$ = cf_file_exists($2); } | /* Silence means agreement */ { $$ = 1; } ;
diff --git a/doc/bird.sgml b/doc/bird.sgml index a0b45f4..03682cb 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -493,8 +493,9 @@ protocol (see sections talking about the protocols). <p>Several options use a <m/switch/ argument. It can be either <cf/on/, <cf/yes/ or a numeric expression with a non-zero value for the option to be enabled or <cf/off/, <cf/no/ or a numeric expression evaluating to zero to -disable it. An empty <m/switch/ is equivalent to <cf/on/ ("silence means -agreement"). +disable it. Alternatively you can gate the value of <m/switch/ on the presence +of a file through the <cf/filename/ "<m/name/" directive. An empty <m/switch/ +is equivalent to <cf/on/ ("silence means agreement").
<descrip> <tag>preference <m/expr/</tag>
That's what we do now, and it sucks. You still end up with embedding BIRD syntax outside of BIRD. If you use no wildcards in the include statement, the file must always be present otherwise the config is invalid, so you now shifted the responsibility of managing "disabled on|off" statements elsewhere. So you have the added complexity of having to read in the file, parse it to see if it matches your understanding of the world, and then rewrite it back out if not. The presence or absence of a file is a much more explicit signalling mechanism. On Tue, May 24, 2016 at 6:00 AM, Baptiste Jonglez <baptiste@bitsofnetworks.org> wrote:
Hi,
On Sun, May 22, 2016 at 04:50:12PM -0700, João Taveira Araújo wrote:
Toggling session parameters currently requires editing the configuration file and reloading BIRD. Doing so programatically requires keeping up with the syntax and layout of a particular configuration.
This commit introduces an alternative method for gating configuration of boolean protocol properties. In addition to the keywords on/off and yes/no, a user can instead provide a filename on which to predicate whether the flag is set.
In particular, this makes toggling protocols programatically much simpler, since we can decouple state from configuration more cleanly, i.e:
protocol kernel { disabled filename "/etc/disable-kernel"; }
Can't you achieve the same effect with an include? The included file would just need to contain either nothing, or "disabled yes".
--- conf/cf-lex.l | 23 +++++++++++++++++++++++ conf/conf.h | 1 + conf/confbase.Y | 3 ++- doc/bird.sgml | 5 +++-- 4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 5a2a4d6..af85291 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -693,6 +693,29 @@ cf_symbol_class_name(struct symbol *sym) } }
+/** + * cf_file_exists - check if expanded filename exists + * @arg: filename + * + * This function expands relative filenames and returns + * whether file is present. + */ +int +cf_file_exists(char *arg) +{ + char *patt = arg; + + if (*arg != '/') + { + int dlen = strlen(ifs->file_name); + char *dir = alloca(dlen + 1); + patt = alloca(dlen + strlen(arg) + 2); + memcpy(dir, ifs->file_name, dlen + 1); + sprintf(patt, "%s/%s", dirname(dir), arg); + } + + return access(patt, F_OK) != -1; +}
/** * DOC: Parser diff --git a/conf/conf.h b/conf/conf.h index 89a2c5b..6f6a33d 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -160,6 +160,7 @@ char *cf_symbol_class_name(struct symbol *sym); static inline int cf_symbol_is_constant(struct symbol *sym) { return (sym->class & 0xff00) == SYM_CONSTANT; }
+int cf_file_exists(char *arg);
/* Parser */
diff --git a/conf/confbase.Y b/conf/confbase.Y index 5f487c1..7ee26f3 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -88,7 +88,7 @@ CF_DECLS %left '!' %nonassoc '.'
-CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT) +CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, FILENAME)
CF_GRAMMAR
@@ -143,6 +143,7 @@ bool: | YES { $$ = 1; } | OFF { $$ = 0; } | NO { $$ = 0; } + | FILENAME text { $$ = cf_file_exists($2); } | /* Silence means agreement */ { $$ = 1; } ;
diff --git a/doc/bird.sgml b/doc/bird.sgml index a0b45f4..03682cb 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -493,8 +493,9 @@ protocol (see sections talking about the protocols). <p>Several options use a <m/switch/ argument. It can be either <cf/on/, <cf/yes/ or a numeric expression with a non-zero value for the option to be enabled or <cf/off/, <cf/no/ or a numeric expression evaluating to zero to -disable it. An empty <m/switch/ is equivalent to <cf/on/ ("silence means -agreement"). +disable it. Alternatively you can gate the value of <m/switch/ on the presence +of a file through the <cf/filename/ "<m/name/" directive. An empty <m/switch/ +is equivalent to <cf/on/ ("silence means agreement").
<descrip> <tag>preference <m/expr/</tag>
Personally, I don't really like this feature very much. On 24-05-2016 14:29, João Taveira Araújo wrote:
That's what we do now, and it sucks. You still end up with embedding BIRD syntax outside of BIRD. If you use no wildcards in the include statement, the file must always be present otherwise the config is invalid, so you now shifted the responsibility of managing "disabled on|off" statements elsewhere.
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want). In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it. In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction. Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
So you have the added complexity of having to read in the file, parse it to see if it matches your understanding of the world, and then rewrite it back out if not. The presence or absence of a file is a much more explicit signalling mechanism.
Either the include file is considered generated content, or it's not. That's the point in separating machine-generated configs to another file. If the file is human-maintained, your scripts have no reason to mess with it; and if it's machine-maintained, the machine can just overwrite it. Presumably, your humans know which files they need to edit in their day to day configurations, but it's a trivial matter of adding a header to the file in your script, e.g.: -----8<------ /* * WARNING WARNING * This file is automatically generated by script-foo.sh. * Any manual edits will be overwritten! */ disable yes; ----->8------ -- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
Hi, On Tue, May 24, 2016 at 7:31 AM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
Personally, I don't really like this feature very much.
That's fine, I personally don't like RIP and don't feel obliged to use it...
On 24-05-2016 14:29, João Taveira Araújo wrote:
That's what we do now, and it sucks. You still end up with embedding BIRD syntax outside of BIRD. If you use no wildcards in the include statement, the file must always be present otherwise the config is invalid, so you now shifted the responsibility of managing "disabled on|off" statements elsewhere.
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want).
If the file is not present, the disabled statement is off. In both cases the configuration is correct.
In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it.
"Accidentally deleting a file" is about the same as "accidentally putting the wrong value into a stanza". If you want to avoid exposure to either case, you don't use either feature.
In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction.
Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
I value practicality over common practice, my use cases are wildly different to most.
So you have the added complexity of having to read in the file, parse it to see if it matches your understanding of the world, and then rewrite it back out if not. The presence or absence of a file is a much more explicit signalling mechanism.
Either the include file is considered generated content, or it's not. That's the point in separating machine-generated configs to another file. If the file is human-maintained, your scripts have no reason to mess with it; and if it's machine-maintained, the machine can just overwrite it.
Presumably, your humans know which files they need to edit in their day to day configurations, but it's a trivial matter of adding a header to the file in your script, e.g.:
-----8<------ /* * WARNING WARNING * This file is automatically generated by script-foo.sh. * Any manual edits will be overwritten! */ disable yes; ----->8------
We've used that sort of include script in production for many years. It's OK (and unavoidable if you want to have dynamically generated prefix sets), but as an interface it's more complex and as an abstraction it's less elegant. Cheers, - j
-- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
On 24-05-2016 19:36, João Taveira Araújo wrote:
Hi,
On Tue, May 24, 2016 at 7:31 AM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want).
If the file is not present, the disabled statement is off. In both cases the configuration is correct.
You are referring to syntactic validity; I'm referring to semantic validity. A correct configuration for me is one in which the router does what I want it to do.
In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it.
"Accidentally deleting a file" is about the same as "accidentally putting the wrong value into a stanza". If you want to avoid exposure to either case, you don't use either feature.
Please note that the problem of disappearing files was brought up by you in your initial email: "the file must always be present otherwise the config is invalid". I merely noted that if you're in a situation where you have to worry about configuration files suddenly disappearing, then you will most definitely want the daemon to break and throw up when that happens. Not silently toggle a flag and change half your network.
In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction.
Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
I value practicality over common practice, my use cases are wildly different to most.
Please cf the principle of least surprise. Nothing's stopping you from patching Bird to read binary-encoded prefixes from an inode's timestamps... and while that may seem very practical for some wildly different use case, it will still surprise the living sanity out of anyone unfortunate enough to be hired to manage such a system.
We've used that sort of include script in production for many years. It's OK (and unavoidable if you want to have dynamically generated prefix sets), but as an interface it's more complex and as an abstraction it's less elegant.
I would argue that this alteration is what adds complexity to the interface... As for elegance, I would ask about consistency. Why only boolean values? What if I want to specify a timeout value using the amount of files in a directory? Can I create 50 files to mean 50 seconds? Why use files? It could be the content of a symlink. Or the presence of a certain username. That way I can toggle the configuration just by logging in. Surely that must be practical for some wild use case too... Regards, -- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
Hi, Any feedback on this? I didn't follow up with a reply because the argument presented against was a straw man fallacy followed by a slippery slope. I realize that I could very well encode a boolean in 134 characters as in the example provided, but would rather signal that through the presence of a file. Cheers, - j On Tue, May 24, 2016 at 12:09 PM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
On 24-05-2016 19:36, João Taveira Araújo wrote:
Hi,
On Tue, May 24, 2016 at 7:31 AM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want).
If the file is not present, the disabled statement is off. In both cases the configuration is correct.
You are referring to syntactic validity; I'm referring to semantic validity. A correct configuration for me is one in which the router does what I want it to do.
In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it.
"Accidentally deleting a file" is about the same as "accidentally putting the wrong value into a stanza". If you want to avoid exposure to either case, you don't use either feature.
Please note that the problem of disappearing files was brought up by you in your initial email: "the file must always be present otherwise the config is invalid".
I merely noted that if you're in a situation where you have to worry about configuration files suddenly disappearing, then you will most definitely want the daemon to break and throw up when that happens. Not silently toggle a flag and change half your network.
In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction.
Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
I value practicality over common practice, my use cases are wildly different to most.
Please cf the principle of least surprise. Nothing's stopping you from patching Bird to read binary-encoded prefixes from an inode's timestamps... and while that may seem very practical for some wildly different use case, it will still surprise the living sanity out of anyone unfortunate enough to be hired to manage such a system.
We've used that sort of include script in production for many years. It's OK (and unavoidable if you want to have dynamically generated prefix sets), but as an interface it's more complex and as an abstraction it's less elegant.
I would argue that this alteration is what adds complexity to the interface...
As for elegance, I would ask about consistency. Why only boolean values? What if I want to specify a timeout value using the amount of files in a directory? Can I create 50 files to mean 50 seconds? Why use files? It could be the content of a symlink. Or the presence of a certain username. That way I can toggle the configuration just by logging in. Surely that must be practical for some wild use case too...
Regards,
-- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
Hello All, Personally I like the proposed "existence-of-a-file-is-a-Boolean" approach because of the exact reason That it was originally proposed: It simplifies, clarifies, and significantly easies integrating bird config and control into other applications. Thanks! Edward Pendzik :-) -----Original Message----- From: Bird-users [mailto:bird-users-bounces@network.cz] On Behalf Of João Taveira Araújo Sent: Thursday, July 28, 2016 2:09 PM To: Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> Cc: bird-users@network.cz Subject: Re: [PATCH] Gate boolean protocol options on filename. Hi, Any feedback on this? I didn't follow up with a reply because the argument presented against was a straw man fallacy followed by a slippery slope. I realize that I could very well encode a boolean in 134 characters as in the example provided, but would rather signal that through the presence of a file. Cheers, - j On Tue, May 24, 2016 at 12:09 PM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
On 24-05-2016 19:36, João Taveira Araújo wrote:
Hi,
On Tue, May 24, 2016 at 7:31 AM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want).
If the file is not present, the disabled statement is off. In both cases the configuration is correct.
You are referring to syntactic validity; I'm referring to semantic validity. A correct configuration for me is one in which the router does what I want it to do.
In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it.
"Accidentally deleting a file" is about the same as "accidentally putting the wrong value into a stanza". If you want to avoid exposure to either case, you don't use either feature.
Please note that the problem of disappearing files was brought up by you in your initial email: "the file must always be present otherwise the config is invalid".
I merely noted that if you're in a situation where you have to worry about configuration files suddenly disappearing, then you will most definitely want the daemon to break and throw up when that happens. Not silently toggle a flag and change half your network.
In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction.
Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
I value practicality over common practice, my use cases are wildly different to most.
Please cf the principle of least surprise. Nothing's stopping you from patching Bird to read binary-encoded prefixes from an inode's timestamps... and while that may seem very practical for some wildly different use case, it will still surprise the living sanity out of anyone unfortunate enough to be hired to manage such a system.
We've used that sort of include script in production for many years. It's OK (and unavoidable if you want to have dynamically generated prefix sets), but as an interface it's more complex and as an abstraction it's less elegant.
I would argue that this alteration is what adds complexity to the interface...
As for elegance, I would ask about consistency. Why only boolean values? What if I want to specify a timeout value using the amount of files in a directory? Can I create 50 files to mean 50 seconds? Why use files? It could be the content of a symlink. Or the presence of a certain username. That way I can toggle the configuration just by logging in. Surely that must be practical for some wild use case too...
Regards,
-- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
On 07/28/2016 07:09 PM, João Taveira Araújo wrote:
Hi,
Any feedback on this?
I didn't follow up with a reply because the argument presented against was a straw man fallacy followed by a slippery slope. I realize that I could very well encode a boolean in 134 characters as in the example provided, but would rather signal that through the presence of a file.
Actually, no. I realize it's easier to just dismiss any confrontation by yelling persecution, but you still haven't made any case as to the utility of this feature, much less its sanity. You mentioned some special "wildly different" use cases, which might which even have shown this to be useful, but unfortunately you didn't care to elaborate. Instead, the reader is left to evaluate the merits of this idea based solely on the claim that it is hard to "keep up with the syntax and layout of a particular configuration". Someone suggested using include files, which makes perfect sense. You dismissed that with some vague hand waving about how if the included file wasn't there, the config would be invalid. Totally ignoring the suggestion, as the whole point was that you don't need any magically disappearing files. You put your desired configuration in a file. Bird reads the file. Done. Enabling a variable means "bla = 1", disabling it means "bla = 0". You further dismissed the suggestion you were given, going on some tangent about having to parse configuration files. Nothing like that was suggested or required. I then mentioned that, if you're worried about files going missing when they're not supposed to, then that kind of defeats the purpose of using the presence of files to signal something. Either you are in control of their presence, or you are not. If you can't control their presence, game over. If you can, then you can rely on them being there, and can use their content for something useful, like configuring Bird. Presumably you already know which features you want to enable, yes? Great! Now just write these 2 lines of Python: for variable, value in my_variables: conffile.write("%s = %s" % (variable, value)) Want it in Bash? Ok: variable1=$(do_i_want_to_enable_A) variable2=$(do_i_want_to_enable_B) cat > conffile <<_EOF variable1 = $variable1 variable2 = $variable2 _EOF You don't have to parse anything. The config file is a generated file. You overwrite it with your (correct) version of the truth. You can even include a warning header if you want to.
Cheers, - j
On Tue, May 24, 2016 at 12:09 PM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
On 24-05-2016 19:36, João Taveira Araújo wrote:
Hi,
On Tue, May 24, 2016 at 7:31 AM, Israel G. Lugo <israel.lugo@tecnico.ulisboa.pt> wrote:
But that is still the case in your approach... The file being present dictates whether or not the configuration is valid (does what you want).
If the file is not present, the disabled statement is off. In both cases the configuration is correct.
You are referring to syntactic validity; I'm referring to semantic validity. A correct configuration for me is one in which the router does what I want it to do.
In fact, for me your approach is more dangerous: in the "include" case, an accidentally deleted file will trigger an error (which you will notice and fix), but in your case it's impossible to tell whether a missing file is an error, or you really mean it.
"Accidentally deleting a file" is about the same as "accidentally putting the wrong value into a stanza". If you want to avoid exposure to either case, you don't use either feature.
Please note that the problem of disappearing files was brought up by you in your initial email: "the file must always be present otherwise the config is invalid".
I merely noted that if you're in a situation where you have to worry about configuration files suddenly disappearing, then you will most definitely want the daemon to break and throw up when that happens. Not silently toggle a flag and change half your network.
In my opinion, configuration error (in this case an accidentally deleted file) should break rather than silently malfunction.
Put in other words, you now shifted the responsibility of configuring the service on the mere presence of files in specific places. That's not a very common practice...
I value practicality over common practice, my use cases are wildly different to most.
Please cf the principle of least surprise. Nothing's stopping you from patching Bird to read binary-encoded prefixes from an inode's timestamps... and while that may seem very practical for some wildly different use case, it will still surprise the living sanity out of anyone unfortunate enough to be hired to manage such a system.
We've used that sort of include script in production for many years. It's OK (and unavoidable if you want to have dynamically generated prefix sets), but as an interface it's more complex and as an abstraction it's less elegant.
I would argue that this alteration is what adds complexity to the interface...
As for elegance, I would ask about consistency. Why only boolean values? What if I want to specify a timeout value using the amount of files in a directory? Can I create 50 files to mean 50 seconds? Why use files? It could be the content of a symlink. Or the presence of a certain username. That way I can toggle the configuration just by logging in. Surely that must be practical for some wild use case too...
Regards,
-- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
-- Israel G. Lugo Núcleo de Redes e Comunicações Direção de Serviços de Informática Instituto Superior Técnico
On Thu, Jul 28, 2016 at 11:09:08AM -0700, João Taveira Araújo wrote:
Hi,
Any feedback on this?
Hi Although i agree that we should have better ways to control BIRD programmatically, this feature seems to me like too specific and too bizarre. I see at least two alternatives already awailable: 1) Use include directive in the usual way (so you would have to use file cointaining "disabled;" or appropriate option instead of empty file). If you want to treat non-existing files as no change, then just add '*' at the end of the file name. 2) Note that include directive looks like regular configuration statement, but it is not. It is more like preprocessor directive and can be used even inside other statements, like: protocol ... { disabled include "xxx.conf";; } Then file xxx.conf should contain just the value (yes or no). This approach can be used with any kind of option and seems like more generic and more natural approach than gated boolean options. Note that include has to be on separate line to be parsed correctly and there has to be two semicolons (first for include, second for the option). This is something that we will probably address in future version (so that 'disabled include "xxx.conf";' would be enough). -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
Hi, On Fri, Jul 29, 2016 at 3:43 AM, Ondrej Zajicek <santiago@crfreenet.org> wrote:
On Thu, Jul 28, 2016 at 11:09:08AM -0700, João Taveira Araújo wrote:
Hi,
Any feedback on this?
Hi
Although i agree that we should have better ways to control BIRD programmatically, this feature seems to me like too specific and too bizarre.
I see at least two alternatives already awailable:
1) Use include directive in the usual way (so you would have to use file cointaining "disabled;" or appropriate option instead of empty file). If you want to treat non-existing files as no change, then just add '*' at the end of the file name.
2) Note that include directive looks like regular configuration statement, but it is not. It is more like preprocessor directive and can be used even inside other statements, like:
protocol ... {
disabled include "xxx.conf";;
}
Then file xxx.conf should contain just the value (yes or no). This approach can be used with any kind of option and seems like more generic and more natural approach than gated boolean options.
Note that include has to be on separate line to be parsed correctly and there has to be two semicolons (first for include, second for the option). This is something that we will probably address in future version (so that 'disabled include "xxx.conf";' would be enough).
I'm aware of both options, and I've been using 1) for a while, which was why I was asking if there was any other way. It feels odd to embed BIRD syntax into multiple agents that may control BIRD, and makes integration testing clunkier because I have to verify the contents of a file. In this respect, "disabled include 'xxx.conf';", while easier to read, provides no more value for us than the existing solution. If your main concern is that it only applies to the disabled command, then I agree that it should be generalized. We also do withdrawal of prefixes based on the presence of a file ("if exists("withdraw_anycast")" then ...), because that way configuration is decoupled from state. It's the only reasonable way we've found for our configuration to be updated (e.g. adding anycast prefixes) regularly without affecting our policy (e.g. "don't announce anycast for this session"). IIRC however there are differences between config and filter syntax that made "disabled if exists("bla");" less trivial to implement. Cheers, - joao
-- Elen sila lumenn' omentielvo
Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
participants (5)
-
Baptiste Jonglez -
Israel G. Lugo -
João Taveira Araújo -
Ondrej Zajicek -
Pendzik, Edward