aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-09-27 15:01:01 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-09-27 15:04:42 +0300
commitff8594b8cc916ba665961bd1e4e956810057f0ea (patch)
tree140e903f09d53ee87ab6e0f564d70ddf21402c69
parent0c8a7ab953a86426a13aa0eccaf2b2c46f8271c0 (diff)
downloadeclat-ff8594b8cc916ba665961bd1e4e956810057f0ea.tar.gz
eclat-ff8594b8cc916ba665961bd1e4e956810057f0ea.tar.bz2
Implement describe-instances and some bugfixes.
* configure.ac: Change bug-reporting email. * grecs: Upgrade. * lib/forlan.c (eval_comp0): Set root. * lib/xmltree.c (eclat_partial_tree_end_handler): Set type to grecs_node_block for empty blocks. * src/Makefile.am: Add new files. * src/eclat.c: Rewrite and simplify command name matcher. Implement describe-instances. * src/eclat.conf (DescribeInstances): New format. * src/eclat.h (eclat_describe_instances): New proto.
-rw-r--r--configure.ac2
m---------grecs0
-rw-r--r--lib/forlan.c1
-rw-r--r--lib/xmltree.c3
-rw-r--r--src/Makefile.am3
-rw-r--r--src/dscrinsts-cl.opt30
-rw-r--r--src/dscrinsts.c34
-rw-r--r--src/eclat.c75
-rw-r--r--src/eclat.conf68
-rw-r--r--src/eclat.h1
10 files changed, 163 insertions, 54 deletions
diff --git a/configure.ac b/configure.ac
index 5850232..8f8ccfc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@
# along with Eclat. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.63)
-AC_INIT([eclat], 0.1, [gray+eclat@gnu.org.ua],,
+AC_INIT([eclat], 0.1, [bug-eclat@gnu.org.ua],,
[http://www.gnu.org/software/eclat])
AC_CONFIG_SRCDIR([src/eclat.h])
AC_CONFIG_AUX_DIR([build-aux])
diff --git a/grecs b/grecs
-Subproject 7bc88d60ab7398631be3f85750965e812ba7ceb
+Subproject 4b49dd31f76faf42aa0771af2aeb8161e38f2fe
diff --git a/lib/forlan.c b/lib/forlan.c
index b7f7280..174b60b 100644
--- a/lib/forlan.c
+++ b/lib/forlan.c
@@ -273,6 +273,7 @@ eval_comp0(forlan_eval_env_t env, union forlan_node *p)
if (p->comp.wildcards) {
root = grecs_match_buf_first(mb, root);
} else {
+ grecs_match_buf_set_root(mb, root);
if (root->type != grecs_node_root)
root = root->down;
grecs_tree_recurse(root, grecs_node_exact_match, mb);
diff --git a/lib/xmltree.c b/lib/xmltree.c
index e5d4772..6431d28 100644
--- a/lib/xmltree.c
+++ b/lib/xmltree.c
@@ -164,7 +164,8 @@ eclat_partial_tree_end_handler(void *data, const XML_Char *name)
}
}
noderef->flags &= ~NODEREF_TEXT;
- }
+ } else if (node->type == (enum grecs_node_type)-1)
+ node->type = grecs_node_block;
if (!tos)
grecs_list_push(noderef->stack, node);
diff --git a/src/Makefile.am b/src/Makefile.am
index 042b833..5b114cc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,8 @@ eclat_SOURCES=\
config.c\
dscrtags.c\
dscrtags-cl.h\
+ dscrinsts.c\
+ dscrinsts-cl.h\
dscrinststat.c\
dscrinststat-cl.h\
eclat.c\
@@ -40,6 +42,7 @@ AM_CPPFLAGS= \
-DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)"
OPTFILES=\
+ dscrinsts-cl.opt\
dscrinststat-cl.opt\
dscrtags-cl.opt\
startinst-cl.opt
diff --git a/src/dscrinsts-cl.opt b/src/dscrinsts-cl.opt
new file mode 100644
index 0000000..2ecd327
--- /dev/null
+++ b/src/dscrinsts-cl.opt
@@ -0,0 +1,30 @@
+/* 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/>. */
+
+OPTIONS_BEGIN("eclat describe-instances",
+ [<List instances>],
+ [<[FILTER...]>],
+ [<gnu>],
+ [<nousage>],
+ [<noversion>])
+
+OPTIONS_END
+
+static void
+parse_options(int argc, char *argv[], int *index)
+{
+ GETOPT(argc, argv, *index, exit(EX_USAGE))
+}
diff --git a/src/dscrinsts.c b/src/dscrinsts.c
new file mode 100644
index 0000000..a66853c
--- /dev/null
+++ b/src/dscrinsts.c
@@ -0,0 +1,34 @@
+/* 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 "eclat.h"
+#include "dscrinsts-cl.h"
+
+int
+eclat_describe_instances(CURL *curl, int argc, char **argv)
+{
+ int i;
+ struct ec2_query *q;
+ CURLcode res;
+ char *url;
+
+ parse_options(argc, argv, &i);
+ argv += i;
+ argc -= i;
+
+ q = describe_query_create(curl, "DescribeInstances", argc, argv);
+ return eclat_send_query(curl, q);
+}
diff --git a/src/eclat.c b/src/eclat.c
index a93c7ae..df35e86 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -210,7 +210,6 @@ node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b)
struct command {
const char *ident;
- size_t match_len;
const char *tag;
eclat_command_handler_t handler;
char *fmt;
@@ -218,11 +217,13 @@ struct command {
};
struct command cmdtab[] = {
- { "start-instances", 1, "StartInstances", eclat_start_instance },
- { "stop-instances", 1, "StopInstances", eclat_stop_instance },
- { "describe-tags", 1, "DescribeTags", eclat_describe_tags },
- { "describe-instance-status", 1, "DescribeInstanceStatus",
- eclat_describe_instance_status }
+ { "start-instances", "StartInstances", eclat_start_instance },
+ { "stop-instances", "StopInstances", eclat_stop_instance },
+ { "describe-tags", "DescribeTags", eclat_describe_tags },
+ { "describe-instance-status", "DescribeInstanceStatus",
+ eclat_describe_instance_status },
+ { "describe-instances", "DescribeInstances",
+ eclat_describe_instances },
};
size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]);
@@ -234,43 +235,6 @@ cmdcmp(const void *a, const void *b)
}
void
-init_cmdtab()
-{
- size_t i;
-
- /* Sort commands alphabetically */
- qsort(cmdtab, cmdcnt, sizeof(cmdtab[0]), cmdcmp);
- /* Determine minimum abbreviations */
- for (i = 0; i < cmdcnt; i++) {
- const char *sample = cmdtab[i].ident;
- size_t sample_len = strlen(sample);
- size_t minlen = cmdtab[i].match_len;
- size_t j;
-
- for (j = i + 1; j < cmdcnt; j++) {
- size_t len = strlen(cmdtab[j].ident);
- if (len >= minlen && memcmp(cmdtab[j].ident, sample,
- minlen) == 0)
- do {
- minlen++;
- if (minlen <= strlen(cmdtab[j].ident))
- cmdtab[j].match_len = minlen;
- if (minlen == sample_len)
- break;
- } while (len >= minlen &&
- memcmp(cmdtab[j].ident,
- sample, minlen) == 0);
- else if (cmdtab[j].ident[0] == sample[0])
- cmdtab[j].match_len = minlen;
- else
- break;
- }
- if (minlen <= sample_len)
- cmdtab[i].match_len = minlen;
- }
-}
-
-void
listcmd()
{
struct command *cp;
@@ -288,15 +252,28 @@ listcmd()
struct command *
find_command_name(const char *name)
{
- struct command *cp;
+ struct command *cp, *match = NULL;
size_t namelen = strlen(name);
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
- if (cp->match_len <= namelen &&
- memcmp(name, cp->ident, namelen) == 0)
- return cp;
+ if (!strncmp(cp->ident, name, namelen)) {
+ if (strlen(cp->ident) == namelen)
+ return cp;
+ else if (!match)
+ match = cp;
+ else {
+ /* Second match */
+ err("ambiguous command %s:");
+ err(" %s", match->ident);
+ err(" %s", cp->ident);
+ while (++cp < cmdtab + cmdcnt)
+ if (!strncmp(cp->ident, name, namelen))
+ err(" %s", cp->ident);
+ exit(EX_USAGE);
+ }
+ }
}
- return NULL;
+ return match;
}
struct command *
@@ -417,7 +394,6 @@ list_filters(FILE *fp)
fputc('\n', fp);
}
-
int
main(int argc, char **argv)
@@ -432,7 +408,6 @@ main(int argc, char **argv)
struct command *command = NULL;
set_program_name(argv[0]);
- init_cmdtab();
proginfo.print_help_hook = listcmd;
debug_init();
forlan_init();
diff --git a/src/eclat.conf b/src/eclat.conf
index 88cd959..ec371e3 100644
--- a/src/eclat.conf
+++ b/src/eclat.conf
@@ -50,8 +50,11 @@ if (.DescribeInstanceStatusResponse.instanceStatusSet) {
var.instanceState.name);
if (var.instanceState.name[running]) {
print("\t",var.systemStatus.status);
- for (detail in var.systemStatus.details.item.*) {
- print("\t",detail.name,"=",detail.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");
@@ -97,5 +100,66 @@ else {
}
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(.);
+}
+EOT;
+
diff --git a/src/eclat.h b/src/eclat.h
index 9cc1c74..c886fd0 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -59,6 +59,7 @@ 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);
int eclat_describe_instance_status(CURL *curl, int argc, char **argv);
+int eclat_describe_instances(CURL *curl, int argc, char **argv);
char *region_to_endpoint(const char *region);

Return to:

Send suggestions and report system problems to the System administrator.