+
+ conn = getEucaConnection()
+ if not conn:
+ print >>sys.stderr, 'Error: Cannot create a connection to Eucalyptus'
+ return False
+
+ # Validate RSpec
+ schemaXML = ET.parse(EUCALYPTUS_RSPEC_SCHEMA)
+ rspecValidator = ET.RelaxNG(schemaXML)
+ rspecXML = ET.XML(xml)
+ if not rspecValidator(rspecXML):
+ error = rspecValidator.error_log.last_error
+ message = '%s (line %s)' % (error.message, error.line)
+ # XXX: InvalidRSpec is new. Currently, I am not working with Trunk code.
+ #raise InvalidRSpec(message)
+ raise Exception(message)
+
+ # Get the slice from db or create one.
+ s = Slice.select(Slice.q.slice_hrn == hrn).getOne(None)
+ if s is None:
+ s = Slice(slice_hrn = hrn)
+
+ # Process any changes in existing instance allocation
+ pendingRmInst = []
+ for sliceInst in s.instances:
+ pendingRmInst.append(sliceInst.instance_id)
+ existingInstGroup = rspecXML.findall('.//euca_instances')
+ for instGroup in existingInstGroup:
+ for existingInst in instGroup:
+ if existingInst.get('id') in pendingRmInst:
+ pendingRmInst.remove(existingInst.get('id'))
+ for inst in pendingRmInst:
+ print >>sys.stderr, 'Instance %s will be terminated' % inst
+ dbInst = EucaInstance.select(EucaInstance.q.instance_id == inst).getOne(None)
+ dbInst.destroySelf()
+ conn.terminate_instances(pendingRmInst)
+
+ # Process new instance requests
+ requests = rspecXML.findall('.//request')
+ for req in requests:
+ vmTypeElement = req.getparent()
+ instType = vmTypeElement.get('name')
+ numInst = int(req.find('instances').text)
+ instKernel = req.find('kernel_image').get('id')
+ instDiskImg = req.find('disk_image').get('id')
+ instKey = req.find('keypair').text
+
+ ramDiskElement = req.find('ramdisk')
+ ramDiskAttr = ramDiskElement.attrib
+ if 'id' in ramDiskAttr:
+ instRamDisk = ramDiskAttr['id']
+ else:
+ instRamDisk = None
+
+ # Create the instances
+ for i in range(0, numInst):
+ eucaInst = EucaInstance(slice = s,
+ kernel_id = instKernel,
+ image_id = instDiskImg,
+ ramdisk_id = instRamDisk,
+ key_pair = instKey,
+ inst_type = instType)
+ eucaInst.reserveInstance(conn)
+