Search in sources :

Example 86 with VmwareContext

use of com.cloud.hypervisor.vmware.util.VmwareContext in project cloudstack by apache.

the class VmwareStorageProcessor method cleanUpDatastore.

/**
 * 1) Possibly expand the datastore.
 * 2) Possibly consolidate all relevant VMDK files into one VMDK file.
 * 3) Possibly move the VMDK file to the root folder (may already be there).
 * 4) If the VMDK file wasn't already in the root folder, then delete the folder the VMDK file was in.
 * 5) Possibly rename the VMDK file (this will lead to there being a delta file with the new name and the
 *    original file with the original name).
 *
 * Note: If the underlying VMDK file was for a root disk, the 'vmdk' parameter's value might look, for example,
 *  like "i-2-32-VM/ROOT-32.vmdk".
 *
 * Note: If the underlying VMDK file was for a data disk, the 'vmdk' parameter's value might look, for example,
 *  like "-iqn.2010-01.com.solidfire:4nhe.data-32.79-0.vmdk".
 *
 * Returns the (potentially new) name of the VMDK file.
 */
private String cleanUpDatastore(Command cmd, HostDatastoreSystemMO hostDatastoreSystem, DatastoreMO dsMo, Map<String, String> details) throws Exception {
    s_logger.debug(String.format("Executing clean up in DataStore: [%s].", dsMo.getName()));
    boolean expandDatastore = Boolean.parseBoolean(details.get(DiskTO.EXPAND_DATASTORE));
    // reserve value in use is set to the minimum for the cloned volume), but that's fine.
    if (expandDatastore) {
        expandDatastore(hostDatastoreSystem, dsMo);
    }
    String vmdk = details.get(DiskTO.VMDK);
    String fullVmdkPath = new DatastoreFile(dsMo.getName(), vmdk).getPath();
    VmwareContext context = hostService.getServiceContext(null);
    VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
    DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
    String vmName = getVmName(vmdk);
    // If vmName is not null, then move all VMDK files out of this folder to the root folder and then delete the folder named vmName.
    if (vmName != null) {
        String workerVmName = hostService.getWorkerName(context, cmd, 0, dsMo);
        VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName, null);
        if (vmMo == null) {
            throw new Exception("Unable to create a worker VM for volume creation");
        }
        vmMo.attachDisk(new String[] { fullVmdkPath }, dsMo.getMor());
        List<String> backingFiles = new ArrayList<>(1);
        List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
        VirtualDisk virtualDisk = virtualDisks.get(0);
        VirtualDeviceBackingInfo virtualDeviceBackingInfo = virtualDisk.getBacking();
        while (virtualDeviceBackingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
            VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo) virtualDeviceBackingInfo;
            backingFiles.add(backingInfo.getFileName());
            virtualDeviceBackingInfo = backingInfo.getParent();
        }
        vmMo.detachAllDisksAndDestroy();
        VmwareStorageLayoutHelper.moveVolumeToRootFolder(dcMo, backingFiles);
        vmdk = new DatastoreFile(vmdk).getFileName();
        // Delete the folder the VMDK file was in.
        DatastoreFile folderToDelete = new DatastoreFile(dsMo.getName(), vmName);
        dsMo.deleteFolder(folderToDelete.getPath(), dcMo.getMor());
    }
    return vmdk;
}
Also used : VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) ArrayList(java.util.ArrayList) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) VirtualDeviceBackingInfo(com.vmware.vim25.VirtualDeviceBackingInfo) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) RemoteException(java.rmi.RemoteException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) VirtualDisk(com.vmware.vim25.VirtualDisk) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VirtualDiskFlatVer2BackingInfo(com.vmware.vim25.VirtualDiskFlatVer2BackingInfo) DatastoreFile(com.cloud.hypervisor.vmware.mo.DatastoreFile) DatacenterMO(com.cloud.hypervisor.vmware.mo.DatacenterMO)

Example 87 with VmwareContext

use of com.cloud.hypervisor.vmware.util.VmwareContext in project cloudstack by apache.

the class VmwareStorageProcessor method copyVolumeFromPrimaryToSecondary.

@Override
public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
    VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO();
    VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO();
    String vmName = srcVolume.getVmName();
    VmwareContext context = hostService.getServiceContext(cmd);
    try {
        DataStoreTO primaryStorage = srcVolume.getDataStore();
        NfsTO destStore = (NfsTO) destVolume.getDataStore();
        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
        Pair<String, String> result;
        result = copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, primaryStorage.getUuid(), srcVolume.getPath(), destVolume.getPath(), destStore.getUrl(), hostService.getWorkerName(context, cmd, 0, null));
        VolumeObjectTO newVolume = new VolumeObjectTO();
        newVolume.setPath(result.first() + File.separator + result.second());
        return new CopyCmdAnswer(newVolume);
    } catch (Throwable e) {
        return new CopyCmdAnswer(hostService.createLogMessageException(e, cmd));
    }
}
Also used : VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) NfsTO(com.cloud.agent.api.to.NfsTO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 88 with VmwareContext

use of com.cloud.hypervisor.vmware.util.VmwareContext in project cloudstack by apache.

the class HypervisorHostHelper method readOVF.

public static List<Pair<String, Boolean>> readOVF(VmwareHypervisorHost host, String ovfFilePath, DatastoreMO dsMo) throws Exception {
    List<Pair<String, Boolean>> ovfVolumeInfos = new ArrayList<Pair<String, Boolean>>();
    List<String> files = new ArrayList<String>();
    ManagedObjectReference morRp = host.getHyperHostOwnerResourcePool();
    assert (morRp != null);
    ManagedObjectReference morHost = host.getMor();
    String importEntityName = UUID.randomUUID().toString();
    OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams();
    importSpecParams.setHostSystem(morHost);
    importSpecParams.setLocale("US");
    importSpecParams.setEntityName(importEntityName);
    importSpecParams.setDeploymentOption("");
    String ovfDescriptor = removeOVFNetwork(HttpNfcLeaseMO.readOvfContent(ovfFilePath));
    VmwareContext context = host.getContext();
    OvfCreateImportSpecResult ovfImportResult = context.getService().createImportSpec(context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, dsMo.getMor(), importSpecParams);
    if (ovfImportResult == null) {
        String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath;
        s_logger.error(msg);
        throw new Exception(msg);
    }
    if (!ovfImportResult.getError().isEmpty()) {
        for (LocalizedMethodFault fault : ovfImportResult.getError()) {
            s_logger.error("createImportSpec error: " + fault.getLocalizedMessage());
        }
        throw new CloudException("Failed to create an import spec from " + ovfFilePath + ". Check log for details.");
    }
    if (!ovfImportResult.getWarning().isEmpty()) {
        for (LocalizedMethodFault fault : ovfImportResult.getError()) {
            s_logger.warn("createImportSpec warning: " + fault.getLocalizedMessage());
        }
    }
    VirtualMachineImportSpec importSpec = (VirtualMachineImportSpec) ovfImportResult.getImportSpec();
    if (importSpec == null) {
        String msg = "createImportSpec() failed to create import specification for OVF template at " + ovfFilePath;
        s_logger.error(msg);
        throw new Exception(msg);
    }
    File ovfFile = new File(ovfFilePath);
    for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) {
        String absFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath();
        files.add(absFile);
    }
    int osDiskSeqNumber = 0;
    VirtualMachineConfigSpec config = importSpec.getConfigSpec();
    String paramVal = getOVFParamValue(config);
    if (paramVal != null && !paramVal.isEmpty()) {
        try {
            osDiskSeqNumber = getOsDiskFromOvfConf(config, paramVal);
        } catch (Exception e) {
            osDiskSeqNumber = 0;
        }
    }
    int diskCount = 0;
    int deviceCount = 0;
    List<VirtualDeviceConfigSpec> deviceConfigList = config.getDeviceChange();
    for (VirtualDeviceConfigSpec deviceSpec : deviceConfigList) {
        Boolean osDisk = false;
        VirtualDevice device = deviceSpec.getDevice();
        if (device instanceof VirtualDisk) {
            if ((osDiskSeqNumber == 0 && diskCount == 0) || osDiskSeqNumber == deviceCount) {
                osDisk = true;
            }
            Pair<String, Boolean> ovfVolumeInfo = new Pair<String, Boolean>(files.get(diskCount), osDisk);
            ovfVolumeInfos.add(ovfVolumeInfo);
            diskCount++;
        }
        deviceCount++;
    }
    return ovfVolumeInfos;
}
Also used : OvfFileItem(com.vmware.vim25.OvfFileItem) LocalizedMethodFault(com.vmware.vim25.LocalizedMethodFault) VirtualDeviceConfigSpec(com.vmware.vim25.VirtualDeviceConfigSpec) ArrayList(java.util.ArrayList) VirtualDevice(com.vmware.vim25.VirtualDevice) OvfCreateImportSpecResult(com.vmware.vim25.OvfCreateImportSpecResult) CloudException(com.cloud.exception.CloudException) InvalidParameterException(java.security.InvalidParameterException) CloudException(com.cloud.exception.CloudException) TransformerException(javax.xml.transform.TransformerException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) SAXException(org.xml.sax.SAXException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) VirtualDisk(com.vmware.vim25.VirtualDisk) OvfCreateImportSpecParams(com.vmware.vim25.OvfCreateImportSpecParams) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VirtualMachineConfigSpec(com.vmware.vim25.VirtualMachineConfigSpec) VirtualMachineImportSpec(com.vmware.vim25.VirtualMachineImportSpec) OvfFile(com.vmware.vim25.OvfFile) File(java.io.File) Pair(com.cloud.utils.Pair) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 89 with VmwareContext

use of com.cloud.hypervisor.vmware.util.VmwareContext in project cloudstack by apache.

the class HypervisorHostHelper method prepareNetwork.

/**
 * Prepares network (for non-standard virtual switch) for the VM NIC based on the parameters.
 * Can create a new portgroup or update an existing.
 * @return Pair of network's ManagedObjectReference and name
 * @throws Exception
 */
public static Pair<ManagedObjectReference, String> prepareNetwork(String physicalNetwork, String namePrefix, HostMO hostMo, String vlanId, String secondaryvlanId, Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, VirtualSwitchType vSwitchType, int numPorts, String gateway, boolean configureVServiceInNexus, BroadcastDomainType broadcastDomainType, Map<String, String> vsmCredentials, Map<NetworkOffering.Detail, String> details) throws Exception {
    ManagedObjectReference morNetwork = null;
    VmwareContext context = hostMo.getContext();
    ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter();
    DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
    DistributedVirtualSwitchMO dvSwitchMo = null;
    ManagedObjectReference morEthernetPortProfile = null;
    String ethPortProfileName = null;
    ManagedObjectReference morDvSwitch = null;
    String dvSwitchName = null;
    boolean bWaitPortGroupReady = false;
    boolean createGCTag = false;
    String vcApiVersion;
    String minVcApiVersionSupportingAutoExpand;
    boolean autoExpandSupported;
    String networkName;
    Integer vid = null;
    // secondary pvlan id
    Integer spvlanid = null;
    /**
     * This is the list of BroadcastDomainTypes we can actually
     * prepare networks for in this function.
     */
    BroadcastDomainType[] supportedBroadcastTypes = new BroadcastDomainType[] { BroadcastDomainType.Lswitch, BroadcastDomainType.LinkLocal, BroadcastDomainType.Native, BroadcastDomainType.Pvlan, BroadcastDomainType.Storage, BroadcastDomainType.UnDecided, BroadcastDomainType.Vlan };
    if (!Arrays.asList(supportedBroadcastTypes).contains(broadcastDomainType)) {
        throw new InvalidParameterException("BroadcastDomainType " + broadcastDomainType + " it not supported on a VMWare hypervisor at this time.");
    }
    if (broadcastDomainType == BroadcastDomainType.Lswitch) {
        if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
            throw new InvalidParameterException("Nexus Distributed Virtualswitch is not supported with BroadcastDomainType " + broadcastDomainType);
        }
        /**
         * Nicira NVP requires all vms to be connected to a single port-group.
         * A unique vlan needs to be set per port. This vlan is specific to
         * this implementation and has no reference to other vlans in CS
         */
        // FIXME Should be set via a configuration item in CS
        networkName = "br-int";
        // No doubt about this, depending on vid=null to avoid lots of code below
        vid = null;
    } else {
        if (vlanId != null) {
            vlanId = vlanId.replace("vlan://", "");
        }
        networkName = composeCloudNetworkName(namePrefix, vlanId, secondaryvlanId, networkRateMbps, physicalNetwork);
        if (vlanId != null && !UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId) && !StringUtils.containsAny(vlanId, ",-")) {
            createGCTag = true;
            vid = Integer.parseInt(vlanId);
        }
        if (vlanId != null && StringUtils.containsAny(vlanId, ",-")) {
            createGCTag = true;
        }
        if (secondaryvlanId != null) {
            spvlanid = Integer.parseInt(secondaryvlanId);
        }
    }
    if (vSwitchType == VirtualSwitchType.VMwareDistributedVirtualSwitch) {
        vcApiVersion = getVcenterApiVersion(context);
        minVcApiVersionSupportingAutoExpand = "5.0";
        autoExpandSupported = isFeatureSupportedInVcenterApiVersion(vcApiVersion, minVcApiVersionSupportingAutoExpand);
        dvSwitchName = physicalNetwork;
        // and switch types.
        if (dvSwitchName == null) {
            s_logger.warn("Detected null dvSwitch. Defaulting to dvSwitch0");
            dvSwitchName = "dvSwitch0";
        }
        morDvSwitch = dataCenterMo.getDvSwitchMor(dvSwitchName);
        if (morDvSwitch == null) {
            String msg = "Unable to find distributed vSwitch " + dvSwitchName;
            s_logger.error(msg);
            throw new Exception(msg);
        }
        dvSwitchMo = new DistributedVirtualSwitchMO(context, morDvSwitch);
        String dvSwitchVersion = dvSwitchMo.getDVSProductVersion(morDvSwitch);
        s_logger.debug(String.format("Found distributed vSwitch: %s with product version: %s", dvSwitchName, dvSwitchVersion));
        if (broadcastDomainType == BroadcastDomainType.Lswitch) {
            if (!dataCenterMo.hasDvPortGroup(networkName)) {
                throw new InvalidParameterException("NVP integration port-group " + networkName + " does not exist on the DVS " + dvSwitchName);
            }
            bWaitPortGroupReady = false;
        } else {
            boolean dvSwitchSupportNewPolicies = (isFeatureSupportedInVcenterApiVersion(vcApiVersion, MINIMUM_VCENTER_API_VERSION_WITH_DVS_NEW_POLICIES_SUPPORT) && isVersionEqualOrHigher(dvSwitchVersion, MINIMUM_DVS_VERSION_WITH_NEW_POLICIES_SUPPORT));
            DVSTrafficShapingPolicy shapingPolicy = getDVSShapingPolicy(networkRateMbps);
            DVSSecurityPolicy secPolicy = createDVSSecurityPolicy(details);
            DVSMacManagementPolicy macManagementPolicy = createDVSMacManagementPolicy(details);
            // First, if both vlan id and pvlan id are provided, we need to
            // reconfigure the DVSwitch to have a tuple <vlan id, pvlan id> of
            // type isolated.
            String pvlanType = MapUtils.isNotEmpty(details) ? details.get(NetworkOffering.Detail.pvlanType) : null;
            if (vid != null && spvlanid != null) {
                setupPVlanPair(dvSwitchMo, morDvSwitch, vid, spvlanid, pvlanType);
            }
            VMwareDVSPortgroupPolicy portGroupPolicy = null;
            // Next, create the port group. For this, we need to create a VLAN spec.
            createPortGroup(physicalNetwork, networkName, vlanId, vid, spvlanid, dataCenterMo, shapingPolicy, secPolicy, macManagementPolicy, portGroupPolicy, dvSwitchMo, numPorts, autoExpandSupported, dvSwitchSupportNewPolicies);
            bWaitPortGroupReady = true;
        }
    } else if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) {
        ethPortProfileName = physicalNetwork;
        // and switch types.
        if (ethPortProfileName == null) {
            s_logger.warn("Detected null ethrenet port profile. Defaulting to epp0.");
            ethPortProfileName = "epp0";
        }
        morEthernetPortProfile = dataCenterMo.getDvPortGroupMor(ethPortProfileName);
        if (morEthernetPortProfile == null) {
            String msg = "Unable to find Ethernet port profile " + ethPortProfileName;
            s_logger.error(msg);
            throw new Exception(msg);
        } else {
            s_logger.info("Found Ethernet port profile " + ethPortProfileName);
        }
        long averageBandwidth = 0L;
        if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
            averageBandwidth = networkRateMbps.intValue() * 1024L * 1024L;
        }
        // We chose 50% higher allocation than average bandwidth.
        // TODO(sateesh): Optionally let user specify the peak coefficient
        long peakBandwidth = (long) (averageBandwidth * 1.5);
        // TODO(sateesh): Optionally let user specify the burst coefficient
        long burstSize = 5 * averageBandwidth / 8;
        if (vsmCredentials != null) {
            s_logger.info("Stocking credentials of Nexus VSM");
            context.registerStockObject("vsmcredentials", vsmCredentials);
        }
        if (!dataCenterMo.hasDvPortGroup(networkName)) {
            s_logger.info("Port profile " + networkName + " not found.");
            createPortProfile(context, physicalNetwork, networkName, vid, networkRateMbps, peakBandwidth, burstSize, gateway, configureVServiceInNexus);
            bWaitPortGroupReady = true;
        } else {
            s_logger.info("Port profile " + networkName + " found.");
            updatePortProfile(context, physicalNetwork, networkName, vid, networkRateMbps, peakBandwidth, burstSize);
        }
    }
    // Wait for dvPortGroup on vCenter
    if (bWaitPortGroupReady)
        morNetwork = waitForDvPortGroupReady(dataCenterMo, networkName, timeOutMs);
    else
        morNetwork = dataCenterMo.getDvPortGroupMor(networkName);
    if (morNetwork == null) {
        String msg = "Failed to create guest network " + networkName;
        s_logger.error(msg);
        throw new Exception(msg);
    }
    if (createGCTag) {
        NetworkMO networkMo = new NetworkMO(hostMo.getContext(), morNetwork);
        networkMo.setCustomFieldValue(CustomFieldConstants.CLOUD_GC_DVP, "true");
        s_logger.debug("Added custom field : " + CustomFieldConstants.CLOUD_GC_DVP);
    }
    return new Pair<ManagedObjectReference, String>(morNetwork, networkName);
}
Also used : VMwareDVSPortgroupPolicy(com.vmware.vim25.VMwareDVSPortgroupPolicy) DVSTrafficShapingPolicy(com.vmware.vim25.DVSTrafficShapingPolicy) InvalidParameterException(java.security.InvalidParameterException) CloudException(com.cloud.exception.CloudException) TransformerException(javax.xml.transform.TransformerException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) SAXException(org.xml.sax.SAXException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) DVSMacManagementPolicy(com.vmware.vim25.DVSMacManagementPolicy) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) InvalidParameterException(java.security.InvalidParameterException) BroadcastDomainType(com.cloud.network.Networks.BroadcastDomainType) DVSSecurityPolicy(com.vmware.vim25.DVSSecurityPolicy) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference) Pair(com.cloud.utils.Pair)

Example 90 with VmwareContext

use of com.cloud.hypervisor.vmware.util.VmwareContext in project cloudstack by apache.

the class HypervisorHostHelper method importVmFromOVF.

/**
 * deploys a new VM from a ovf spec. It ignores network, defaults locale to 'US'
 * @throws Exception shoud be a VmwareResourceException
 */
public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, ManagedObjectReference morRp, ManagedObjectReference morHost, String configurationId) throws CloudRuntimeException, IOException {
    assert (morRp != null);
    OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams();
    importSpecParams.setHostSystem(morHost);
    importSpecParams.setLocale("US");
    importSpecParams.setEntityName(vmName);
    String deploymentOption = StringUtils.isNotBlank(configurationId) ? configurationId : "";
    importSpecParams.setDeploymentOption(deploymentOption);
    // diskOption: thin, thick, etc
    importSpecParams.setDiskProvisioning(diskOption);
    String ovfDescriptor = removeOVFNetwork(HttpNfcLeaseMO.readOvfContent(ovfFilePath));
    VmwareContext context = host.getContext();
    OvfCreateImportSpecResult ovfImportResult = null;
    try {
        ovfImportResult = context.getService().createImportSpec(context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, dsMo.getMor(), importSpecParams);
    } catch (ConcurrentAccessFaultMsg | FileFaultFaultMsg | InvalidDatastoreFaultMsg | InvalidStateFaultMsg | RuntimeFaultFaultMsg | TaskInProgressFaultMsg | VmConfigFaultFaultMsg error) {
        throw new CloudRuntimeException("ImportSpec creation failed", error);
    }
    if (ovfImportResult == null) {
        String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + vmName + ", diskOption: " + diskOption;
        s_logger.error(msg);
        throw new CloudRuntimeException(msg);
    }
    if (!ovfImportResult.getError().isEmpty()) {
        for (LocalizedMethodFault fault : ovfImportResult.getError()) {
            s_logger.error("createImportSpec error: " + fault.getLocalizedMessage());
        }
        throw new CloudRuntimeException("Failed to create an import spec from " + ovfFilePath + ". Check log for details.");
    }
    if (!ovfImportResult.getWarning().isEmpty()) {
        for (LocalizedMethodFault fault : ovfImportResult.getError()) {
            s_logger.warn("createImportSpec warning: " + fault.getLocalizedMessage());
        }
    }
    DatacenterMO dcMo = null;
    try {
        dcMo = new DatacenterMO(context, host.getHyperHostDatacenter());
    } catch (Exception e) {
        throw new CloudRuntimeException(String.format("no datacenter for host '%s' available in context", context.getServerAddress()), e);
    }
    ManagedObjectReference folderMO = null;
    try {
        folderMO = dcMo.getVmFolder();
    } catch (Exception e) {
        throw new CloudRuntimeException("no management handle for VmFolder", e);
    }
    ManagedObjectReference morLease = null;
    try {
        morLease = context.getService().importVApp(morRp, ovfImportResult.getImportSpec(), folderMO, morHost);
    } catch (DuplicateNameFaultMsg | FileFaultFaultMsg | InsufficientResourcesFaultFaultMsg | InvalidDatastoreFaultMsg | InvalidNameFaultMsg | OutOfBoundsFaultMsg | RuntimeFaultFaultMsg | VmConfigFaultFaultMsg fault) {
        throw new CloudRuntimeException("import vApp failed", fault);
    }
    if (morLease == null) {
        String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + vmName + ", diskOption: " + diskOption;
        s_logger.error(msg);
        throw new CloudRuntimeException(msg);
    }
    boolean importSuccess = true;
    final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease);
    HttpNfcLeaseState state = null;
    try {
        state = leaseMo.waitState(new HttpNfcLeaseState[] { HttpNfcLeaseState.READY, HttpNfcLeaseState.ERROR });
    } catch (Exception e) {
        throw new CloudRuntimeException("exception while waiting for leaseMO", e);
    }
    try {
        if (state == HttpNfcLeaseState.READY) {
            final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult);
            File ovfFile = new File(ovfFilePath);
            HttpNfcLeaseInfo httpNfcLeaseInfo = null;
            try {
                httpNfcLeaseInfo = leaseMo.getLeaseInfo();
            } catch (Exception e) {
                throw new CloudRuntimeException("error waiting for lease info", e);
            }
            List<HttpNfcLeaseDeviceUrl> deviceUrls = httpNfcLeaseInfo.getDeviceUrl();
            long bytesAlreadyWritten = 0;
            final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter();
            try {
                for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) {
                    String deviceKey = deviceUrl.getImportKey();
                    for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) {
                        if (deviceKey.equals(ovfFileItem.getDeviceId())) {
                            String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath();
                            s_logger.info("Uploading file: " + absoluteFile);
                            File f = new File(absoluteFile);
                            if (f.exists()) {
                                String urlToPost = deviceUrl.getUrl();
                                urlToPost = resolveHostNameInUrl(dcMo, urlToPost);
                                context.uploadVmdkFile(ovfFileItem.isCreate() ? "PUT" : "POST", urlToPost, absoluteFile, bytesAlreadyWritten, new ActionDelegate<Long>() {

                                    @Override
                                    public void action(Long param) {
                                        progressReporter.reportProgress((int) (param * 100 / totalBytes));
                                    }
                                });
                                bytesAlreadyWritten += ovfFileItem.getSize();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                String erroMsg = "File upload task failed to complete due to: " + e.getMessage();
                s_logger.error(erroMsg);
                // Set flag to cleanup the stale template left due to failed import operation, if any
                importSuccess = false;
                throw new CloudRuntimeException(erroMsg, e);
            } catch (Throwable th) {
                String errorMsg = "throwable caught during file upload task: " + th.getMessage();
                s_logger.error(errorMsg);
                // Set flag to cleanup the stale template left due to failed import operation, if any
                importSuccess = false;
                throw new CloudRuntimeException(errorMsg, th);
            } finally {
                progressReporter.close();
            }
            if (bytesAlreadyWritten == totalBytes) {
                try {
                    leaseMo.updateLeaseProgress(100);
                } catch (Exception e) {
                    throw new CloudRuntimeException("error while waiting for lease update", e);
                }
            }
        } else if (state == HttpNfcLeaseState.ERROR) {
            LocalizedMethodFault error = null;
            try {
                error = leaseMo.getLeaseError();
            } catch (Exception e) {
                throw new CloudRuntimeException("error getting lease error", e);
            }
            MethodFault fault = error.getFault();
            String erroMsg = "Object creation on vCenter failed due to: Exception: " + fault.getClass().getName() + ", message: " + error.getLocalizedMessage();
            s_logger.error(erroMsg);
            throw new CloudRuntimeException(erroMsg);
        }
    } finally {
        try {
            if (!importSuccess) {
                s_logger.error("Aborting the lease on " + vmName + " after import operation failed.");
                leaseMo.abortLease();
            } else {
                leaseMo.completeLease();
            }
        } catch (Exception e) {
            throw new CloudRuntimeException("error completing lease", e);
        }
    }
}
Also used : OvfCreateImportSpecResult(com.vmware.vim25.OvfCreateImportSpecResult) RuntimeFaultFaultMsg(com.vmware.vim25.RuntimeFaultFaultMsg) InsufficientResourcesFaultFaultMsg(com.vmware.vim25.InsufficientResourcesFaultFaultMsg) ConcurrentAccessFaultMsg(com.vmware.vim25.ConcurrentAccessFaultMsg) InvalidDatastoreFaultMsg(com.vmware.vim25.InvalidDatastoreFaultMsg) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) FileFaultFaultMsg(com.vmware.vim25.FileFaultFaultMsg) InvalidNameFaultMsg(com.vmware.vim25.InvalidNameFaultMsg) HttpNfcLeaseDeviceUrl(com.vmware.vim25.HttpNfcLeaseDeviceUrl) OvfFileItem(com.vmware.vim25.OvfFileItem) MethodFault(com.vmware.vim25.MethodFault) LocalizedMethodFault(com.vmware.vim25.LocalizedMethodFault) LocalizedMethodFault(com.vmware.vim25.LocalizedMethodFault) TaskInProgressFaultMsg(com.vmware.vim25.TaskInProgressFaultMsg) InvalidParameterException(java.security.InvalidParameterException) CloudException(com.cloud.exception.CloudException) TransformerException(javax.xml.transform.TransformerException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) SAXException(org.xml.sax.SAXException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) OvfCreateImportSpecParams(com.vmware.vim25.OvfCreateImportSpecParams) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) InvalidStateFaultMsg(com.vmware.vim25.InvalidStateFaultMsg) VmConfigFaultFaultMsg(com.vmware.vim25.VmConfigFaultFaultMsg) DuplicateNameFaultMsg(com.vmware.vim25.DuplicateNameFaultMsg) HttpNfcLeaseInfo(com.vmware.vim25.HttpNfcLeaseInfo) OvfFile(com.vmware.vim25.OvfFile) File(java.io.File) OutOfBoundsFaultMsg(com.vmware.vim25.OutOfBoundsFaultMsg) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference) HttpNfcLeaseState(com.vmware.vim25.HttpNfcLeaseState)

Aggregations

VmwareContext (com.cloud.hypervisor.vmware.util.VmwareContext)106 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)66 VmwareHypervisorHost (com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost)65 RemoteException (java.rmi.RemoteException)53 ManagedObjectReference (com.vmware.vim25.ManagedObjectReference)49 UnsupportedEncodingException (java.io.UnsupportedEncodingException)48 VirtualMachineMO (com.cloud.hypervisor.vmware.mo.VirtualMachineMO)39 IOException (java.io.IOException)38 CloudException (com.cloud.exception.CloudException)36 ConfigurationException (javax.naming.ConfigurationException)34 InternalErrorException (com.cloud.exception.InternalErrorException)31 ConnectException (java.net.ConnectException)31 DatastoreMO (com.cloud.hypervisor.vmware.mo.DatastoreMO)26 HostMO (com.cloud.hypervisor.vmware.mo.HostMO)23 DatacenterMO (com.cloud.hypervisor.vmware.mo.DatacenterMO)21 Pair (com.cloud.utils.Pair)20 ClusterMO (com.cloud.hypervisor.vmware.mo.ClusterMO)15 VmwareManager (com.cloud.hypervisor.vmware.manager.VmwareManager)14 DataStoreTO (com.cloud.agent.api.to.DataStoreTO)13 PrimaryDataStoreTO (org.apache.cloudstack.storage.to.PrimaryDataStoreTO)13