def POST_receiveMigratedSVMDiskFile(self): # Get the id and load the metadata for this SVM. svm_id = request.params.get('id') migrated_svm = ServiceVM.by_id(svm_id) if not migrated_svm: abort(404, '404 Not Found - SVM with id %s not found' % svm_id) # Receive the transferred file and update its path. print 'Storing disk image file of SVM in migration.' destination_folder = os.path.join(app_globals.cloudlet.svmInstancesFolder, svm_id) disk_image_object = request.params.get('disk_image_file').file migrated_svm.vm_image.store(destination_folder, disk_image_object) print 'Migrated SVM disk image file stored.' # Check that we have the backing file, and rebase the new file so it will point to the correct backing file. service = Service.by_id(migrated_svm.service_id) if service: print 'Rebasing backing file for service %s.' % migrated_svm.service_id backing_disk_file = service.vm_image.disk_image migrated_svm.vm_image.rebase_disk_image(backing_disk_file) else: # Migration will be unsuccessful since we won't have the backing file. print 'Service %s not found in local cloudlet.' % migrated_svm.service_id abort(500, '500 Server Error - Service is not installed on target cloudlet.') # Save to internal DB. migrated_svm.save() return ajaxutils.JSON_OK
def GET_export_svm(self, sid): service = Service.by_id(sid) if not service: return "Service Not Found" path = request.params.get("export_path") if not path: path = os.path.join(app_globals.cloudlet.export_path, service.service_id + ".csvm") print "Disk Image: ", service.vm_image.disk_image print "State Image: ", service.vm_image.state_image print "Starting export to: ", path tar = tarfile.open(path, "w:gz") add_file_to_tar(filepath=service.vm_image.disk_image, tar=tar) add_file_to_tar(filepath=service.vm_image.state_image, tar=tar) add_string_to_tar(data=service.export(), filename="service.json", tar=tar) tar.close() print "Export complete" return path
def GET_import(self): print "Starting SVM import" filename = request.params.get("filename") if not filename.endswith(".csvm"): print "Invalid file" return {"error": "Invalid file"} if not os.path.exists(filename): print "File does not exist" return {"error": "File does not exist"} print "Importing file: ", filename tar = tarfile.open(filename, "r") service = Service(get_service_json(tar)) svm_cache = app_globals.cloudlet.svmCache svm_path = os.path.join(svm_cache, service.service_id) disk_image = service.vm_image.disk_image state_image = service.vm_image.state_image if os.path.exists(svm_path): print "Service path already exists" return {"error": "Service already exists"} os.makedirs(svm_path) service.vm_image.disk_image = os.path.join(svm_path, disk_image) service.vm_image.state_image = os.path.join(svm_path, state_image) try: # Extract the disk image to its permanent location. tar.extract(disk_image, path=svm_path) try: # Extract the memory image to its permanent location. tar.extract(state_image, path=svm_path) # Since usually the memory state from an imported SVM will be incompatible with another computer, # refresh the memory state. service.refresh_image_memory_state() except Exception as e: # Create a memory image from a XML template, since the one in the tar was not valid. print str(e) print "Could not load VM XML info; creating new one from disk image and standard XML template." service.create_image_memory_state(svm_path) service.save() except Exception as e: print "Exception while importing: " + str(e) shutil.rmtree(svm_path) return {"error": str(e)} print "Done importing!" return service
def GET_list(self): print '\n*************************************************************************************************' timelog.TimeLog.reset() timelog.TimeLog.stamp("Request received: get list of Services.") services = Service.find() # Send the response. timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) return services
def GET_removeService(self, id): try: service = Service.find_and_remove(id) if service: service.destroy(force=True) except Exception as e: # If there was a problem removing the service, return that there was an error. msg = 'Error removing Service: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def GET_metadata(self): timelog.TimeLog.reset() timelog.TimeLog.stamp("Request received: get metadata.") ret = Cloudlet.system_information() if bool_param('services'): ret.services = Service.find() if bool_param('apps'): ret.apps = App.find() timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) return ret
def GET_find(self): # Look for the VM in the repository. sid = request.params.get('serviceId', None) print '\n*************************************************************************************************' timelog.TimeLog.reset() timelog.TimeLog.stamp("Request received: find cached Service VM.") ret = Service.by_id(sid) if not ret: abort(404, '404 Not Found - service for %s not found' % sid) else: # Send the response. timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) return ret
def GET_import(self): print "Starting SVM import" filename = request.params.get("filename") if not filename.endswith(".csvm"): return {"error": "Invalid file"} if not os.path.exists(filename): return {"error": "File does not exist"} print "Importing file: ", filename tar = tarfile.open(filename, "r") service = Service(get_service_json(tar)) svm_cache = app_globals.cloudlet.svmCache svm_path = os.path.join(svm_cache, service.service_id) disk_image = service.vm_image.disk_image state_image = service.vm_image.state_image if os.path.exists(svm_path): return {"error": "Service already exists"} os.makedirs(svm_path) try: tar.extract(disk_image, path=svm_path) tar.extract(state_image, path=svm_path) service.vm_image.disk_image = os.path.join(svm_path, disk_image) service.vm_image.state_image = os.path.join(svm_path, state_image) service.save() except Exception as e: print "Exception while importing: ", str(e) return {"error", str(e)} print "Done importing!" return service
def GET_listServices(self): # Mark the active tab. c.services_active = 'active' # Get a list of existing stored VMs in the cache. services = Service.find() # Pass the grid and render the page. servicesPage = ServicesPage() # servicesPage.servicesGrid = servicesGrid servicesPage.services = services return servicesPage.render()
def loadDataIntoPage(self, page, serviceID): # Setup the page to render. page.form_values = {} page.form_errors = {} page.os_options = {'Linux':'Linux','Windows':'Windows'} # URL to create a new Service VM. page.createSVMURL = h.url_for(controller="modify", action='createSVM') # Check if we are editing or creating a new service. creatingNew = serviceID is None page.saveInstanceURL = h.url_for(controller='modify', action='saveInstanceToRoot', id=None) page.stopInstanceURL = h.url_for(controller='instances', action='stopInstance', id='') page.startInstanceURL = h.url_for(controller='instances', action='startInstance', id='') page.chooseImageURL = h.url_for(controller='modify', action='getImageInfo', id=None) if(creatingNew): # We are creating a new service. page.newService = True page.internalServiceId = '' else: # Look for the service with this id. service = Service.by_id(serviceID) # We are editing an existing service. page.newService = False page.internalServiceId = service._id if service: # Metadata values. page.form_values['serviceID'] = service.service_id page.form_values['servicePort'] = service.port page.form_values['serviceDescription'] = service.description page.form_values['serviceVersion'] = service.version page.form_values['serviceTags'] = ",".join(service.tags) page.form_values['numClientsSupported'] = service.num_users page.form_values['reqMinMem'] = service.min_memory page.form_values['reqIdealMem'] = service.ideal_memory # VM Image values. The ...Value fields are for storing data, while the others are for # showing it only. Since the vmDiskImageFile and vmStateImageFile fields are disabled, # (read-only) their value is not sent, and we have to store that value in hidden variables. if(service.vm_image.disk_image): page.form_values['vmStoredFolder'] = os.path.dirname(service.vm_image.disk_image) page.form_values['vmDiskImageFile'] = service.vm_image.disk_image page.form_values['vmDiskImageFileValue'] = service.vm_image.disk_image if(service.vm_image.state_image): page.form_values['vmStateImageFile'] = service.vm_image.state_image page.form_values['vmStateImageFileValue'] = service.vm_image.state_image return page
def GET_saveInstanceToRoot(self, id): try: if id is None: msg = "No VM id was provided, VM can't be saved." return ajaxutils.show_and_return_error_dict(msg) # Save the VM state. print "Saving machine state for SVM with id " + str(id) svm = ServiceVM.find_and_remove(id) svm.stop(foce_save_state=True) print "Service VM stopped, and machine state saved." print 'Editing? ' + str(request.params.get('editing')) if request.params.get('editing') == 'false': # Use the service id as the folder for this new saved SVM. vm_image_folder = os.path.join(g.cloudlet.svmCache, svm.service_id) else: # Get the folder of the permanent VM image, to overwrite the previous one. service = Service.by_id(svm.service_id) vm_image_folder = os.path.dirname(service.vm_image.disk_image) # Permanently store the VM. print 'Moving Service VM Image to cache, from folder {} to folder {}.'.format(os.path.dirname(svm.vm_image.disk_image), vm_image_folder) svm.vm_image.move(vm_image_folder) # Ensure we own the new image files. fileutils.chown_to_current_user(svm.vm_image.disk_image) fileutils.chown_to_current_user(svm.vm_image.state_image) # Make the VM image read only. print 'Making VM Image read-only.' try: svm.vm_image.protect() print 'VM Image updated.' except: print 'Error making VM read-only. Check permissions on file.' # Everything went well, return image info. return svm.vm_image except Exception as e: # If there was a problem opening the SVM, return that there was an error. msg = 'Error saving Service VM: ' + str(e) return ajaxutils.show_and_return_error_dict(msg)
def GET_saveInstanceToRoot(self): try: id = str(request.params.get('id')) if id is None: msg = "No VM id was provided, VM can't be saved." return ajaxutils.show_and_return_error_dict(msg) # Save the VM state. print "Saving machine state for SVM with id " + str(id) svm = ServiceVM.by_id(id) svm.stop(foce_save_state=True, cleanup_files=False) print "Service VM stopped, and machine state saved." print 'Editing? ' + str(request.params.get('editing')) if request.params.get('editing') == 'false': # Use the service id as the folder for this new saved SVM. vm_image_folder = os.path.join(app_globals.cloudlet.svmCache, svm.service_id) else: # Get the folder of the permanent VM image, to overwrite the previous one. service = Service.by_id(svm.service_id) vm_image_folder = os.path.dirname(service.vm_image.disk_image) # Permanently store the VM. print 'Moving Service VM Image to cache, from folder {} to folder {}.'.format( os.path.dirname(svm.vm_image.disk_image), vm_image_folder) svm.vm_image.move(vm_image_folder) # Make the VM image read only. print 'Making VM Image read-only.' try: svm.vm_image.protect() print 'VM Image updated.' except: print 'Error making VM read-only. Check permissions on file.' # Everything went well, return image info. return svm.vm_image except Exception as e: # If there was a problem opening the SVM, return that there was an error. msg = 'Error saving Service VM: ' + str(e) return ajaxutils.show_and_return_error_dict(msg)
def GET_list(self): # Mark the active tab. c.apps_active = 'active' # Create the actual page. page = AppsPage() # Get a list of existing stored apps. page.apps = App.find() # Prepare service list. page.stored_services = {} services = Service.find() for service in services: page.stored_services[service.service_id] = service.service_id page.os_options = {'Android': 'Android'} # Pass the grid and render the page. return page.render()
def GET_start(self): # Start the Service VM on a random port. print '\n*************************************************************************************************' # Get variables. sid = request.params.get('serviceId', None) if not sid: # If we didnt get a valid one, just return an error message. abort(400, 'Must provide service id') timelog.TimeLog.stamp("Request received: start VM with service id " + sid) service = Service.by_id(sid) if not service: abort(400, 'Service vm for %s not found' % sid) # Check the flags that indicates whether we could join an existing instance. join = request.params.get('join', False) if not isinstance(join, bool): join = join.upper() in ['T', 'TRUE', 'Y', 'YES'] # Get a ServiceVM instance svm = None try: svm = service.get_vm_instance(join=join) # Update the amount of users on this SVM, and save that change. svm.num_current_users += 1 svm.save() # Send the response. timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) timelog.TimeLog.writeToFile() return svm except Exception as e: if svm: # If there was a problem starting the instance, stop it. svm.stop() print 'Error starting Service VM Instance: ' + str(e) abort(500, '%s' % str(e))
def GET_startInstance(self, id): # Look for the service with this id service = Service.by_id(id) if service: clone_full_image = False if request.params.get('clone_full_image'): clone_full_image = True # Get a ServiceVM instance svm = service.get_vm_instance(clone_full_image=clone_full_image) try: # Start the instance, if it works, save it and return ok svm.start() svm.save() return svm except Exception as e: # If there was a problem starting the instance, return that there was an error. msg = 'Error starting Service VM Instance: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) else: msg = 'Service {} not found.'.format(id) return ajaxutils.show_and_return_error_dict(msg)
def GET_startInstance(self, id): # Look for the service with this id service = Service.by_id(id) if service: clone_full_image = False if request.params.get('clone_full_image'): clone_full_image = True svm = None try: # Get a ServiceVM instance svm = service.get_vm_instance( clone_full_image=clone_full_image) return svm except Exception as e: if svm: # If there was a problem starting the instance, return that there was an error. svm.stop() msg = 'Error starting Service VM Instance: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) else: msg = 'Service {} not found.'.format(id) return ajaxutils.show_and_return_error_dict(msg)
def receive_migrated_svm_disk_file(svm_id, disk_image_object, svm_instances_folder): # Get the id and load the metadata for this SVM. migrated_svm = ServiceVM.by_id(svm_id, only_find_ready_ones=False) if not migrated_svm: raise SVMNotFoundException("No SVM found with the given id: {}".format(svm_id)) # Receive the transferred file and update its path. print 'Storing disk image file of SVM in migration.' destination_folder = os.path.join(svm_instances_folder, svm_id) migrated_svm.vm_image.store(destination_folder, disk_image_object) print 'Migrated SVM disk image file stored.' # Check that we have the backing file, and rebase the new file so it will point to the correct backing file. service = Service.by_id(migrated_svm.service_id) if service: print 'Rebasing backing file for service %s.' % migrated_svm.service_id backing_disk_file = service.vm_image.disk_image migrated_svm.vm_image.rebase_disk_image(backing_disk_file) else: raise MigrationException("No backing file found for service {}".format(migrated_svm.service_id)) # Save to internal DB. migrated_svm.save()
def GET_start(self): # Start the Service VM on a random port. print '\n*************************************************************************************************' # Get variables. sid = request.params.get('serviceId', None) if not sid: # If we didnt get a valid one, just return an error message. abort(400, '400 Bad Request - must provide service id') else: timelog.TimeLog.stamp("Request received: start VM with service id " + sid) # Check the flags that indicates whether we could join an existing instance. join = request.params.get('join', False) if not isinstance(join, bool): join = join.upper() in ['T', 'TRUE', 'Y', 'YES'] service = Service.by_id(sid) if service: # Get a ServiceVM instance svm = service.get_vm_instance(join=join) try: # Start the instance, if it works, save it and return the svm if not svm.running: svm.start() svm.save() # Send the response. timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) timelog.TimeLog.writeToFile() return svm except Exception as e: # If there was a problem starting the instance, return that there was an error. print 'Error starting Service VM Instance: ' + str(e) abort(500, '500 Internal Server Error - %s' % str(e)) else: abort(400, '404 Not Found - service vm for %s not found' % sid)
def POST_index(self): # Mark the active tab. c.services_active = 'active' # Get the internal id. internalServiceId = request.params.get("internalServiceId") print 'Internal service id ' + internalServiceId # Check if there is another service already with this service id. service_id = request.params.get("serviceID") previous_service = Service.by_id(service_id) if previous_service and str( previous_service['_id']) != internalServiceId: # TODO: somehow notify the error. print "A service can't have the same service id as an existing service." return h.redirect_to(controller='services') # Look for a service with this id. service = Service.by_internal_id(internalServiceId) if not internalServiceId or not service: # If we didn't get an internal service id or we couldn't find such service, we are creating a new one. print 'Creating new service' service = Service() else: print 'Service found, with internal id ' + str(service._id) # Service service.service_id = request.params.get("serviceID") service.version = request.params.get("serviceVersion") service.description = request.params.get("serviceDescription") service.tags = request.params.get("serviceTags") if service.tags: service.tags = service.tags.split(',') else: service.tags = [] service.port = request.params.get("servicePort") service.num_users = request.params.get("numClientsSupported", "") try: service.num_users = int(service.num_users) except Exception as e: service.num_users = 0 # Requirements service.min_memory = request.params.get("reqMinMem") service.ideal_memory = request.params.get("reqIdealMem") # VM Image info. service.vm_image = VMImage() service.vm_image.disk_image = request.params.get( "vmDiskImageFileValue") service.vm_image.state_image = request.params.get( "vmStateImageFileValue") # Create or update the information. service.save() # Render the page. return h.redirect_to(controller='services')
def loadDataIntoPage(self, page, serviceID): # Setup the page to render. page.form_values = {} page.form_errors = {} page.os_options = {'Linux': 'Linux', 'Windows': 'Windows'} # URL to create a new Service VM. page.createSVMURL = h.url_for(controller="modify", action='createSVM') # Check if we are editing or creating a new service. creatingNew = serviceID is None page.saveInstanceURL = h.url_for(controller='modify', action='saveInstanceToRoot') page.stopInstanceURL = h.url_for(controller='instances', action='stopInstance', id='') page.startInstanceURL = h.url_for(controller='instances', action='startInstance', id='') page.chooseImageURL = h.url_for(controller='modify', action='getImageInfo', id=None) if (creatingNew): # We are creating a new service. page.newService = True page.internalServiceId = '' else: # Look for the service with this id. service = Service.by_id(serviceID) # We are editing an existing service. page.newService = False page.internalServiceId = service._id if service: # Metadata values. page.form_values['serviceID'] = service.service_id page.form_values['servicePort'] = service.port page.form_values['serviceDescription'] = service.description page.form_values['serviceVersion'] = service.version page.form_values['serviceTags'] = ",".join(service.tags) page.form_values['numClientsSupported'] = service.num_users page.form_values['reqMinMem'] = service.min_memory page.form_values['reqIdealMem'] = service.ideal_memory # VM Image values. The ...Value fields are for storing data, while the others are for # showing it only. Since the vmDiskImageFile and vmStateImageFile fields are disabled, # (read-only) their value is not sent, and we have to store that value in hidden variables. if (service.vm_image.disk_image): page.form_values['vmStoredFolder'] = os.path.dirname( service.vm_image.disk_image) page.form_values[ 'vmDiskImageFile'] = service.vm_image.disk_image page.form_values[ 'vmDiskImageFileValue'] = service.vm_image.disk_image if (service.vm_image.state_image): page.form_values[ 'vmStateImageFile'] = service.vm_image.state_image page.form_values[ 'vmStateImageFileValue'] = service.vm_image.state_image return page
def POST_index(self): # Mark the active tab. c.services_active = 'active' # Get the internal id. internalServiceId = request.params.get("internalServiceId") print 'Internal service id ' + internalServiceId # Check if there is another service already with this service id. service_id = request.params.get("serviceID") previous_service = Service.by_id(service_id) if previous_service and str(previous_service['_id']) != internalServiceId: # TODO: somehow notify the error. print "A service can't have the same service id as an existing service." return h.redirect_to(controller='services') # Look for a service with this id. service = Service.by_internal_id(internalServiceId) if not internalServiceId or not service: # If we didn't get an internal service id or we couldn't find such service, we are creating a new one. print 'Creating new service' service = Service() else: print 'Service found, with internal id ' + str(service._id) # Service service.service_id = request.params.get("serviceID") service.version = request.params.get("serviceVersion") service.description = request.params.get("serviceDescription") service.tags = request.params.get("serviceTags") if service.tags: service.tags = service.tags.split(',') else: service.tags = [] service.port = request.params.get("servicePort") service.num_users = request.params.get("numClientsSupported", "") try: service.num_users = int(service.num_users) except Exception as e: service.num_users = 0 # Requirements service.min_memory = request.params.get("reqMinMem") service.ideal_memory = request.params.get("reqIdealMem") # VM Image info. service.vm_image = VMImage() service.vm_image.disk_image = request.params.get("vmDiskImageFileValue") service.vm_image.state_image = request.params.get("vmStateImageFileValue") # Create or update the information. service.save() # Render the page. return h.redirect_to(controller='services')