Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
0
 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
Example #7
0
    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
Example #8
0
    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
Example #9
0
 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
Example #10
0
    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
Example #11
0
    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()
Example #12
0
 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
Example #13
0
    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
Example #14
0
    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)
Example #15
0
    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)
Example #16
0
    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()
Example #17
0
    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()
Example #18
0
    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))
Example #19
0
    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)
Example #20
0
    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
Example #21
0
    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)
Example #22
0
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()
Example #23
0
    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)
Example #24
0
    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')
Example #25
0
    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
Example #26
0
    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')