From 205d53a8e930d3fd126075ab083d316cc344ebaf Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Thu, 20 Sep 2012 11:48:40 +0300 Subject: Require libexpat, implement DescribeTags. * configure.ac: Require libexpat * src/descrtags.c: New file. * src/Makefile.am: Add new files. * src/accfile.c (access_file_lookup): Bugfix (stripped the first byte from the returned access_key). * src/cmdline.opt: New option --describe-tags * src/eclat.c: Register eclat_describe_tags handler. * src/eclat.h: Include expat.h (dry_run_mode): New extern. (eclat_command_describe_tags): New command code. (eclat_describe_tags): New proto. * src/startinst.c: More debugging info. Implement dry-run, --- configure.ac | 6 +++++ src/Makefile.am | 8 +++++- src/accfile.c | 3 ++- src/cmdline.opt | 8 ++++++ src/descrtags.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/eclat.c | 6 +++-- src/eclat.h | 6 ++++- src/startinst.c | 19 +++++++++----- 8 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 src/descrtags.c diff --git a/configure.ac b/configure.ac index c6384ab..fd22d37 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,12 @@ if test -z "$CURL_LIBS"; then # FIXME: Check curl version? fi +# Check for libexpat +AC_CHECK_HEADER([expat.h], [], + [AC_MSG_ERROR([expat.h is not found])]) +AC_CHECK_LIB([expat], [XML_Parse],[], + [AC_MSG_ERROR([required library libexpat is not found])]) + # Grecs subsystem GRECS_SETUP([grecs],[tests getopt git2chg]) diff --git a/src/Makefile.am b/src/Makefile.am index a16aff8..b5f7912 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,7 @@ eclat_SOURCES=\ accfile.c\ cmdline.h\ config.c\ + descrtags.c\ diag.c\ eclat.c\ eclat.h\ @@ -35,10 +36,15 @@ AM_CPPFLAGS= \ -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)" BUILT_SOURCES=cmdline.h -EXTRA_DIST=cmdline.opt +EXTRA_DIST=cmdline.opt eclat.conf SUFFIXES=.opt .c .h .opt.h: m4 -s $(top_srcdir)/grecs/build-aux/getopt.m4 $< | sed '1d' > $@ +install-data-local: + @test -z "$(DESTDIR)$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)" + @if [ -r $(DESTDIR)$(sysconfdir)/eclat.conf ]; then :; \ + else ${INSTALL} -m 644 $(top_srcdir)/src/eclat.conf \ + $(DESTDIR)$(sysconfdir)/eclat.conf; fi diff --git a/src/accfile.c b/src/accfile.c index 3fe669d..0c4912e 100644 --- a/src/accfile.c +++ b/src/accfile.c @@ -72,13 +72,14 @@ access_file_lookup(const char *id, char **access_key_ptr, char **secret_key_ptr) } } else { acc = grecs_txtacc_create(); - while ((c = getc(fp)) != EOF && c != ':') { + while (c != EOF && c != ':') { if (c == '\n') { err("%s:%u: incomplete line", access_file_name, line); break; } grecs_txtacc_grow_char(acc, c); + c = getc(fp); } if (c == ':') { grecs_txtacc_grow_char(acc, 0); diff --git a/src/cmdline.opt b/src/cmdline.opt index 25dc542..82e0e95 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -59,6 +59,8 @@ OPTION(dry-run,n,, []) BEGIN dry_run_mode = 1; + parse_debug_level("main.1"); + parse_debug_level("curl.1"); END OPTION(config-file,c,FILE, @@ -81,6 +83,12 @@ BEGIN eclat_command = eclat_command_stop_instances; END +OPTION(describe-tags,,, + []) +BEGIN + eclat_command = eclat_command_describe_tags; +END + GROUP(Modifiers) OPTION(region,,NAME, diff --git a/src/descrtags.c b/src/descrtags.c new file mode 100644 index 0000000..2fc44ef --- /dev/null +++ b/src/descrtags.c @@ -0,0 +1,81 @@ +/* This file is part of Eclat. + Copyright (C) 2012 Sergey Poznyakoff. + + Eclat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Eclat is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Eclat. If not, see . */ + +#include "eclat.h" + +int +eclat_describe_tags(CURL *curl, int argc, char **argv) +{ + int i, j, k; + struct ec2_query *q; + char *url; + char *bufptr = NULL; + size_t bufsize = 0; + size_t bs; + CURLcode res; + struct wordsplit ws; + int wsflags; + + q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/"); + eclat_query_add_param(q, "Action", "DescribeTags"); + + ws.ws_delim = ","; + wsflags = WRDSF_DEFFLAGS | WRDSF_DELIM; + for (i = 0, j = 1; i < argc; i++) { + char *p = strchr(argv[i], '='); + if (!p) + die(EX_USAGE, "maformed filter: %s", argv[i]); + *p++ = 0; + grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Name", j); + eclat_query_add_param(q, bufptr, argv[i]); + + if (wordsplit(p, &ws, wsflags)) + die(EX_SOFTWARE, "wordsplit failed at \"%s\": %s", + p, wordsplit_strerror(&ws)); + wsflags |= WRDSF_REUSE; + + for (k = 0; k < ws.ws_wordc; k++) { + grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Value.%d", + j, k+1); + eclat_query_add_param(q, bufptr, ws.ws_wordv[k]); + } + } + if (wsflags & WRDSF_REUSE) + wordsplit_free(&ws); + free(bufptr); + + eclat_query_add_param(q, "AWSAccessKeyId", access_key); + + eclat_query_signature(q, secret_key); + url = eclat_query_to_url(q, NULL); + + debug(ECLAT_DEBCAT_MAIN, 1, ("using URL: %s", url)); + curl_easy_setopt(curl, CURLOPT_URL, url); + + free(url); + eclat_query_free(q); + + if (dry_run_mode) + debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request")); + else { + res = curl_easy_perform(curl); + + if (res != CURLE_OK) + err("CURL: %s", curl_easy_strerror(res)); + } + + return 0; +} diff --git a/src/eclat.c b/src/eclat.c index f0440e3..c5994fe 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -177,7 +177,8 @@ eclat_trace_fun(CURL *handle, curl_infotype type, eclat_command_handler_t handler_tab[] = { NULL, eclat_start_instance, - eclat_stop_instance + eclat_stop_instance, + eclat_describe_tags }; int @@ -234,7 +235,8 @@ main(int argc, char **argv) die(EX_UNAVAILABLE, "cannot find authentication credentials"); } - + debug(ECLAT_DEBCAT_MAIN, 1, ("using access key %s", access_key)); + if (eclat_command == eclat_command_unspecified) die(EX_USAGE, "no command given"); diff --git a/src/eclat.h b/src/eclat.h index 31914a0..b0d46ac 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "grecs.h" #include "wordsplit.h" #include "libeclat.h" @@ -39,6 +40,7 @@ extern int debug_level[]; extern char *endpoint; extern int use_ssl; +extern int dry_run_mode; extern char *region_name; extern char *access_file_name; extern char *access_key; @@ -70,7 +72,8 @@ int run_config_finish_hooks(void); enum eclat_command { eclat_command_unspecified, eclat_command_start_instances, - eclat_command_stop_instances + eclat_command_stop_instances, + eclat_command_describe_tags }; extern enum eclat_command eclat_command; @@ -79,5 +82,6 @@ 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); +int eclat_describe_tags(CURL *curl, int argc, char **argv); char *region_to_endpoint(const char *region); diff --git a/src/startinst.c b/src/startinst.c index d2b9cad..bf1c364 100644 --- a/src/startinst.c +++ b/src/startinst.c @@ -44,30 +44,35 @@ start_stop_instance(CURL *curl, const char *action, int argc, char **argv) eclat_query_signature(q, secret_key); url = eclat_query_to_url(q, NULL); - debug(ECLAT_DEBCAT_MAIN, 2, ("using URL: %s", url)); + debug(ECLAT_DEBCAT_MAIN, 1, ("using URL: %s", url)); curl_easy_setopt(curl, CURLOPT_URL, url); free(url); eclat_query_free(q); - res = curl_easy_perform(curl); - - if (res != CURLE_OK) - err("CURL: %s", curl_easy_strerror(res)); - - return 0; + if (dry_run_mode) + debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request")); + else { + res = curl_easy_perform(curl); + + if (res != CURLE_OK) + err("CURL: %s", curl_easy_strerror(res)); + } + return 0; } int eclat_start_instance(CURL *curl, int argc, char **argv) { + debug(ECLAT_DEBCAT_MAIN, 1, ("starting instances")); start_stop_instance(curl, "StartInstances", argc, argv); } int eclat_stop_instance(CURL *curl, int argc, char **argv) { + debug(ECLAT_DEBCAT_MAIN, 1, ("stopping instances")); start_stop_instance(curl, "StopInstances", argc, argv); } -- cgit v1.2.1