From d4c4643ddc82ba60f39bdb7104b65523ffc577b6 Mon Sep 17 00:00:00 2001 From: "roberto@fiorenzo" Date: Sun, 14 Nov 2010 20:20:41 +0100 Subject: [PATCH] YAML config file support --- buildconf/core.ini | 1 + buildconf/default.ini | 1 + buildconf/rack.ini | 1 + buildconf/rackp.ini | 1 + ini.c | 13 +-- ldap.c | 16 +-- master.c | 1 - plugins/mono/mono_plugin.c | 35 ++++++ utils.c | 6 +- uwsgi.c | 39 +++++-- uwsgi.h | 23 ++-- uwsgiconfig.py | 4 + werkzeug.yml | 21 ++++ xmlconf.c | 14 +-- yaml.c | 230 +++++++++++++++++++++++++++++++++++++ 15 files changed, 362 insertions(+), 44 deletions(-) create mode 100644 werkzeug.yml create mode 100644 yaml.c diff --git a/buildconf/core.ini b/buildconf/core.ini index c414915f..a9f8a57c 100644 --- a/buildconf/core.ini +++ b/buildconf/core.ini @@ -1,6 +1,7 @@ [uwsgi] xml = true ini = true +yaml = true snmp = true sctp = false erlang = false diff --git a/buildconf/default.ini b/buildconf/default.ini index 27b82608..9639494a 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -1,6 +1,7 @@ [uwsgi] xml = true ini = true +yaml = true snmp = true sctp = false erlang = false diff --git a/buildconf/rack.ini b/buildconf/rack.ini index 265773e1..901ec72a 100644 --- a/buildconf/rack.ini +++ b/buildconf/rack.ini @@ -1,6 +1,7 @@ [uwsgi] xml = true ini = true +yaml = true snmp = true sctp = false erlang = false diff --git a/buildconf/rackp.ini b/buildconf/rackp.ini index 983f63db..89bb993d 100644 --- a/buildconf/rackp.ini +++ b/buildconf/rackp.ini @@ -1,6 +1,7 @@ [uwsgi] xml = true ini = true +yaml = true snmp = true sctp = false erlang = false diff --git a/ini.c b/ini.c index 2dd89e66..34fb723d 100644 --- a/ini.c +++ b/ini.c @@ -2,16 +2,13 @@ #include "uwsgi.h" +extern struct uwsgi_server uwsgi; + /* ini file must be read ALL into memory. This memory must not be freed for all the server lifecycle */ -enum { - ini_key_start, - ini_val_start, -}; - void ini_rstrip(char *line) { off_t i; @@ -74,7 +71,7 @@ char *ini_get_line(char *ini, off_t size) { } -void uwsgi_ini_config(char *file, struct option *long_options) { +void uwsgi_ini_config(char *file) { int fd; ssize_t len; @@ -101,6 +98,8 @@ void uwsgi_ini_config(char *file, struct option *long_options) { } } + uwsgi_log("[uWSGI] getting INI configuration from %s\n", file); + fd = open(file, O_RDONLY); if (fd < 0) { uwsgi_error("open()"); @@ -155,7 +154,7 @@ void uwsgi_ini_config(char *file, struct option *long_options) { ini_rstrip(key); val = ini_lstrip(val); ini_rstrip(val); - lopt = long_options; + lopt = uwsgi.long_options; while ((aopt = lopt)) { if (!aopt->name) break; diff --git a/ldap.c b/ldap.c index 1be87314..b69558d0 100644 --- a/ldap.c +++ b/ldap.c @@ -37,10 +37,10 @@ int calc_ldap_name(char *name) { return strlen(name) + counter; } -void uwsgi_ldap_schema_dump_ldif(struct option *lo) { +void uwsgi_ldap_schema_dump_ldif() { struct option *aopt, *lopt; - lopt = lo; + lopt = uwsgi.long_options; int i; int counter = 30000; @@ -91,7 +91,7 @@ next: uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n"); - lopt = lo; + lopt = uwsgi.long_options; uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( "); @@ -130,10 +130,10 @@ next2: exit(0); } -void uwsgi_ldap_schema_dump(struct option *lo) { +void uwsgi_ldap_schema_dump() { struct option *aopt, *lopt; - lopt = lo; + lopt = uwsgi.long_options; int i; int counter = 30000; int pythonpath_found = 0; @@ -179,7 +179,7 @@ next: uwsgi_log("attributetype ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n"); - lopt = lo; + lopt = uwsgi.long_options; uwsgi_log("objectclass ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( "); @@ -216,7 +216,7 @@ next2: exit(0); } -void uwsgi_ldap_config(struct option *long_options) { +void uwsgi_ldap_config() { LDAP *ldp; LDAPMessage *results, *entry; @@ -318,7 +318,7 @@ void uwsgi_ldap_config(struct option *long_options) { memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len); uwsgi_val[bervalues[0]->bv_len] = 0; - lopt = long_options; + lopt = uwsgi.long_options; while ((aopt = lopt)) { if (!aopt->name) break; diff --git a/master.c b/master.c index f5d72e87..84ca00a9 100644 --- a/master.c +++ b/master.c @@ -388,7 +388,6 @@ void master_loop(char **argv, char **environ) { // TODO rewrite without using exit code (targeted at 0.9.7) - uwsgi_log("CHECK FOR DIED PROCESS %d\n", WEXITSTATUS(waitpid_status)); #ifdef __sun__ /* horrible hack... what the FU*K is doing Solaris ??? */ if (WIFSIGNALED(waitpid_status)) { diff --git a/plugins/mono/mono_plugin.c b/plugins/mono/mono_plugin.c index e69de29b..541cca5d 100644 --- a/plugins/mono/mono_plugin.c +++ b/plugins/mono/mono_plugin.c @@ -0,0 +1,35 @@ +#include "../../uwsgi.h" + +struct uwsgi_mono { + + char *assembly_name ; + +} um; + +int uwsgi_mono_init() { + + + MonoDomain *domain; + + MonoAssembly *assembly; + MonoImage *image, *corlib; + + domain = mono_jit_init("uwsgi"); + + corlib = mono_get_corlib(); + if (!corlib) { + uwsgi_log("unable to initialize MONO engine\n"); + exit(1); + } + + + image = mono_assembly_get_image(assembly); + +} + + +struct uwsgi_plugin mono_plugin = { + + .name = "mono", + .init = uwsgi_mono_init, +}; diff --git a/utils.c b/utils.c index 61a58811..0099b77e 100644 --- a/utils.c +++ b/utils.c @@ -518,7 +518,7 @@ void env_to_arg(char *src, char *dst) { dst[strlen(src)] = 0; } -void parse_sys_envs(char **envs, struct option *long_options) { +void parse_sys_envs(char **envs) { struct option *lopt, *aopt; @@ -539,7 +539,7 @@ void parse_sys_envs(char **envs, struct option *long_options) { } eq_pos[0] = 0; - lopt = long_options; + lopt = uwsgi.long_options; while ((aopt = lopt)) { if (!aopt->name) @@ -1050,7 +1050,7 @@ void add_exported_option(int i, char *value) { } } - uwsgi_log("%s = %s\n", key, value); + //uwsgi_log("%s = %s\n", key, value); if (!key) return; diff --git a/uwsgi.c b/uwsgi.c index 151cdf5c..48d13e9f 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -29,7 +29,7 @@ extern char **environ; static char *short_options = NULL; -static char *base_short_options = "s:p:t:x:d:l:v:b:mcaCTiMhrR:z:A:Q:L"; +static char *base_short_options = "s:p:t:x:d:l:v:b:mcaCTiMhrR:z:A:Q:L:y:"; UWSGI_DECLARE_EMBEDDED_PLUGINS @@ -70,6 +70,10 @@ static struct option long_base_options[] = { #ifdef UWSGI_INI {"ini", required_argument, 0, LONG_ARGS_INI}, #endif +#ifdef UWSGI_YAML + {"yaml", required_argument, 0, 'y'}, + {"yml", required_argument, 0, 'y'}, +#endif #ifdef UWSGI_LDAP {"ldap", required_argument, 0, LONG_ARGS_LDAP}, {"ldap-schema", no_argument, 0, LONG_ARGS_LDAP_SCHEMA}, @@ -462,7 +466,7 @@ int main(int argc, char *argv[], char *envp[]) UWSGI_LOAD_EMBEDDED_PLUGINS // now a bit of magic, if the argv[0] contains a _ try to automatically load a plugin - uwsgi_log("executable name: %s\n", argv[0]); + //uwsgi_log("executable name: %s\n", argv[0]); char *p = strtok(argv[0], "_"); plugins_requested = NULL; while (p != NULL) { @@ -502,9 +506,16 @@ int main(int argc, char *argv[], char *envp[]) if (!strcmp(lazy+strlen(lazy)-4, ".xml")) { uwsgi.xml_config = lazy; } +#ifdef UWSGI_INI else if (!strcmp(lazy+strlen(lazy)-4, ".ini")) { uwsgi.ini = lazy; } +#endif +#ifdef UWSGI_YAML + else if (!strcmp(lazy+strlen(lazy)-4, ".yml")) { + uwsgi.yaml = lazy; + } +#endif // manage magic mountpoint else if (lazy[0] == '/' && strchr(lazy,'=')) { } @@ -534,22 +545,27 @@ int main(int argc, char *argv[], char *envp[]) #ifdef UWSGI_XML if (uwsgi.xml_config != NULL) { - uwsgi_xml_config(uwsgi.wsgi_req, uwsgi.long_options); + uwsgi_xml_config(uwsgi.wsgi_req, 0); } #endif #ifdef UWSGI_INI if (uwsgi.ini != NULL) { - uwsgi_ini_config(uwsgi.ini, uwsgi.long_options); + uwsgi_ini_config(uwsgi.ini); + } +#endif +#ifdef UWSGI_YAML + if (uwsgi.yaml != NULL) { + uwsgi_yaml_config(uwsgi.yaml); } #endif #ifdef UWSGI_LDAP if (uwsgi.ldap != NULL) { - uwsgi_ldap_config(uwsgi.long_options); + uwsgi_ldap_config(); } #endif //parse environ - parse_sys_envs(environ, uwsgi.long_options); + parse_sys_envs(environ); //call after_opt hooks @@ -1153,7 +1169,7 @@ uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 /*parse xml for tags */ #ifdef UWSGI_XML if (uwsgi.xml_round2 && uwsgi.xml_config != NULL) { - uwsgi_xml_config(uwsgi.wsgi_req, NULL); + uwsgi_xml_config(uwsgi.wsgi_req, 1); } #endif @@ -1482,10 +1498,10 @@ end: uwsgi.ldap = optarg; return 1; case LONG_ARGS_LDAP_SCHEMA: - uwsgi_ldap_schema_dump(uwsgi.long_options); + uwsgi_ldap_schema_dump(); return 1; case LONG_ARGS_LDAP_SCHEMA_LDIF: - uwsgi_ldap_schema_dump_ldif(uwsgi.long_options); + uwsgi_ldap_schema_dump_ldif(); return 1; #endif case LONG_ARGS_MODE: @@ -1627,6 +1643,11 @@ end: case LONG_ARGS_UPLOAD_PROGRESS: uwsgi.upload_progress = optarg; return 1; +#ifdef UWSGI_YAML + case 'y': + uwsgi.yaml = optarg; + return 1; +#endif #ifdef UWSGI_INI case LONG_ARGS_INI: uwsgi.ini = optarg; diff --git a/uwsgi.h b/uwsgi.h index 69c9dabc..eaad4d10 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -720,12 +720,13 @@ struct uwsgi_server { struct uwsgi_route routes[MAX_UWSGI_ROUTES]; #endif +#ifdef UWSGI_YAML + char *yaml; +#endif + #ifdef UWSGI_INI char *ini; #endif -#ifdef UWSGI_PASTE - char *paste; -#endif int single_interpreter; @@ -927,7 +928,7 @@ void harakiri(void); void stats(void); #ifdef UWSGI_XML -void uwsgi_xml_config(struct wsgi_request *, struct option *); +void uwsgi_xml_config(struct wsgi_request *, int); #endif void internal_server_error(int, char *); @@ -1062,7 +1063,7 @@ inline struct wsgi_request *current_wsgi_req(void); void sanitize_args(void); void env_to_arg(char *, char *); -void parse_sys_envs(char **, struct option *); +void parse_sys_envs(char **); void uwsgi_log(const char *,...); void uwsgi_log_verbose(const char *,...); @@ -1077,14 +1078,18 @@ void http_loop(void); int unconfigured_hook(struct wsgi_request *); #ifdef UWSGI_INI -void uwsgi_ini_config(char *, struct option *); +void uwsgi_ini_config(char *); +#endif + +#ifdef UWSGI_YAML +void uwsgi_yaml_config(char *); #endif #ifdef UWSGI_LDAP -void uwsgi_ldap_schema_dump(struct option *); -void uwsgi_ldap_schema_dump_ldif(struct option *); -void uwsgi_ldap_config(struct option *); +void uwsgi_ldap_schema_dump(void); +void uwsgi_ldap_schema_dump_ldif(void); +void uwsgi_ldap_config(void); #endif #ifdef __clang__ diff --git a/uwsgiconfig.py b/uwsgiconfig.py index 149ce079..6c7caa47 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -217,6 +217,10 @@ class uConf(): self.cflags.append("-DUWSGI_INI") self.gcc_list.append('ini') + if self.get('yaml'): + self.cflags.append("-DUWSGI_YAML") + self.gcc_list.append('yaml') + if self.get('proxy'): self.depends_on('proxy', ['async']) self.cflags.append("-DUWSGI_PROXY") diff --git a/werkzeug.yml b/werkzeug.yml new file mode 100644 index 00000000..210e7d9d --- /dev/null +++ b/werkzeug.yml @@ -0,0 +1,21 @@ +# werkzeug test module via YAML +uwsgi: + module: werkzeug.testapp:test_app # a comment + socket: :3032 # another comment +# a line comment +# another line comment + +# adding a tab as separator (discouraged) + master: 1 + processes: 8 # the number of processes + memory-report: 1 + +# now a psgi app via plugin +app2: + plugins: psgi + socket: :3032 # another comment +# adding a tab as separator (discouraged) + master: 1 + processes: 8 # the number of processes + memory-report: 1 + psgi: test.psgi diff --git a/xmlconf.c b/xmlconf.c index 98607964..a2916385 100644 --- a/xmlconf.c +++ b/xmlconf.c @@ -9,7 +9,7 @@ extern struct uwsgi_server uwsgi; #include #include -void uwsgi_xml_config(struct wsgi_request *wsgi_req, struct option *long_options) { +void uwsgi_xml_config(struct wsgi_request *wsgi_req, int app_tag) { xmlDoc *doc = NULL; xmlNode *element = NULL; xmlNode *node = NULL; @@ -42,7 +42,7 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, struct option *long_options exit(1); } - if (long_options) { + if (!app_tag) { uwsgi_log( "[uWSGI] parsing config file %s\n", uwsgi.xml_config); } @@ -76,7 +76,7 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, struct option *long_options } - if (long_options) { + if (!app_tag) { // first check for options for (node = element->children; node; node = node->next) { if (node->type == XML_CDATA_SECTION_NODE) { @@ -101,7 +101,7 @@ void uwsgi_xml_config(struct wsgi_request *wsgi_req, struct option *long_options continue; } #endif - lopt = long_options; + lopt = uwsgi.long_options; while ((aopt = lopt)) { if (!aopt->name) break; @@ -258,9 +258,9 @@ next: /* We cannot free xml resources on the first round (and with routing enabled) as the string pointer must be valid for all the server lifecycle */ #ifdef UWSGI_ROUTING - if (!long_options && !uwsgi.routing) { + if (app_tag && !uwsgi.routing) { #else - if (!long_options) { + if (app_tag) { #endif xmlFreeDoc (doc); xmlCleanupParser (); @@ -352,7 +352,7 @@ void uwsgi_startElement(void *userData, const char *name, const char **attrs) { struct option *lopt, *aopt; - lopt = long_options; + lopt = uwsgi.long_options; while ((aopt = lopt)) { if (!aopt->name) break; diff --git a/yaml.c b/yaml.c new file mode 100644 index 00000000..26afb86e --- /dev/null +++ b/yaml.c @@ -0,0 +1,230 @@ +#ifdef UWSGI_YAML + +#include "uwsgi.h" + +extern struct uwsgi_server uwsgi; + +/* + yaml file must be read ALL into memory. + This memory must not be freed for all the server lifecycle + */ + +void yaml_rstrip(char *line) { + + off_t i; + + for(i = strlen(line)-1;i>=0; i--) { + if (line[i] == ' ' || line[i] == '\t') { + line[i] = 0; + continue; + } + break; + } +} + +char *yaml_lstrip(char *line) { + + off_t i; + char *ptr = line; + + for(i=0;i< (int) strlen(line);i++) { + if (line[i] == ' ' || line[i] == '\t') { + ptr++; + continue; + } + break; + } + + return ptr; +} + + +int yaml_get_depth(char *line) { + + off_t i; + int depth = 0; + + for(i=0;i< (int) strlen(line);i++) { + if (line[i] == ' ') { + depth++; + continue; + } + else if (line[i] == '\t') { + depth+=8; + continue; + } + break; + } + + return depth; +} + +char *yaml_get_line(char *yaml, off_t size) { + + off_t i; + char *ptr = yaml; + int comment = 0; + + for(i=0;i current_depth && !in_uwsgi_section) { + goto next; + } + + key = yaml_lstrip(yaml); + // skip empty line + if (key[0] == 0) goto next; + + // skip list and {} defined dict + if (key[0] == '-' || key[0] == '[' || key[0] == '{') { + if (in_uwsgi_section) goto end; + goto next; + } + + if (!in_uwsgi_section) { + section = strchr(key,':'); + if (!section) goto next; + section[0] = 0; + if (!strcmp(key, section_asked)) { + in_uwsgi_section = 1; + } + } + else { + // get dict value + val = strstr(key, ": "); + if (!val) { + val = strstr(key, ":\t"); + } + if (!val) goto end; + // get the right key + val[0] = 0; + // yeah overengeneering.... + yaml_rstrip(key); + + val = yaml_lstrip(val+2); + yaml_rstrip(val); + + //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 { + manage_opt(aopt->val, val); + } + } + lopt++; + } + } +next: + sb.st_size -= (yaml_line - yaml); + yaml += (yaml_line - yaml); + + } + +end: + + close(fd); + +} + +#endif