diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-05 18:06:37 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-05 18:06:37 +0300 |
commit | d19bab14d9f3e8093ea8288c08f4df5249f2801c (patch) | |
tree | 64124e0bfb195664ba5ef3562c80437091d6b0d5 | |
parent | 9205135a977cacebb79df1309ef5eaab57127f06 (diff) | |
download | eclat-d19bab14d9f3e8093ea8288c08f4df5249f2801c.tar.gz eclat-d19bab14d9f3e8093ea8288c08f4df5249f2801c.tar.bz2 |
Implement create-image and deregister-image.
* TODO: Update.
* etc/create-image.fln: New file.
* etc/deregister-image.fln: New file.
* etc/Makefile.am (FLNFILES): Add new files.
* lib/envmap.c: New file.
* lib/Makefile.am (libeclat_a_SOURCES): Add new files.
* lib/libeclat.h (eclat_encode_devmap): New proto.
* src/creimg-cl.opt: New file.
* src/creimg.c: New file.
* src/drgimg.c: New file.
* src/Makefile.am: Add new files.
* src/dscrimgs-cl.opt: Change short option to -u for
consistency with other commands.
* src/eclat.c: New commands create-image and
deregister-image.
* src/eclat.h (eclat_create_image)
(eclat_deregister_image): New prototypes.
* src/runinsts.c (encode_devmap): Move to the library.
-rw-r--r-- | TODO | 6 | ||||
-rw-r--r-- | etc/Makefile.am | 2 | ||||
-rw-r--r-- | etc/create-image.fln | 19 | ||||
-rw-r--r-- | etc/deregister-image.fln | 20 | ||||
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/envmap.c | 154 | ||||
-rw-r--r-- | lib/libeclat.h | 3 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/creimg-cl.opt | 52 | ||||
-rw-r--r-- | src/creimg.c | 49 | ||||
-rw-r--r-- | src/drgimg.c | 38 | ||||
-rw-r--r-- | src/dscrimgs-cl.opt | 2 | ||||
-rw-r--r-- | src/eclat.c | 4 | ||||
-rw-r--r-- | src/eclat.h | 2 | ||||
-rw-r--r-- | src/runinsts.c | 131 |
15 files changed, 352 insertions, 134 deletions
@@ -27,7 +27,7 @@ CancelSpotInstanceRequests CANSPOTINSTREQS [ ] [ ] ConfirmProductInstance CFRMPRODINST [ ] [ ] CreateCustomerGateway CRECUSTGW [ ] [ ] CreateDhcpOptions CREDHCPOPTS [ ] [ ] -CreateImage CREIMG [ ] [ ] +CreateImage CREIMG [X] [ ] CreateInstanceExportTask CREINSTEXPTSK [ ] [ ] CreateInternetGateway CREINETGW [ ] [ ] CreateKeyPair CREKEYPAIR [ ] [ ] @@ -68,7 +68,7 @@ DeleteVpc DELVPC [ ] [ ] DeleteVpnConnection DELVPNCNCT [ ] [ ] DeleteVpnConnectionRoute DELVPNCNCTROUT [ ] [ ] DeleteVpnGateway DELVPNGW [ ] [ ] -DeregisterImage DRGIMG [ ] [ ] +DeregisterImage DRGIMG [X] [ ] DescribeAddresses DSCRADRS [X] [X] DescribeAvailabilityZones DSCRAZS [X] [X] DescribeBundleTasks DSCRBUNTSKS [ ] [ ] @@ -129,7 +129,7 @@ MonitorInstances MONINSTS [ ] [ ] PurchaseReservedInstancesOffering PURRSRVDINSTSOFR [ ] [ ] RebootInstances RBTINSTS [X] [X] RegisterImage REGIMG [ ] [ ] -ReleaseAddress RLSADR [X] [ ] +ReleaseAddress RLSADR [X] [X] ReplaceNetworkAclAssociation RPLNETACLASCN [ ] [ ] ReplaceNetworkAclEntry RPLNETACLENT [ ] [ ] ReplaceRoute RPLROUT [ ] [ ] diff --git a/etc/Makefile.am b/etc/Makefile.am index d44ccfe..a8a903b 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -20,12 +20,14 @@ FLNFILES=\ allocate-address.fln\ attach-volume.fln\ associate-address.fln\ + create-image.fln\ create-snapshot.fln\ create-tags.fln\ create-volume.fln\ delete-snapshot.fln\ delete-tags.fln\ delete-volume.fln\ + deregister-image.fln\ describe-addresses.fln\ describe-availability-zones.fln\ describe-images.fln\ diff --git a/etc/create-image.fln b/etc/create-image.fln new file mode 100644 index 0000000..938926a --- /dev/null +++ b/etc/create-image.fln @@ -0,0 +1,19 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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 (.CreateImageResponse) { + print(.CreateImageResponse.imageId,"\n"); +} diff --git a/etc/deregister-image.fln b/etc/deregister-image.fln new file mode 100644 index 0000000..8ada92c --- /dev/null +++ b/etc/deregister-image.fln @@ -0,0 +1,20 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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 (.DeregisterImageResponse.return) { + if (!.DeregisterImageResponse.return[true]) + error("Return: ",.DeregisterImageResponse.return,"\n"); +} diff --git a/lib/Makefile.am b/lib/Makefile.am index 62f58b9..d6eaa56 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,6 +36,7 @@ libeclat_a_SOURCES=\ base64.c\ confirm.c\ diag.c\ + envmap.c\ expand.c\ forlan.c\ forlan.h\ diff --git a/lib/envmap.c b/lib/envmap.c new file mode 100644 index 0000000..2e3f8aa --- /dev/null +++ b/lib/envmap.c @@ -0,0 +1,154 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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 <config.h> +#include <string.h> +#include <ctype.h> +#include <sysexits.h> +#include "libeclat.h" +#include "wordsplit.h" +#include "grecs.h" + +static int +isnumstr(const char *p) +{ + for (; *p; p++) + if (!isdigit(*p)) + return 0; + return 1; +} + +void +eclat_encode_devmap(struct ec2_query *q, struct grecs_list *list) +{ + int i; + char *bufptr = NULL; + size_t bufsize = 0; + struct grecs_list_entry *ep; + + if (!list) + return; + for (i = 1, ep = list->head; ep; ep = ep->next, i++) { + char *dev = ep->data; + char *p = strchr(dev, '='); + + if (!p) + die(EX_USAGE, "malformed device mapping: %s", dev); + *p++ = 0; + + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.DeviceName", + i); + eclat_query_add_param(q, bufptr, dev); + + if (strcmp(p, "none") == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.NoDevice", + i); + eclat_query_add_param(q, bufptr, NULL); + } else if (strncmp(p, "ephemeral", 9) == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.VirtualName", + i); + eclat_query_add_param(q, bufptr, p); + } else { + struct wordsplit ws; + + /* [snapshot-id]:[volume-size]:[true|false]:[standard|io1[:iops]] */ + ws.ws_delim = ":"; + if (wordsplit(p, &ws, + WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM)) + die(EX_SOFTWARE, + "failed to split string %s: %s", + p, + wordsplit_strerror(&ws)); + if (ws.ws_wordc == 1) { + if (strncmp(ws.ws_wordv[0], "snap-", 5) == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.SnapshotId", + i); + } else if (isnumstr(ws.ws_wordv[0])) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.VolumeSize", + i); + } else + die(EX_USAGE, + "unrecognized word \"%s\", " + "expected either a snapshot ID, " + "or disk size", + ws.ws_wordv[0]); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[0]); + } else { + if (ws.ws_wordv[0]) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.SnapshotId", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[0]); + } + + if (ws.ws_wordv[1]) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.VolumeSize", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[1]); + } + } + + switch (ws.ws_wordc) { + default: + die(EX_USAGE, + "too many parts in device mapping \"%s\"", + p); + case 5: + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.Ebs.Iops", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[4]); + /* fall through */ + case 4: + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.Ebs.VolumeType", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[3]); + /* fall through */ + case 3: + if (strcmp(ws.ws_wordv[2], "false") && + strcmp(ws.ws_wordv[2], "true")) + die(EX_USAGE, + "expected \"true\" or \"false\", " + "but found \"%s\"", + ws.ws_wordv[2]); + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.DeleteOnTermination", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[2]); + } + wordsplit_free(&ws); + } + } + free(bufptr); +} diff --git a/lib/libeclat.h b/lib/libeclat.h index 107d15d..7c0d2fb 100644 --- a/lib/libeclat.h +++ b/lib/libeclat.h @@ -93,6 +93,9 @@ void eclat_query_signature(struct ec2_query *req, char *secret); char *eclat_query_to_url(struct ec2_query *req, char **post_params); void eclat_query_encode(struct ec2_query *q); + +void eclat_encode_devmap(struct ec2_query *q, struct grecs_list *list); + typedef struct eclat_partial_tree *eclat_partial_tree_t; diff --git a/src/Makefile.am b/src/Makefile.am index 0492bd9..8638b45 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ eclat_SOURCES=\ attvol.c\ cmdline.h\ config.c\ + creimg.c\ cretags.c\ cresnap.c\ crevol.c\ @@ -30,6 +31,7 @@ eclat_SOURCES=\ delvol.c\ detvol.c\ disassaddr.c\ + drgimg.c\ dscraddrs.c\ dscrazs.c\ dscrsnap.c\ @@ -63,6 +65,7 @@ AM_CPPFLAGS = \ OPTFILES=\ allocaddr-cl.opt\ asscaddr-cl.opt\ + creimg-cl.opt\ cretags-cl.opt\ crevol-cl.opt\ detvol-cl.opt\ diff --git a/src/creimg-cl.opt b/src/creimg-cl.opt new file mode 100644 index 0000000..18c9716 --- /dev/null +++ b/src/creimg-cl.opt @@ -0,0 +1,52 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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 create-image", + [<create an AMI>], + [<NAME INSTANCE>], + [<gnu>], + [<nousage>], + [<noversion>]) + +OPTION(description,d,[<STRING>], + [<image description>]) +BEGIN + descr = optarg; +END + +OPTION(noreboot,N,, + [<don't shut down the instance before creating the image>]) +ALIAS(no-reboot) +BEGIN + noreboot = 1; +END + +OPTION(devmap,m,[<DEV=SPEC>], + [<set block device mapping>]) +ALIAS(block-device-mapping) +BEGIN + if (!devmap) + devmap = grecs_list_create(); + grecs_list_append(devmap, optarg); +END + +OPTIONS_END + +static void +parse_options(int argc, char *argv[], int *index) +{ + GETOPT(argc, argv, *index, exit(EX_USAGE)) +} diff --git a/src/creimg.c b/src/creimg.c new file mode 100644 index 0000000..bcc52f6 --- /dev/null +++ b/src/creimg.c @@ -0,0 +1,49 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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" +int noreboot; +char *descr; +struct grecs_list *devmap; +#include "creimg-cl.h" + +int +eclat_create_image(eclat_command_env_t *env, int argc, char **argv) +{ + int i; + struct ec2_query *q = env->query; + + parse_options(argc, argv, &i); + argc -= i; + argv += i; + if (argc != 2) + die(EX_USAGE, "wrong number of arguments"); + + translate_ids(1, argv+1, "InstanceId"); + eclat_query_add_param(q, "Name", argv[0]); + eclat_query_add_param(q, "InstanceId", argv[1]); + + if (descr) + eclat_query_add_param(q, "Description", descr); + + if (noreboot) + eclat_query_add_param(q, "NoReboot", "True"); + + if (devmap) + eclat_encode_devmap(q, devmap); + + return 0; +} diff --git a/src/drgimg.c b/src/drgimg.c new file mode 100644 index 0000000..73fda13 --- /dev/null +++ b/src/drgimg.c @@ -0,0 +1,38 @@ +/* This file is part of Eclat. + Copyright (C) 2013 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" + +int +eclat_deregister_image(eclat_command_env_t *env, int argc, char **argv) +{ + int i; + + generic_proginfo->args_doc = "AMI-ID"; + generic_parse_options("eclat deregister-image", + "deregister AMI", + argc, argv, &i); + argv += i; + argc -= i; + + if (argc != 1) + die(EX_USAGE, "bad number of arguments"); + + translate_ids(argc, argv, "ImageId"); + eclat_query_add_param(env->query, "ImageId", argv[0]); + return 0; +} + diff --git a/src/dscrimgs-cl.opt b/src/dscrimgs-cl.opt index b358058..a176e60 100644 --- a/src/dscrimgs-cl.opt +++ b/src/dscrimgs-cl.opt @@ -31,7 +31,7 @@ BEGIN eclat_query_add_param(q, bufptr, "all"); END -OPTION(owner,o,[<ID|amazon|aws-marketplace|self|all>], +OPTION(owner,u,[<ID|amazon|aws-marketplace|self|all>], [<select AMIs with a particular owner>]) BEGIN grecs_asprintf(&bufptr, &bufsize, "Owner.%d", ++owner_n); diff --git a/src/eclat.c b/src/eclat.c index d198345..ef2f348 100644 --- a/src/eclat.c +++ b/src/eclat.c @@ -276,6 +276,10 @@ struct command cmdtab[] = { eclat_describe_images }, { "run-instances", "RunInstances", eclat_run_instances, CMD_MOD }, + { "create-image", "CreateImage", + eclat_create_image, CMD_MOD }, + { "deregister-image", "DeregisterImage", + eclat_deregister_image, CMD_MOD|CMD_DESTR } }; size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]); diff --git a/src/eclat.h b/src/eclat.h index 011b666..36a5349 100644 --- a/src/eclat.h +++ b/src/eclat.h @@ -109,6 +109,8 @@ int eclat_modify_instance_attribute(eclat_command_env_t *env, int argc, char **argv); int eclat_run_instances(eclat_command_env_t *env, int argc, char **argv); int eclat_describe_images(eclat_command_env_t *env, int argc, char **argv); +int eclat_create_image(eclat_command_env_t *env, int argc, char **argv); +int eclat_deregister_image(eclat_command_env_t *env, int argc, char **argv); char *region_to_endpoint(const char *region); diff --git a/src/runinsts.c b/src/runinsts.c index 826377d..c13361a 100644 --- a/src/runinsts.c +++ b/src/runinsts.c @@ -17,135 +17,6 @@ #include "eclat.h" #include "runinsts-cl.h" -static int -isnumstr(const char *p) -{ - for (; *p; p++) - if (!isdigit(*p)) - return 0; - return 1; -} - -static void -encode_devmap(struct ec2_query *q) -{ - int i; - char *bufptr = NULL; - size_t bufsize = 0; - struct grecs_list_entry *ep; - - for (i = 1, ep = devmap->head; ep; ep = ep->next, i++) { - char *dev = ep->data; - char *p = strchr(dev, '='); - - if (!p) - die(EX_USAGE, "malformed device mapping: %s", dev); - *p++ = 0; - - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d.DeviceName", - i); - eclat_query_add_param(q, bufptr, dev); - - if (strcmp(p, "none") == 0) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d.NoDevice", - i); - eclat_query_add_param(q, bufptr, NULL); - } else if (strncmp(p, "ephemeral", 9) == 0) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d.VirtualName", - i); - eclat_query_add_param(q, bufptr, p); - } else { - struct wordsplit ws; - - /* [snapshot-id]:[volume-size]:[true|false]:[standard|io1[:iops]] */ - ws.ws_delim = ":"; - if (wordsplit(p, &ws, - WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM)) - die(EX_SOFTWARE, - "failed to split string %s: %s", - p, - wordsplit_strerror(&ws)); - if (ws.ws_wordc == 1) { - if (strncmp(ws.ws_wordv[0], "snap-", 5) == 0) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d." - "Ebs.SnapshotId", - i); - } else if (isnumstr(ws.ws_wordv[0])) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d." - "Ebs.VolumeSize", - i); - } else - die(EX_USAGE, - "unrecognized word \"%s\", " - "expected either a snapshot ID, " - "or disk size", - ws.ws_wordv[0]); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[0]); - } else { - if (ws.ws_wordv[0]) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d." - "Ebs.SnapshotId", - i); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[0]); - } - - if (ws.ws_wordv[1]) { - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d." - "Ebs.VolumeSize", - i); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[1]); - } - } - - switch (ws.ws_wordc) { - default: - die(EX_USAGE, - "too many parts in device mapping \"%s\"", - p); - case 5: - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d.Ebs.Iops", - i); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[4]); - /* fall through */ - case 4: - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d.Ebs.VolumeType", - i); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[3]); - /* fall through */ - case 3: - if (strcmp(ws.ws_wordv[2], "false") && - strcmp(ws.ws_wordv[2], "true")) - die(EX_USAGE, - "expected \"true\" or \"false\", " - "but found \"%s\"", - ws.ws_wordv[2]); - grecs_asprintf(&bufptr, &bufsize, - "BlockDeviceMapping.%d." - "Ebs.DeleteOnTermination", - i); - eclat_query_add_param(q, bufptr, - ws.ws_wordv[2]); - } - wordsplit_free(&ws); - } - } - free(bufptr); -} - /* format: dev-index:subnet:description:priv-ip:sgs:DOT:sip-count:sips @@ -302,7 +173,7 @@ eclat_run_instances(eclat_command_env_t *env, int argc, char **argv) eclat_query_add_param(q, "RamdiskId", ramdisk); if (devmap) - encode_devmap(q); + eclat_encode_devmap(q, devmap); if (monitor) eclat_query_add_param(q, "Monitoring.Enabled", "true"); |