summaryrefslogtreecommitdiffstats
path: root/core/modules/qemu/runvirt-plugin-qemu/src/main/java/org/openslx/runvirt/virtualization/LibvirtHypervisor.java
blob: 757fc7061bef7e6555e1fd2a56f85060827d62d8 (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
198
199
200
201
202
203
204
205
206
207
208
209
package org.openslx.runvirt.virtualization;

import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;

import org.libvirt.Connect;
import org.libvirt.LibvirtException;
import org.openslx.libvirt.capabilities.Capabilities;
import org.openslx.libvirt.xml.LibvirtXmlDocumentException;
import org.openslx.libvirt.xml.LibvirtXmlSerializationException;
import org.openslx.libvirt.xml.LibvirtXmlValidationException;
import org.openslx.virtualization.Version;

/**
 * Representation of a Libvirt hypervisor backend (e.g. QEMU or VMware).
 * <p>
 * The representation allows to connect to a running Libvirt service and query the host system's
 * capabilities or manage virtual machines.
 * 
 * @implNote This class is the abstract representation to implement various Libvirt hypervisor
 *           backends using inheritance.
 * 
 * @author Manuel Bentele
 * @version 1.0
 */
public abstract class LibvirtHypervisor implements Closeable
{
	/**
	 * Connection to a Libvirt hypervisor backend.
	 */
	protected Connect hypervisor = null;

	/**
	 * List of registered machines on the Libvirt hypervisor backend.
	 */
	private List<LibvirtVirtualMachine> machines;

	/**
	 * Creates a new Libvirt hypervisor backend specified by an URI and connects to the specified
	 * backend.
	 * 
	 * @param connectionUri URI of a specific Libvirt hypervisor backend.
	 * @throws LibvirtHypervisorException failed to connect to the specified Libvirt hypervisor
	 *            backend.
	 */
	public LibvirtHypervisor( String connectionUri ) throws LibvirtHypervisorException
	{
		this.connect( connectionUri );
		this.machines = new ArrayList<LibvirtVirtualMachine>();
	}

	/**
	 * Connects to the Libvirt hypervisor backend specified by an URI.
	 * 
	 * @param connectionUri URI of a specific Libvirt hypervisor backend.
	 * @throws LibvirtHypervisorException failed to connect to the specified Libvirt hypervisor
	 *            backend.
	 */
	protected void connect( String connectionUri ) throws LibvirtHypervisorException
	{
		try {
			this.hypervisor = new Connect( connectionUri );
		} catch ( LibvirtException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}
	}

	/**
	 * Returns the URI of the connection to the Libvirt hypervisor backend.
	 * 
	 * @return URI of the connection to the hypervisor.
	 * @throws LibvirtHypervisorException failed to return the connection URI of the Libvirt
	 *            hypervisor backend.
	 */
	public String getConnectionUri() throws LibvirtHypervisorException
	{
		String connectionUri = null;

		try {
			connectionUri = this.hypervisor.getURI();
		} catch ( LibvirtException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}

		return connectionUri;
	}

	/**
	 * Returns the queried Libvirt hypervisor's host system capabilities.
	 * 
	 * @return queried Libvirt hypervisor's host system capabilities.
	 * @throws LibvirtHypervisorException failed to query and return the Libvirt hypervisor's host
	 *            system capabilities.
	 */
	public Capabilities getCapabilites() throws LibvirtHypervisorException
	{
		Capabilities hypervisorCapabilities = null;

		try {
			final String hypervisorCapabilitiesString = this.hypervisor.getCapabilities();
			hypervisorCapabilities = new Capabilities( hypervisorCapabilitiesString );
		} catch ( LibvirtException | LibvirtXmlDocumentException | LibvirtXmlSerializationException
				| LibvirtXmlValidationException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}

		return hypervisorCapabilities;
	}

	/**
	 * Returns the version of the Libvirt hypervisor backend.
	 * 
	 * @return version of the Libvirt hypervisor backend.
	 * @throws LibvirtHypervisorException failed to get the version of the Libvirt hypervisor
	 *            backend.
	 */
	public Version getVersion() throws LibvirtHypervisorException
	{
		long hypervisorVersionRaw = 0;
		Version hypervisorVersion = null;

		try {
			hypervisorVersionRaw = this.hypervisor.getVersion();
		} catch ( LibvirtException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}

		if ( hypervisorVersionRaw > 0 ) {
			final short major = Long.valueOf( hypervisorVersionRaw / Long.valueOf( 1000000 ) ).shortValue();
			hypervisorVersionRaw %= Long.valueOf( 1000000 );
			final short minor = Long.valueOf( hypervisorVersionRaw / Long.valueOf( 1000 ) ).shortValue();
			hypervisorVersion = new Version( major, minor );
		}

		return hypervisorVersion;
	}

	/**
	 * Register a virtual machine by the Libvirt hypervisor based on a virtualization configuration.
	 * 
	 * @param vmConfiguration virtualization configuration for the virtual machine.
	 * @return instance of the registered and defined virtual machine.
	 * @throws LibvirtHypervisorException failed to register and define virtual machine.
	 */
	public LibvirtVirtualMachine registerVm( org.openslx.libvirt.domain.Domain vmConfiguration )
			throws LibvirtHypervisorException
	{
		final String xmlVmConfiguration = vmConfiguration.toString();
		org.libvirt.Domain internalConfiguration = null;

		try {
			internalConfiguration = this.hypervisor.domainDefineXML( xmlVmConfiguration );
		} catch ( LibvirtException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}

		final LibvirtVirtualMachine vm = new LibvirtVirtualMachine( internalConfiguration, vmConfiguration );
		this.machines.add( vm );

		return vm;
	}

	/**
	 * Deregisters an already registered virtual machine by the Libvirt hypervisor.
	 * 
	 * @param vm virtual machine that should be deregistered
	 * @throws LibvirtHypervisorException failed to deregister virtual machine by the Libvirt
	 *            hypervisor.
	 * @throws LibvirtVirtualMachineException failed to check and stop the virtual machine.
	 */
	public void deregisterVm( LibvirtVirtualMachine vm )
			throws LibvirtHypervisorException, LibvirtVirtualMachineException
	{
		// stop virtual machine if machine is running
		if ( vm.isRunning() ) {
			vm.stop();
		}

		// deregister and remove virtual machine from hypervisor
		try {
			vm.getLibvirtDomain().undefine();
		} catch ( LibvirtException e ) {
			throw new LibvirtHypervisorException( e.getLocalizedMessage() );
		}

		this.machines.remove( vm );
	}

	@Override
	public void close()
	{
		// deregister all VMs defined on the hypervisor
		for ( LibvirtVirtualMachine vm : this.machines ) {
			try {
				this.deregisterVm( vm );
			} catch ( LibvirtHypervisorException | LibvirtVirtualMachineException e ) {
				e.printStackTrace();
			}
		}

		// close connection to the hypervisor
		try {
			this.hypervisor.close();
		} catch ( LibvirtException e ) {
			e.printStackTrace();
		}
	}
}