aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-01-18 13:29:25 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-01-18 13:29:25 +0200
commit0766417065bfec9747bf0f41f9b68c27e378f817 (patch)
treed670f4b005311aa8af3ff2223c5f66ac1ddd0383
parentda045fc11d890e55b99b7cf842f7cb92dce532bb (diff)
downloadeclat-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.c16
-rw-r--r--src/eclat.h5
-rw-r--r--src/io.c2
-rw-r--r--src/util.c101
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);
diff --git a/src/io.c b/src/io.c
index e2a496a..366861e 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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)
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;
+}

Return to:

Send suggestions and report system problems to the System administrator.