summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/virtualization/disk/DiskImage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/virtualization/disk/DiskImage.java')
-rw-r--r--src/main/java/org/openslx/virtualization/disk/DiskImage.java253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/virtualization/disk/DiskImage.java b/src/main/java/org/openslx/virtualization/disk/DiskImage.java
new file mode 100644
index 0000000..dfb242a
--- /dev/null
+++ b/src/main/java/org/openslx/virtualization/disk/DiskImage.java
@@ -0,0 +1,253 @@
+package org.openslx.virtualization.disk;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.openslx.bwlp.thrift.iface.Virtualizer;
+import org.openslx.thrifthelper.TConst;
+import org.openslx.util.Util;
+import org.openslx.virtualization.Version;
+
+/**
+ * Disk image for virtual machines.
+ *
+ * @implNote This class is the abstract base class to implement various specific disk images (like
+ * QCOW2 or VMDK).
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public abstract class DiskImage implements Closeable
+{
+ /**
+ * Stores the image file of the disk.
+ */
+ private RandomAccessFile diskImage = null;
+
+ /**
+ * Creates a new disk image from an existing image file with a known disk image format.
+ *
+ * @param diskImage file to a disk storing the image content.
+ *
+ * @implNote Do not use this constructor to create a new disk image from an image file with
+ * unknown disk image format. Instead, use the factory method
+ * {@link #newInstance(File)} to probe unknown disk image files before creation.
+ */
+ protected DiskImage( RandomAccessFile diskImage )
+ {
+ this.diskImage = diskImage;
+ }
+
+ /**
+ * Returns the disk image file.
+ *
+ * @return the disk image file.
+ */
+ protected RandomAccessFile getDiskImage()
+ {
+ return this.diskImage;
+ }
+
+ /**
+ * Checks whether disk image is standalone and do not depend on other files (e.g. snapshot
+ * files).
+ *
+ * @return state whether disk image is standalone or not.
+ *
+ * @throws DiskImageException unable to check if disk image is standalone.
+ */
+ public abstract boolean isStandalone() throws DiskImageException;
+
+ /**
+ * Checks whether disk image is compressed.
+ *
+ * @return state whether disk image is compressed or not.
+ *
+ * @throws DiskImageException unable to check whether disk image is compressed.
+ */
+ public abstract boolean isCompressed() throws DiskImageException;
+
+ /**
+ * Checks whether disk image is a snapshot.
+ *
+ * @return state whether disk image is a snapshot or not.
+ *
+ * @throws DiskImageException unable to check whether disk image is a snapshot.
+ */
+ public abstract boolean isSnapshot() throws DiskImageException;
+
+ /**
+ * Returns the version of the disk image format.
+ *
+ * @return version of the disk image format.
+ *
+ * @throws DiskImageException unable to obtain version of the disk image format.
+ */
+ public abstract Version getVersion() throws DiskImageException;
+
+ /**
+ * Returns the disk image description.
+ *
+ * @return description of the disk image.
+ *
+ * @throws DiskImageException unable to obtain description of the disk image.
+ */
+ public abstract String getDescription() throws DiskImageException;
+
+ /**
+ * Returns the format of the disk image.
+ *
+ * @return format of the disk image.
+ */
+ public abstract ImageFormat getFormat();
+
+ /**
+ * Creates a new disk image from an existing image file with an unknown disk image format.
+ *
+ * @param diskImagePath file to a disk storing the image content.
+ * @return concrete disk image instance.
+ *
+ * @throws FileNotFoundException cannot find specified disk image file.
+ * @throws IOException cannot access the content of the disk image file.
+ * @throws DiskImageException disk image file has an invalid and unknown disk image format.
+ */
+ public static DiskImage newInstance( File diskImagePath )
+ throws FileNotFoundException, IOException, DiskImageException
+ {
+ // Make sure this doesn't escape the scope, in case instantiation fails - we can't know when the GC
+ // would come along and close this file, which is problematic on Windows (blocking rename/delete)
+ final RandomAccessFile fileHandle = new RandomAccessFile( diskImagePath, "r" );
+
+ try {
+ if ( DiskImageQcow2.probe( fileHandle ) ) {
+ return new DiskImageQcow2( fileHandle );
+ } else if ( DiskImageVdi.probe( fileHandle ) ) {
+ return new DiskImageVdi( fileHandle );
+ } else if ( DiskImageVmdk.probe( fileHandle ) ) {
+ return new DiskImageVmdk( fileHandle );
+ }
+ } catch ( Exception e ) {
+ Util.safeClose( fileHandle );
+ throw e;
+ }
+ Util.safeClose( fileHandle );
+ final String errorMsg = "File '" + diskImagePath.getAbsolutePath() + "' is not a valid disk image!";
+ throw new DiskImageException( errorMsg );
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ Util.safeClose( diskImage );
+ }
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ close();
+ }
+
+ /**
+ * Format of a disk image.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum ImageFormat
+ {
+ // @formatter:off
+ NONE ( "none" ),
+ QCOW2( "qcow2" ),
+ VDI ( "vdi" ),
+ VMDK ( "vmdk" );
+ // @formatter:on
+
+ /**
+ * Stores filename extension of the disk image format.
+ */
+ public final String extension;
+
+ /**
+ * Create new disk image format.
+ *
+ * @param extension filename extension of the disk image format.
+ */
+ ImageFormat( String extension )
+ {
+ this.extension = extension;
+ }
+
+ /**
+ * Returns filename extension of the disk image.
+ *
+ * @return filename extension of the disk image.
+ */
+ public String getExtension()
+ {
+ return this.extension;
+ }
+
+ /**
+ * Checks if the disk image format is supported by a virtualizer.
+ *
+ * @param supportedImageFormats list of supported disk image formats of a virtualizer.
+ * @return <code>true</code> if image type is supported by the virtualizer; otherwise
+ * <code>false</code>.
+ */
+ public boolean isSupportedbyVirtualizer( List<ImageFormat> supportedImageFormats )
+ {
+ Predicate<ImageFormat> matchDiskFormat = supportedImageFormat -> supportedImageFormat.toString()
+ .equalsIgnoreCase( this.toString() );
+ return supportedImageFormats.stream().anyMatch( matchDiskFormat );
+ }
+
+ /**
+ * Returns default (preferred) disk image format for the specified virtualizer.
+ *
+ * @param virt virtualizer for that the default disk image should be determined.
+ * @return default (preferred) disk image format.
+ */
+ public static ImageFormat defaultForVirtualizer( Virtualizer virt )
+ {
+ if ( virt == null ) {
+ return null;
+ } else {
+ return ImageFormat.defaultForVirtualizer( virt.virtId );
+ }
+ }
+
+ /**
+ * Returns default (preferred) disk image format for the specified virtualizer.
+ *
+ * @param virtId ID of a virtualizer for that the default disk image should be determined.
+ * @return default (preferred) disk image format.
+ */
+ public static ImageFormat defaultForVirtualizer( String virtId )
+ {
+ ImageFormat imgFormat = null;
+
+ if ( TConst.VIRT_DOCKER.equals( virtId ) ) {
+ imgFormat = NONE;
+ } else if ( TConst.VIRT_QEMU.equals( virtId ) ) {
+ imgFormat = QCOW2;
+ } else if ( TConst.VIRT_VIRTUALBOX.equals( virtId ) ) {
+ imgFormat = VDI;
+ } else if ( TConst.VIRT_VMWARE.equals( virtId ) ) {
+ imgFormat = VMDK;
+ }
+
+ return imgFormat;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getExtension();
+ }
+ }
+}