Esempio n. 1
0
    def form_valid(self, *args, **kwargs):
        form=kwargs['form']
        #Create the key object and save it
                
        #Was a file uploaded? If so, first check if access_key_id and secret_key are blank
        if self.request.FILES.get('access_key_file'):
            if form.cleaned_data['access_key_id'] != '' or form.cleaned_data['secret_key'] != '':
                form._errors[NON_FIELD_ERRORS] = 'Either upload a file or enter the key details manually'
                return self.form_invalid(self, *args, **kwargs)
            
            #Try and save the key file to a temp file
            temp_file_descriptor, temp_filename = tempfile.mkstemp()
            form_tools.handle_uploaded_file(self.request.FILES['access_key_file'], temp_filename)
            
            access_key_re = re.compile(r'AWSAccessKeyId\=(?P<access_key>.{20})\n*')
            secret_key_re = re.compile(r'AWSSecretKey\=(?P<secret_key>.{40})\n*')
            
            access_key=''
            secret_key=''
            
            temp_file = open(temp_filename, 'r')
            total_read_lines = 5 #How many lines to read before giving up
            line_count = 0
            for line in temp_file.readlines():
                if access_key_re.match(line):
                    access_key = access_key_re.match(line).group('access_key')
                elif secret_key_re.match(line):
                    secret_key = secret_key_re.match(line).group('secret_key')
                if line_count < total_read_lines:
                    line_count +=1
                    #Count the numeber of lines. Should be in the first 2 lines anyway, so this gives a bit of leeway
                else:
                    break
            temp_file.close()
            os.remove(temp_filename)

            if not (access_key and secret_key):
                form._errors[NON_FIELD_ERRORS] = 'The uploaded access key could not be read'
                return self.form_invalid(self, *args, **kwargs)
            
            key = AWSAccessKey(access_key_id = access_key, secret_key=secret_key)
        else:
            if form.cleaned_data['access_key_id'] == '' or  form.cleaned_data['secret_key'] == '':
                form._errors[NON_FIELD_ERRORS] = 'Either upload a file or enter the key details manually'
                return self.form_invalid(self, *args, **kwargs)
            else:
                key = AWSAccessKey()
                key.access_key_id = form.cleaned_data['access_key_id']
                key.secret_key = form.cleaned_data['secret_key']

        key.user = self.request.user
        key.name = form.cleaned_data['name']
        key.save()
        try:
            #Authenticate the keypair
            vpc_connection, ec2_connection = aws_tools.create_connections(key)
            #Run a test API call
            ec2_connection.get_all_regions()
            
        except Exception, e:
            #Since we are about to return form_invalid, add the errors directly to the form non field error list
            #kwargs['errors']=aws_tools.process_errors([e])
            key.delete()
            error_list = [x[1] for x in e.errors]
            form._errors[NON_FIELD_ERRORS] = ErrorList(error_list)
            return self.form_invalid(self, *args, **kwargs)
Esempio n. 2
0
    def form_valid(self, form, *args, **kwargs):

        # Check we are authorized to run on this pool
        compute_pool = form.cleaned_data["compute_pool"]
        request = self.request

        assert isinstance(compute_pool, CondorPool)
        assert compute_pool.user == request.user

        log.debug("Submitting task to compute pool %s (%s)" % (compute_pool.name, compute_pool.get_pool_type()))

        ########################################################################
        # Process the uploaded copasi file (and other files?)
        ########################################################################

        # Handle uploaded files...
        # Ensure the directory we're adding the file to exists
        if not os.path.exists(settings.STORAGE_DIR):
            os.mkdir(settings.STORAGE_DIR)

        # And the directory for the user
        # Takes the form userid.username
        user_dir = "%d.%s" % (request.user.id, request.user.username)
        user_dir_path = os.path.join(settings.STORAGE_DIR, user_dir)
        if not os.path.exists(user_dir_path):
            os.mkdir(user_dir_path)

        task = Task()
        task.name = form.cleaned_data["name"]
        task.condor_pool = form.cleaned_data["compute_pool"]
        task.user = request.user
        task.task_type = form.cleaned_data["task_type"]

        task.original_model = "original_model.cps"

        # Get a list of all fields that are only in the task form, and not in the base

        extra_fields = []
        base_form = base.BaseTaskForm
        for field_name in form.fields:
            if field_name not in base_form.base_fields:
                extra_fields.append((field_name, form.fields[field_name]))

        # We have not yet created the directory to hold the files
        directory_created = False
        task.save()  # Save the task so we can get a valid id

        # Save the custom task fields
        for field_name, field_object in extra_fields:

            # TODO: Is the file a zip file? Try unzipping it...
            if isinstance(field_object, forms.FileField) and isinstance(form.cleaned_data[field_name], UploadedFile):
                try:
                    # Create a directory to store the files for the task
                    # This will just be the id of the task
                    task_dir = str(task.id)
                    task_dir_path = os.path.join(user_dir_path, task_dir)

                    if os.path.exists(task_dir_path):
                        os.rename(task_dir_path, task_dir_path + ".old." + str(datetime.now()))

                    os.mkdir(task_dir_path)
                    directory_created = True

                    data_file = request.FILES[field_name]
                    filename = data_file.name
                    data_destination = os.path.join(task_dir_path, filename)
                    form_tools.handle_uploaded_file(data_file, data_destination)

                    # Next, attempt to extract the file
                    # If this fails, assume the file is an ASCII data file, not a zip file
                    try:
                        data_files_list = []
                        z = zipfile.ZipFile(data_destination)
                        # Record the name of each file in the zipfile

                        for name in z.namelist():
                            data_files_list.append(name)

                        z.extractall(task_dir_path)
                    except zipfile.BadZipfile:
                        data_files_list = []
                        # Assume instead that, if not a zip file, the file must be a data file, so leave it be.
                        # Write the name of the data file to data_files_list
                        data_files_list.append(filename)
                    task.set_custom_field("data_files", data_files_list)
                except Exception, e:
                    log.exception(e)
                    error_messages = ["An error occured while preparing the task", str(e)]
                    form._errors[NON_FIELD_ERRORS] = forms.forms.ErrorList(error_messages)
                    try:
                        shutil.rmtree(task.directory)
                    except:
                        pass
                    try:
                        task.delete()
                    except:
                        pass
                    kwargs["form"] = form
                    return self.form_invalid(self, *args, **kwargs)

            else:
                task.set_custom_field(field_name, form.cleaned_data[field_name])
Esempio n. 3
0
    def form_valid(self, *args, **kwargs):
        form=kwargs['form']
        #Create the key object and save it
                
        #Was a file uploaded? If so, first check if access_key_id and secret_key are blank
        if self.request.FILES.get('access_key_file'):
            if form.cleaned_data['access_key_id'] != '' or form.cleaned_data['secret_key'] != '':
                form._errors[NON_FIELD_ERRORS] = 'Either upload a file or enter the key details manually'
                return self.form_invalid(self, *args, **kwargs)
            
            #Try and save the key file to a temp file
            temp_file_descriptor, temp_filename = tempfile.mkstemp()
            form_tools.handle_uploaded_file(self.request.FILES['access_key_file'], temp_filename)
            
            access_key_re = re.compile(r'AWSAccessKeyId\=(?P<access_key>.{20})\n*')
            secret_key_re = re.compile(r'AWSSecretKey\=(?P<secret_key>.{40})\n*')
            
            access_key=''
            secret_key=''
            
            temp_file = open(temp_filename, 'r')
            total_read_lines = 5 #How many lines to read before giving up
            line_count = 0
            for line in temp_file.readlines():
                if access_key_re.match(line):
                    access_key = access_key_re.match(line).group('access_key')
                elif secret_key_re.match(line):
                    secret_key = secret_key_re.match(line).group('secret_key')
                if line_count < total_read_lines:
                    line_count +=1
                    #Count the numeber of lines. Should be in the first 2 lines anyway, so this gives a bit of leeway
                else:
                    break
            temp_file.close()
            os.remove(temp_filename)

            if not (access_key and secret_key):
                form._errors[NON_FIELD_ERRORS] = 'The uploaded access key could not be read'
                return self.form_invalid(self, *args, **kwargs)
            
            key = AWSAccessKey(access_key_id = access_key, secret_key=secret_key)
        else:
            if form.cleaned_data['access_key_id'] == '' or  form.cleaned_data['secret_key'] == '':
                form._errors[NON_FIELD_ERRORS] = 'Either upload a file or enter the key details manually'
                return self.form_invalid(self, *args, **kwargs)
            else:
                key = AWSAccessKey()
                key.access_key_id = form.cleaned_data['access_key_id']
                key.secret_key = form.cleaned_data['secret_key']

        key.user = self.request.user
        key.name = form.cleaned_data['name']
        key.save()
        try:
            #Authenticate the keypair
            vpc_connection, ec2_connection = aws_tools.create_connections(key)
            #Run a test API call
            ec2_connection.get_all_regions()
            
        except Exception as e:
            #Since we are about to return form_invalid, add the errors directly to the form non field error list
            #kwargs['errors']=aws_tools.process_errors([e])
            key.delete()
            error_list = [x[1] for x in e.errors]
            form._errors[NON_FIELD_ERRORS] = ErrorList(error_list)
            return self.form_invalid(self, *args, **kwargs)
        
        #And launch the VPC
        try:            
            
            vpc = vpc_tools.create_vpc(key, vpc_connection, ec2_connection)

        except Exception as e:
            log.exception(e)
            try:
                vpc.delete()
            except:
                pass
            try:
                key.delete()
            except:
                pass
            form._errors[NON_FIELD_ERRORS] = 'Error launching VPC for key'
            return self.form_invalid(self, *args, **kwargs)
        return super(KeysAddView, self).form_valid(*args, **kwargs)
Esempio n. 4
0
    def form_valid(self, form, *args, **kwargs):

        #Check we are authorized to run on this pool
        compute_pool = form.cleaned_data['compute_pool']
        request = self.request

        assert isinstance(compute_pool, CondorPool)
        assert compute_pool.user == request.user

        log.debug('Submitting task to compute pool %s (%s)' %
                  (compute_pool.name, compute_pool.get_pool_type()))

        ########################################################################
        #Process the uploaded copasi file (and other files?)
        ########################################################################

        #Handle uploaded files...
        #Ensure the directory we're adding the file to exists
        if not os.path.exists(settings.STORAGE_DIR):
            os.mkdir(settings.STORAGE_DIR)

        #And the directory for the user
        #Takes the form userid.username
        user_dir = '%d.%s' % (request.user.id, request.user.username)
        user_dir_path = os.path.join(settings.STORAGE_DIR, user_dir)
        if not os.path.exists(user_dir_path):
            os.mkdir(user_dir_path)

        task = Task()
        task.name = form.cleaned_data['name']
        task.condor_pool = form.cleaned_data['compute_pool']
        task.user = request.user
        task.task_type = form.cleaned_data['task_type']

        task.original_model = 'original_model.cps'

        #Get a list of all fields that are only in the task form, and not in the base

        extra_fields = []
        base_form = base.BaseTaskForm
        for field_name in form.fields:
            if field_name not in base_form.base_fields:
                extra_fields.append((field_name, form.fields[field_name]))

        #We have not yet created the directory to hold the files
        directory_created = False
        task.save()  # Save the task so we can get a valid id

        #Save the custom task fields
        for field_name, field_object in extra_fields:
            #TODO: Is the file a zip file? Try unzipping it...
            if isinstance(field_object, forms.FileField) and isinstance(
                    form.cleaned_data[field_name], UploadedFile):
                try:
                    #Create a directory to store the files for the task
                    #This will just be the id of the task
                    task_dir = str(task.id)
                    task_dir_path = os.path.join(user_dir_path, task_dir)

                    if os.path.exists(task_dir_path):
                        os.rename(
                            task_dir_path,
                            task_dir_path + '.old.' + str(datetime.now()))

                    os.mkdir(task_dir_path)
                    directory_created = True

                    data_file = request.FILES[field_name]
                    filename = data_file.name
                    data_destination = os.path.join(task_dir_path, filename)
                    form_tools.handle_uploaded_file(data_file,
                                                    data_destination)

                    #Next, attempt to extract the file
                    #If this fails, assume the file is an ASCII data file, not a zip file
                    try:
                        data_files_list = []
                        z = zipfile.ZipFile(data_destination)
                        #Record the name of each file in the zipfile

                        for name in z.namelist():
                            data_files_list.append(name)

                        z.extractall(task_dir_path)
                    except zipfile.BadZipfile:
                        data_files_list = []
                        #Assume instead that, if not a zip file, the file must be a data file, so leave it be.
                        #Write the name of the data file to data_files_list
                        data_files_list.append(filename)
                    task.set_custom_field('data_files', data_files_list)
                except Exception as e:
                    log.exception(e)
                    error_messages = [
                        'An error occured while preparing the task data files',
                        str(e),
                    ]
                    form._errors[NON_FIELD_ERRORS] = forms.forms.ErrorList(
                        error_messages)
                    try:
                        shutil.rmtree(task.directory)
                    except:
                        pass
                    try:
                        task.delete()
                    except:
                        pass
                    kwargs['form'] = form
                    return self.form_invalid(self, *args, **kwargs)

            else:
                task.set_custom_field(field_name,
                                      form.cleaned_data[field_name])

        task.save()

        try:
            if not directory_created:
                #Create a directory to store the files for the task
                #This will just be the id of the task
                task_dir = str(task.id)
                task_dir_path = os.path.join(user_dir_path, task_dir)

                if os.path.exists(task_dir_path):
                    os.rename(task_dir_path,
                              task_dir_path + '.old.' + str(datetime.now()))

                os.mkdir(task_dir_path)

            task.directory = task_dir_path
            task.save()
            #Next we need to create the directory to store the files for the task

            #working_dir = tempfile.mkdtemp(dir=settings.STORAGE_DIR)
            model_file = request.FILES['model_file']

            full_filename = os.path.join(task_dir_path, task.original_model)

            form_tools.handle_uploaded_file(model_file, full_filename)

            TaskClass = tools.get_task_class(form.cleaned_data['task_type'])

            task_instance = TaskClass(task)
        except Exception as e:
            log.exception(e)
            error_messages = [
                'An error occured while preparing the task model file',
                str(e),
            ]
            form._errors[NON_FIELD_ERRORS] = forms.forms.ErrorList(
                error_messages)
            try:
                shutil.rmtree(task.directory)
            except:
                pass
            try:
                task.delete()
            except:
                pass
            kwargs['form'] = form
            return self.form_invalid(self, *args, **kwargs)

        #Validate the task
        valid = task_instance.validate()
        if valid != True:
            #valid message contained in valid hopefully.
            error_messages = [
                'Model file is not valid for the current task type',
                str(valid),
            ]
            form._errors[NON_FIELD_ERRORS] = forms.forms.ErrorList(
                error_messages)
            shutil.rmtree(task.directory)
            task.delete()
            kwargs['form'] = form

            return self.form_invalid(self, *args, **kwargs)

        try:
            task_instance.initialize_subtasks()

            subtask = task_instance.prepare_subtask(1)

            condor_tools.submit_task(subtask)

            task.status = 'running'
            task.save()
        except Exception as e:
            log.exception(e)
            error_messages = [
                'An error occured while preparing the subtask',
                str(e),
            ]
            form._errors[NON_FIELD_ERRORS] = forms.forms.ErrorList(
                error_messages)
            try:
                shutil.rmtree(task.directory)
            except:
                pass
            try:
                task.delete()
            except:
                pass
            kwargs['form'] = form
            return self.form_invalid(self, *args, **kwargs)

        return HttpResponseRedirect(
            reverse_lazy('task_details', kwargs={'task_id': task.id}))