Ejemplo n.º 1
0
    def respondToThankyouFile(self, filename):
        """
        deal with a thank you file: delete the receipt file and the
        thank you file itself

        (input filename is the basename)
        """
        thankyou_path = self.getPathInIncoming(filename)
        try:
            thankyou_file = ThankyouFile.ThankyouFile(thankyou_path)
            (rcpt_file_name,) = thankyou_file.read()
        except ThankyouFile.Invalid:
            if futils.getFileAge(thankyou_path) < self.max_age_for_bad_ctl_file:
                return
            else:
                self.warn("Unparseable thank-you file %s" % thankyou_path)
        else:
            rcpt_file_path = self.getPathInIncoming(rcpt_file_name)
            futils.deleteFile(rcpt_file_path)
            self.debug("deleted receipt file %s" % rcpt_file_path)
            
        futils.deleteFile(thankyou_path)
        self.debug("deleted thankyou file %s" % thankyou_path)
Ejemplo n.º 2
0
    def deleteFilesWhileVeryLowDisk(self, dconfig, deletions):
        """
        Keep deleting files from a data_stream while disk state is 
        very low.  Return a True/False value for whether a
        better (i.e. not VLOW) disk state was reached.

        dconfig is the DatasetConfig object
        'deletions' argument is an array provided by the caller;
          it will be appended to with pathnames deleted, so that
          the caller can log these
        """

        for tu_path in self.getTUsForDeletion(dconfig):

            # test disk space before deleting
            if self.getDiskState() != DiskState.VLOW:
                return True

            deletions.append(tu_path)
            if os.path.isdir(tu_path):
                # recursive deletion - may take a while, so 
                # move it inside a temporary dot-dir first (and then
                # delete from the level of the dot-dir itself) to
                # reduce chance of races with TransferUnitController 
                # trying to transfer it
                parent_dir = os.path.dirname(tu_path)
                del_dir = tempfile.mkdtemp(dir = parent_dir,
                                          prefix = ".del_tmp_")
                os.rename(tu_path, del_dir)
                status = futils.deleteDir(del_dir)
            else:
                status = futils.deleteFile(tu_path)
            if not status:
                self.warn("could not delete %s: %s" % \
                              (tu_path, status))

        # repeat the test one final time (after last deletion)
        # to determine return value
        return (self.getDiskState() != DiskState.VLOW)
Ejemplo n.º 3
0
    def respondToControlFile(self, filename):
        """
        Respond to a control file, generating receipt file with appropriate
        response, and delivering the data file to the data_stream directory if
        appropriate.

        Argument is the basename of the control file.

        Returns the data file name if it was all okay, otherwise None
        """
        data_file_delivered = False
        ctl_path = self.getPathInIncoming(filename)
        try:                        
            ctl_file = ControlFile.ControlFile(ctl_path)
            filename, correct_size, correct_cksum, rcpt_file_name \
                      = ctl_file.read()
        except ControlFile.Invalid:
            # an invalid control file - either it is
            # very recent or it is stale

            if futils.getFileAge(ctl_path) < self.max_age_for_bad_ctl_file:
                # invalid but recent control file
                # just ignore it, may still be coming in.                
                return
            else:
                # We can't really respond because the control file specifies the
                # name of the receipt file to use, and we couldn't parse the control
                # file.  Just log it.  The sender will time out and then retry.
                self.warn("Unparseable control file %s" % filename)
                futils.deleteFile(ctl_path)
                return
        else:
            # good control file
            self.info("control file %s says %s size %s cksum %s" %
                      (ctl_path, filename, correct_size, correct_cksum))
            file_path = self.getPathInIncoming(filename)
            rcpt_data = self.checkFile(file_path, correct_size,
                                       correct_cksum)        

        if rcpt_data[0] == ReceiptFile.SUCCESS:
            # we liked it - deliver the datafile to the data_stream dir
            try:
                os.rename(file_path,
                          self.getPathInDataDir(filename))
                data_file_delivered = True
                self.info("File %s accepted (size %d, cksum %s)" %
                          (filename, correct_size, correct_cksum))
            except OSError:
                self.error("I/O error testing file %s" % filename)

        else:
            # we didn't like the data file so delete it
            futils.deleteFile(file_path)
            self.warn("File %s rejected" % filename)

        # delete control file before making receipt file - reason is that if we are heavily loaded,
        # and the checksum is bad, it is just possible (though unlikely) that the remote end
        # might have already started sending the control file for the next attempt before we
        # get round to deleting what we think is the "old" one

        futils.deleteFile(ctl_path)
        self.createReceiptFile(rcpt_file_name, filename, rcpt_data)

        self.debug("deleted control file %s" % ctl_path)

        if data_file_delivered:
            return filename