diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-01-18 13:29:25 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-01-18 13:29:25 +0200 |
commit | 0766417065bfec9747bf0f41f9b68c27e378f817 (patch) | |
tree | d670f4b005311aa8af3ff2223c5f66ac1ddd0383 | |
parent | da045fc11d890e55b99b7cf842f7cb92dce532bb (diff) | |
download | eclat-0766417065bfec9747bf0f41f9b68c27e378f817.tar.gz eclat-0766417065bfec9747bf0f41f9b68c27e378f817.tar.bz2 |
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.
-rw-r--r-- | src/eclat.c | 16 | ||||
-rw-r--r-- | src/eclat.h | 5 | ||||
-rw-r--r-- | src/io.c | 2 | ||||
-rw-r--r-- | src/util.c | 101 |
4 files changed, 118 insertions, 6 deletions
diff --git a/src/eclat.c b/src/eclat.c index 566a5ba..88592d2 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -755,12 +755,18 @@ main(int argc, char **argv) if (!command) die(EX_USAGE, "no command given"); - if (region_name) { - endpoint = region_to_endpoint(region_name); - if (!endpoint) - die(EX_USAGE, - "cannot find endpoint for region %s", region_name); + if (!region_name) { + debug(ECLAT_DEBCAT_MAIN, 1, + ("getting availability region")); + region_name = eclat_get_instance_zone(); + debug(ECLAT_DEBCAT_MAIN, 1, + ("availability region %s", region_name)); } + + endpoint = region_to_endpoint(region_name); + if (!endpoint) + die(EX_USAGE, + "cannot find endpoint for region %s", region_name); if (!secret_key) { if (get_access_creds(access_key, &access_key, &secret_key)) diff --git a/src/eclat.h b/src/eclat.h index 528ae95..b9c90ba 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -100,6 +100,10 @@ void eclat_io_free(struct eclat_io *io); void eclat_io_shutdown(struct eclat_io *io); struct grecs_node *eclat_io_finish(struct eclat_io *io); +int eclat_trace_fun(CURL *handle, curl_infotype type, + char *data, size_t size, + void *userp); + int eclat_start_instance(eclat_command_env_t *env, int argc, char **argv); int eclat_stop_instance(eclat_command_env_t *env, int argc, char **argv); @@ -168,6 +172,7 @@ void describe_query_update(eclat_command_env_t *env, int argc, char **argv, const char *uparm, int n_in, int *n_out); int eclat_send_query(CURL *curl, struct ec2_query *q); +char *eclat_get_instance_zone(void); int eclat_actcmp(const char *a, const char *b); @@ -67,7 +67,7 @@ dump(const char *text, FILE *stream, unsigned char *ptr, size_t size) fflush(stream); } -static int +int eclat_trace_fun(CURL *handle, curl_infotype type, char *data, size_t size, void *userp) @@ -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; +} |