summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/virtualization/configuration/logic/ConfigurationLogicDozModServerToDozModClient.java
blob: acbf4fc0037afc9bed8e4b965b222b5179156b77 (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package org.openslx.virtualization.configuration.logic;

import java.util.Map;

import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.virtualization.configuration.VirtualizationConfiguration;
import org.openslx.virtualization.configuration.VirtualizationConfigurationException;
import org.openslx.virtualization.configuration.data.ConfigurationDataDozModServerToDozModClient;
import org.openslx.virtualization.configuration.transformation.TransformationException;

/**
 * Transformation logic for virtualization configurations between a dozmod-server and a
 * dozmod-client.
 * <p>
 * This transformation logic is applied while downloading an existing virtualization configuration
 * from a dozmod-server to a dozmod-client.
 * 
 * <pre>
 *   +------------------------------+  DozModServerToDozModClient   +------------------------------+
 *   | virtualization configuration | ----------------------------▶ | virtualization configuration |
 *   +---------------+--------------+     transformation logic      +---------------+--------------+
 *   | dozmod-server |                                              | dozmod-client |
 *   +---------------+                                              +---------------+
 * </pre>
 * 
 * @author Manuel Bentele
 * @version 1.0
 */
public class ConfigurationLogicDozModServerToDozModClient
		extends ConfigurationLogic<ConfigurationDataDozModServerToDozModClient>
{
	/**
	 * Name of the transformation logic for virtualization configurations.
	 */
	private static final String CONFIGURATION_LOGIC_NAME = "Transformation of virtualization configuration during download from DozMod server to DozMod client";

	/**
	 * Default number of CPU cores set by the configuration logic for the virtualization
	 * configuration's virtualizer.
	 */
	private static final int CONFIGURATION_LOGIC_NUM_CPU_CORES = 1;

	/**
	 * Default memory in megabytes set by the configuration logic for the virtualization
	 * configuration's virtualizer.
	 */
	private static final int CONFIGURATION_LOGIC_MEMORY_MIN = 1024;

	/**
	 * Creates a new transformation logic for virtualization configurations between a dozmod-server
	 * and a dozmod-client.
	 */
	public ConfigurationLogicDozModServerToDozModClient()
	{
		super( ConfigurationLogicDozModServerToDozModClient.CONFIGURATION_LOGIC_NAME );
	}

	/**
	 * Validates a virtualization configuration and input arguments for a transformation.
	 * 
	 * @param config virtualization configuration for the validation.
	 * @param args input arguments for the validation.
	 * @throws TransformationException validation has failed.
	 */
	private void validateInputs( VirtualizationConfiguration config,
			ConfigurationDataDozModServerToDozModClient args )
			throws TransformationException
	{
		if ( config == null || args == null ) {
			throw new TransformationException( "Virtualization configuration or input arguments are missing!" );
		} else if ( args.getDisplayName() == null || args.getDisplayName().isEmpty() ) {
			throw new TransformationException( "Valid display name is not specified!" );
		} else if ( args.getDiskImage() == null || !args.getDiskImage().exists() ) {
			throw new TransformationException( "Valid disk image file is not specified!" );
		} else if ( ! ( args.getTotalMemory() > 0 ) ) {
			throw new TransformationException( "Total memory amount is not specified!" );
		}
	}

	/**
	 * Rounds a given value to the nearest factor.
	 * 
	 * @param value input value for the rounding.
	 * @param nearestFactor nearest factor for the rounding.
	 * @return rounded value as a multiple of the nearest factor.
	 * 
	 * @apiNote This utility method rounds the given value to an integer value and no to a floating
	 *          point value.
	 */
	private static int roundToNearest( int value, int nearestFactor )
	{
		return ( value / nearestFactor ) * nearestFactor;
	}

	/**
	 * Calculates the amount of memory for the virtualization configuration depending on the
	 * available resources of the dozmod-client's host system.
	 * 
	 * @param totalMemory maximum memory available on the dozmod-client's host system.
	 * @param osMaxMemory maximum memory supported by the defined operating system in the
	 *           virtualization configuration.
	 * @return amount of memory for the virtualization configuration in megabytes
	 */
	private static int calculateVirtualizationMemoryOnDozmodClient( int totalMemory, int osMaxMemory )
	{
		// calculate the amount of memory
		int memory = totalMemory / 2 - 512;

		// increase calculated memory if lower memory limit is undercut
		if ( memory < ConfigurationLogicDozModServerToDozModClient.CONFIGURATION_LOGIC_MEMORY_MIN ) {
			memory = ConfigurationLogicDozModServerToDozModClient.CONFIGURATION_LOGIC_MEMORY_MIN;
		}

		// limit virtualization memory if the available host's system memory amount is smaller
		if ( osMaxMemory > 0 && memory > osMaxMemory ) {
			memory = osMaxMemory;
		}

		// round to nearest factor of 4, otherwise VMware virtualization configuration files are invalid
		return ConfigurationLogicDozModServerToDozModClient.roundToNearest( memory, 4 );
	}

	@Override
	public void transform( VirtualizationConfiguration config,
			ConfigurationDataDozModServerToDozModClient args )
			throws TransformationException
	{
		// check if input parameters for a transformation are valid 
		this.validateInputs( config, args );

		// set display name
		if ( !config.addDisplayName( args.getDisplayName() ) ) {
			throw new TransformationException( "Can not set display name in virtualization configuration!" );
		}

		// append hard disk drive
		if ( !config.addHddTemplate( args.getDiskImage(), null, null ) ) {
			throw new TransformationException( "Can not configure hard disk in virtualization configuration!" );
		}

		// append default NAT interface
		if ( !config.addDefaultNat() ) {
			throw new TransformationException( "Can not configure NAT interface in virtualization configuration!" );
		}

		// set the guest OS if specified
		final OperatingSystem guestOs = args.getGuestOs();
		final String virtualizerId = args.getVirtualizerId();
		int osMaxMemory = 0;

		if ( guestOs != null && virtualizerId != null ) {
			final Map<String, String> virtOsIdMap = guestOs.getVirtualizerOsId();
			if ( virtOsIdMap != null ) {
				// set guest operating system if possible
				final String virtOsId = virtOsIdMap.get( virtualizerId );
				if ( virtOsId != null ) {
					config.setOs( virtOsId );
				}

				// get maximum memory of editable host for guestOs if possible
				final int maxMemMb = guestOs.getMaxMemMb();
				if ( maxMemMb > 0 ) {
					osMaxMemory = maxMemMb;
				}
			}
		}

		// set CPU core count
		if ( !config.addCpuCoreCount( ConfigurationLogicDozModServerToDozModClient.CONFIGURATION_LOGIC_NUM_CPU_CORES ) ) {
			throw new TransformationException( "Can not set CPU core count in virtualization configuration!" );
		}

		// calculate and set memory
		final int virtualizationMemory = ConfigurationLogicDozModServerToDozModClient
				.calculateVirtualizationMemoryOnDozmodClient( args.getTotalMemory(), osMaxMemory );
		if ( !config.addRam( virtualizationMemory ) ) {
			throw new TransformationException( "Can not set memory in virtualization configuration!" );
		}

		// append first empty floppy drive
		config.addFloppy( 0, null, true );
		// append second empty floppy drive
		config.addFloppy( 1, null, true );

		// append first empty (ISO-based) CDROM drive
		config.addCdrom( "" );
		// append second CDROM drive connected to the host's physical drive
		config.addCdrom( null );

		// apply settings to edit virtualized system locally
		try {
			config.transformEditable();
		} catch ( VirtualizationConfigurationException e ) {
			throw new TransformationException( e.getLocalizedMessage() );
		}
	}
}