config: Add option to NOT preserve effective context when changing a template

Let's say you have a template T with variable VAR1 = ON and you have a
context C(T) that doesn't specify VAR1.  If you read C, the effective value
of VAR1 is ON.  Now you change T VAR1 to OFF and call
ast_config_text_file_save.  The current behavior is that the file gets
re-written with T/VAR1=OFF but C/VAR1=ON is added.  Personally, I think this
is a bug. It's preserving the effective state of C even though I didn't
specify C/VAR1 in th first place.  I believe the behavior should be that if
I didn't specify C/VAR1 originally, then the effective value of C/VAR1 should
continue to follow the inherited state.  Now, if I DID explicitly specify
C/VAR1, the it should be preserved even if the template changes.

Even though I think the existing behavior is a bug, it's been that way forever
so I'm not changing it.  Instead, I've created ast_config_text_file_save2()
that takes a bitmask of flags, one of which is to preserve the effective context
(the current behavior).  The original ast_config_text_file_save calls *2 with
the preserve flag.  If you want the new behavior, call *2 directly without a
flag.

I've also updated Manager UpdateConfig with a new parameter
'PreserveEffectiveContext' whose default is 'yes'.  If you want the new behavior
with UpdateConfig, set 'PreserveEffectiveContext: no'.

Tested-by: George Joseph

Review: https://reviewboard.asterisk.org/r/4297/
........

Merged revisions 430295 from http://svn.asterisk.org/svn/asterisk/branches/13


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430296 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/42/42/1
George Joseph 10 years ago
parent 0c5234f12a
commit 56de48107f

@ -47,6 +47,14 @@ enum {
CONFIG_FLAG_NOREALTIME = (1 << 3),
};
/*! Flags for ast_config_text_file_save2()
*/
enum config_save_flags {
CONFIG_SAVE_FLAG_NONE = (0),
/*! Insure a context doesn't effectively change if a template changes (pre 13.2 behavior) */
CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT = (1 << 0),
};
#define CONFIG_STATUS_FILEMISSING (void *)0
#define CONFIG_STATUS_FILEUNCHANGED (void *)-1
#define CONFIG_STATUS_FILEINVALID (void *)-2
@ -86,7 +94,8 @@ struct ast_variable {
int lineno;
int object; /*!< 0 for variable, 1 for object */
int blanklines; /*!< Number of blanklines following entry */
int blanklines; /*!< Number of blanklines following entry */
int inherited; /*!< 1 for inherited from template or other base */
struct ast_comment *precomments;
struct ast_comment *sameline;
struct ast_comment *trailing; /*!< the last object in the list will get assigned any trailing comments when EOF is hit */
@ -907,6 +916,28 @@ struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, s
int ast_variable_update(struct ast_category *category, const char *variable,
const char *value, const char *match, unsigned int object);
/*!
* \brief Save a config text file
* \since 13.2.0
*
* \param filename Filename
* \param cfg ast_config
* \param generator generator
* \param flags List of config_save_flags
*
* \return 0 on success or -1 on failure.
*/
int ast_config_text_file_save2(const char *filename, const struct ast_config *cfg, const char *generator, uint32_t flags);
/*!
* \brief Save a config text file preserving the pre 13.2 behavior
*
* \param filename Filename
* \param cfg ast_config
* \param generator generator
*
* \return 0 on success or -1 on failure.
*/
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator) __attribute__((deprecated));

@ -1250,8 +1250,11 @@ void ast_category_inherit(struct ast_category *new, const struct ast_category *b
strcpy(x->name, base->name);
x->inst = base;
AST_LIST_INSERT_TAIL(&new->template_instances, x, next);
for (var = base->root; var; var = var->next)
ast_variable_append(new, variable_clone(var));
for (var = base->root; var; var = var->next) {
struct ast_variable *cloned = variable_clone(var);
cloned->inherited = 1;
ast_variable_append(new, cloned);
}
}
struct ast_config *ast_config_new(void)
@ -2358,10 +2361,15 @@ static void insert_leading_blank_lines(FILE *fp, struct inclfile *fi, struct ast
int config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
{
return ast_config_text_file_save(configfile, cfg, generator);
return ast_config_text_file_save2(configfile, cfg, generator, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT);
}
int ast_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator)
{
return ast_config_text_file_save2(configfile, cfg, generator, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT);
}
int ast_config_text_file_save2(const char *configfile, const struct ast_config *cfg, const char *generator, uint32_t flags)
{
FILE *f;
char fn[PATH_MAX];
@ -2522,13 +2530,27 @@ int ast_config_text_file_save(const char *configfile, const struct ast_config *c
AST_LIST_TRAVERSE(&cat->template_instances, x, next) {
struct ast_variable *v;
for (v = x->inst->root; v; v = v->next) {
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
found = 1;
break;
if (flags & CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT) {
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
found = 1;
break;
}
} else {
if (var->inherited) {
found = 1;
break;
} else {
if (!strcasecmp(var->name, v->name) && !strcmp(var->value, v->value)) {
found = 1;
break;
}
}
}
}
if (found)
if (found) {
break;
}
}
if (found) {
var = var->next;

@ -420,6 +420,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="Reload">
<para>Whether or not a reload should take place (or name of specific module).</para>
</parameter>
<parameter name="PreserveEffectiveContext">
<para>Whether the effective category contents should be preserved on template change. Default is true (pre 13.2 behavior).</para>
</parameter>
<parameter name="Action-000000">
<para>Action to take.</para>
<para>0's represent 6 digit number beginning with 000000.</para>
@ -3775,6 +3778,8 @@ static int action_updateconfig(struct mansession *s, const struct message *m)
const char *dfn = astman_get_header(m, "DstFilename");
int res;
const char *rld = astman_get_header(m, "Reload");
int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
enum error_type result;
@ -3792,7 +3797,10 @@ static int action_updateconfig(struct mansession *s, const struct message *m)
result = handle_updates(s, m, cfg, dfn);
if (!result) {
ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
res = ast_config_text_file_save(dfn, cfg, "Manager");
if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
}
res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
ast_config_destroy(cfg);
if (res) {
astman_send_error(s, m, "Save of config failed");

Loading…
Cancel
Save