def POST_edit(self): try: # Create a new app object if we are adding, or get the current if we are updating. if request.params.get('appId') == '': print 'Creating new app' app = App() else: # Get the existing app from the DB, if it can be found. print 'Updating app with id ' + request.params.get('appId') app = App.by_id(ObjectId(request.params.get('appId'))) if not app: # If there was a problem getting the app to update, return a json-formated error. msg = 'Error getting app to modify: app was not found' return ajaxutils.show_and_return_error_dict(msg) # Set the values for all the apps' fields. app.name = request.params.get('name') app.service_id = request.params.get('serviceId') app.description = request.params.get('description') app.app_version = request.params.get('version') app.package_name = request.params.get('package') app.tags = request.params.get('tags') if app.tags: app.tags = app.tags.split(',') else: app.tags = [] app.min_android_version = request.params.get('minOsVersion') # Check if we are uploading a new apk. if(request.params.get('appNewFile') != None): print 'Updating file: ' + str(request.params.get('appNewFile')) app.apk_file = os.path.join(os.path.abspath(app_globals.cloudlet.appFolder), request.params.get('appNewFile').filename) # Store the file in the folder first. apk_file_dest = open(app.apk_file, 'w') shutil.copyfileobj(request.params.get('appNewFile').file, apk_file_dest) # TODO add these to the DB. md5 will have to be calculated. app.md5sum = None # Save the new/updated app to the DB. app.save() if(request.params.get('appNewFile') != None): # Rename the app file to be unique and update its filename in the DB. new_apk_filename = os.path.join(os.path.dirname(app.apk_file), str(app._id) + '-' + os.path.basename(app.apk_file)) os.rename(app.apk_file, new_apk_filename) app.apk_file = new_apk_filename app.save() print 'App data stored.' except Exception as e: # If there was a problem creating the app, return a json-formatted error. msg = 'Error creating App: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. print 'Returning success' return ajaxutils.JSON_OK
def POST_discover(self): try: secret = request.params.get('secret', None) print secret # Disable any lingering ad-hoc connections. wifi_adhoc.disable_adhoc_mode() # Enable ad-hoc mode. wifi_adhoc.enable_adhoc_mode(SKA_SERVER_IP) # Wait for messages. cloudlet = get_cloudlet_instance() server = WiFiSKAServer( host=SKA_SERVER_IP, port=SKA_SERVER_PORT, secret=secret, files_path=cloudlet.cloudletCredentialsFolder, pairing_handler=PairingHandler(), fqdn=Cloudlet.get_fqdn()) server.wait_for_messages() except Exception, e: message = 'Error setting up connection or receiving data (' + type( e).__name__ + '): ' + str(e) print message return ajaxutils.show_and_return_error_dict(message)
def GET_wifiDisconnect(self): try: WifiManager.disconnect_from_network( interface=app_globals.cloudlet.wifi_adapter) return ajaxutils.JSON_OK except Exception as e: msg = 'Error disconnecting from Wi-Fi networks: {}'.format(str(e)) return ajaxutils.show_and_return_error_dict(msg)
def GET_svmList(self): try: # Get the list of running instances. svm_list = ServiceVM.find() return svm_list except Exception as e: # If there was a problem stopping the instance, return that there was an error. msg = 'Error getting list of instance changes: ' + str(e) return ajaxutils.show_and_return_error_dict(msg)
def GET_svmList(self): try: # Get the list of running instances. svm_list = ServiceVM.find_all(connect_to_vm=False) return svm_list except Exception as e: # If there was a problem stopping the instance, return that there was an error. msg = 'Error getting list of instance changes: ' + str(e) return ajaxutils.show_and_return_error_dict(msg)
def GET_openVNC(self, id): try: # Get the instance associated with this id. svm = ServiceVM.by_id(id) if not svm: # If we didn't get a valid id, just return an error message. msg = "Service VM id " + id + " was not found on the list of running instances." return ajaxutils.show_and_return_error_dict(msg) # Try to start the VNC window (this will only work if done on the Cloudlet). svm.open_vnc(wait=False) except Exception as e: # If there was a problem connecting through VNC, return that there was an error. msg = 'Error opening VNC window: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def GET_wifiConnect(self): ssid = request.params.get('target') try: WifiManager.connect_to_network(ssid) return ajaxutils.JSON_OK except Exception as e: msg = 'Error connecting to Wi-Fi network {}: {}'.format( ssid, str(e)) return ajaxutils.show_and_return_error_dict(msg)
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_stopInstance(self, id): try: # Stop an existing instance with the given ID. svm = ServiceVM.find_and_remove(id) svm.destroy() except Exception as e: # If there was a problem stopping the instance, return that there was an error. msg = 'Error stopping Service VM Instance: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def POST_get_data(self): # Get the data for the given app. print 'App data request received, data: ' + request.params.get('appId') app_id = ObjectId(request.params.get('appId')) app = App.by_id(app_id) if not app: # If there was a problem getting the app to update, return a json-formated error. msg = 'Error getting app data: app was not found' return ajaxutils.show_and_return_error_dict(msg) return app
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_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 POST_createSVM(self): # Get the manager. print 'Creating SVM...' svm = ServiceVM() svm.generate_random_id() # Parse the body of the request as JSON into a python object. fields = encoded_json_to_dict(request.body) # Create an SVM and open a VNC window to modify the VM. svm.service_id = fields['serviceId'] try: # Set up a new VM image. print 'newVmFolder: ', app_globals.cloudlet.newVmFolder print 'svm._id: ', svm._id temp_svm_folder = os.path.join(app_globals.cloudlet.newVmFolder, svm._id) print 'temp_svm_folder: ', temp_svm_folder new_disk_image = os.path.join(temp_svm_folder, svm.service_id) new_vm_image = VMImage() print 'calling VMImage#create with "%s" and "%s"' % ( fields['source'], new_disk_image) new_vm_image.create(fields['source'], new_disk_image) new_vm_image.unprotect() # Set the OS type. os_type = fields['type'] if os_type == 'Windows': svm.os = "win" else: svm.os = "lin" # Create the VM (this will also start it). print "Creating and starting VM for user access..." template_xml_file = os.path.abspath(app_globals.cloudlet.newVmXml) svm.vm_image = new_vm_image svm.service_port = fields['port'] svm.create(template_xml_file) svm.save() # Return info about the svm. return svm except Exception as e: # If there was a problem creating the SVM, return that there was an error. msg = 'Error creating Service VM: ' + str(e) import traceback, sys traceback.print_exc(file=sys.stdout) #if svm.vm_image: # svm.vm_image.cleanup(force=True) return ajaxutils.show_and_return_error_dict(msg)
def POST_getImageInfo(self): # Parse the body of the request as JSON into a python object. fields = encoded_json_to_dict(request.body) # Load VM Image information from the folder. image_folder = fields['folder'] vm_image = VMImage() try: vm_image.load_from_folder(image_folder) except Exception as e: msg = 'Error selecting existing VM image: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) return vm_image
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 POST_createSVM(self): # Get the manager. print 'Creating SVM...' svm = ServiceVM() svm.generate_random_id() # Parse the body of the request as JSON into a python object. fields = encoded_json_to_dict(request.body) # Create an SVM and open a VNC window to modify the VM. svm.service_id = fields['serviceId'] try: # Set up a new VM image. print 'newVmFolder: ', app_globals.cloudlet.newVmFolder print 'svm._id: ', svm._id temp_svm_folder = os.path.join(g.cloudlet.newVmFolder, svm._id) print 'temp_svm_folder: ', temp_svm_folder new_disk_image = os.path.join(temp_svm_folder, svm.service_id) new_vm_image = VMImage() print 'calling VMImage#create with "%s" and "%s"' % (fields['source'], new_disk_image) new_vm_image.create(fields['source'], new_disk_image) new_vm_image.unprotect() # Set the OS type. os_type = fields['type'] if os_type == 'Windows': svm.os = "win" else: svm.os = "lin" # Create the VM (this will also start it). print "Creating and starting VM for user access..." template_xml_file = os.path.abspath(g.cloudlet.newVmXml) svm.vm_image = new_vm_image svm.service_port = fields['port'] svm.create(template_xml_file) svm.save() # Return info about the svm. return svm except Exception as e: # If there was a problem creating the SVM, return that there was an error. msg = 'Error creating Service VM: ' + str(e) import traceback, sys traceback.print_exc(file=sys.stdout) #if svm.vm_image: # svm.vm_image.cleanup(force=True) return ajaxutils.show_and_return_error_dict(msg)
def POST_remove(self): print 'App removal request received' try: # Remove the app. appId = ObjectId(request.params.get('appId')) app = App.find_and_remove(appId) # Try to remove the app file. if (os.path.isfile(app.apk_file)): os.remove(app.apk_file) # Check if we succeeded. if app: print 'App removed.' else: msg = 'Error removing app: app was not found.' return ajaxutils.show_and_return_error_dict(msg) except Exception as e: msg = 'Error removing App: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def POST_remove(self): print 'App removal request received' try: # Remove the app. appId = ObjectId(request.params.get('appId')) app = App.find_and_remove(appId) # Try to remove the app file. if(os.path.isfile(app.apk_file)): os.remove(app.apk_file) # Check if we succeeded. if app: print 'App removed.' else: msg = 'Error removing app: app was not found.' return ajaxutils.show_and_return_error_dict(msg) except Exception as e: msg = 'Error removing App: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def GET_stopInstance(self, id): try: # Stop an existing instance with the given ID. svm = ServiceVM.by_id(id) if not svm: raise Exception( "No ready SVM with id {} was found.".format(id)) svm.stop() except Exception as e: # If there was a problem stopping the instance, return that there was an error. msg = 'Error stopping Service VM Instance: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. return ajaxutils.JSON_OK
def GET_migrateInstance(self, id): try: remote_host_info = request.params.get('target', None).split(':') remote_ip = remote_host_info[0] remote_host = remote_host_info[1] + ':' + remote_host_info[2] encrypted = True if remote_host_info[ 3] == 'encryption-enabled' else False migrator.migrate_svm(id, remote_host, remote_ip, encrypted) if WifiManager.is_connected_to_cloudlet_network( interface=app_globals.cloudlet.wifi_adapter): print 'Disconnecting from cloudlet Wi-Fi network.' WifiManager.disconnect_from_network( interface=app_globals.cloudlet.wifi_adapter) except Exception, e: msg = 'Error migrating: ' + str(e) return ajaxutils.show_and_return_error_dict(msg)
def GET_pair(self, id): device_type = 'mobile' connection = request.params.get('connection', None) if connection is None: connection = 'bt' curr_device = None try: # Create a device depending on the type. if connection == 'bt': port = request.params.get('port', None) name = request.params.get('name', None) curr_device = BluetoothSKADevice({ 'host': id, 'port': int(port), 'name': name }) else: curr_device = ADBSKADevice(id) # Now the pairing process will be followed, generating all required credentials. # The first step is to connect to the device. successful_connection = curr_device.connect() if not successful_connection: raise Exception( "Could not connect to device with id {}.".format(id)) # Get the device id. id_data = curr_device.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Pair the device, send the credentials, and clear their local files. deployment = Deployment.get_instance() device_keys = deployment.pair_device(device_internal_id, curr_device.get_name(), device_type) deployment.send_paired_credentials(curr_device, device_keys) deployment.clear_device_keys(device_keys) except Exception, e: return ajaxutils.show_and_return_error_dict(e.message)
# Send RADIUS certificate to the device. radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file, app_globals.cloudlet.radius_certs_folder, app_globals.cloudlet.radius_eap_conf_file) cert_file_name = radius.RADIUS_CERT_FILE_NAME curr_device.send_file(radius_server.cert_file_path, cert_file_name) # Send a command to create a Wi-Fi profile on the device. The message has to contain three key pairs: # ssid, the RADIUS certificate filename, and the password to be used in the profile. ssid = app_globals.cloudlet.ssid curr_device.send_data({'command': 'wifi-profile', 'ssid': ssid, 'server_cert_name': cert_file_name, 'password': device_keys.auth_password}) # Remove the device private key and password files, for security cleanup. device_keys.delete_key_files() except Exception, e: return ajaxutils.show_and_return_error_dict("Error pairing with device: " + str(e)) finally: if curr_device is not None: try: print 'Closing connection.' curr_device.disconnect() except Exception, e: return ajaxutils.show_and_return_error_dict("Error closing connection with device: " + str(e)) # Go to the pairing devices page to add it to the DB. Does not really return the ajax call in case of success. return h.redirect_to(controller='devices', action='authorize', did=device_internal_id, cid=curr_device.get_name(), auth_password=device_keys.auth_password, enc_password=device_keys.encryption_password)
# The first step is to connect to the device. successful_connection = curr_device.connect() if not successful_connection: raise Exception( "Could not connect to device with id {}.".format(id)) # Get the device id. id_data = curr_device.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Pair the device, send the credentials, and clear their local files. deployment = Deployment.get_instance() device_keys = deployment.pair_device(device_internal_id, curr_device.get_name(), device_type) deployment.send_paired_credentials(curr_device, device_keys) deployment.clear_device_keys(device_keys) except Exception, e: return ajaxutils.show_and_return_error_dict(e.message) finally: if curr_device is not None: try: print 'Closing connection.' curr_device.disconnect() except Exception, e: error = "Error closing connection with device: " + str(e) return ajaxutils.show_and_return_error_dict(error) return ajaxutils.JSON_OK
fqdn=Cloudlet.get_fqdn()) server.wait_for_messages() except Exception, e: message = 'Error setting up connection or receiving data (' + type( e).__name__ + '): ' + str(e) print message return ajaxutils.show_and_return_error_dict(message) finally: try: print 'Listener will shut down.' wifi_adhoc.disable_adhoc_mode() except Exception, e: error = 'Error stopping ad-hoc mode' + type( e).__name__ + ': ' + str(e) print error return ajaxutils.show_and_return_error_dict(e.message) return ajaxutils.JSON_OK ############################################################################################################ # Displays the discover page for cloudlet pairing. ############################################################################################################ def GET_discover(self): page = CloudletDiscoveryPage() # Generate ssid and random psk here # ssid should be "<cloudlet machine name>-<alphanumeric and 6 symbols long>" ssid_suffix_length = 6 ssid_suffix = generate_random_alphanumeric_string(ssid_suffix_length) machine_name = os.uname()[1] page.ssid = machine_name + "-" + ssid_suffix
def POST_edit(self): try: # Create a new app object if we are adding, or get the current if we are updating. if request.params.get('appId') == '': print 'Creating new app' app = App() else: # Get the existing app from the DB, if it can be found. print 'Updating app with id ' + request.params.get('appId') app = App.by_id(ObjectId(request.params.get('appId'))) if not app: # If there was a problem getting the app to update, return a json-formated error. msg = 'Error getting app to modify: app was not found' return ajaxutils.show_and_return_error_dict(msg) # Set the values for all the apps' fields. app.name = request.params.get('name') app.service_id = request.params.get('serviceId') app.description = request.params.get('description') app.app_version = request.params.get('version') app.package_name = request.params.get('package') app.tags = request.params.get('tags') if app.tags: app.tags = app.tags.split(',') else: app.tags = [] app.min_android_version = request.params.get('minOsVersion') # Check if we are uploading a new apk. if (request.params.get('appNewFile') != None): print 'Updating file: ' + str(request.params.get('appNewFile')) app.apk_file = os.path.join( os.path.abspath(app_globals.cloudlet.appFolder), request.params.get('appNewFile').filename) # Store the file in the folder first. apk_file_dest = open(app.apk_file, 'w') shutil.copyfileobj( request.params.get('appNewFile').file, apk_file_dest) # TODO add these to the DB. md5 will have to be calculated. app.md5sum = None # Save the new/updated app to the DB. app.save() if (request.params.get('appNewFile') != None): # Rename the app file to be unique and update its filename in the DB. new_apk_filename = os.path.join( os.path.dirname(app.apk_file), str(app._id) + '-' + os.path.basename(app.apk_file)) os.rename(app.apk_file, new_apk_filename) app.apk_file = new_apk_filename app.save() print 'App data stored.' except Exception as e: # If there was a problem creating the app, return a json-formatted error. msg = 'Error creating App: ' + str(e) return ajaxutils.show_and_return_error_dict(msg) # Everything went well. print 'Returning success' return ajaxutils.JSON_OK
def POST_pair(self): # Generate secret to display device_type = 'cloudlet' secret = request.params.get('secret', None) ssid = request.params.get('ssid', None) psk = request.params.get('psk', None) print ssid + '-' + psk + '-' + secret connection = request.params.get('connection', None) if connection is None: connection = 'wifi' remote_cloudlet = None try: if connection == 'wifi': # Disable any lingering ad-hoc connections. wifi_adhoc.disable_adhoc_mode() # Set up the ad-hoc network. wifi_adhoc.configure_wpa2_params(ssid, psk) wifi_adhoc.enable_adhoc_mode(SKA_CLIENT_IP) # Connect to the server (cloudlet) in the network. remote_cloudlet_name = "WiFiServer" remote_cloudlet = WiFiSKADevice( { 'host': SKA_SERVER_IP, 'port': int(SKA_SERVER_PORT), 'name': remote_cloudlet_name, 'secret': secret }, fqdn=Cloudlet.get_fqdn()) print 'Connecting to cloudlet server' successful_connection = remote_cloudlet.connect() if not successful_connection: raise Exception( "Could not connect to cloudlet with id {}.".format( ssid)) else: print 'Connected to cloudlet server' # TODO: test this. # Get the device id. id_data = remote_cloudlet.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Pair the device, send the credentials, and clear their local files. deployment = Deployment.get_instance() device_keys = deployment.pair_device(device_internal_id, remote_cloudlet.get_name(), device_type) deployment.send_paired_credentials(remote_cloudlet, device_keys) deployment.clear_device_keys(device_keys) except Exception, e: error_message = 'Error connecting or pairing: (' + type( e).__name__ + '): ' + str(e) print error_message return ajaxutils.show_and_return_error_dict(error_message)
def GET_migrateInstance(self, id): try: # Parse the body of the request as JSON into a python object. # First remove URL quotes added to string, and then remove trailing "=" (no idea why it is there). #parsedJsonString = urllib.unquote(request.body)[:-1] #fields = json.loads(parsedJsonString) # The host we are migrating to. remote_host = request.params.get('target', None) # Find the SVM. svm = ServiceVM.by_id(id) print 'VM found: ' + str(svm) # TODO: assuming remote cloudlet is listening on same port as local cloudlet. api_port = app_globals.cloudlet.api_port print 'Migrating to remote cloudlet: ' + remote_host remote_http_host = 'http://%s:%s' % (remote_host, api_port) # Transfer the metadata. print 'Starting metadata file transfer...' remote_url = '%s/instances/receiveMigratedSVMMetadata' % remote_http_host payload = json.dumps(svm) headers = {'content-type': 'application/json'} result = requests.post(remote_url, data=payload, headers=headers) if result.status_code != requests.codes.ok: raise Exception('Error transferring metadata.') print 'Metadata was transferred: ' + str(result) # We pause the VM before transferring its disk and memory state. print 'Pausing VM...' result = svm.pause() if result == -1: raise Exception("Cannot pause VM: %s", str(id)) print 'VM paused.' # Ensure we own the image file to migrate. fileutils.chown_to_current_user(svm.vm_image.disk_image) # Transfer the disk image file. print 'Starting disk image file transfer...' disk_image_full_path = os.path.abspath(svm.vm_image.disk_image) remote_url = '%s/instances/receiveMigratedSVMDiskFile' % remote_http_host payload = {'id': id} files = {'disk_image_file': open(disk_image_full_path, 'rb')} result = requests.post(remote_url, data=payload, files=files) if result.status_code != requests.codes.ok: raise Exception('Error transferring disk image file.') print 'Disk image file was transferred: ' + str(result) # Do the memory state migration. print 'Migrating through libvirt to ' + remote_host svm.migrate(remote_host, p2p=False) # TODO: if migration fails, ask remote to remove svm. # Notify remote cloudlet that migration finished. print 'Telling target cloudlet that migration has finished.' remote_url = '%s/instances/resumeMigratedSVM' % remote_http_host payload = {'id': id} result = requests.post(remote_url, data=payload) if result.status_code != requests.codes.ok: raise Exception('Error notifying migration end.') print 'Cloudlet notified: ' + str(result) # Remove the local VM. svm = ServiceVM.find_and_remove(id) svm.destroy() except Exception, e: msg = 'Error migrating: ' + str(e) import traceback traceback.print_exc() return ajaxutils.show_and_return_error_dict(msg)
def GET_pair(self, id): connection = request.params.get('connection', None) if connection is None: connection = 'bt' curr_device = None try: # Create a device depending on the type. if connection == 'bt': port = request.params.get('port', None) name = request.params.get('name', None) curr_device = BluetoothSKADevice({'host': id, 'port': int(port), 'name': name}) else: curr_device = ADBSKADevice(id) # Now the pairing process will be followed, generating all required credentials. # The first step is to connect to the device. successful_connection = curr_device.connect() if not successful_connection: return ajaxutils.show_and_return_error_dict("Could not connect to device with id {}.".format(id)) # Get the device id. id_data = curr_device.get_data({'device_id': 'none'}) device_internal_id = id_data['device_id'] print 'Device id: ' + device_internal_id # Check if the device was already paired, and if so, abort. previously_paired_device = PairedDevice.by_id(device_internal_id) if previously_paired_device: return ajaxutils.show_and_return_error_dict("Device with id {} is already paired.".format(device_internal_id)) # Prepare the server and device credential objects. server_keys = credentials.ServerCredentials.create_object(app_globals.cloudlet.credentials_type, app_globals.cloudlet.data_folder) device_keys = credentials.DeviceCredentials.create_object(app_globals.cloudlet.credentials_type, app_globals.cloudlet.data_folder, device_internal_id, server_keys.private_key_path) # Create the device's private key and the device's passwords. device_keys.generate_and_save_to_file() # Send the server's public key. curr_device.send_file(server_keys.public_key_path, 'server_public.key') # Send the device's private key to the device. curr_device.send_file(device_keys.private_key_path, 'device.key') # Send RADIUS certificate to the device. radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file, app_globals.cloudlet.radius_certs_folder, app_globals.cloudlet.radius_eap_conf_file) cert_file_name = radius.RADIUS_CERT_FILE_NAME curr_device.send_file(radius_server.cert_file_path, cert_file_name) # Send a command to create a Wi-Fi profile on the device. The message has to contain three key pairs: # ssid, the RADIUS certificate filename, and the password to be used in the profile. ssid = app_globals.cloudlet.ssid curr_device.send_data({'command': 'wifi-profile', 'ssid': ssid, 'server_cert_name': cert_file_name, 'password': device_keys.auth_password}) # Remove the device private key and password files, for security cleanup. device_keys.delete_key_files() except Exception, e: return ajaxutils.show_and_return_error_dict("Error pairing with device: " + str(e))