summaryrefslogtreecommitdiffstats
path: root/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/plugin/qemu/configuration/TransformationGenericDiskCdromDevices.java
blob: a7c3b01537ed15606195265603657b8154fb301a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package org.openslx.runvirt.plugin.qemu.configuration;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;

import org.openslx.libvirt.domain.Domain;
import org.openslx.libvirt.domain.device.Disk.BusType;
import org.openslx.libvirt.domain.device.Disk.StorageType;
import org.openslx.libvirt.domain.device.DiskCdrom;
import org.openslx.runvirt.plugin.qemu.cmdln.CommandLineArgs;
import org.openslx.virtualization.configuration.VirtualizationConfigurationQemuUtils;
import org.openslx.virtualization.configuration.transformation.TransformationException;
import org.openslx.virtualization.configuration.transformation.TransformationGeneric;

/**
 * Generic CDROM drive transformation for Libvirt/QEMU virtualization configurations.
 * 
 * @author Manuel Bentele
 * @version 1.0
 */
public class TransformationGenericDiskCdromDevices extends TransformationGeneric<Domain, CommandLineArgs>
{
	/**
	 * Name of the configuration transformation.
	 */
	private static final String NAME = "Disk CDROM devices";

	/**
	 * Creates a new generic CDROM drive transformation for Libvirt/QEMU virtualization
	 * configurations.
	 */
	public TransformationGenericDiskCdromDevices()
	{
		super( TransformationGenericDiskCdromDevices.NAME );
	}

	/**
	 * Validates a virtualization configuration and input arguments for this transformation.
	 * 
	 * @param config virtualization configuration for the validation.
	 * @param args input arguments for the validation.
	 * @throws TransformationException validation has failed.
	 */
	private void validateInputs( Domain config, CommandLineArgs args ) throws TransformationException
	{
		if ( config == null || args == null ) {
			throw new TransformationException( "Virtualization configuration or input arguments are missing!" );
		}
	}

	/**
	 * Sets the storage of a CDROM drive from a virtualization configuration.
	 * 
	 * @param disk CDROM drive from a virtualization configuration.
	 * @param fileName path to a storage that is set for the specified CDROM drive (e.g. block device
	 *           or image)
	 */
	private void setDiskCdromStorage( DiskCdrom disk, String fileName )
	{
		if ( fileName == null ) {
			// remove disk storage device if disk image file name is not set
			disk.remove();
		} else if ( fileName.isEmpty() ) {
			// remove storage source if empty string is specified to emulate an empty CDROM drive
			disk.removeStorage();
		} else {
			// set disk image file as storage source of the disk CDROM drive
			// check before, whether the referenced file is a regular file or a block device file
			final Path diskFilePath = Paths.get( fileName );
			BasicFileAttributes diskFileAttrs = null;

			// get file attributes from referenced file
			try {
				diskFileAttrs = Files.readAttributes( diskFilePath, BasicFileAttributes.class );
			} catch ( IOException e ) {
				diskFileAttrs = null;
			}

			// set storage type according to the file attributes of the referenced file
			if ( diskFileAttrs != null ) {
				if ( diskFileAttrs.isOther() && !diskFileAttrs.isRegularFile() ) {
					// referenced file is a block device file
					// set block device storage type
					disk.setStorage( StorageType.BLOCK, fileName );
				} else {
					// referenced file is a regular file
					// set file storage type
					disk.setStorage( StorageType.FILE, fileName );
				}
			}
		}
	}

	/**
	 * Transforms a CDROM drive in a virtualization configuration selected by its {@code index}.
	 * 
	 * @param config virtualization configuration for the transformation.
	 * @param fileName name of the image file for the CDROM drive.
	 * @param index number of the CDROM drive in the virtualization configuration that is selected.
	 * @throws TransformationException transformation has failed.
	 */
	private void transformDiskCdromDevice( Domain config, String fileName, int index ) throws TransformationException
	{
		final ArrayList<DiskCdrom> devices = config.getDiskCdromDevices();
		final DiskCdrom disk = VirtualizationConfigurationQemuUtils.getArrayIndex( devices, index );

		if ( disk == null ) {
			if ( fileName != null ) {
				// CDROM drive does not exist, so create new CDROM drive
				final BusType devBusType = BusType.SATA;
				final String targetDevName = VirtualizationConfigurationQemuUtils.createDeviceName( config, devBusType );
				final DiskCdrom newDisk = config.addDiskCdromDevice();
				newDisk.setBusType( devBusType );
				newDisk.setTargetDevice( targetDevName );

				this.setDiskCdromStorage( newDisk, fileName );
			}
		} else {
			// CDROM drive exists, so update existing CDROM drive
			this.setDiskCdromStorage( disk, fileName );
		}
	}

	@Override
	public void transform( Domain config, CommandLineArgs args ) throws TransformationException
	{
		// validate configuration and input arguments
		this.validateInputs( config, args );

		// alter CDROM drives
		this.transformDiskCdromDevice( config, args.getVmDiskFileNameCdrom0(), 0 );
		this.transformDiskCdromDevice( config, args.getVmDiskFileNameCdrom1(), 1 );

		// remove all additional disk CDROM devices
		final ArrayList<DiskCdrom> devices = config.getDiskCdromDevices();
		for ( int i = 2; i < devices.size(); i++ ) {
			devices.get( i ).remove();
		}
	}
}