diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-28 11:23:09 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-09-28 11:32:04 +0300 |
commit | ac1d6cbbcf5323d5db59886b98a24c45bafa64b8 (patch) | |
tree | f2a77092e072faa680b47d9d6d960e7214e46876 | |
parent | d902742081bc31a6eda274268da0178107e4abb4 (diff) | |
download | eclat-ac1d6cbbcf5323d5db59886b98a24c45bafa64b8.tar.gz eclat-ac1d6cbbcf5323d5db59886b98a24c45bafa64b8.tar.bz2 |
Improve testsuite. Reorganize directory structure.
* Makefile.am (SUBDIRS): Add etc
(distuninstallcheck_listfiles): Ignore *.forlan files.
* configure.ac: New options --split-format and --format-dir
* etc/Makefile.am: New file.
* etc/default.fln: New file.
* etc/describe-instance-status.fln: New file.
* etc/describe-instances.fln: New file.
* etc/describe-tags.fln: New file.
* etc/eclat.cfin: New file.
* etc/flncat.c: New file.
* etc/start-instances.fln: New file.
* etc/stop-instances.fln: New file.
* src/Makefile.am: Remove eclat.conf. It is built in /etc now.
* src/eclat.conf: Remove.
* src/cmdline.opt: Update.
* src/config.c: New configuration statement "format-file".
* src/eclat.c (format_file_option): New global.
(main): Read format from format-file, if supplied. Expand
keywords in its argument.
* src/eclat.h (format_file_option): New extern.
* tests/.gitignore: Update.
* tests/Makefile.am: Add new files.
* tests/describe-instance-status.at: New test case.
* tests/describe-instances.at: New test case.
* tests/describe-tags.at: New test case.
* tests/dscrinststat.at: New test case.
* tests/start-instances.at: New test case.
* tests/stop-instances.at: New test case.
* tests/testsuite.at (ECLAT_TEST_FORMAT): New macro.
Include new test cases.
* tests/trws.c: New file.
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 26 | ||||
-rw-r--r-- | etc/.gitignore | 3 | ||||
-rw-r--r-- | etc/Makefile.am | 60 | ||||
-rw-r--r-- | etc/default.fln | 22 | ||||
-rw-r--r-- | etc/describe-instance-status.fln | 36 | ||||
-rw-r--r-- | etc/describe-instances.fln | 69 | ||||
-rw-r--r-- | etc/describe-tags.fln | 24 | ||||
-rw-r--r-- | etc/eclat.cfin | 32 | ||||
-rw-r--r-- | etc/flncat.c | 94 | ||||
-rw-r--r-- | etc/start-instances.fln | 23 | ||||
-rw-r--r-- | etc/stop-instances.fln | 23 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/cmdline.opt | 2 | ||||
-rw-r--r-- | src/config.c | 4 | ||||
-rw-r--r-- | src/eclat.c | 72 | ||||
-rw-r--r-- | src/eclat.conf | 165 | ||||
-rw-r--r-- | src/eclat.h | 1 | ||||
-rw-r--r-- | tests/.gitignore | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 6 | ||||
-rw-r--r-- | tests/describe-instance-status.at | 154 | ||||
-rw-r--r-- | tests/describe-instances.at | 274 | ||||
-rw-r--r-- | tests/describe-tags.at | 68 | ||||
-rw-r--r-- | tests/dscrinststat.at | 128 | ||||
-rw-r--r-- | tests/start-instances.at | 38 | ||||
-rw-r--r-- | tests/stop-instances.at | 39 | ||||
-rw-r--r-- | tests/testsuite.at | 17 | ||||
-rw-r--r-- | tests/trws.c | 46 |
28 files changed, 1245 insertions, 194 deletions
diff --git a/Makefile.am b/Makefile.am index 171250b..d78d1f6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,16 +13,16 @@ # # You should have received a copy of the GNU General Public License # along with Eclat. If not, see <http://www.gnu.org/licenses/>. ACLOCAL_AMFLAGS = -I grecs/am -SUBDIRS = grecs lib src tests +SUBDIRS = grecs lib src etc tests .PHONY: ChangeLog ChangeLog: $(AM_V_GEN)if test -d .git; then \ git log --pretty='format:%ct %an <%ae>%n%n%s%n%n%b%n' | \ awk -f $(top_srcdir)/grecs/build-aux/git2chg.awk > ChangeLog; \ fi -distuninstallcheck_listfiles = find . -type f -not -name 'eclat.conf' -print +distuninstallcheck_listfiles = find . -type f -not -name 'eclat.conf' -not -name '*.forlan' -print diff --git a/configure.ac b/configure.ac index 8f8ccfc..7c744ff 100644 --- a/configure.ac +++ b/configure.ac @@ -60,17 +60,41 @@ AC_CHECK_LIB([expat], [XML_Parse],[], [AC_MSG_ERROR([required library libexpat is not found])]) # Grecs subsystem GRECS_SETUP([grecs],[tests getopt git2chg]) +# +AC_SUBST(FORMATDIR) +AC_ARG_ENABLE([split-format], + [AC_HELP_STRING([--enable-split-format], + [build split format files])], + [split_fmt=$enableval], + [split_fmt=no]) + +if test $split_fmt = yes; then + FORMATDIR="\$(sysconfdir)/\$(PACKAGE)" +else + FORMATDIR="\$(sysconfdir)" +fi +AM_CONDITIONAL([SPLIT_FORMATS],[test $split_fmt = yes]) + +AC_ARG_WITH([format-dir], + [AC_HELP_STRING([--format-dir=DIR], + [install format files to that directory])], + [case $withval in + /*) FORMATDIR=$withval;; + *) FORMATDIR='$(prefix)/'$withval + esac]) + # Initialize the test suite. AC_CONFIG_TESTDIR(tests) AC_CONFIG_FILES([tests/Makefile tests/atlocal]) AM_MISSING_PROG([AUTOM4TE], [autom4te]) AC_CONFIG_FILES([Makefile lib/Makefile - src/Makefile]) + src/Makefile + etc/Makefile]) AC_OUTPUT diff --git a/etc/.gitignore b/etc/.gitignore new file mode 100644 index 0000000..b22bf5d --- /dev/null +++ b/etc/.gitignore @@ -0,0 +1,3 @@ +*.forlan +eclat.conf +flncat diff --git a/etc/Makefile.am b/etc/Makefile.am new file mode 100644 index 0000000..5eec565 --- /dev/null +++ b/etc/Makefile.am @@ -0,0 +1,60 @@ +# 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 <http://www.gnu.org/licenses/>. + +noinst_PROGRAMS = flncat + +FLNFILES=\ + describe-instance-status.fln\ + describe-instances.fln\ + describe-tags.fln\ + start-instances.fln\ + stop-instances.fln + +EXTRA_DIST=$(FLNFILES) default.fln eclat.cfin + +noinst_SCRIPTS=eclat.conf +CLEANFILES=eclat.conf +SUFFIXES=.cfin .conf + +if SPLIT_FORMATS +SUFFIXES += .forlan .fln +.fln.forlan: + $(AM_V_GEN)$(abs_builddir)/flncat $< default.fln > $@ +formatdir = @FORMATDIR@ +noinst_SCRIPTS += $(FLNFILES:.fln=.forlan) +CLEANFILES += $(FLNFILES:.fln=.forlan) +FORMATNAME = $${command} +else +formatdir = @FORMATDIR@ +noinst_SCRIPTS += eclat.forlan +CLEANFILES += eclat.forlan +eclat.forlan: $(FLNFILES) default.fln + $(AM_V_GEN)(cd $(srcdir); $(abs_builddir)/flncat $(FLNFILES) default.fln) > eclat.forlan +FORMATNAME = eclat +endif + +.cfin.conf: + $(AM_V_GEN)sed 's^FORMATDIR^$(formatdir)^;s^FORMATNAME^$(FORMATNAME)^' $< > $@ + +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; \ + for file in $(noinst_SCRIPTS); do \ + ${INSTALL} -m 644 $$file $(DESTDIR)$(formatdir)/$$file; \ + done; \ + fi diff --git a/etc/default.fln b/etc/default.fln new file mode 100644 index 0000000..2e2f690 --- /dev/null +++ b/etc/default.fln @@ -0,0 +1,22 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.Response.Errors) + error("Error: ",.Response.Errors.Error.Message,"\n"); +else { + error("Unrecognized response:\n"); + dump(.); +} diff --git a/etc/describe-instance-status.fln b/etc/describe-instance-status.fln new file mode 100644 index 0000000..85b88b3 --- /dev/null +++ b/etc/describe-instance-status.fln @@ -0,0 +1,36 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.DescribeInstanceStatusResponse.instanceStatusSet) { + for (var in .DescribeInstanceStatusResponse.instanceStatusSet.item) { + print(var.instanceId,"\t", + var.availabilityZone,"\t", + var.instanceState.name); + if (var.instanceState.name[running]) { + print("\t",var.systemStatus.status); + for (detail in var.systemStatus.details.item) { + print("\tSys.",detail.name,"=",detail.status); + } + for (detail in var.instanceStatus.details.item) { + print("\tInst.",detail.name,"=",detail.status); + } + } + print("\n"); + for (event in var.eventsSet.item) { + error(var.instanceId,"\t","Event: ", event.description,"\n"); + } + } +} diff --git a/etc/describe-instances.fln b/etc/describe-instances.fln new file mode 100644 index 0000000..538aa5c --- /dev/null +++ b/etc/describe-instances.fln @@ -0,0 +1,69 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.DescribeInstancesResponse.reservationSet) { + for (var in .DescribeInstancesResponse.reservationSet.item) { + print("Reservation ID: ", var.reservationId, "\n"); + print("Owner ID: ", var.ownerId, "\n"); + if (var.groupSet) { + print("Groups:\n"); + for (grp in var.groupSet.item) + print("\t", grp.groupId,"\t", grp.groupName, "\n"); + } + if (var.instancesSet) { + // print("Instances:\n"); + for (inst in var.instancesSet.item) { + print("\nInstance: ", inst.instanceId, "\n"); + print("\tImage ID: ", inst.imageId, "\n"); + print("\tState: ", inst.instanceState.name, "\n"); + print("\tKernel ID: ", inst.kernelId, "\n"); + print("\tArchitecture: ", inst.architecture, "\n"); + print("\tPrivate DNS: ", inst.privateDnsName, "\n"); + print("\tPublic DNS: ", inst.dnsName, "\n"); + print("\tKey: ", inst.keyName, "\n"); + print("\tType: ", inst.instanceType, "\n"); + print("\tLaunch Time: ", inst.launchTime, "\n"); + print("\tAvailability Zone: ", inst.placement.availabilityZone, "\n"); + print("\tGroup Name: ", inst.placement.groupName, "\n"); + print("\tTenancy: ", inst.placement.tenancy, "\n"); + print("\tPrivate IP: ", inst.privateIpAddress, "\n"); + print("\tPublic IP: ", inst.ipAddress, "\n"); + if (inst.groupSet.item) { + print("\tGroups:\n"); + for (grp in inst.groupSet.item) + print("\t\t", inst.groupSet.item.groupId, " -- ", inst.groupSet.item.groupName, "\n"); + } + print("\tRoot Device Type: ", inst.rootDeviceType, "\n"); + print("\tRoot Device Name: ", inst.rootDeviceName, "\n"); + print("\tDevice mapping:\n"); + for (dev in inst.blockDeviceMapping.item) { + print("\t\t", dev.deviceName, " ", dev.ebs.volumeId, " ", + dev.ebs.status, " ", dev.ebs.attachTime, " ", + dev.ebs.deleteOnTermination, "\n"); + } + print("\tVirtualization: ", inst.virtualizationType, "\n"); + print("\tTag Set:\n"); + for (tag in inst.tagSet.item) { + print("\t\t", tag.key, "=", tag.value, "\n"); + } + print("\tHypervisor: ", inst.hypervisor, "\n"); + // FIXME: networkInterfaceSet + print("\tEBS Optimized: ", inst.ebsOptimized, "\n"); + print("End of instance\n\n"); + } + } + } +}
\ No newline at end of file diff --git a/etc/describe-tags.fln b/etc/describe-tags.fln new file mode 100644 index 0000000..30d8798 --- /dev/null +++ b/etc/describe-tags.fln @@ -0,0 +1,24 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.DescribeTagsResponse) { + for (var in .DescribeTagsResponse.tagSet.item) { + print(var.resourceId,"\t", + var.resourceType,"\t", + var.key,"\t", + var.value,"\n"); + } +}
\ No newline at end of file diff --git a/etc/eclat.cfin b/etc/eclat.cfin new file mode 100644 index 0000000..006f6d9 --- /dev/null +++ b/etc/eclat.cfin @@ -0,0 +1,32 @@ +/* Default configuration file for Eclat. + * + * See eclat.conf(5) or run "info eclat configuration" for a detailed + * description. + */ + +# Use this endpoint by default. +default-endpoint "ec2.amazonaws.com"; + +# Declare what endpoints to use for each availability region. +# The syntax is: +# region REGNAME ENDPOINT; + +# US East (Northern Virginia) Region +region us-east-1 ec2.us-east-1.amazonaws.com; +# US West (Oregon) Region +region us-west-2 ec2.us-west-2.amazonaws.com; +# US West (Northern California) Region +region us-west-1 ec2.us-west-1.amazonaws.com; +# EU (Ireland) Region +region eu-west-1 ec2.eu-west-1.amazonaws.com; +# Asia Pacific (Singapore) Region +region ap-southeast-1 ec2.ap-southeast-1.amazonaws.com; +# Asia Pacific (Tokyo) Region +region ap-northeast-1 ec2.ap-northeast-1.amazonaws.com; +# South America (Sao Paulo) Region +region sa-east-1 ec2.sa-east-1.amazonaws.com; + +format-file "FORMATDIR/FORMATNAME.forlan"; + + + diff --git a/etc/flncat.c b/etc/flncat.c new file mode 100644 index 0000000..6f67e0e --- /dev/null +++ b/etc/flncat.c @@ -0,0 +1,94 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <ctype.h> +#include <assert.h> + +int +comment(FILE *fp, int c) +{ + if (c != '/') { + ungetc(c, fp); + return 0; + } + + if ((c = getc(fp)) == '/') { + while ((c = getc(fp)) != EOF && c != '\n') + ; + return 1; + } + + if (c == '*') { + do { + while ((c = getc(fp)) != '*') { + if (c == EOF) + return 0; + } + } while ((c = getc(fp)) != '/'); + return 1; + } + ungetc(c, fp); + ungetc('/', fp); + return 0; +} + +int +main(int argc, char **argv) +{ + int i; + FILE *fp; + int c; + char buf[128]; + size_t lev = 0; + + for (i = 1; i < argc; i++) { + fp = fopen(*++argv, "r"); + if (!fp) { + perror(*argv); + return 1; + } + + if (i > 1) { + /* Skip whitespace and comment lines */ + do { + while ((c = fgetc(fp)) != EOF && isspace(c)) + ; + } while (c != EOF && comment(fp, c)); + printf(" else "); + } + + while ((c = fgetc(fp)) != EOF) { + putchar(c); + if (c == '}') { + lev = 0; + while ((c = fgetc(fp)) != EOF && + isspace(c)) { + assert(lev < sizeof(buf)); + buf[lev++] = c; + } + if (c == EOF) + break; + else { + buf[lev++] = c; + fwrite(buf, lev, 1, stdout); + } + } + } + fclose(fp); + } + return 0; +} diff --git a/etc/start-instances.fln b/etc/start-instances.fln new file mode 100644 index 0000000..137a202 --- /dev/null +++ b/etc/start-instances.fln @@ -0,0 +1,23 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.StartInstancesResponse) { + for (var in .StartInstancesResponse.instancesSet.item) { + print(var.instanceId,": ", + var.previousState.name," => ", + var.currentState.name,"\n"); + } +}
\ No newline at end of file diff --git a/etc/stop-instances.fln b/etc/stop-instances.fln new file mode 100644 index 0000000..bb45347 --- /dev/null +++ b/etc/stop-instances.fln @@ -0,0 +1,23 @@ +/* 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 <http://www.gnu.org/licenses/>. */ + +if (.StopInstancesResponse) { + for (var in .StopInstancesResponse.instancesSet.item) { + print(var.instanceId,": ", + var.previousState.name," => ", + var.currentState.name,"\n"); + } +}
\ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 5b114cc..7f3e1f0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,19 +53,13 @@ BUILT_SOURCES=\ dscrinststat-cl.h\ dscrtags-cl.h\ startinst-cl.h EXTRA_DIST=\ cmdline.opt\ - $(OPTFILES)\ - eclat.conf + $(OPTFILES) 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/cmdline.opt b/src/cmdline.opt index d07309f..3f0549f 100644 --- a/src/cmdline.opt +++ b/src/cmdline.opt @@ -109,13 +109,13 @@ BEGIN use_ssl = 1; END OPTION(format,F,FILE, [<use FILE to format the output>]) BEGIN - format_file = optarg; + format_file_option = optarg; END OPTION(sort,s,, [<sort the returned XML teee prior to outputting it>]) BEGIN sort_option = 1; diff --git a/src/config.c b/src/config.c index 82033d3..aa60323 100644 --- a/src/config.c +++ b/src/config.c @@ -136,13 +136,15 @@ static struct grecs_keyword eclat_kw[] = { grecs_type_string, GRECS_DFLT, &access_file_name }, { "default-region", "name", "Define default AWS region", grecs_type_string, GRECS_DFLT, ®ion_name }, { "format", "<command: string> <format: string>", "Set default format for the <command>", - grecs_type_string, GRECS_MULT, NULL, 0, cb_format }, + grecs_type_string, GRECS_MULT, NULL, 0, cb_format }, + { "format-file", "file", "Read format from <file>", + grecs_type_string, GRECS_DFLT, &format_file }, { NULL } }; void config_help() { diff --git a/src/eclat.c b/src/eclat.c index a8c5728..31f2144 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -23,14 +23,15 @@ int preprocess_only = 0; char *endpoint = "ec2.amazonaws.com"; int use_ssl; char *access_key; char *secret_key; char *region_name; -char *format_file; +char *format_file_option; int sort_option; +char *format_file; FILE *xml_dump_file; static char *categories[] = { "main", @@ -330,23 +331,12 @@ compile_format_file(const char *fmtfile) if (!env) exit(EX_UNAVAILABLE); return env; } -forlan_eval_env_t -compile_default_format(struct command *cmd) -{ - forlan_eval_env_t env; - - env = forlan_parse_buffer(cmd->fmt, strlen(cmd->fmt), &cmd->locus.beg); - if (!env) - exit(EX_UNAVAILABLE); - - return env; -} struct filter_descr *available_filters; static char *aws_typestr[] = { "String", "dateType" @@ -391,12 +381,63 @@ list_filters(FILE *fp) } fputc('\n', fp); } fputc('\n', fp); } +static forlan_eval_env_t +read_format(struct command *cmd) +{ + forlan_eval_env_t env = NULL; + + if (format_file_option) + env = compile_format_file(format_file_option); + else if (cmd && cmd->fmt) + env = forlan_parse_buffer(cmd->fmt, strlen(cmd->fmt), + &cmd->locus.beg); + else if (format_file) { + struct wordsplit ws; + const char *kve[5]; + struct grecs_locus_point pt; + FILE *fp; + + kve[0] = "command"; + kve[1] = cmd->ident; + kve[2] = "action"; + kve[3] = cmd->tag; + kve[4] = NULL; + + ws.ws_env = kve; + if (wordsplit(format_file, &ws, + WRDSF_NOSPLIT | WRDSF_NOCMD | + WRDSF_ENV | WRDSF_ENV_KV)) + die(EX_SOFTWARE, + "error expanding format-file: %s", + wordsplit_strerror(&ws)); + + fp = fopen(ws.ws_wordv[0], "r"); + if (!fp) + die(EX_UNAVAILABLE, + "cannot open format file %s: %s", + ws.ws_wordv[0], strerror(errno)); + + pt.file = ws.ws_wordv[0]; + pt.line = 1; + pt.col = 0; + + env = forlan_parse_file(fp, &pt); + fclose(fp); + wordsplit_free(&ws); + } else + return NULL; + + if (!env) + exit(EX_UNAVAILABLE); + return env; +} + int main(int argc, char **argv) { int index, rc; struct grecs_node *tree; @@ -445,17 +486,14 @@ main(int argc, char **argv) warn("no configuration file"); run_config_finish_hooks(); } else die(EX_OSFILE, "cannot access \"%s\": %s", conffile, strerror(errno)); - if (format_file) - env = compile_format_file(format_file); - else if (command && command->fmt) - env = compile_default_format(command); - + env = read_format(command); + if (lint_mode) exit(0); if (!command) die(EX_USAGE, "no command given"); diff --git a/src/eclat.conf b/src/eclat.conf deleted file mode 100644 index ec371e3..0000000 --- a/src/eclat.conf +++ /dev/null @@ -1,165 +0,0 @@ -/* Default configuration file for Eclat. - * - * See eclat.conf(5) or run "info eclat configuration" for a detailed - * description. - */ - -# Use this endpoint by default. -default-endpoint "ec2.amazonaws.com"; - -# Declare what endpoints to use for each availability region. -# The syntax is: -# region REGNAME ENDPOINT; - -# US East (Northern Virginia) Region -region us-east-1 ec2.us-east-1.amazonaws.com; -# US West (Oregon) Region -region us-west-2 ec2.us-west-2.amazonaws.com; -# US West (Northern California) Region -region us-west-1 ec2.us-west-1.amazonaws.com; -# EU (Ireland) Region -region eu-west-1 ec2.eu-west-1.amazonaws.com; -# Asia Pacific (Singapore) Region -region ap-southeast-1 ec2.ap-southeast-1.amazonaws.com; -# Asia Pacific (Tokyo) Region -region ap-northeast-1 ec2.ap-northeast-1.amazonaws.com; -# South America (Sao Paulo) Region -region sa-east-1 ec2.sa-east-1.amazonaws.com; - -format "DescribeTags" <<\EOT -if (.DescribeTagsResponse) { - for (var in .DescribeTagsResponse.tagSet.item) { - print(var.resourceId,"\t", - var.resourceType,"\t", - var.key,"\t", - var.value,"\n"); - } -} else if (.Response.Errors) - error("Error: ",.Response.Errors.Error.Message,"\n"); -else { - error("Unrecognized response:\n"); - dump(.); -} -EOT; - -format "DescribeInstanceStatus" <<\EOT -if (.DescribeInstanceStatusResponse.instanceStatusSet) { - for (var in .DescribeInstanceStatusResponse.instanceStatusSet.item) { - print(var.instanceId,"\t", - var.availabilityZone,"\t", - var.instanceState.name); - if (var.instanceState.name[running]) { - print("\t",var.systemStatus.status); - for (detail in var.systemStatus.details.item) { - print("\tSys.",detail.name,"=",detail.status); - } - for (detail in var.instanceStatus.details.item) { - print("\tInst.",detail.name,"=",detail.status); - } - } - print("\n"); - for (event in var.eventsSet.item) { - error(var.instanceId,"\t","Event: ", event.description,"\n"); - } - } -} else if (.Response.Errors) - error("Error: ",.Response.Errors.Error.Message,"\n"); -else { - error("Unrecognized response:\n"); - dump(.); -} -EOT; - -format "StartInstances" <<\EOT -if (.StartInstancesResponse) { - for (var in .StartInstancesResponse.instancesSet.item) { - print(var.instanceId,": ", - var.previousState.name," => ", - var.currentState.name,"\n"); - } -} else if (.Response.Errors) - error("Error: ",.Response.Errors.Error.Message,"\n"); -else { - error("Unrecognized response:\n"); - dump(.); -} -EOT; - -format "StopInstances" <<\EOT -if (.StopInstancesResponse) { - for (var in .StopInstancesResponse.instancesSet.item) { - print(var.instanceId,": ", - var.previousState.name," => ", - var.currentState.name,"\n"); - } -} else if (.Response.Errors) - error("Error: ",.Response.Errors.Error.Message,"\n"); -else { - error("Unrecognized response:\n"); - dump(.); -} -EOT; - -format "DescribeInstances" <<\EOT -if (.DescribeInstancesResponse.reservationSet) { - for (var in .DescribeInstancesResponse.reservationSet.item) { - print("Reservation ID: ", var.reservationId, "\n"); - print("Owner ID: ", var.ownerId, "\n"); - if (var.groupSet) { - print("Groups:\n"); - for (grp in var.groupSet.item) - print("\t", grp.groupId,"\t", grp.groupName, "\n"); - } - if (var.instancesSet) { - // print("Instances:\n"); - for (inst in var.instancesSet.item) { - print("\nInstance: ", inst.instanceId, "\n"); - print("\tImage ID: ", inst.imageId, "\n"); - print("\tState: ", inst.instanceState.name, "\n"); - print("\tKernel ID: ", inst.kernelId, "\n"); - print("\tArchitecture: ", inst.architecture, "\n"); - print("\tPrivate DNS: ", inst.privateDnsName, "\n"); - print("\tPublic DNS: ", inst.dnsName, "\n"); - print("\tKey: ", inst.keyName, "\n"); - print("\tType: ", inst.instanceType, "\n"); - print("\tLaunch Time: ", inst.launchTime, "\n"); - print("\tAvailability Zone: ", inst.placement.availabilityZone, "\n"); - print("\tGroup Name: ", inst.placement.groupName, "\n"); - print("\tTenancy: ", inst.placement.tenancy, "\n"); - print("\tPrivate IP: ", inst.privateIpAddress, "\n"); - print("\tPublic IP: ", inst.ipAddress, "\n"); - if (inst.groupSet.item) { - print("\tGroups:\n"); - for (grp in inst.groupSet.item) - print("\t\t", inst.groupSet.item.groupId, " -- ", inst.groupSet.item.groupName, "\n"); - } - print("\tRoot Device Type: ", inst.rootDeviceType, "\n"); - print("\tRoot Device Name: ", inst.rootDeviceName, "\n"); - print("\tDevice mapping:\n"); - for (dev in inst.blockDeviceMapping.item) { - print("\t\t", dev.deviceName, " ", dev.ebs.volumeId, " ", - dev.ebs.status, " ", dev.ebs.attachTime, " ", - dev.ebs.deleteOnTermination, "\n"); - } - print("\tVirtualization: ", inst.virtualizationType, "\n"); - print("\tTag Set:\n"); - for (tag in inst.tagSet.item) { - print("\t\t", tag.key, "=", tag.value, "\n"); - } - print("\tHypervisor: ", inst.hypervisor, "\n"); - // FIXME: networkInterfaceSet - print("\tEBS Optimized: ", inst.ebsOptimized, "\n"); - print("End of instance\n\n"); - } - } - } -} else if (.Response.Errors) - error("Error: ",.Response.Errors.Error.Message,"\n"); -else { - error("Unrecognized response:\n"); - dump(.); |