Exemple #1
0
    def transfer_needed(self, event_list, event, remote_endpoint, ui,
                        display_event, emailaddr, thread_list):
        """
        Start a transfer job for any files that arent local, but do exist remotely

        Globus user must already be logged in

        Parameters:
            event_list (EventList): the list to push information into
            event (threadding.event): the thread event to trigger a cancel
        """
        if self.active_transfers >= 2:
            return False
        # required files dont exist locally, do exist remotely
        # or if they do exist locally have a different local and remote size
        self.mutex.acquire()
        try:
            required_files = [
                x for x in DataFile.select().where(
                    (DataFile.remote_status == filestatus['EXISTS'])
                    & (DataFile.local_status != filestatus['IN_TRANSIT'])
                    & ((DataFile.local_status == filestatus['NOT_EXIST'])
                       | (DataFile.local_size != DataFile.remote_size)))
            ]
            if len(required_files) == 0:
                return False
            target_files = []
            target_size = 1e11  # 100 GB
            total_size = 0
            for file in required_files:
                if total_size + file.remote_size < target_size:
                    target_files.append({
                        'name': file.name,
                        'local_size': file.local_size,
                        'local_path': file.local_path,
                        'local_status': file.local_status,
                        'remote_size': file.remote_size,
                        'remote_path': file.remote_path,
                        'remote_status': file.remote_status
                    })
                    total_size += file.remote_size
                else:
                    break
        except Exception as e:
            print_debug(e)
            return False
        finally:
            if self.mutex.locked():
                self.mutex.release()

        logging.info('Transfering required files')
        print 'total transfer size {size} gigabytes for {nfiles} files'.format(
            size=(total_size / 1e9), nfiles=len(target_files))
        transfer_config = {
            'file_list': target_files,
            'source_endpoint': self.remote_endpoint,
            'destination_endpoint': self.local_endpoint,
            'source_path': self.remote_path,
            'destination_path': self.local_path,
            'source_email': emailaddr,
            'display_event': display_event,
            'ui': ui,
        }
        transfer = Transfer(config=transfer_config, event_list=event_list)
        print 'starting transfer for:'
        transfer_names = [x['name'] for x in transfer.file_list]
        for file in transfer.file_list:
            print '   ' + file['name']
            logging.info(file['name'])
        self.mutex.acquire()
        try:
            DataFile.update(local_status=filestatus['IN_TRANSIT']).where(
                DataFile.name << transfer_names).execute()
            print 'following files are in transit'
            for df in DataFile.select():
                if df.local_status == filestatus['IN_TRANSIT']:
                    print '   ' + df.name
        except Exception as e:
            print_debug(e)
            return False
        finally:
            if self.mutex.locked():
                self.mutex.release()

        args = (transfer, event, event_list)
        thread = threading.Thread(target=self._handle_transfer,
                                  name='filemanager_transfer',
                                  args=args)
        thread_list.append(thread)
        thread.start()
        return True
    def transfer_needed(self, event_list, event):
        """
        Start a transfer job for any files that arent local, but do exist remotely

        Globus user must already be logged in
        """

        # required files dont exist locally, do exist remotely
        # or if they do exist locally have a different local and remote size
        target_files = list()
        self._mutex.acquire()
        try:
            q = (DataFile.select(DataFile.case).where(
                DataFile.local_status == FileStatus.NOT_PRESENT.value))
            caselist = [x.case for x in q.execute()]
            if not caselist or len(caselist) == 0:
                return
            cases = list()
            for case in caselist:
                if case not in cases:
                    cases.append(case)

            for case in cases:
                q = (DataFile.select().where((DataFile.case == case) & (
                    DataFile.local_status == FileStatus.NOT_PRESENT.value)))
                required_files = [x for x in q.execute()]
                for file in required_files:
                    if file.transfer_type == 'local':
                        required_files.remove(file)
                if not required_files:
                    msg = 'ERROR: all missing files are marked as local'
                    print_line(msg, self._event_list)
                    return
                # mark files as in-transit so we dont double-copy
                q = (DataFile.update({
                    DataFile.local_status:
                    FileStatus.IN_TRANSIT
                }).where(DataFile.name << [x.name for x in required_files]))
                q.execute()

                for file in required_files:
                    target_files.append({
                        'local_path': file.local_path,
                        'remote_path': file.remote_path,
                    })

                if required_files[0].transfer_type == 'globus':
                    msg = 'Starting globus file transfer of {} files'.format(
                        len(required_files))
                    print_line(msg, self._event_list)
                    msg = 'See https://www.globus.org/app/activity for transfer details'
                    print_line(msg, self._event_list)

                    client = get_client()
                    remote_uuid = required_files[0].remote_uuid
                    local_uuid = self._config['global']['local_globus_uuid']
                    thread_name = '{}_globus_transfer'.format(
                        required_files[0].case)
                    _args = (client, remote_uuid, local_uuid, target_files,
                             self.kill_event)
                    thread = Thread(target=globus_transfer,
                                    name=thread_name,
                                    args=_args)
                    self.thread_list.append(thread)
                    thread.start()
                elif required_files[0].transfer_type == 'sftp':
                    msg = 'Starting sftp file transfer of {} files'.format(
                        len(required_files))
                    print_line(msg, self._event_list)

                    client = get_ssh_client(required_files[0].remote_hostname)
                    thread_name = '{}_sftp_transfer'.format(
                        required_files[0].case)
                    _args = (target_files, client, self.kill_event)
                    thread = Thread(target=self._ssh_transfer,
                                    name=thread_name,
                                    args=_args)
                    self.thread_list.append(thread)
                    thread.start()
        except Exception as e:
            print_debug(e)
            return False
        finally:
            if self._mutex.locked():
                self._mutex.release()
Exemple #3
0
    def update_remote_status(self, client):
        """
        Check remote location for existance of the files on our list
        If they exist, update their status in the DB

        Parameters:
            client (globus_sdk.client): the globus client to use for remote query
        """
        result = client.endpoint_autoactivate(self.remote_endpoint,
                                              if_expires_in=2880)
        if result['code'] == "AutoActivationFailed":
            return False
        if self.sta:
            for _type in self.types:
                if _type == 'rest':
                    if not self.updated_rest:
                        self.mutex.acquire()
                        name, path, size = self.update_remote_rest_sta_path(
                            client)
                        DataFile.update(
                            remote_status=filestatus['EXISTS'],
                            remote_size=size,
                            remote_path=path,
                            name=name).where(
                                DataFile.datatype == 'rest').execute()
                        if self.mutex.locked():
                            self.mutex.release()
                        self.updated_rest = True
                    continue
                elif _type in [
                        'streams.ocean', 'streams.cice', 'mpas-o_in',
                        'mpas-cice_in'
                ]:
                    remote_path = os.path.join(self.remote_path, 'run')
                elif _type == 'meridionalHeatTransport':
                    remote_path = os.path.join(self.remote_path, 'archive',
                                               'ocn', 'hist')
                else:
                    remote_path = os.path.join(self.remote_path, 'archive',
                                               _type, 'hist')
                print 'Querying globus for {}'.format(_type)
                res = self._get_ls(client=client, path=remote_path)

                self.mutex.acquire()
                try:
                    names = [
                        x.name for x in DataFile.select().where(
                            DataFile.datatype == _type)
                    ]
                    to_update_name = [
                        x['name'] for x in res if x['name'] in names
                    ]
                    to_update_size = [
                        x['size'] for x in res if x['name'] in names
                    ]
                    q = DataFile.update(
                        remote_status=filestatus['EXISTS'],
                        remote_size=to_update_size[to_update_name.index(
                            DataFile.name)]).where(
                                (DataFile.name << to_update_name)
                                & (DataFile.datatype == _type))
                    n = q.execute()
                except Exception as e:
                    print_debug(e)
                    print "Do you have the correct start and end dates?"
                finally:
                    if self.mutex.locked():
                        self.mutex.release()
        else:

            remote_path = self.remote_path
            res = self._get_ls(client=client, path=remote_path)
            self.mutex.acquire()
            try:
                for _type in self.types:
                    names = [
                        x.name for x in DataFile.select().where(
                            DataFile.datatype == _type)
                    ]
                    to_update_name = [
                        x['name'] for x in res if x['name'] in names
                    ]
                    to_update_size = [
                        x['size'] for x in res if x['name'] in names
                    ]

                    q = DataFile.update(
                        remote_status=filestatus['EXISTS'],
                        remote_size=to_update_size[to_update_name.index(
                            DataFile.name)]).where(
                                (DataFile.name << to_update_name)
                                & (DataFile.datatype == _type))
                    n = q.execute()
                    print 'updated {} records'.format(n)
            except Exception as e:
                print_debug(e)
            finally:
                if self.mutex.locked():
                    self.mutex.release()