Exemple #1
0
def extractTar(tmpdir, filepath):
    """
   Extracts the indicated tar file to the indicated tmpdir.
   @param tmpdir: Temp directory to extract to.
   @param filepath: Path to tarfile to extract.
   @raise ValueError: If a path cannot be encoded properly.
   """
    # pylint: disable=E1101
    tmpdir = encodePath(tmpdir)
    filepath = encodePath(filepath)
    tar = tarfile.open(filepath)
    try:
        tar.format = tarfile.GNU_FORMAT
    except AttributeError:
        tar.posix = False
    for tarinfo in tar:
        tar.extract(tarinfo, tmpdir)
Exemple #2
0
 def _setLogfile(self, value):
     """
   Property target used to set the logfile parameter.
   @raise ValueError: If the value cannot be encoded properly.
   """
     if value is not None:
         if len(value) < 1:
             raise ValueError(
                 "The logfile parameter must be a non-empty string.")
     self._logfile = encodePath(value)
Exemple #3
0
def buildPath(components):
    """
   Builds a complete path from a list of components.
   For instance, constructs C{"/a/b/c"} from C{["/a", "b", "c",]}.
   @param components: List of components.
   @returns: String path constructed from components.
   @raise ValueError: If a path cannot be encoded properly.
   """
    path = components[0]
    for component in components[1:]:
        path = os.path.join(path, component)
    return encodePath(path)
Exemple #4
0
def validateDevice(device, unittest=False):
    """
   Validates a configured device.
   The device must be an absolute path, must exist, and must be writable.
   The unittest flag turns off validation of the device on disk.
   @param device: Filesystem device path.
   @param unittest: Indicates whether we're unit testing.
   @return: Device as a string, for instance C{"/dev/cdrw"}
   @raise ValueError: If the device value is invalid.
   @raise ValueError: If some path cannot be encoded properly.
   """
    if device is None:
        raise ValueError("Device must be filled in.")
    device = encodePath(device)
    if not os.path.isabs(device):
        raise ValueError("Backup device must be an absolute path.")
    if not unittest and not os.path.exists(device):
        raise ValueError("Backup device must exist on disk.")
    if not unittest and not os.access(device, os.W_OK):
        raise ValueError("Backup device is not writable by the current user.")
    return device
Exemple #5
0
    def writeImage(self, imagePath):
        """
      Writes this image to disk using the image path.

      @param imagePath: Path to write image out as
      @type imagePath: String representing a path on disk

      @raise IOError: If there is an error writing the image to disk.
      @raise ValueError: If there are no filesystem entries in the image
      @raise ValueError: If a path cannot be encoded properly.
      """
        imagePath = encodePath(imagePath)
        if len(self.entries.keys()) == 0:
            raise ValueError("Image does not contain any entries.")
        args = self._buildWriteArgs(self.entries, imagePath)
        command = resolveCommand(MKISOFS_COMMAND)
        (result, output) = executeCommand(command, args, returnOutput=False)
        if result != 0:
            raise IOError(
                "Error (%d) executing mkisofs command to build image." %
                result)
Exemple #6
0
def changeFileAge(filename, subtract=None):
    """
   Changes a file age using the C{os.utime} function.

   @note: Some platforms don't seem to be able to set an age precisely.  As a
   result, whereas we might have intended to set an age of 86400 seconds, we
   actually get an age of 86399.375 seconds.  When util.calculateFileAge()
   looks at that the file, it calculates an age of 0.999992766204 days, which
   then gets truncated down to zero whole days.  The tests get very confused.
   To work around this, I always subtract off one additional second as a fudge
   factor.  That way, the file age will be I{at least} as old as requested
   later on.

   @param filename: File to operate on.
   @param subtract: Number of seconds to subtract from the current time.
   @raise ValueError: If a path cannot be encoded properly.
   """
    filename = encodePath(filename)
    newTime = time.time() - 1
    if subtract is not None:
        newTime -= subtract
    os.utime(filename, (newTime, newTime))
Exemple #7
0
def removedir(tree):
    """
   Recursively removes an entire directory.
   This is basically taken from an example on python.com.
   @param tree: Directory tree to remove.
   @raise ValueError: If a path cannot be encoded properly.
   """
    tree = encodePath(tree)
    for root, dirs, files in os.walk(tree, topdown=False):
        for name in files:
            path = os.path.join(root, name)
            if os.path.islink(path):
                os.remove(path)
            elif os.path.isfile(path):
                os.remove(path)
        for name in dirs:
            path = os.path.join(root, name)
            if os.path.islink(path):
                os.remove(path)
            elif os.path.isdir(path):
                os.rmdir(path)
    os.rmdir(tree)
Exemple #8
0
    def initializeImage(self, newDisc, tmpdir, mediaLabel=None):
        """
      Initializes the writer's associated ISO image.

      This method initializes the C{image} instance variable so that the caller
      can use the C{addImageEntry} method.  Once entries have been added, the
      C{writeImage} method can be called with no arguments.

      @param newDisc: Indicates whether the disc should be re-initialized
      @type newDisc: Boolean true/false

      @param tmpdir: Temporary directory to use if needed
      @type tmpdir: String representing a directory path on disk

      @param mediaLabel: Media label to be applied to the image, if any
      @type mediaLabel: String, no more than 25 characters long
      """
        self._image = _ImageProperties()
        self._image.newDisc = newDisc
        self._image.tmpdir = encodePath(tmpdir)
        self._image.mediaLabel = mediaLabel
        self._image.entries = {}  # mapping from path to graft point (if any)
Exemple #9
0
    def addEntry(self,
                 path,
                 graftPoint=None,
                 override=False,
                 contentsOnly=False):
        """
      Adds an individual file or directory into the ISO image.

      The path must exist and must be a file or a directory.  By default, the
      entry will be placed into the image at the root directory, but this
      behavior can be overridden using the C{graftPoint} parameter or instance
      variable.

      You can use the C{contentsOnly} behavior to revert to the "original"
      C{mkisofs} behavior for adding directories, which is to add only the
      items within the directory, and not the directory itself.

      @note: Things get I{odd} if you try to add a directory to an image that
      will be written to a multisession disc, and the same directory already
      exists in an earlier session on that disc.  Not all of the data gets
      written.  You really wouldn't want to do this anyway, I guess.

      @note: An exception will be thrown if the path has already been added to
      the image, unless the C{override} parameter is set to C{True}.

      @note: The method C{graftPoints} parameter overrides the object-wide
      instance variable.  If neither the method parameter or object-wide value
      is set, the path will be written at the image root.  The graft point
      behavior is determined by the value which is in effect I{at the time this
      method is called}, so you I{must} set the object-wide value before
      calling this method for the first time, or your image may not be
      consistent.

      @note: You I{cannot} use the local C{graftPoint} parameter to "turn off"
      an object-wide instance variable by setting it to C{None}.  Python's
      default argument functionality buys us a lot, but it can't make this
      method psychic. :)

      @param path: File or directory to be added to the image
      @type path: String representing a path on disk

      @param graftPoint: Graft point to be used when adding this entry
      @type graftPoint: String representing a graft point path, as described above

      @param override: Override an existing entry with the same path.
      @type override: Boolean true/false

      @param contentsOnly: Add directory contents only (standard C{mkisofs} behavior).
      @type contentsOnly: Boolean true/false

      @raise ValueError: If path is not a file or directory, or does not exist.
      @raise ValueError: If the path has already been added, and override is not set.
      @raise ValueError: If a path cannot be encoded properly.
      """
        path = encodePath(path)
        if not override:
            if path in self.entries.keys():
                raise ValueError("Path has already been added to the image.")
        if os.path.islink(path):
            raise ValueError("Path must not be a link.")
        if os.path.isdir(path):
            if graftPoint is not None:
                if contentsOnly:
                    self.entries[path] = graftPoint
                else:
                    self.entries[path] = os.path.join(graftPoint,
                                                      os.path.basename(path))
            elif self.graftPoint is not None:
                if contentsOnly:
                    self.entries[path] = self.graftPoint
                else:
                    self.entries[path] = os.path.join(self.graftPoint,
                                                      os.path.basename(path))
            else:
                if contentsOnly:
                    self.entries[path] = None
                else:
                    self.entries[path] = os.path.basename(path)
        elif os.path.isfile(path):
            if graftPoint is not None:
                self.entries[path] = graftPoint
            elif self.graftPoint is not None:
                self.entries[path] = self.graftPoint
            else:
                self.entries[path] = None
        else:
            raise ValueError("Path must be a file or a directory.")
Exemple #10
0
    def writeImage(self, imagePath=None, newDisc=False, writeMulti=True):
        """
      Writes an ISO image to the media in the device.

      If C{newDisc} is passed in as C{True}, we assume that the entire disc
      will be re-created from scratch.  Note that unlike C{CdWriter},
      C{DvdWriter} does not blank rewritable media before reusing it; however,
      C{growisofs} is called such that the media will be re-initialized as
      needed.

      If C{imagePath} is passed in as C{None}, then the existing image
      configured with C{initializeImage()} will be used.  Under these
      circumstances, the passed-in C{newDisc} flag will be ignored and the
      value passed in to C{initializeImage()} will apply instead.

      The C{writeMulti} argument is ignored.  It exists for compatibility with
      the Cedar Backup image writer interface.

      @note: The image size indicated in the log ("Image size will be...") is
      an estimate.  The estimate is conservative and is probably larger than
      the actual space that C{dvdwriter} will use.

      @param imagePath: Path to an ISO image on disk, or C{None} to use writer's image
      @type imagePath: String representing a path on disk

      @param newDisc: Indicates whether the disc should be re-initialized
      @type newDisc: Boolean true/false.

      @param writeMulti: Unused
      @type writeMulti: Boolean true/false

      @raise ValueError: If the image path is not absolute.
      @raise ValueError: If some path cannot be encoded properly.
      @raise IOError: If the media could not be written to for some reason.
      @raise ValueError: If no image is passed in and initializeImage() was not previously called
      """
        if not writeMulti:
            logger.warn("writeMulti value of [%s] ignored.", writeMulti)
        if imagePath is None:
            if self._image is None:
                raise ValueError(
                    "Must call initializeImage() before using this method with no image path."
                )
            size = self.getEstimatedImageSize()
            logger.info("Image size will be %s (estimated).",
                        displayBytes(size))
            available = self.retrieveCapacity(
                entireDisc=self._image.newDisc).bytesAvailable
            if size > available:
                logger.error(
                    "Image [%s] does not fit in available capacity [%s].",
                    displayBytes(size), displayBytes(available))
                raise IOError(
                    "Media does not contain enough capacity to store image.")
            self._writeImage(self._image.newDisc, None, self._image.entries,
                             self._image.mediaLabel)
        else:
            if not os.path.isabs(imagePath):
                raise ValueError("Image path must be absolute.")
            imagePath = encodePath(imagePath)
            self._writeImage(newDisc, imagePath, None)