/***************************************************************************
* Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
package com.vmware.aurora.vc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.vmware.aurora.util.AuAssert;
import com.vmware.vim.binding.vim.vm.ConfigInfo;
import com.vmware.vim.binding.vim.vm.device.VirtualController;
import com.vmware.vim.binding.vim.vm.device.VirtualDevice;
import com.vmware.vim.binding.vim.vm.device.VirtualDevice.BackingInfo;
import com.vmware.vim.binding.vim.vm.device.VirtualDisk;
import com.vmware.vim.binding.vmodl.ManagedObject;
public interface VcVmBase extends VcObject {
VirtualDevice getVirtualDevice(DeviceId srcDeviceId);
List<DeviceId> getVirtualDiskIds();
void dumpDevices();
VirtualController getVirtualController(DeviceId deviceId);
VirtualDevice getDeviceByLabel(String label);
String getDiskChangeId(DeviceId deviceId);
abstract VcDatacenter getDatacenter();
}
/**
* Abstract class for shared resources and operations
* on a VM or a VM snapshot.
*/
@SuppressWarnings("serial")
abstract class VcVmBaseImpl extends VcObjectImpl implements VcVmBase {
protected VcVmBaseImpl(ManagedObject mo) {
super(mo);
}
abstract protected ConfigInfo getConfig();
public abstract VcDatacenter getDatacenter();
protected VirtualDevice[] getDevice() {
return getConfig().getHardware().getDevice();
}
/**
* Get a list of virtual disks attached to the VM.
*
* @return a list of disk IDs.
*/
@Override
public List<DeviceId> getVirtualDiskIds() {
VirtualDevice[] devices = getDevice();
HashMap<Integer, VirtualController> controllers =
new HashMap<Integer, VirtualController>();
List<DeviceId> diskIds = new ArrayList<DeviceId>();
// Find all valid controllers.
for (VirtualDevice device : devices) {
if (DeviceId.isSupportedController(device)) {
controllers.put(device.getKey(), (VirtualController)device);
}
}
// Find all valid disk devices.
for (VirtualDevice device : devices) {
if (device instanceof VirtualDisk) {
VirtualController controller = controllers.get(device.getControllerKey());
if (controller != null) {
diskIds.add(new DeviceId(controller, device));
}
}
}
return diskIds;
}
@Override
public void dumpDevices() {
for (VirtualDevice dev : getDevice()) {
logger.info(VmConfigUtil.getVirtualDeviceInfo(dev));
}
}
/*
* Lookup a virtual controller device in the VM.
*/
protected static VirtualController
findVirtualController(VirtualDevice[] devices, DeviceId id) {
Class<?> controllerType = id.getTypeClass();
for (VirtualDevice device : devices) {
if (controllerType.isInstance(device) &&
((VirtualController)device).getBusNumber() == id.busNum) {
return (VirtualController)device;
}
}
return null;
}
/*
* Lookup an end-point virtual device in the VM.
*/
protected static VirtualDevice
findVirtualDevice(VirtualDevice[] devices, DeviceId id) {
AuAssert.check(id.unitNum != null);
VirtualDevice controller = findVirtualController(devices, id);
if (controller == null) {
return null;
}
Integer key = controller.getKey();
for (VirtualDevice device : devices) {
if (key.equals(device.getControllerKey()) &&
id.unitNum.equals(device.getUnitNumber())) {
return device;
}
}
return null;
}
/**
* Get an end-point virtual device.
* @param deviceId unique virtual device location id
* @return the end-point virtual disk device
*/
@Override
public VirtualDevice getVirtualDevice(DeviceId deviceId) {
return findVirtualDevice(getDevice(), deviceId);
}
/**
* Get a virtual controller device.
* @param devicdId unique virtual disk or controller location id
* @return the virtual controller device
*/
@Override
public VirtualController getVirtualController(DeviceId deviceId) {
return findVirtualController(getDevice(), deviceId);
}
/**
* Get a virtual device by device label.
* @param label virtual device label
* @return virtual device, null if not found
*/
public VirtualDevice getDeviceByLabel(String label) {
VirtualDevice target = null;
for (VirtualDevice device : getDevice()) {
if (device.getDeviceInfo().getLabel().equalsIgnoreCase(label)) {
target = device;
break;
}
}
return target;
}
/**
* Get the change id for the specified disk. This is useful for Changed Block
* Tracking.
* @param deviceId id for the disk
* @return the disk change id string.
*/
public String getDiskChangeId(DeviceId deviceId) {
VirtualDevice dev = getVirtualDevice(deviceId);
BackingInfo backing = dev.getBacking();
if (backing instanceof VirtualDisk.FlatVer2BackingInfo) {
return ((VirtualDisk.FlatVer2BackingInfo) backing).getChangeId();
} else if (backing instanceof VirtualDisk.SparseVer2BackingInfo) {
return ((VirtualDisk.SparseVer2BackingInfo) backing).getChangeId();
} else if (backing instanceof VirtualDisk.SeSparseBackingInfo) {
return ((VirtualDisk.SeSparseBackingInfo) backing).getChangeId();
} else {
return null;
}
}
}