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