Esempio n. 1
0
    def test_convert_from_vmdk_old_qemu(self, mock_vmdktool, mock_qemuimg, *_):
        """Test conversion from streamOptimized VMDK with old QEMU."""
        RAW.from_other_image(VMDK(self.blank_vmdk), self.temp_dir)

        mock_vmdktool.assert_called_with([
            '-s', os.path.join(self.temp_dir, "blank.img"), self.blank_vmdk])
        mock_qemuimg.assert_not_called()
Esempio n. 2
0
 def test_create_with_capacity(self):
     """Creation of a raw image of a particular size."""
     disk_path = os.path.join(self.temp_dir, "out.raw")
     RAW.create_file(disk_path, capacity="16M")
     raw = RAW(disk_path)
     self.assertEqual(raw.disk_format, 'raw')
     self.assertEqual(raw.disk_subformat, None)
Esempio n. 3
0
 def test_create_with_capacity(self):
     """Creation of a raw image of a particular size."""
     disk_path = os.path.join(self.temp_dir, "out.raw")
     RAW.create_file(disk_path, capacity="16M")
     raw = RAW(disk_path)
     self.assertEqual(raw.disk_format, 'raw')
     self.assertEqual(raw.disk_subformat, None)
Esempio n. 4
0
 def test_create_with_files(self):
     """Creation of a raw image with specific file contents."""
     disk_path = os.path.join(self.temp_dir, "out.raw")
     RAW.create_file(disk_path, files=[self.input_ovf])
     raw = RAW(disk_path)
     self.assertEqual(raw.files, [os.path.basename(self.input_ovf)])
     self.assertEqual(raw.capacity, "8388608")
Esempio n. 5
0
 def test_create_with_files_and_capacity(self):
     """Creation of raw image with specified capacity and file contents."""
     disk_path = os.path.join(self.temp_dir, "out.img")
     RAW.create_file(disk_path, files=[self.input_ovf], capacity="64M")
     raw = RAW(disk_path)
     self.assertEqual(raw.files, [os.path.basename(self.input_ovf)])
     self.assertEqual(raw.capacity, "67108864")
Esempio n. 6
0
    def test_convert_from_vmdk_new_qemu(self, mock_vmdktool, mock_qemuimg, *_):
        """Test conversion from streamOptimized VMDK with new QEMU."""
        RAW.from_other_image(VMDK(self.blank_vmdk), self.temp_dir)

        mock_vmdktool.assert_not_called()
        mock_qemuimg.assert_called_with([
            'convert', '-O', 'raw', self.blank_vmdk,
            os.path.join(self.temp_dir, "blank.img")])
Esempio n. 7
0
 def test_create_with_files_and_capacity(self):
     """Creation of raw image with specified capacity and file contents."""
     disk_path = os.path.join(self.temp_dir, "out.img")
     RAW.create_file(disk_path, files=[self.input_ovf], capacity="64M")
     raw = RAW(disk_path)
     self.assertEqual(raw.files,
                      [os.path.basename(self.input_ovf)])
     self.assertEqual(raw.capacity, "67108864")
Esempio n. 8
0
    def test_convert_from_vmdk_old_qemu(self, mock_vmdktool, mock_qemuimg, *_):
        """Test conversion from streamOptimized VMDK with old QEMU."""
        RAW.from_other_image(VMDK(self.blank_vmdk), self.temp_dir)

        mock_vmdktool.assert_called_with(
            ['-s',
             os.path.join(self.temp_dir, "blank.img"), self.blank_vmdk])
        mock_qemuimg.assert_not_called()
Esempio n. 9
0
 def test_create_with_files(self):
     """Creation of a raw image with specific file contents."""
     disk_path = os.path.join(self.temp_dir, "out.raw")
     RAW.create_file(disk_path, files=[self.input_ovf])
     raw = RAW(disk_path)
     self.assertEqual(raw.files,
                      [os.path.basename(self.input_ovf)])
     self.assertEqual(raw.capacity, "8388608")
Esempio n. 10
0
    def test_convert_from_vmdk_new_qemu(self, mock_vmdktool, mock_qemuimg, *_):
        """Test conversion from streamOptimized VMDK with new QEMU."""
        RAW.from_other_image(VMDK(self.blank_vmdk), self.temp_dir)

        mock_vmdktool.assert_not_called()
        mock_qemuimg.assert_called_with([
            'convert', '-O', 'raw', self.blank_vmdk,
            os.path.join(self.temp_dir, "blank.img")
        ])
Esempio n. 11
0
    def test_from_other_image_raw(self):
        """Test conversion of raw format to qcow2."""
        qcow2 = QCOW2.from_other_image(RAW(self.temp_disk), self.temp_dir)

        self.assertEqual(qcow2.disk_format, 'qcow2')
        self.assertEqual(qcow2.disk_subformat, None)
        self.assertEqual(qcow2.predicted_drive_type, 'harddisk')
Esempio n. 12
0
    def test_convert_from_vmdk(self):
        """Test conversion of a RAW image from a VMDK."""
        old = DiskRepresentation.from_file(self.blank_vmdk)
        raw = RAW.from_other_image(old, self.temp_dir)

        self.assertEqual(raw.disk_format, 'raw')
        self.assertEqual(raw.disk_subformat, None)
Esempio n. 13
0
    def from_other_image(cls, input_image, output_dir, output_subformat=None):
        """Convert the other disk image into an image of this type.

        Args:
          input_image (DiskRepresentation): Existing image representation.
          output_dir (str): Output directory to store the new image in.
          output_subformat (str): Any relevant subformat information.

        Returns:
          QCOW2: representation of newly created qcow2 image file
        """
        file_name = os.path.basename(input_image.path)
        (file_prefix, _) = os.path.splitext(file_name)
        output_path = os.path.join(output_dir, file_prefix + ".qcow2")
        if (input_image.disk_format == 'vmdk'
                and input_image.disk_subformat == 'streamOptimized'):
            helper = helper_select([('qemu-img', '1.2.0'), 'vmdktool'])
            # Special case: qemu-img < 1.2.0 can't read streamOptimized VMDKs
            if helper.name == 'vmdktool':
                # vmdktool can convert streamOptimized VMDK to raw
                # Convert vmdk to raw, then raw to qcow2
                # Note that vmdktool takes its arguments in unusual order -
                # output file comes before input file
                from COT.disks import RAW
                try:
                    temp_image = RAW.from_other_image(input_image, output_dir)
                    return cls.from_other_image(temp_image, output_dir,
                                                output_subformat)
                finally:
                    os.remove(temp_image.path)

        helpers['qemu-img'].call(
            ['convert', '-O', 'qcow2', input_image.path, output_path])
        return cls(output_path)
Esempio n. 14
0
    def test_convert_from_vmdk(self):
        """Test conversion of a RAW image from a VMDK."""
        old = DiskRepresentation.from_file(self.blank_vmdk)
        raw = RAW.from_other_image(old, self.temp_dir)

        self.assertEqual(raw.disk_format, 'raw')
        self.assertEqual(raw.disk_subformat, None)
Esempio n. 15
0
    def test_convert_from_vmdk_old_qemu(self, mock_qemuimg, mock_raw, *_):
        """Test conversion from streamOptimized VMDK with old QEMU."""
        mock_raw.return_value = RAW(self.temp_disk)

        QCOW2.from_other_image(VMDK(self.blank_vmdk), self.temp_dir)

        mock_qemuimg.assert_called_with([
            'convert', '-O', 'qcow2', self.temp_disk,
            os.path.join(self.temp_dir, 'blank.qcow2')
        ])
Esempio n. 16
0
    def from_other_image(cls, input_image, output_dir, output_subformat=None):
        """Convert the other disk image into an image of this type.

        Args:
          input_image (DiskRepresentation): Existing image representation.
          output_dir (str): Output directory to store the new image in.
          output_subformat (str): Any relevant subformat information.

        Returns:
          QCOW2: representation of newly created qcow2 image file
        """
        file_name = os.path.basename(input_image.path)
        (file_prefix, _) = os.path.splitext(file_name)
        output_path = os.path.join(output_dir, file_prefix + ".qcow2")
        if (input_image.disk_format == 'vmdk' and
                input_image.disk_subformat == 'streamOptimized'):
            helper = helper_select([('qemu-img', '1.2.0'), 'vmdktool'])
            # Special case: qemu-img < 1.2.0 can't read streamOptimized VMDKs
            if helper.name == 'vmdktool':
                # vmdktool can convert streamOptimized VMDK to raw
                # Convert vmdk to raw, then raw to qcow2
                # Note that vmdktool takes its arguments in unusual order -
                # output file comes before input file
                from COT.disks import RAW
                try:
                    temp_image = RAW.from_other_image(input_image, output_dir)
                    return cls.from_other_image(temp_image, output_dir,
                                                output_subformat)
                finally:
                    os.remove(temp_image.path)

        helpers['qemu-img'].call(['convert',
                                  '-O', 'qcow2',
                                  input_image.path,
                                  output_path])
        return cls(output_path)
Esempio n. 17
0
    def from_other_image(cls, input_image, output_dir,
                         output_subformat="streamOptimized"):
        """Convert the other disk image into an image of this type.

        Args:
          input_image (DiskRepresentation): Existing image representation.
          output_dir (str): Output directory to store the new image in.
          output_subformat (str): VMDK subformat string.
              Defaults to "streamOptimized" if unset.

        Returns:
          VMDK: representation of newly created VMDK file.

        .. note::

          Creation of streamOptimized subformat VMDKs (ESXi's preferred
          subformat for OVAs, hence COT's default subformat) is more complex
          than it seems due to the underlying helpers required.

          - Prior to QEMU 2.1.0, ``qemu-img`` effectively can't write
            streamOptimized subformat at all (it tends to error out).
          - In QEMU 2.1.0 through 2.5.0, ``qemu-img`` supports output to
            streamOptimized subformat, but it outputs VMDK images declaring
            version 1 of the VMDK format, which newer versions of ESXi
            (and probably other VMware products) reject with the message
            ``"Not a supported disk format (sparse VMDK version too old)"``.
          - In QEMU 2.5.1 and later, ``qemu-img`` produces "version 3" VMDK
            images, which suffices to make ESXi happy.
          - ``vmdktool`` (any released version) also makes "version 3" VMDKs,
            but is less likely to be available on most user systems, and it
            can only convert from RAW format images to streamOptimized VMDK.

          So, when creating streamOptimized VMDKs, if we have QEMU 2.5.1+,
          we're golden. Else, if we have ``vmdktool``, use it, after
          converting the :attr:`input_image` to RAW format first if necessary.
          Else, fail back to QEMU 2.1.0+ but warn the user that the resulting
          image may not be usable with ESXi.
        """
        file_name = os.path.basename(input_image.path)
        (file_prefix, _) = os.path.splitext(file_name)
        output_path = os.path.join(output_dir, file_prefix + ".vmdk")
        if output_subformat == "streamOptimized":
            helper = helper_select([
                ('qemu-img', '2.5.1'),  # best option, all needed functionality
                'vmdktool',  # supports VMDK v.3, but only converts from RAW
                ('qemu-img', '2.1.0'),  # fallback - produces VMDK v.1
            ])
            if helper.name == 'vmdktool':
                if input_image.disk_format != 'raw':
                    # vmdktool needs a raw image as input
                    from COT.disks import RAW
                    temp_image = None
                    try:
                        temp_image = RAW.from_other_image(input_image,
                                                          output_dir)
                        return cls.from_other_image(temp_image,
                                                    output_dir,
                                                    output_subformat)
                    finally:
                        if temp_image is not None:
                            os.remove(temp_image.path)
                            temp_image = None

                # Note that vmdktool takes its arguments in unusual order -
                # output file comes before input file
                helper.call(['-z9', '-v', output_path, input_image.path])
                return cls(output_path)

            # else, fall through to default (qemu-img), with one extra:
            if helpers['qemu-img'].version < StrictVersion("2.5.1"):
                logger.warning(
                    "QEMU version %s produces 'version 1' VMDK images, which"
                    " newer versions of VMware ESXi will reject with the"
                    " message '%s'.\nIn order to generate the preferred"
                    " 'version 3' images, please upgrade to QEMU 2.5.1 or"
                    " later, or install vmdktool.",
                    str(helpers['qemu-img'].version),
                    "Not a supported disk format"
                    " (sparse VMDK version too old)")

        helpers['qemu-img'].call([
            'convert',
            '-O', 'vmdk',
            '-o', 'subformat={0}'.format(output_subformat),
            input_image.path,
            output_path])
        return cls(output_path)
Esempio n. 18
0
 def test_representation_invalid(self):
     """Representation of a file that isn't really a raw disk."""
     fake_raw = RAW(self.input_iso)
     with self.assertRaises(HelperError):
         assert fake_raw.files
Esempio n. 19
0
    def from_other_image(cls,
                         input_image,
                         output_dir,
                         output_subformat="streamOptimized"):
        """Convert the other disk image into an image of this type.

        Args:
          input_image (DiskRepresentation): Existing image representation.
          output_dir (str): Output directory to store the new image in.
          output_subformat (str): VMDK subformat string.
              Defaults to "streamOptimized" if unset.

        Returns:
          VMDK: representation of newly created VMDK file.

        .. note::

          Creation of streamOptimized subformat VMDKs (ESXi's preferred
          subformat for OVAs, hence COT's default subformat) is more complex
          than it seems due to the underlying helpers required.

          - Prior to QEMU 2.1.0, ``qemu-img`` effectively can't write
            streamOptimized subformat at all (it tends to error out).
          - In QEMU 2.1.0 through 2.5.0, ``qemu-img`` supports output to
            streamOptimized subformat, but it outputs VMDK images declaring
            version 1 of the VMDK format, which newer versions of ESXi
            (and probably other VMware products) reject with the message
            ``"Not a supported disk format (sparse VMDK version too old)"``.
          - In QEMU 2.5.1 and later, ``qemu-img`` produces "version 3" VMDK
            images, which suffices to make ESXi happy.
          - ``vmdktool`` (any released version) also makes "version 3" VMDKs,
            but is less likely to be available on most user systems, and it
            can only convert from RAW format images to streamOptimized VMDK.

          So, when creating streamOptimized VMDKs, if we have QEMU 2.5.1+,
          we're golden. Else, if we have ``vmdktool``, use it, after
          converting the :attr:`input_image` to RAW format first if necessary.
          Else, fail back to QEMU 2.1.0+ but warn the user that the resulting
          image may not be usable with ESXi.
        """
        file_name = os.path.basename(input_image.path)
        (file_prefix, _) = os.path.splitext(file_name)
        output_path = os.path.join(output_dir, file_prefix + ".vmdk")
        if output_subformat == "streamOptimized":
            helper = helper_select([
                ('qemu-img', '2.5.1'),  # best option, all needed functionality
                'vmdktool',  # supports VMDK v.3, but only converts from RAW
                ('qemu-img', '2.1.0'),  # fallback - produces VMDK v.1
            ])
            if helper.name == 'vmdktool':
                if input_image.disk_format != 'raw':
                    # vmdktool needs a raw image as input
                    from COT.disks import RAW
                    temp_image = None
                    try:
                        temp_image = RAW.from_other_image(
                            input_image, output_dir)
                        return cls.from_other_image(temp_image, output_dir,
                                                    output_subformat)
                    finally:
                        if temp_image is not None:
                            os.remove(temp_image.path)
                            temp_image = None

                # Note that vmdktool takes its arguments in unusual order -
                # output file comes before input file
                helper.call(['-z9', '-v', output_path, input_image.path])
                return cls(output_path)

            # else, fall through to default (qemu-img), with one extra:
            if helpers['qemu-img'].version < StrictVersion("2.5.1"):
                logger.warning(
                    "QEMU version %s produces 'version 1' VMDK images, which"
                    " newer versions of VMware ESXi will reject with the"
                    " message '%s'.\nIn order to generate the preferred"
                    " 'version 3' images, please upgrade to QEMU 2.5.1 or"
                    " later, or install vmdktool.",
                    str(helpers['qemu-img'].version),
                    "Not a supported disk format"
                    " (sparse VMDK version too old)")

        helpers['qemu-img'].call([
            'convert', '-O', 'vmdk', '-o',
            'subformat={0}'.format(output_subformat), input_image.path,
            output_path
        ])
        return cls(output_path)