1
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
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
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
70
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
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
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