summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java
blob: 36c64fdf637aa7dae211f974e1f624124c741d36 (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
package org.openslx.dozmod.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
import org.openslx.util.vm.VmwareMetaData;

public class VmWrapper {

	private static final Logger LOGGER = Logger.getLogger(VmWrapper.class);

	public static void wrapVm(File diskFile, String imageName, byte[] machineDescription,
			String virtualizerId, int osId) throws MetaDataMissingException, IOException {
		// TODO This is very vmware specific, but should support others too some day
		if (!diskFile.exists())
			throw new FileNotFoundException("Disk file " + diskFile.getAbsolutePath() + " does not exist");
		// Handle machine description to generate *.vmx
		VmwareMetaData vmwareConfig = null;
		if (machineDescription == null) {
			// TODO: Generate fallback vmx
			return;
		} else {
			vmwareConfig = new VmwareMetaData(MetaDataCache.getOperatingSystems(), machineDescription,
					machineDescription.length);
		}
		// Append disk & NAT
		if (!vmwareConfig.addDefaultNat() || !vmwareConfig.addHddTemplate(diskFile.getName())) {
			throw new MetaDataMissingException();
		}
		// The guestOS should be in the vmx, but the user could have changed it by editing
		// the image via the GUI. Those changes are not written back to the stored vmx
		int osMaxMemMb = 0;
		if (virtualizerId != null && osId != 0) {
			OperatingSystem os = MetaDataCache.getOsById(osId);
			if (os != null && os.virtualizerOsId != null) {
				String virtOsId = os.virtualizerOsId.get(virtualizerId);
				if (virtOsId != null) {
					vmwareConfig.setOs(virtOsId);
				}
				if (os.maxMemMb > 0) {
					osMaxMemMb = os.maxMemMb;
				}
			}
		}
		vmwareConfig.addDisplayName(imageName);
		int mem = getMainMemoryMb() / 2;
		if (mem < 1024) {
			mem = 1024;
		}
		if (osMaxMemMb > 0 && mem > osMaxMemMb) {
			mem = osMaxMemMb;
		}
		vmwareConfig.addRam(mem);
		// Output vmx
		File vmxFile = new File(diskFile.getAbsolutePath() + ".vmx");
		vmxFile.delete();
		FileUtils.writeByteArrayToFile(vmxFile, vmwareConfig.getFilteredDefinitionArray());
	}

	/**
	 * Generates a filename based on the given imageName and with the proper
	 * extension depending on the virtualizer
	 * 
	 * @param imageName
	 * @param virtualizerId
	 * @return the generated name as String
	 */
	public static String generateFilename(String imageName, String virtualizerId) {
		String fileName = imageName.replaceAll("[^a-zA-Z0-9_\\.\\-]+", "_");
		if (fileName.length() > 50) {
			fileName = fileName.substring(0, 50);
		}
		if (virtualizerId == null) {
			fileName += ".img";
		} else if ("vmware".equals(virtualizerId)) {
			fileName += ".vmdk";
		} else if ("virtualbox".equals(virtualizerId)) {
			fileName += ".vdi";
		} else {
			fileName += "." + virtualizerId;
		}
		return fileName;
	}

	public static class MetaDataMissingException extends Exception {
		private static final long serialVersionUID = -7842986428831219758L;
	}

	private static int getMainMemoryMb() {
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
		Object attribute;
		try {
			attribute = mBeanServer.getAttribute(new ObjectName("java.lang", "type", "OperatingSystem"),
					"TotalPhysicalMemorySize");
		} catch (AttributeNotFoundException | InstanceNotFoundException | MalformedObjectNameException
				| MBeanException | ReflectionException e) {
			return -1;
		}
		try {
			return (int) (Long.parseLong(attribute.toString()) / (1024 * 1024));
		} catch (Exception e) {
			return -1;
		}
	}

}