From 0766417065bfec9747bf0f41f9b68c27e378f817 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 18 Jan 2015 13:29:25 +0200 Subject: If no region is specified, get it from the instance store * src/eclat.c: If no region is specified, try to get it from the instance store. * src/eclat.h (eclat_trace_fun): New proto. (eclat_get_instance_zone): New proto. * src/io.c (eclat_trace_fun): Remove static qualifier. * src/util.c (eclat_get_instance_meta_data): New function. (eclat_get_instance_zone): New function. --- src/util.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'src/util.c') diff --git a/src/util.c b/src/util.c index 641d304..f70f70a 100644 --- a/src/util.c +++ b/src/util.c @@ -367,3 +367,104 @@ canonattrname(char **attrs, const char *arg, char *delim, size_t *plen) return NULL; } +static size_t +get_meta_data_cb(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + char *v; + + if (debug_level(ECLAT_DEBCAT_MAIN) >= 10) + debug_printf("Got %*.*s", realsize, realsize, ptr); + + v = grecs_malloc(realsize + 1); + memcpy(v, ptr, realsize); + v[realsize] = 0; + *(char**)data = v; + return realsize; +} + +char * +eclat_get_instance_meta_data(char *url) +{ + CURLcode res; + CURL *curl = curl_easy_init(); + char *retval = NULL; + long http_resp; + + if (!curl) + die(EX_UNAVAILABLE, "curl_easy_init failed"); + + if (debug_level(ECLAT_DEBCAT_CURL)) { + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + if (debug_level(ECLAT_DEBCAT_CURL) > 1) + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, + eclat_trace_fun); + } + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_meta_data_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &retval); + + curl_easy_setopt(curl, CURLOPT_URL, url); + + res = curl_easy_perform(curl); + + if (res != CURLE_OK) + die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res)); + + res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp); + if (res != CURLE_OK) + die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res)); + + if (http_resp != 200) + die(EX_UNAVAILABLE, "CURL: unexpected error code %3ld", res); + + curl_easy_cleanup(curl); + + return retval; +} + +#define URL_INST_DOCUMENT\ + "http://169.254.169.254/latest/dynamic/instance-identity/document" + +char * +eclat_get_instance_zone() +{ + char *doc; + char *retval = NULL; + struct wordsplit ws; + size_t i; + int lev; + + doc = eclat_get_instance_meta_data(URL_INST_DOCUMENT); + + if (wordsplit(doc, &ws, + WRDSF_NOVAR | WRDSF_NOCMD | + WRDSF_SQUEEZE_DELIMS | + WRDSF_DQUOTE)) { + die(EX_UNAVAILABLE, "wordsplit: %s", wordsplit_strerror(&ws)); + } + free(doc); + + lev = 0; + for (i = 0; i < ws.ws_wordc; i++) { + if (strcmp(ws.ws_wordv[i], "{") == 0) + ++lev; + else if (strcmp(ws.ws_wordv[i], "}") == 0) + --lev; + else if (lev == 1 && strcmp(ws.ws_wordv[i], "region") == 0) { + if (i + 2 < ws.ws_wordc && + strcmp(ws.ws_wordv[i+1], ":") == 0) { + size_t len; + + retval = grecs_strdup(ws.ws_wordv[i+2]); + len = strlen(retval); + if (retval[len-1] == ',') + retval[len-1] = 0; + break; + } + } + } + wordsplit_free(&ws); + + return retval; +} -- cgit v1.2.1