/*************************************************************************** * 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.composition; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import javax.xml.bind.JAXBException; import com.vmware.aurora.global.DiskSize; import com.vmware.aurora.composition.DiskSchema.Disk; import com.vmware.aurora.util.AuAssert; import com.vmware.aurora.vc.DeviceId; import com.vmware.aurora.vc.DiskType; import com.vmware.aurora.vc.VcCluster; import com.vmware.aurora.vc.VcDatastore; import com.vmware.aurora.vc.VcHost; import com.vmware.aurora.vc.VcResourcePool; import com.vmware.aurora.vc.VcVirtualMachine.DiskCreateSpec; /** * Utility Class for the DiskSchema * * @author sridharr * */ public class DiskSchemaUtil { public static DiskSchema getSchema(String xmlSchema) throws JAXBException { return SchemaUtil.getSchema(xmlSchema, DiskSchema.class); } public static DiskSchema getSchema(File file) throws JAXBException { return SchemaUtil.getSchema(file, DiskSchema.class); } /** * * @param template * @param diskMap */ public static void getTemplateDiskMap(VmSchema vmSchema, HashMap<String, Disk.Operation> diskMap) { for (DiskSchema.Disk disk : vmSchema.diskSchema.getDisks()) { diskMap.put(disk.externalAddress, Disk.Operation.CLONE); } } /** * Get the set of disks to add to the newly cloned Vm (from the DiskSchema * information) * * @param hostList * the list of hosts that have access to the datastores on which * the disks are to be added * @param rp * the resource pool in which the VM is * @param datastore * the default datastore to add the disk to, if not specified in * diskSchema * @param diskSchema * the VM's diskSchema * @return ArrayList of CreateSpec for the new disks to add hostList is * updated */ public static List<DiskCreateSpec> getDisksToAdd(List<VcHost> hostList, VcResourcePool rp, VcDatastore ds, DiskSchema diskSchema, HashMap<String, Disk.Operation> diskMap) { List<DiskCreateSpec> result = new ArrayList<DiskCreateSpec>(); /* XXX : TODO Go through the hierarchy of DiskSchemas to ensure that these * disks are to be added, not modified. However, it appears that changing * disk mode to independent_persistent is not supported in vSphere 5.1. * That means we can no longer mark the OS and BIN disks to independent_persistent * so that they are not snapshoted */ VcCluster cluster = rp.getVcCluster(); HashMap<VcHost, Integer> hostCount = new HashMap<VcHost, Integer>(); int numDisks = 0; for (DiskSchema.Disk disk : diskSchema.getDisks()) { if (disk.vmdkPath != null && !disk.vmdkPath.isEmpty()) { // existed virtual disk, no need to create, need to attach. continue; } if (DiskType.OS.getTypeName().equals(disk.type)) { // system disk is either be cloned or attached, it will never be added. continue; } numDisks++; VcDatastore diskDs = null; if (!disk.datastore.equals("")) { // Find the right datastore from the list of cluster datastores diskDs = cluster.getDatastore(disk.datastore); AuAssert.check(diskDs != null); for (VcHost h : diskDs.getHosts()) { if (hostCount.containsKey(h)) { hostCount.put(h, hostCount.get(h) + 1); } else { hostCount.put(h, 1); } } } if (disk.attributes != null && disk.attributes.contains(DiskSchema.DiskAttribute.PROMOTE)) { diskMap.put(disk.externalAddress, Disk.Operation.PROMOTE); } else { // Make sure we don't already have an existing disk of the same address AuAssert.check(diskMap.get(disk.externalAddress) == null); DiskCreateSpec createSpec = new DiskCreateSpec(new DeviceId(disk.externalAddress), diskDs, disk.name, disk.mode, DiskSize.sizeFromMB(disk.initialSizeMB), disk.allocationType); result.add(createSpec); } } for (Entry<VcHost, Integer> entry : hostCount.entrySet()) { if (entry.getValue().intValue() == numDisks) { hostList.add(entry.getKey()); } } return result; } }