From 3e82b5cd33e16be82e0d453101e2a9fe09ab1c16 Mon Sep 17 00:00:00 2001 From: "roberto@sirius" Date: Mon, 7 Mar 2011 16:06:59 +0100 Subject: [PATCH] improved configuration system --- buildconf/default.ini | 1 - ini.c | 28 +----- plugins/python/python_plugin.c | 3 + utils.c | 74 ++++----------- uwsgi.c | 162 ++++++++++++++++++++++++++------- uwsgi.h | 6 +- vassals/cc.ini | 9 ++ vassals/multi.xml | 31 +++++++ xmlconf.c | 63 ++++--------- yaml.c | 28 +----- 10 files changed, 213 insertions(+), 192 deletions(-) create mode 100644 vassals/cc.ini create mode 100644 vassals/multi.xml diff --git a/buildconf/default.ini b/buildconf/default.ini index f1f28f9a..4edf3286 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -15,7 +15,6 @@ async = true evdis = false ldap = false pcre = auto -stackless = false debug = false unbit = false xml_implementation = libxml2 diff --git a/ini.c b/ini.c index 7616a577..5e3e512c 100644 --- a/ini.c +++ b/ini.c @@ -84,7 +84,6 @@ void uwsgi_ini_config(char *file, char *magic_table[]) { int lines = 1; - struct option *lopt, *aopt; char *section_asked = "uwsgi"; char *colon; @@ -126,32 +125,7 @@ void uwsgi_ini_config(char *file, char *magic_table[]) { ini_rstrip(key); val = ini_lstrip(val); ini_rstrip(val); - lopt = uwsgi.long_options; - while ((aopt = lopt)) { - if (!aopt->name) - break; - if (!strcmp(key, aopt->name)) { - if (aopt->flag) { - *aopt->flag = aopt->val; - add_exported_option(0, (char *)key); - } - else { - if (aopt->has_arg == optional_argument) { - if (!strcmp("true", val)) { - val = NULL; - } - } - if (aopt->has_arg == no_argument) { - if (!strcmp("false", val) || val[0] == '0') { - lopt++; - continue; - } - } - manage_opt(aopt->val, val); - } - } - lopt++; - } + add_exported_option((char *)key, val, 0); } } } diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 9c366678..0ce06777 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -798,6 +798,9 @@ int uwsgi_python_xml(char *node, char *content) { uwsgi.wsgi_req->module_len = strlen(uwsgi.wsgi_req->module); return init_uwsgi_app(LOADER_DYN, uwsgi.wsgi_req, uwsgi.wsgi_req, interpreter); } + else { + return init_uwsgi_app(LOADER_UWSGI, content, uwsgi.wsgi_req, interpreter); + } return 1; } else if (!strcmp("pyhome", node)) { diff --git a/utils.c b/utils.c index 989f2f3d..3e3e3771 100644 --- a/utils.c +++ b/utils.c @@ -614,13 +614,11 @@ void env_to_arg(char *src, char *dst) { void parse_sys_envs(char **envs) { - struct option *lopt, *aopt; - char **uenvs = envs; char *earg, *eq_pos; while(*uenvs) { - if (!strncmp(*uenvs, "UWSGI_", 6)) { + if (!strncmp(*uenvs, "UWSGI_", 6) && strncmp(*uenvs, "UWSGI_RELOADS=",14)) { earg = uwsgi_malloc(strlen(*uenvs+6)+1); env_to_arg(*uenvs+6, earg); eq_pos = strchr(earg, '='); @@ -629,27 +627,7 @@ void parse_sys_envs(char **envs) { } eq_pos[0] = 0; - lopt = uwsgi.long_options; - - while ((aopt = lopt)) { - if (!aopt->name) - break; - if (!strcmp(earg, aopt->name)) { - if (aopt->flag) { - *aopt->flag = aopt->val; - } - else { - if (eq_pos[1] != 0) { - manage_opt(aopt->val, eq_pos+1); - } - else { - manage_opt(aopt->val, NULL); - } - } - } - lopt++; - } - + add_exported_option(earg, eq_pos+1, 0); } uenvs++; } @@ -1173,37 +1151,7 @@ end: return 0; } -void add_exported_option(int i, char *value) { - - char *key = NULL; - struct option *lopt, *aopt; - - if (i == 0) { - key = value; - value = NULL; - } - else { - lopt = uwsgi.long_options; - while ((aopt = lopt)) { - if (!aopt->name) - break; - if (aopt->val == 0 && *aopt->flag == i) { - key = (char *) aopt->name; - break; - } - if (aopt->val == i) { - key = (char *) aopt->name; - break; - } - lopt++; - } - } - - //uwsgi_log("%s = %s\n", key, value); - - if (!key) return; - - +void add_exported_option(char *key, char *value, int configured) { if (!uwsgi.exported_opts) { uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt*)); @@ -1216,10 +1164,10 @@ void add_exported_option(int i, char *value) { } } - uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt)); uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key; uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value; + uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured; uwsgi.exported_opts_cnt++; } @@ -1489,6 +1437,7 @@ void init_magic_table(char *magic_table[]) { } magic_table['%'] = "%"; + magic_table['('] = "%("; } char *uwsgi_get_last_char(char *what, char c) { @@ -1654,3 +1603,16 @@ void uwsgi_unix_signal(int signum, void (*func)(int)) { uwsgi_error("sigaction()"); } } + +char *uwsgi_get_exported_opt(char *key) { + + int i; + + for (i = 0; i < uwsgi.exported_opts_cnt; i++) { + if (!strcmp(uwsgi.exported_opts[i]->key, key)) { + return uwsgi.exported_opts[i]->value; + } + } + + return NULL; +} diff --git a/uwsgi.c b/uwsgi.c index efbd0b71..c81dbfe4 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -160,6 +160,7 @@ static struct option long_base_options[] = { {"plugins", required_argument, 0, LONG_ARGS_PLUGINS}, {"remap-modifier", required_argument, 0, LONG_ARGS_REMAP_MODIFIER}, {"dump-options", no_argument, &uwsgi.dump_options, 1}, + {"show-config", no_argument, &uwsgi.show_config, 1}, {"print", required_argument, 0, LONG_ARGS_PRINT}, {"version", no_argument, 0, LONG_ARGS_VERSION}, {0, 0, 0, 0} @@ -425,7 +426,7 @@ static void vacuum(void) int main(int argc, char *argv[], char *envp[]) { - int i; + int i, j; int rlen; FILE *pidfile; @@ -584,21 +585,14 @@ int main(int argc, char *argv[], char *envp[]) while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) { if (i == 0) { - add_exported_option(0, (char *)uwsgi.long_options[uwsgi.option_index].name); + add_exported_option((char *)uwsgi.long_options[uwsgi.option_index].name, "1", 0); } else { + add_exported_option((char *)uwsgi.long_options[uwsgi.option_index].name, optarg, 1); manage_opt(i, optarg); } } - if (uwsgi.dump_options) { - struct option *lopt = uwsgi.long_options; - while(lopt->name) { - uwsgi_log("--%s\n", lopt->name); - lopt++; - } - } - if (optind < argc) { char *lazy = argv[optind]; @@ -647,10 +641,18 @@ int main(int argc, char *argv[], char *envp[]) } } + if (gethostname(uwsgi.hostname, 255)) { + uwsgi_error("gethostname()"); + } + uwsgi.hostname_len = strlen(uwsgi.hostname); + + + magic_table['v'] = uwsgi.cwd; + magic_table['h'] = uwsgi.hostname; + #ifdef UWSGI_XML if (uwsgi.xml_config != NULL) { magic_table['o'] = uwsgi.xml_config; - magic_table['v'] = uwsgi.cwd; if (uwsgi.xml_config[0] == '/') { magic_table['p'] = uwsgi.xml_config; } @@ -662,12 +664,12 @@ int main(int argc, char *argv[], char *envp[]) if (uwsgi_get_last_char(uwsgi.xml_config, '.')) magic_table['e'] = uwsgi_get_last_char(uwsgi.xml_config, '.')+1; if (uwsgi_get_last_char(magic_table['s'], '.')) magic_table['n'] = uwsgi_concat2n(magic_table['s'], uwsgi_get_last_char(magic_table['s'], '.')-magic_table['s'], "", 0) ; uwsgi_xml_config(uwsgi.wsgi_req, 0, magic_table); + uwsgi.xml_config = magic_table['p']; } #endif #ifdef UWSGI_INI if (uwsgi.ini != NULL) { magic_table['o'] = uwsgi.ini; - magic_table['v'] = uwsgi.cwd; if (uwsgi.ini[0] == '/') { magic_table['p'] = uwsgi.ini; } @@ -685,7 +687,6 @@ int main(int argc, char *argv[], char *envp[]) #ifdef UWSGI_YAML if (uwsgi.yaml != NULL) { magic_table['o'] = uwsgi.yaml; - magic_table['v'] = uwsgi.cwd; if (uwsgi.yaml[0] == '/') { magic_table['p'] = uwsgi.yaml; } @@ -708,12 +709,121 @@ int main(int argc, char *argv[], char *envp[]) //parse environ parse_sys_envs(environ); - if (gethostname(uwsgi.hostname, 255)) { - uwsgi_error("gethostname()"); + + // second pass + for (i = 0; i < uwsgi.exported_opts_cnt; i++) { + int has_percent = 0; + char *magic_key = NULL; + char *magic_val = NULL; + if (uwsgi.exported_opts[i]->value && !uwsgi.exported_opts[i]->configured) { + for(j=0;j<(int)strlen(uwsgi.exported_opts[i]->value);j++) { + if (uwsgi.exported_opts[i]->value[j] == '%') { + has_percent = 1; + } + else if (uwsgi.exported_opts[i]->value[j] == '(' && has_percent == 1) { + has_percent = 2; + magic_key = uwsgi.exported_opts[i]->value + j + 1; + } + else if (has_percent > 1) { + if (uwsgi.exported_opts[i]->value[j] == ')') { + if (has_percent <= 2) { + magic_key = NULL; + has_percent = 0; + continue; + } +#ifdef UWSGI_DEBUG + uwsgi_log("need to interpret the %.*s tag\n", has_percent-2, magic_key); +#endif + char *tmp_magic_key = uwsgi_concat2n(magic_key, has_percent-2, "", 0); + magic_val = uwsgi_get_exported_opt(tmp_magic_key); + free(tmp_magic_key); + if (!magic_val) { + magic_key = NULL; + has_percent = 0; + continue; + } + uwsgi.exported_opts[i]->value = uwsgi_concat4n( + uwsgi.exported_opts[i]->value, (magic_key-2) - uwsgi.exported_opts[i]->value, + magic_val, strlen(magic_val), + magic_key + (has_percent-1), + strlen(magic_key + (has_percent-1)), "", 0); +#ifdef UWSGI_DEBUG + uwsgi_log("computed new value = %s\n", uwsgi.exported_opts[i]->value); +#endif + magic_key = NULL; + has_percent = 0; + } + else { + has_percent++; + } + } + else { + has_percent = 0; + } + } + } } - uwsgi.hostname_len = strlen(uwsgi.hostname); + // ok, the options dictionary is available, lets manage it + + struct option *lopt = uwsgi.long_options; + struct option *aopt; + char *val; + + for(i=0;iconfigured) continue; + lopt = uwsgi.long_options;; + while ((aopt = lopt)) { + if (!aopt->name) break; + + if (!strcmp(aopt->name, uwsgi.exported_opts[i]->key)) { + val = uwsgi.exported_opts[i]->value; + + if (aopt->flag) *aopt->flag = aopt->val; + else if (val) { + if (aopt->has_arg == optional_argument) { + if (!strcasecmp("true", val)) { + val = NULL; + } + } + if (aopt->has_arg == no_argument) { + if (!strcasecmp("false", val) || val[0] == '0') { + lopt++; + continue; + } + } + manage_opt(aopt->val, val); + } + } + lopt++; + } + } + + + /* uWSGI IS CONFIGURED !!! */ + + if (uwsgi.dump_options) { + struct option *lopt = uwsgi.long_options; + while(lopt->name) { + uwsgi_log("--%s\n", lopt->name); + lopt++; + } + } + + if (uwsgi.show_config) { + fprintf(stdout, "\n;uWSGI instance configuration\n[uwsgi]\n"); + for(i=0;ivalue) { + fprintf(stdout,"%s = %s\n", uwsgi.exported_opts[i]->key, uwsgi.exported_opts[i]->value); + } + else { + fprintf(stdout,"%s = true\n", uwsgi.exported_opts[i]->key); + } + } + fprintf(stdout, ";end of configuration\n\n"); + } #ifdef UWSGI_UDP @@ -2393,14 +2503,12 @@ end: int j; if (manage_base_opt(i, optarg)) { - add_exported_option( i, optarg ); return; } for (j = 0; j < 0xFF; j++) { if (uwsgi.p[j]->manage_opt) { if (uwsgi.p[j]->manage_opt(i, optarg)) { - add_exported_option( i, optarg ); return; } } @@ -2409,7 +2517,6 @@ end: for (j = 0; j < uwsgi.gp_cnt; j++) { if (uwsgi.gp[j]->manage_opt) { if (uwsgi.gp[j]->manage_opt(i, optarg)) { - add_exported_option( i, optarg ); return; } } @@ -2661,27 +2768,12 @@ void build_options() { void manage_string_opt(char *key, uint16_t keylen, char *val, uint16_t vallen, void *data) { - struct option *lopt, *aopt; - // never free this value char *key2 = uwsgi_concat2n(key, keylen, "", 0); char *val2 = uwsgi_concat2n(val, vallen, "", 0); uwsgi_log("%s = %s\n", key2, val2); - lopt = uwsgi.long_options; - while ((aopt = lopt)) { - if (!aopt->name) break; - if (!strcmp(key2, aopt->name)) { - if (aopt->flag) { - *aopt->flag = aopt->val; - add_exported_option(0, key2); - } - else { - manage_opt(aopt->val, val2); - } - } - lopt++; - } + add_exported_option(key2, val2, 0); } #ifdef UWSGI_UDP diff --git a/uwsgi.h b/uwsgi.h index 5b20e310..c98be7ec 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -273,6 +273,7 @@ struct uwsgi_cache_item { struct uwsgi_opt { char *key; char *value; + int configured; }; #define MAX_CLUSTER_NODES 100 @@ -721,6 +722,7 @@ struct uwsgi_server { struct uwsgi_opt **exported_opts; int exported_opts_cnt; int dump_options; + int show_config; //base for all the requests(even on async mode) struct wsgi_request **wsgi_requests; struct wsgi_request *wsgi_req; @@ -1367,7 +1369,7 @@ ssize_t uwsgi_sendfile(struct wsgi_request *); void uwsgi_register_loop(char *, void *); void *uwsgi_get_loop(char *); -void add_exported_option(int, char *); +void add_exported_option(char *, char *, int); ssize_t uwsgi_send_empty_pkt(int , char *, uint8_t , uint8_t); @@ -1586,3 +1588,5 @@ struct uwsgi_rb_timer *uwsgi_min_rb_timer(struct rb_root *); void uwsgi_nuclear_blast(); void uwsgi_unix_signal(int, void (*)(int)); + +char *uwsgi_get_exported_opt(char *); diff --git a/vassals/cc.ini b/vassals/cc.ini new file mode 100644 index 00000000..b29f359a --- /dev/null +++ b/vassals/cc.ini @@ -0,0 +1,9 @@ +[uwsgi] + +trac = trac.web.main +id = myapp +socket = /tmp/%(id).sock +env = TRAC_ENV=/opt/projects/%(id) +module = %(trac):dispatch_request +processes = 8 +master = true diff --git a/vassals/multi.xml b/vassals/multi.xml new file mode 100644 index 00000000..ae9a0e45 --- /dev/null +++ b/vassals/multi.xml @@ -0,0 +1,31 @@ + + + app001 + + starting dir is %v + + %v/../ + 127.0.0.1 + + %(localhost):3031 + /tmp/%(id).sock + + 4 + werkzeug.testapp:test_app + + + + + + + %(cpus) + + + + + + + + + + diff --git a/xmlconf.c b/xmlconf.c index 784a9085..ae4f747a 100644 --- a/xmlconf.c +++ b/xmlconf.c @@ -18,12 +18,11 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta xmlChar *xml_uwsgi_mountpoint = NULL; xmlChar *xml_uwsgi_domain = NULL; xmlChar *node_mode; - struct option *lopt, *aopt; char *colon; - char *xml_id; int i; + char *xml_id; char *xml_content; int xml_size = 0; @@ -105,52 +104,26 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag, char *magic_ta continue; } #endif - lopt = uwsgi.long_options; - while ((aopt = lopt)) { - if (!aopt->name) - break; - if (!strcmp((char *) node->name, aopt->name)) { - if (!node->children && aopt->has_arg) { - uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name); - exit(1); - } - if (node->children) { - if (!node->children->content && aopt->has_arg) { - uwsgi_log( "[uWSGI] %s option need a value. skip.\n", aopt->name); - exit(1); - } - } + node_mode = xmlGetProp(node, (const xmlChar *) "mode"); + if (uwsgi.mode && node_mode) { + if (strcmp(uwsgi.mode, (char *) node_mode)) { + continue; + } + } - node_mode = xmlGetProp(node, (const xmlChar *) "mode"); - if (uwsgi.mode && node_mode) { - if (strcmp(uwsgi.mode, (char *) node_mode)) { - goto next; - } - } + xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id"); + if (colon && xml_id) { + if (strcmp(colon, xml_id)) { + continue; + } + } - xml_id = (char *) xmlGetProp(node, (const xmlChar *) "id"); - if (colon && xml_id) { - if (strcmp(colon, xml_id)) { - goto next; - } - } - - if (aopt->flag) { - *aopt->flag = aopt->val; - add_exported_option(0, (char *) node->name); - } - else { - if (node->children) { - manage_opt(aopt->val, (char *) node->children->content); - } - else { - manage_opt(aopt->val, NULL); - } - } - } -next: - lopt++; + if (node->children) { + add_exported_option((char *) node->name, (char *) node->children->content, 0); + } + else { + add_exported_option((char *) node->name, "1", 0); } } } diff --git a/yaml.c b/yaml.c index ead0ef7f..5abae377 100644 --- a/yaml.c +++ b/yaml.c @@ -101,7 +101,6 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) { int lines = 1; - struct option *lopt, *aopt; char *section_asked = "uwsgi"; char *colon; @@ -171,32 +170,7 @@ void uwsgi_yaml_config(char *file, char *magic_table[]) { //uwsgi_log("YAML: %s = %s\n", key, val); - lopt = uwsgi.long_options; - while ((aopt = lopt)) { - if (!aopt->name) - break; - if (!strcmp(key, aopt->name)) { - if (aopt->flag) { - *aopt->flag = aopt->val; - add_exported_option(0, (char *)key); - } - else { - if (aopt->has_arg == optional_argument) { - if (!strcmp("true", val)) { - val = NULL; - } - } - if (aopt->has_arg == no_argument) { - if (!strcmp("false", val) || val[0] == '0') { - lopt++; - continue; - } - } - manage_opt(aopt->val, val); - } - } - lopt++; - } + add_exported_option((char *)key, val, 0); } next: len -= (yaml_line - yaml);