diff --git a/bin/aws/delete_subnets.sh b/bin/aws/aws_delete_subnets.sh similarity index 100% rename from bin/aws/delete_subnets.sh rename to bin/aws/aws_delete_subnets.sh diff --git a/bin/aws/delete_test_instances.sh b/bin/aws/aws_delete_test_instances.sh similarity index 100% rename from bin/aws/delete_test_instances.sh rename to bin/aws/aws_delete_test_instances.sh diff --git a/bin/aws/init_aws_configs.sh b/bin/aws/aws_init_configs.sh similarity index 100% rename from bin/aws/init_aws_configs.sh rename to bin/aws/aws_init_configs.sh diff --git a/bin/aws/list_regions.sh b/bin/aws/aws_list_regions.sh similarity index 100% rename from bin/aws/list_regions.sh rename to bin/aws/aws_list_regions.sh diff --git a/bin/aws/list_test_instances.sh b/bin/aws/aws_list_test_instances.sh similarity index 100% rename from bin/aws/list_test_instances.sh rename to bin/aws/aws_list_test_instances.sh diff --git a/bin/aws/set_aws_region.sh b/bin/aws/aws_set_region.sh similarity index 100% rename from bin/aws/set_aws_region.sh rename to bin/aws/aws_set_region.sh diff --git a/bin/do/do_delete_image.sh b/bin/do/do_delete_image.sh new file mode 100755 index 00000000..a3f451da --- /dev/null +++ b/bin/do/do_delete_image.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +IMAGEID=${1:?no IMAGEID provided} +THISDIR=$(cd $(dirname ${0}) && pwd) +DOCURL=${THISDIR}/docurl + +if [[ ${IMAGEID} == "-n" ]] ; then + IMAGE_NAME=${2:?no image name provided} + echo "Deleting image named: ${IMAGE_NAME}" + ${0} $(${DOCURL} "images?private=true" | jq -r '.images[] | select(.name=="'${IMAGE_NAME}'") | .id') || echo "Error deleting image named: ${IMAGE_NAME}" + +else + echo "Deleting image: ${IMAGEID}" + ${DOCURL} images/${IMAGEID} -X DELETE || echo "Error deleting image: ${IMAGEID}" +fi diff --git a/bin/do/do_delete_instance.sh b/bin/do/do_delete_instance.sh new file mode 100755 index 00000000..6036efab --- /dev/null +++ b/bin/do/do_delete_instance.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +DROPLETID=${1:?no DROPLETID provided} +THISDIR=$(cd $(dirname ${0}) && pwd) +DOCURL=${THISDIR}/docurl + +if [[ ${DROPLETID} == "-n" ]] ; then + DROPLET_NAME=${2:?no droplet name provided} + echo "Deleting droplet named: ${DROPLET_NAME}" + ${0} $(${DOCURL} droplets | jq -r '.droplets[] | select(.name=="'${DROPLET_NAME}'") | .id') || echo "Error deleting droplet named: ${DROPLET_NAME}" + +else + echo "Deleting instance: ${DROPLETID}" + ${DOCURL} droplets/${DROPLETID} -X DELETE || echo "Error deleting instance: ${DROPLETID}" +fi diff --git a/bin/do/do_list_images.sh b/bin/do/do_list_images.sh new file mode 100755 index 00000000..44033e18 --- /dev/null +++ b/bin/do/do_list_images.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +THISDIR=$(cd $(dirname ${0}) && pwd) +DOCURL=${THISDIR}/docurl + +DO_OUTPUT=${1} + +if [[ -z "${DO_OUTPUT}" ]] ; then + ${DOCURL} "images?private=true" | jq . +else + ${DOCURL} "images?private=true" | jq -r .images[].${DO_OUTPUT} +fi diff --git a/bin/do/do_list_instances.sh b/bin/do/do_list_instances.sh new file mode 100755 index 00000000..52071f3f --- /dev/null +++ b/bin/do/do_list_instances.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +THISDIR=$(cd $(dirname ${0}) && pwd) +DOCURL=${THISDIR}/docurl + +DO_OUTPUT=${1} + +if [[ -z "${DO_OUTPUT}" ]] ; then + ${DOCURL} droplets | jq . +else + ${DOCURL} droplets | jq -r .droplets[].${DO_OUTPUT} +fi diff --git a/bin/do/docurl b/bin/do/docurl new file mode 100755 index 00000000..b3667304 --- /dev/null +++ b/bin/do/docurl @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ -z "${DIGITALOCEAN_API_KEY}" ]] ; then + echo "DIGITALOCEAN_API_KEY not defined in environment" + exit 1 +fi + +path=${1:?no path provided} +shift + +curl ${@} -s -H "Authorization: Bearer ${DIGITALOCEAN_API_KEY}" 'https://api.digitalocean.com/v2/'"${path}"'' diff --git a/bin/vultr/vcurl b/bin/vultr/vcurl new file mode 100755 index 00000000..fe8538ca --- /dev/null +++ b/bin/vultr/vcurl @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ -z "${VULTR_API_KEY}" ]] ; then + echo "VULTR_API_KEY not defined in environment" + exit 1 +fi + +path=${1:?no path provided} +shift + +curl ${@} -s -H "API-Key: ${VULTR_API_KEY}" https://api.vultr.com/v1/${path} diff --git a/bin/vultr/vultr_delete_instance.sh b/bin/vultr/vultr_delete_instance.sh new file mode 100755 index 00000000..af8f6c83 --- /dev/null +++ b/bin/vultr/vultr_delete_instance.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +SUBID=${1:?no SUBID provided} +THISDIR=$(cd $(dirname ${0}) && pwd) +VCURL=${THISDIR}/vcurl + +echo "Deleting instance: ${SUBID}" +${VCURL} server/destroy -X POST -d "SUBID=${SUBID}" || echo "Error deleting instance: ${SUBID}" diff --git a/bin/vultr/vultr_delete_snapshot.sh b/bin/vultr/vultr_delete_snapshot.sh new file mode 100755 index 00000000..25cbc8d8 --- /dev/null +++ b/bin/vultr/vultr_delete_snapshot.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +SNAPSHOTID=${1:?no SNAPSHOTID provided} +THISDIR=$(cd $(dirname ${0}) && pwd) +VCURL=${THISDIR}/vcurl + +if [[ ${SNAPSHOTID} == "-n" ]] ; then + SNAPSHOT_NAME=${2:?no snapshot name provided} + echo "Deleting snapshot named: ${SNAPSHOT_NAME}" + ${0} $(${VCURL} snapshot/list | jq -r 'to_entries | .[] | select(.value.description=="'${SNAPSHOT_NAME}'") | .value.SNAPSHOTID') || echo "Error deleting snapshot named: ${SNAPSHOT_NAME}" + +else + echo "Deleting snapshot: ${SNAPSHOTID}" + ${VCURL} snapshot/destroy -X POST -d "SNAPSHOTID=${SNAPSHOTID}" || echo "Error deleting snapshot: ${SNAPSHOTID}" +fi diff --git a/bin/vultr/vultr_list_instances.sh b/bin/vultr/vultr_list_instances.sh new file mode 100755 index 00000000..edaba92b --- /dev/null +++ b/bin/vultr/vultr_list_instances.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +THISDIR=$(cd $(dirname ${0}) && pwd) +VCURL=${THISDIR}/vcurl + +VULTR_OUTPUT=${1} + +if [[ -z "${VULTR_OUTPUT}" ]] ; then + ${VCURL} server/list | jq . +else + ${VCURL} server/list | jq -r .[].${VULTR_OUTPUT} +fi diff --git a/bin/vultr/vultr_list_snapshots.sh b/bin/vultr/vultr_list_snapshots.sh new file mode 100755 index 00000000..bb857eed --- /dev/null +++ b/bin/vultr/vultr_list_snapshots.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +THISDIR=$(cd $(dirname ${0}) && pwd) +VCURL=${THISDIR}/vcurl + +VULTR_OUTPUT=${1} + +if [[ -z "${VULTR_OUTPUT}" ]] ; then + ${VCURL} snapshot/list | jq . +else + ${VCURL} snapshot/list | jq -r .[].${VULTR_OUTPUT} +fi diff --git a/bubble-server/src/main/java/bubble/cloud/compute/digitalocean/DigitalOceanPackerImageParser.java b/bubble-server/src/main/java/bubble/cloud/compute/digitalocean/DigitalOceanPackerImageParser.java index b42f8353..6762818f 100644 --- a/bubble-server/src/main/java/bubble/cloud/compute/digitalocean/DigitalOceanPackerImageParser.java +++ b/bubble-server/src/main/java/bubble/cloud/compute/digitalocean/DigitalOceanPackerImageParser.java @@ -28,7 +28,7 @@ public class DigitalOceanPackerImageParser extends PackerImageParserBase { final PackerImage image = new PackerImage().setName(name); - if (item.has("id")) image.setId(item.get("id").textValue()); + if (item.has("id")) image.setId(item.get("id").asText()); if (item.has("regions")) { final JsonNode regionsNode = item.get("regions"); diff --git a/bubble-server/src/main/java/bubble/service/packer/PackerJob.java b/bubble-server/src/main/java/bubble/service/packer/PackerJob.java index 745e739d..0c8ca841 100644 --- a/bubble-server/src/main/java/bubble/service/packer/PackerJob.java +++ b/bubble-server/src/main/java/bubble/service/packer/PackerJob.java @@ -47,6 +47,7 @@ import static org.cobbzilla.util.network.NetworkUtil.getExternalIp; import static org.cobbzilla.util.string.StringUtil.truncate; import static org.cobbzilla.util.system.CommandShell.hostname; import static org.cobbzilla.util.time.TimeUtil.DATE_FORMAT_YYYYMMDDHHMMSS; +import static org.cobbzilla.util.time.TimeUtil.formatDuration; @Slf4j public class PackerJob implements Callable> { @@ -223,6 +224,7 @@ public class PackerJob implements Callable> { toFileOrDie(abs(tempDir) + "/packer.json", packerJson); // run packer, return handle to running packer + final long start = now(); log.info("running packer for " + installType + "..."); final int packerParallelBuilds = computeDriver.getPackerParallelBuilds(); final CommandResult commandResult = CommandShell.exec(new Command(new CommandLine(PACKER_BINARY) @@ -256,7 +258,7 @@ public class PackerJob implements Callable> { } if (imagesRef != null) imagesRef.set(images); - log.info("packer images created: "+images); + log.info("packer images created in "+formatDuration(now() - start)+": "+images); return images; } diff --git a/bubble-server/src/main/resources/bubble/node_progress_meter_ticks.json b/bubble-server/src/main/resources/bubble/node_progress_meter_ticks.json index d7e4e03e..51d8ce82 100644 --- a/bubble-server/src/main/resources/bubble/node_progress_meter_ticks.json +++ b/bubble-server/src/main/resources/bubble/node_progress_meter_ticks.json @@ -9,5 +9,5 @@ { "percent": 92,"messageKey":"restart_algo", "match": "prefix", "pattern":"TASK [Restart algo monitors]" }, { "percent": 95,"messageKey":"snapshot_ansible", "match": "prefix", "pattern":"TASK [finalizer : Snapshot ansible roles]" }, { "percent": 98,"messageKey":"touch_first_setup","match": "prefix", "pattern":"TASK [finalizer : Touch first-time setup file]" }, -{ "percent": 99,"messageKey":"ssh_keys", "match": "prefix", "pattern":"TASK [finalizer : Ensure authorized SSH keys are up-to-date]" } +{ "percent": 100,"messageKey":"ssh_keys", "match": "prefix", "pattern":"TASK [finalizer : Ensure authorized SSH keys are up-to-date]" } ] diff --git a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties index adcce8ae..f049eff2 100644 --- a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties +++ b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties @@ -332,10 +332,10 @@ footprint_description_Worldwide=Your Bubble can run anywhere in the world meter_tick_confirming_network_lock=Thinking about baking a pie meter_tick_validating_node_network_and_plan=Grabbing the cookbook... meter_tick_creating_node=Finding the best pie recipe ever... -meter_tick_launching_node=Assembling pie ingredients... -meter_tick_preparing_roles=Pre-heating the oven... -meter_tick_preparing_install=Peeling the apples... -meter_tick_starting_install=Slicing the apples... +meter_tick_launching_node=Cleaning the kitchen... +meter_tick_preparing_roles=Pre-heating the oven... +meter_tick_preparing_install=Getting all the ingredients together... +meter_tick_starting_install=Peeling and slicing the apples... meter_tick_copying_ansible=Rolling out the pie dough... meter_tick_running_ansible=Whipping the batter... #meter_tick_confirming_network_lock=Confirming network lock @@ -359,7 +359,7 @@ meter_tick_algo_sh=Baking the pie... meter_tick_restart_algo=Removing pie from the oven... meter_tick_snapshot_ansible=Letting the pie cool a bit... meter_tick_touch_first_setup=Setting the table... -meter_tick_ssh_keys=Get everybody, the pie is ready! +meter_tick_ssh_keys=Hey everybody, the pie is ready! #meter_tick_ansible_deps=Installing installer dependencies #meter_tick_config_node=Configuration installation #meter_tick_nginx_dhparam=Securing SSL libraries diff --git a/bubble-web b/bubble-web index 64440fcc..ed569238 160000 --- a/bubble-web +++ b/bubble-web @@ -1 +1 @@ -Subproject commit 64440fcc2386dc49271cc2f99e87b5fcd264f3f8 +Subproject commit ed5692386fa30a431880e4d17778c6545d6cf08a