| # Copyright 2014 Muchos authors (see AUTHORS) |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """ |
| Utility methods |
| """ |
| |
| import os |
| import sys |
| from os.path import isfile, join |
| from optparse import OptionParser |
| |
| |
| class EC2Type: |
| def __init__(self, arch, ephemeral=1, has_nvme=False): |
| self.arch = arch |
| self.ephemeral = ephemeral |
| self.has_nvme = has_nvme |
| |
| AMI_HELP_MSG = """PLEASE NOTE - If you have accepted the software terms for CentOS 7 and still get an error, |
| this could be due to CentOS releasing new images of CentOS 7. When this occurs, the old images |
| are no longer available to new users. If you think this is the case, go to the CentOS 7 product |
| page on AWS Marketplace at the URL below to find the latest AMI: |
| |
| https://aws.amazon.com/marketplace/ordering?productId=b7ee8a69-ee97-4a49-9e68-afaee216db2e |
| |
| On the product page, click 'Manual Launch' to find the latest AMI ID for your EC2 region. |
| This should be used to set the 'aws_ami' property in your muchos.props which will override |
| the default AMI IDs used by Muchos. After setting the 'aws_ami' property, run the launch |
| command again. |
| |
| Also, let us know that this has occured by creating an issue on the Muchos's GitHub page |
| and we'll upgrade the defaults AMIs used by Muchos to be the latest CentOS images. |
| """ |
| |
| instance_types = { |
| "c1.medium": EC2Type("pvm"), |
| "c1.xlarge": EC2Type("pvm", 4), |
| "c3.2xlarge": EC2Type("pvm", 2), |
| "c3.4xlarge": EC2Type("pvm", 2), |
| "c3.8xlarge": EC2Type("pvm", 2), |
| "c3.large": EC2Type("pvm", 2), |
| "c3.xlarge": EC2Type("pvm", 2), |
| "cc2.8xlarge": EC2Type("hvm", 4), |
| "cg1.4xlarge": EC2Type("hvm", 2), |
| "cr1.8xlarge": EC2Type("hvm", 2), |
| "hi1.4xlarge": EC2Type("pvm", 2), |
| "hs1.8xlarge": EC2Type("pvm", 24), |
| "i2.2xlarge": EC2Type("hvm", 2), |
| "i2.4xlarge": EC2Type("hvm", 4), |
| "i2.8xlarge": EC2Type("hvm", 8), |
| "i2.xlarge": EC2Type("hvm"), |
| "i3.large": EC2Type("hvm", 1, True), |
| "i3.xlarge": EC2Type("hvm", 1, True), |
| "i3.2xlarge": EC2Type("hvm", 1, True), |
| "i3.4xlarge": EC2Type("hvm", 2, True), |
| "m1.large": EC2Type("pvm", 2), |
| "m1.medium": EC2Type("pvm"), |
| "m1.small": EC2Type("pvm"), |
| "m1.xlarge": EC2Type("pvm", 4), |
| "m2.2xlarge": EC2Type("pvm", 1), |
| "m2.4xlarge": EC2Type("pvm", 2), |
| "m2.xlarge": EC2Type("pvm"), |
| "m3.2xlarge": EC2Type("hvm", 2), |
| "m3.large": EC2Type("hvm"), |
| "m3.medium": EC2Type("hvm"), |
| "m3.xlarge": EC2Type("hvm", 2), |
| "r3.2xlarge": EC2Type("hvm", 1), |
| "r3.4xlarge": EC2Type("hvm", 1), |
| "r3.8xlarge": EC2Type("hvm", 2), |
| "r3.large": EC2Type("hvm", 1), |
| "r3.xlarge": EC2Type("hvm", 1), |
| "d2.xlarge": EC2Type("hvm", 3), |
| "d2.2xlarge": EC2Type("hvm", 6), |
| "d2.4xlarge": EC2Type("hvm", 12), |
| "d2.8xlarge": EC2Type("hvm", 24) |
| } |
| |
| # AMI given arch & region. PVM arch currently not supported |
| ami_lookup = { |
| "hvm": {"us-east-1": "ami-6d1c2007", |
| "us-west-1": "ami-af4333cf", |
| "us-west-2": "ami-d2c924b2", |
| "eu-west-1": "ami-7abd0209", |
| "eu-central-1": "ami-9bf712f4", |
| "ap-southeast-1": "ami-f068a193", |
| "ap-southeast-2": "ami-fedafc9d", |
| "ap-northeast-1": "ami-eec1c380", |
| "ap-northeast-2": "ami-c74789a9", |
| "sa-east-1": "ami-26b93b4a"}, |
| "pvm": {"us-east-1": None, |
| "us-west-1": None, |
| "us-west-2": None, |
| "eu-west-1": None, |
| "eu-central-1": None, |
| "ap-southeast-1": None, |
| "ap-southeast-2": None, |
| "ap-northeast-1": None, |
| "sa-east-1": None}, |
| } |
| |
| |
| def verify_type(instance_type): |
| if instance_type not in instance_types: |
| print "ERROR - EC2 instance type '%s' is currently not supported!" % instance_type |
| print "This is probably due to the instance type being EBS-only." |
| print "Below is a list of supported instance types:" |
| for key in instance_types: |
| print key |
| sys.exit(1) |
| |
| |
| def get_arch(instance_type): |
| verify_type(instance_type) |
| return instance_types.get(instance_type).arch |
| |
| def get_ephemeral_devices(instance_type): |
| verify_type(instance_type) |
| devices = [] |
| ec2_type = instance_types.get(instance_type) |
| |
| for i in range(0, ec2_type.ephemeral): |
| if ec2_type.has_nvme: |
| devices.append('/dev/nvme' + str(i) + 'n1') |
| else: |
| devices.append('/dev/xvd' + chr(ord('b') + i)) |
| |
| return devices |
| |
| def get_block_device_map(instance_type): |
| verify_type(instance_type) |
| |
| bdm = [{'DeviceName': '/dev/sda1', |
| 'Ebs': {'DeleteOnTermination': True}}] |
| |
| ec2_type = instance_types.get(instance_type) |
| if not ec2_type.has_nvme : |
| for i in range(0, ec2_type.ephemeral): |
| device = {'DeviceName': '/dev/xvd' + chr(ord('b') + i), |
| 'VirtualName': 'ephemeral' + str(i)} |
| bdm.append(device) |
| |
| return bdm |
| |
| def get_ami(instance_type, region): |
| return ami_lookup.get(get_arch(instance_type)).get(region) |
| |
| def parse_args(hosts_dir, input_args=None): |
| parser = OptionParser( |
| usage="muchos [options] <action>\n\n" |
| + "where <action> can be:\n" |
| + " launch Launch cluster in EC2\n" |
| + " status Check status of EC2 cluster\n" |
| + " setup Set up cluster\n" |
| + " sync Sync ansible directory on cluster proxy node\n" |
| + " config Print configuration for that cluster. Requires '-p'. Use '-p all' for all config.\n" |
| + " ssh SSH to cluster proxy node\n" |
| + " kill Kills processes on cluster started by Muchos\n" |
| + " wipe Wipes cluster data and kills processes\n" |
| + " terminate Terminate EC2 cluster\n" |
| + " cancel_shutdown Cancels automatic shutdown of EC2 cluster", |
| add_help_option=False) |
| parser.add_option("-c", "--cluster", dest="cluster", help="Specifies cluster") |
| parser.add_option("-p", "--property", dest="property", help="Specifies property to print (if using 'config' action)" |
| ". Set to 'all' to print every property") |
| parser.add_option("-h", "--help", action="help", help="Show this help message and exit") |
| |
| if input_args: |
| (opts, args) = parser.parse_args(input_args) |
| else: |
| (opts, args) = parser.parse_args() |
| |
| if len(args) == 0: |
| print "ERROR - You must specify on action" |
| return |
| action = args[0] |
| |
| if action == 'launch' and not opts.cluster: |
| print "ERROR - You must specify a cluster if using launch command" |
| return |
| |
| clusters = [f for f in os.listdir(hosts_dir) if isfile(join(hosts_dir, f))] |
| |
| if not opts.cluster: |
| if len(clusters) == 0: |
| print "ERROR - No clusters found in conf/hosts or specified by --cluster option" |
| return |
| elif len(clusters) == 1: |
| opts.cluster = clusters[0] |
| else: |
| print "ERROR - Multiple clusters {0} found in conf/hosts/. " \ |
| "Please pick one using --cluster option".format(clusters) |
| return |
| |
| if action == 'config' and not opts.property: |
| print "ERROR - For config action, you must set -p to a property or 'all'" |
| return |
| |
| return opts, action, args[1:] |