def __enter__(self):
     self.directory = tempfile.mkdtemp()
     self.subdirectory = io.PathJoin(self.directory, "pinky")
     os.mkdir(self.subdirectory)
     self.path = io.PathJoin(self.subdirectory, "bunny")
     self.volume = TestFileDeviceHelper._Make(self.path)
     if self.create_file:
         open(self.path, mode="w").close()
     return self
Ejemplo n.º 2
0
    def Create(cls, unique_id, children, size, spindles, params, excl_stor,
               dyn_params, *args):
        """Create a new file.

    @param size: the size of file in MiB

    @rtype: L{bdev.FileStorage}
    @return: an instance of FileStorage

    """
        if excl_stor:
            raise errors.ProgrammerError("FileStorage device requested with"
                                         " exclusive_storage")
        if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2:
            raise ValueError("Invalid configuration data %s" % str(unique_id))

        full_path = unique_id[1]

        server_addr = params[constants.GLUSTER_HOST]
        port = params[constants.GLUSTER_PORT]
        volume = params[constants.GLUSTER_VOLUME]

        volume_obj = GlusterVolume(server_addr, port, volume)
        full_path = io.PathJoin(volume_obj.mount_point, full_path)

        # Possible optimization: defer actual creation to first Attach, rather
        # than mounting and unmounting here, then remounting immediately after.
        with volume_obj.Mount():
            FileDeviceHelper.CreateFile(full_path, size, create_folders=True)

        return GlusterStorage(unique_id, children, size, params, dyn_params,
                              *args)
Ejemplo n.º 3
0
    def __init__(self, unique_id, children, size, params, dyn_params, *args):
        """Initalizes a file device backend.

    """
        if children:
            base.ThrowError("Invalid setup for file device")

        try:
            driver, path = unique_id
        except ValueError:  # wrong number of arguments
            raise ValueError("Invalid configuration data %s" % repr(unique_id))

        server_addr = params[constants.GLUSTER_HOST]
        port = params[constants.GLUSTER_PORT]
        volume = params[constants.GLUSTER_VOLUME]

        self.volume = GlusterVolume(server_addr, port, volume)
        self.path = path
        self.driver = driver
        self.full_path = io.PathJoin(self.volume.mount_point, self.path)
        self.file = None

        super(GlusterStorage, self).__init__(unique_id, children, size, params,
                                             dyn_params, *args)

        self.Attach()
Ejemplo n.º 4
0
def RunParts(dir_name, env=None, reset_env=False):
  """Run Scripts or programs in a directory

  @type dir_name: string
  @param dir_name: absolute path to a directory
  @type env: dict
  @param env: The environment to use
  @type reset_env: boolean
  @param reset_env: whether to reset or keep the default os environment
  @rtype: list of tuples
  @return: list of (name, (one of RUNDIR_STATUS), RunResult)

  """
  rr = []

  try:
    dir_contents = utils_io.ListVisibleFiles(dir_name)
  except OSError as err:
    logging.warning("RunParts: skipping %s (cannot list: %s)", dir_name, err)
    return rr

  for relname in sorted(dir_contents):
    fname = utils_io.PathJoin(dir_name, relname)
    if not (constants.EXT_PLUGIN_MASK.match(relname) is not None and
            utils_wrapper.IsExecutable(fname)):
      rr.append((relname, constants.RUNPARTS_SKIP, None))
    else:
      try:
        result = RunCmd([fname], env=env, reset_env=reset_env)
      except Exception as err: # pylint: disable=W0703
        rr.append((relname, constants.RUNPARTS_ERR, str(err)))
      else:
        rr.append((relname, constants.RUNPARTS_RUN, result))

  return rr
Ejemplo n.º 5
0
def CreateBdevPartitionMapping(image_path):
    """Create dm device for each partition of disk image.

  This operation will allocate a loopback and a device-mapper device to map
  partitions.
  You must call L{ReleaseBdevPartitionMapping} to clean up resources allocated
  by this function call.

  @type image_path: string
  @param image_path: path of multi-partition disk image
  @rtype: tuple(string, list(string)) or NoneType
  @return: returns the tuple(loopback_device, list(device_mapper_files)) if
    image_path is a multi-partition disk image. otherwise, returns None.

  """
    # Unfortunately, there are two different losetup commands in this world.
    # One has the '-s' switch and the other has the '--show' switch to provide the
    # same functionality.
    result = utils_process.RunCmd(["losetup", "-f", "-s", image_path])
    if result.failed and "invalid option -- 's'" in result.stderr:
        result = utils_process.RunCmd(["losetup", "-f", "--show", image_path])
    if result.failed:
        raise errors.CommandError("Failed to setup loop device for %s: %s" %
                                  (image_path, result.output))
    loop_dev_path = result.stdout.strip()
    logging.debug("Loop dev %s allocated for %s", loop_dev_path, image_path)

    result = utils_process.RunCmd(["kpartx", "-a", "-v", loop_dev_path])
    if result.failed:
        # Just try to cleanup allocated loop device
        utils_process.RunCmd(["losetup", "-d", loop_dev_path])
        raise errors.CommandError(
            "Failed to add partition mapping for %s: %s" %
            (image_path, result.output))
    dm_devs = [x.split(" ") for x in result.stdout.split("\n") if x]
    if dm_devs:
        dm_dev_paths = [
            utils_io.PathJoin("/dev/mapper", x[2]) for x in dm_devs
        ]
        return (loop_dev_path, dm_dev_paths)
    else:
        # image_path is not a multi partition disk image, no need to use
        # device-mapper.
        logging.debug("Release loop dev %s allocated for %s", loop_dev_path,
                      image_path)
        ReleaseBdevPartitionMapping(loop_dev_path)
        return None
Ejemplo n.º 6
0
  @type reset_env: boolean
  @param reset_env: whether to reset or keep the default os environment
  @rtype: list of tuples
  @return: list of (name, (one of RUNDIR_STATUS), RunResult)

  """
  rr = []

  try:
    dir_contents = utils_io.ListVisibleFiles(dir_name)
  except OSError, err:
    logging.warning("RunParts: skipping %s (cannot list: %s)", dir_name, err)
    return rr

  for relname in sorted(dir_contents):
    fname = utils_io.PathJoin(dir_name, relname)
    if not (constants.EXT_PLUGIN_MASK.match(relname) is not None and
            utils_wrapper.IsExecutable(fname)):
      rr.append((relname, constants.RUNPARTS_SKIP, None))
    else:
      try:
        result = RunCmd([fname], env=env, reset_env=reset_env)
      except Exception, err: # pylint: disable=W0703
        rr.append((relname, constants.RUNPARTS_ERR, str(err)))
      else:
        rr.append((relname, constants.RUNPARTS_RUN, result))

  return rr


def _GetProcStatusPath(pid):
Ejemplo n.º 7
0
    def _GuessMountFailReasons(self):
        """Try and give reasons why the mount might've failed.

    @rtype: str
    @return: A semicolon-separated list of problems found with the current setup
             suitable for display to the user.

    """

        reasons = []

        # Does the mount point exist?
        if not os.path.exists(self.mount_point):
            reasons.append("%r: does not exist" % self.mount_point)

        # Okay, it exists, but is it a directory?
        elif not os.path.isdir(self.mount_point):
            reasons.append("%r: not a directory" % self.mount_point)

        # If, for some unfortunate reason, this folder exists before mounting:
        #
        #   /var/run/ganeti/gluster/gv0/10.0.0.1:30000:gv0/
        #   '--------- cwd ------------'
        #
        # and you _are_ trying to mount the gluster volume gv0 on 10.0.0.1:30000,
        # then the mount.glusterfs command parser gets confused and this command:
        #
        #   mount -t glusterfs 10.0.0.1:30000:gv0 /var/run/ganeti/gluster/gv0
        #                      '-- remote end --' '------ mountpoint -------'
        #
        # gets parsed instead like this:
        #
        #   mount -t glusterfs 10.0.0.1:30000:gv0 /var/run/ganeti/gluster/gv0
        #                      '-- mountpoint --' '----- syntax error ------'
        #
        # and if there _is_ a gluster server running locally at the default remote
        # end, localhost:24007, then this is not a network error and therefore... no
        # usage message gets printed out. All you get is a Byson parser error in the
        # gluster log files about an unexpected token in line 1, "". (That's stdin.)
        #
        # Not that we rely on that output in any way whatsoever...

        parser_confusing = io.PathJoin(self.mount_point,
                                       self._GetFUSEMountString())
        if os.path.exists(parser_confusing):
            reasons.append("%r: please delete, rename or move." %
                           parser_confusing)

        # Let's try something else: can we connect to the server?
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((self.server_ip, self.port))
            sock.close()
        except socket.error as err:
            reasons.append("%s:%d: %s" %
                           (self.server_ip, self.port, err.strerror))

        reasons.append("try running 'gluster volume info %s' on %s to ensure"
                       " it exists, it is started and it is using the tcp"
                       " transport" % (self.volume, self.server_ip))

        return "; ".join(reasons)