PageRenderTime 97ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/boto-2.5.2/boto/mashups/order.py

#
Python | 211 lines | 173 code | 15 blank | 23 comment | 20 complexity | fa5bca9d67ad4de609164ca6edd404f0 MD5 | raw file
  1. # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
  2. #
  3. # Permission is hereby granted, free of charge, to any person obtaining a
  4. # copy of this software and associated documentation files (the
  5. # "Software"), to deal in the Software without restriction, including
  6. # without limitation the rights to use, copy, modify, merge, publish, dis-
  7. # tribute, sublicense, and/or sell copies of the Software, and to permit
  8. # persons to whom the Software is furnished to do so, subject to the fol-
  9. # lowing conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included
  12. # in all copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
  16. # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  17. # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  18. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. # IN THE SOFTWARE.
  21. """
  22. High-level abstraction of an EC2 order for servers
  23. """
  24. import boto
  25. import boto.ec2
  26. from boto.mashups.server import Server, ServerSet
  27. from boto.mashups.iobject import IObject
  28. from boto.pyami.config import Config
  29. from boto.sdb.persist import get_domain, set_domain
  30. import time, StringIO
  31. InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge']
  32. class Item(IObject):
  33. def __init__(self):
  34. self.region = None
  35. self.name = None
  36. self.instance_type = None
  37. self.quantity = 0
  38. self.zone = None
  39. self.ami = None
  40. self.groups = []
  41. self.key = None
  42. self.ec2 = None
  43. self.config = None
  44. def set_userdata(self, key, value):
  45. self.userdata[key] = value
  46. def get_userdata(self, key):
  47. return self.userdata[key]
  48. def set_region(self, region=None):
  49. if region:
  50. self.region = region
  51. else:
  52. l = [(r, r.name, r.endpoint) for r in boto.ec2.regions()]
  53. self.region = self.choose_from_list(l, prompt='Choose Region')
  54. def set_name(self, name=None):
  55. if name:
  56. self.name = name
  57. else:
  58. self.name = self.get_string('Name')
  59. def set_instance_type(self, instance_type=None):
  60. if instance_type:
  61. self.instance_type = instance_type
  62. else:
  63. self.instance_type = self.choose_from_list(InstanceTypes, 'Instance Type')
  64. def set_quantity(self, n=0):
  65. if n > 0:
  66. self.quantity = n
  67. else:
  68. self.quantity = self.get_int('Quantity')
  69. def set_zone(self, zone=None):
  70. if zone:
  71. self.zone = zone
  72. else:
  73. l = [(z, z.name, z.state) for z in self.ec2.get_all_zones()]
  74. self.zone = self.choose_from_list(l, prompt='Choose Availability Zone')
  75. def set_ami(self, ami=None):
  76. if ami:
  77. self.ami = ami
  78. else:
  79. l = [(a, a.id, a.location) for a in self.ec2.get_all_images()]
  80. self.ami = self.choose_from_list(l, prompt='Choose AMI')
  81. def add_group(self, group=None):
  82. if group:
  83. self.groups.append(group)
  84. else:
  85. l = [(s, s.name, s.description) for s in self.ec2.get_all_security_groups()]
  86. self.groups.append(self.choose_from_list(l, prompt='Choose Security Group'))
  87. def set_key(self, key=None):
  88. if key:
  89. self.key = key
  90. else:
  91. l = [(k, k.name, '') for k in self.ec2.get_all_key_pairs()]
  92. self.key = self.choose_from_list(l, prompt='Choose Keypair')
  93. def update_config(self):
  94. if not self.config.has_section('Credentials'):
  95. self.config.add_section('Credentials')
  96. self.config.set('Credentials', 'aws_access_key_id', self.ec2.aws_access_key_id)
  97. self.config.set('Credentials', 'aws_secret_access_key', self.ec2.aws_secret_access_key)
  98. if not self.config.has_section('Pyami'):
  99. self.config.add_section('Pyami')
  100. sdb_domain = get_domain()
  101. if sdb_domain:
  102. self.config.set('Pyami', 'server_sdb_domain', sdb_domain)
  103. self.config.set('Pyami', 'server_sdb_name', self.name)
  104. def set_config(self, config_path=None):
  105. if not config_path:
  106. config_path = self.get_filename('Specify Config file')
  107. self.config = Config(path=config_path)
  108. def get_userdata_string(self):
  109. s = StringIO.StringIO()
  110. self.config.write(s)
  111. return s.getvalue()
  112. def enter(self, **params):
  113. self.region = params.get('region', self.region)
  114. if not self.region:
  115. self.set_region()
  116. self.ec2 = self.region.connect()
  117. self.name = params.get('name', self.name)
  118. if not self.name:
  119. self.set_name()
  120. self.instance_type = params.get('instance_type', self.instance_type)
  121. if not self.instance_type:
  122. self.set_instance_type()
  123. self.zone = params.get('zone', self.zone)
  124. if not self.zone:
  125. self.set_zone()
  126. self.quantity = params.get('quantity', self.quantity)
  127. if not self.quantity:
  128. self.set_quantity()
  129. self.ami = params.get('ami', self.ami)
  130. if not self.ami:
  131. self.set_ami()
  132. self.groups = params.get('groups', self.groups)
  133. if not self.groups:
  134. self.add_group()
  135. self.key = params.get('key', self.key)
  136. if not self.key:
  137. self.set_key()
  138. self.config = params.get('config', self.config)
  139. if not self.config:
  140. self.set_config()
  141. self.update_config()
  142. class Order(IObject):
  143. def __init__(self):
  144. self.items = []
  145. self.reservation = None
  146. def add_item(self, **params):
  147. item = Item()
  148. item.enter(**params)
  149. self.items.append(item)
  150. def display(self):
  151. print 'This Order consists of the following items'
  152. print
  153. print 'QTY\tNAME\tTYPE\nAMI\t\tGroups\t\t\tKeyPair'
  154. for item in self.items:
  155. print '%s\t%s\t%s\t%s\t%s\t%s' % (item.quantity, item.name, item.instance_type,
  156. item.ami.id, item.groups, item.key.name)
  157. def place(self, block=True):
  158. if get_domain() == None:
  159. print 'SDB Persistence Domain not set'
  160. domain_name = self.get_string('Specify SDB Domain')
  161. set_domain(domain_name)
  162. s = ServerSet()
  163. for item in self.items:
  164. r = item.ami.run(min_count=1, max_count=item.quantity,
  165. key_name=item.key.name, user_data=item.get_userdata_string(),
  166. security_groups=item.groups, instance_type=item.instance_type,
  167. placement=item.zone.name)
  168. if block:
  169. states = [i.state for i in r.instances]
  170. if states.count('running') != len(states):
  171. print states
  172. time.sleep(15)
  173. states = [i.update() for i in r.instances]
  174. for i in r.instances:
  175. server = Server()
  176. server.name = item.name
  177. server.instance_id = i.id
  178. server.reservation = r
  179. server.save()
  180. s.append(server)
  181. if len(s) == 1:
  182. return s[0]
  183. else:
  184. return s