starcluster.commands.createvolume

Package starcluster :: Package commands :: Module createvolume |
[hide private]
[frames] | no frames]

# Source Code for Module starcluster.commands.createvolume

      1  #!/usr/bin/env python
      2  import os
      3
      4  from starcluster import node
      5  from starcluster import volume
      6  from starcluster import static
      7  from starcluster import exception
      8
      9  from base import CmdBase
     10
     11
     12 -class CmdCreateVolume(CmdBase):
     13      """
     14      createvolume [options] <volume_size> <volume_zone>
     15
     16      Create a new EBS volume for use with StarCluster
     17      """
     18
     19      names = ['createvolume', 'cv']
     20
     21 -    def addopts(self, parser):
     22          parser.add_option(
     23              "-n", "--name", dest="name", action="store", type="string",
     24              default=None, help="Give the volume a user-friendly name "
     25              "(displayed in listvolumes command and in AWS console)")
     26          parser.add_option(
     27              "-b", "--bid", dest="spot_bid", action="store", type="float",
     28              default=None, help="Requests spot instances instead of flat "
     29              "rate instances. Uses SPOT_BID as max bid for the request.")
     30          parser.add_option(
     31              "-k", "--keypair", dest="keypair",
     32              action="store", type="string", default=None,
     33              help="The keypair to use when launching host instance " + \
     34              "(must be defined in the config)")
     35          parser.add_option(
     36              "-H", "--host-instance", dest="host_instance",
     37              action="store", type="string", default=None,
     38              help="Use specified instance as volume host rather than " + \
     39              "launching a new host")
     40          parser.add_option(
     41              "-d", "--detach-volume", dest="detach_vol",
     42              action="store_true", default=False,
     43              help="Detach new volume from host instance after creation")
     44          parser.add_option(
     45              "-s", "--shutdown-volume-host", dest="shutdown_instance",
     46              action="store_true", default=False,
     47              help="Shutdown host instance after creating new volume")
     48          parser.add_option(
     49              "-m", "--mkfs-cmd", dest="mkfs_cmd",
     50              action="store", type="string", default="mkfs.ext3",
     51              help="Specify alternate mkfs command to use when " + \
     52              "formatting volume (default: mkfs.ext3)")
     53          parser.add_option(
     54              "-i", "--image-id", dest="image_id",
     55              action="store", type="string", default=None,
     56              help="The AMI to use when launching volume host instance")
     57          parser.add_option(
     58              "-I", "--instance-type", dest="instance_type",
     59              action="store", type="choice", default="m1.small",
     60              choices=static.INSTANCE_TYPES.keys(),
     61              help="The instance type to use when launching volume " + \
     62              "host instance")
     63          parser.add_option(
     64              "-t", "--tag", dest="tags", action="callback", type="string",
     65              default={}, callback=self._build_dict,
     66              help="One or more tags to apply to the new volume (key=value)")
     67
     68 -    def cancel_command(self, signum, frame):
     69          raise exception.CancelledCreateVolume()
     70
     71 -    def _load_keypair(self, keypair=None):
     72          key_location = None
     73          if keypair:
     74              kp = self.ec2.get_keypair(keypair)
     75              key = self.cfg.get_key(kp.name)
     76              key_location = key.get('key_location', '')
     77          else:
     78              self.log.info("No keypair specified, picking one from config...")
     79              for kp in self.ec2.keypairs:
     80                  if kp.name in self.cfg.keys:
     81                      keypair = kp.name
     82                      kl = self.cfg.get_key(kp.name).get('key_location', '')
     83                      if os.path.exists(kl) and os.path.isfile(kl):
     84                          self.log.info('Using keypair: %s' % keypair)
     85                          key_location = kl
     86                          break
     87          if not keypair:
     88              raise exception.ConfigError(
     89                  "no keypairs in region %s defined in config" % \
     90                  self.ec2.region.name)
     91          if not key_location:
     92              raise exception.ConfigError(
     93                  "cannot determine key_location for keypair %s" % keypair)
     94          if not os.path.exists(key_location):
     95              raise exception.ValidationError(
     96                  "key_location '%s' does not exist." % key_location)
     97          elif not os.path.isfile(key_location):
     98              raise exception.ValidationError(
     99                  "key_location '%s' is not a file." % key_location)
    100          return (keypair, key_location)
    101
    102 -    def _get_size_arg(self, size):
    103          errmsg = "size argument must be an integer >= 1"
    104          try:
    105              size = int(size)
    106              if size <= 0:
    107                  self.parser.error(errmsg)
    108              return size
    109          except ValueError:
    110              self.parser.error(errmsg)
    111
    112 -    def execute(self, args):
    113          if len(args) != 2:
    114              self.parser.error(
    115                  "you must specify a size (in GB) and an availability zone")
    116          size, zone = args
    117          size = self._get_size_arg(size)
    118          zone = self.ec2.get_zone(zone).name
    119          key = self.opts.keypair
    120          host_instance = None
    121          if self.opts.host_instance:
    122              host_instance = self.ec2.get_instance(self.opts.host_instance)
    123              key = host_instance.key_name
    124          keypair, key_location = self._load_keypair(key)
    125          if host_instance:
    126              host_instance = node.Node(host_instance, key_location,
    127                                        alias="volumecreator_host")
    128          kwargs = self.specified_options_dict
    129          kwargs.update(dict(keypair=keypair, key_location=key_location,
    130                             host_instance=host_instance))
    131          vc = volume.VolumeCreator(self.ec2, **kwargs)
    132          if host_instance:
    133              vc._validate_host_instance(host_instance, zone)
    134          self.catch_ctrl_c()
    135          vc.create(size, zone, name=self.opts.name, tags=self.opts.tags)
    136