aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-09-20 01:36:01 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-09-20 01:36:01 +0300
commit0d7ee650f6198c70f2ff06bc16ba160129de70cf (patch)
treea644d54acf3762e84529f68c2364972c9b112a4c
parent64993d198836c3d98643670b4b056701224c854e (diff)
downloadeclat-0d7ee650f6198c70f2ff06bc16ba160129de70cf.tar.gz
eclat-0d7ee650f6198c70f2ff06bc16ba160129de70cf.tar.bz2
Implement multiple regions and StopInstance command.
* src/config.c: Change configuration statements. * src/eclat.c: Translate endpoint if region is given. * src/eclat.h: Update. * src/startinst.c: Implement stop instance.
-rw-r--r--src/config.c59
-rw-r--r--src/eclat.c9
-rw-r--r--src/eclat.h4
-rw-r--r--src/startinst.c22
4 files changed, 80 insertions, 14 deletions
diff --git a/src/config.c b/src/config.c
index 5727167..c40d307 100644
--- a/src/config.c
+++ b/src/config.c
@@ -50,14 +50,63 @@ run_config_finish_hooks()
return rc;
}
+/* Translation table: region -> endpoint. Its elements are of
+ struct ec2_param type. */
+struct grecs_symtab *ec2_regtab;
+
+char *
+region_to_endpoint(const char *region)
+{
+ struct ec2_param *p, key;
+
+ key.name = (char*) region;
+ p = grecs_symtab_lookup_or_install(ec2_regtab, &key, NULL);
+ return p ? p->value : NULL;
+}
+
+static int
+cb_region(enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data)
+{
+ struct ec2_param *p, key;
+ int install = 1;
+
+ if (cmd != grecs_callback_set_value) {
+ grecs_error(locus, 0, "Unexpected block statement");
+ return 1;
+ }
+ if (!value || value->type != GRECS_TYPE_ARRAY || value->v.arg.c != 2) {
+ grecs_error(locus, 0, "expected two strings");
+ return 1;
+ }
+ if (value->v.arg.v[0]->type != GRECS_TYPE_STRING ||
+ value->v.arg.v[1]->type != GRECS_TYPE_STRING) {
+ grecs_error(locus, 0, "expected two strings");
+ return 1;
+ }
+
+ key.name = value->v.arg.v[0]->v.string;
+ p = grecs_symtab_lookup_or_install(ec2_regtab, &key, &install);
+ if (!install)
+ free(p->value); /* FIXME: Redefinition warning */
+ p->value = grecs_strdup(value->v.arg.v[1]->v.string);
+ return 0;
+}
+
static struct grecs_keyword eclat_kw[] = {
- { "host", "hostname",
- "Send queries to <hostname> instead of the default host",
- grecs_type_string, GRECS_DFLT, &default_host },
+ { "default-endpoint", "hostname",
+ "Set default EC2 endpoint",
+ grecs_type_string, GRECS_DFLT, &endpoint },
+ { "region", "<name: string> <endpoint: string>",
+ "Define a region",
+ grecs_type_string, GRECS_MULT, NULL, 0, cb_region },
{ "access-file", "file",
"Specify a file containing `accessID:accessKey' pairs",
grecs_type_string, GRECS_DFLT, &access_file_name },
- { "region", "name",
+ { "default-region", "name",
"Define default AWS region",
grecs_type_string, GRECS_DFLT, &region_name },
@@ -90,6 +139,8 @@ config_init()
grecs_log_to_stderr = 1;
grecs_adjust_string_locations = 1;
grecs_print_diag_fun = grecs_print_diag;
+
+ ec2_regtab = grecs_symtab_create_default(sizeof(struct ec2_param));
}
void
diff --git a/src/eclat.c b/src/eclat.c
index 5625076..f0440e3 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -22,7 +22,7 @@ int debug_level[ECLAT_DEBCAT_MAX];
int dry_run_mode;
int preprocess_only = 0;
-char *default_host = "ec2.amazonaws.com";
+char *endpoint = "ec2.amazonaws.com";
int use_ssl;
char *access_key;
char *secret_key;
@@ -222,6 +222,13 @@ main(int argc, char **argv)
if (lint_mode)
exit(0);
+ if (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 (access_file_lookup(access_key, &access_key, &secret_key))
die(EX_UNAVAILABLE,
diff --git a/src/eclat.h b/src/eclat.h
index 953c34c..31914a0 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -37,7 +37,7 @@
extern const char *program_name;
extern int debug_level[];
-extern char *default_host;
+extern char *endpoint;
extern int use_ssl;
extern char *region_name;
extern char *access_file_name;
@@ -79,3 +79,5 @@ typedef int (*eclat_command_handler_t) (CURL *curl, int argc, char **argv);
int eclat_start_instance(CURL *curl, int argc, char **argv);
int eclat_stop_instance(CURL *curl, int argc, char **argv);
+
+char *region_to_endpoint(const char *region);
diff --git a/src/startinst.c b/src/startinst.c
index f2d3ea8..d2b9cad 100644
--- a/src/startinst.c
+++ b/src/startinst.c
@@ -16,21 +16,20 @@
#include "eclat.h"
-int
-eclat_start_instance(CURL *curl, int argc, char **argv)
+static int
+start_stop_instance(CURL *curl, const char *action, int argc, char **argv)
{
int i;
struct ec2_query *q;
char buf[128], *bend, *url;
size_t bs;
CURLcode res;
+
+ if (argc == 0)
+ die(EX_USAGE, "no instance ids");
- q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0,
- default_host, "/");
- if (region_name)
- eclat_query_add_param(q, "Placement.AvailabilityZone",
- region_name);
- eclat_query_add_param(q, "Action", "StartInstances");
+ q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/");
+ eclat_query_add_param(q, "Action", action);
strcpy(buf, "InstanceId.");
bend = buf + strlen(buf);
@@ -61,7 +60,14 @@ eclat_start_instance(CURL *curl, int argc, char **argv)
}
int
+eclat_start_instance(CURL *curl, int argc, char **argv)
+{
+ start_stop_instance(curl, "StartInstances", argc, argv);
+}
+
+int
eclat_stop_instance(CURL *curl, int argc, char **argv)
{
+ start_stop_instance(curl, "StopInstances", argc, argv);
}

Return to:

Send suggestions and report system problems to the System administrator.