public Task cloneAndStartVm()

in cloud-vmware-server/src/main/java/jetbrains/buildServer/clouds/vmware/connector/VMWareApiConnectorImpl.java [782:890]


  public Task cloneAndStartVm(@NotNull final VmwareCloudInstance instance) throws VmwareCheckedCloudException {
    final VmwareCloudImageDetails imageDetails = instance.getImage().getImageDetails();
    LOG.info(String.format("Attempting to clone VM %s into %s", imageDetails.getSourceVmName(), instance.getName()));

    final Pair<VirtualMachine, Datacenter> pair = findEntityByIdNameOld(imageDetails.getSourceVmName(), VirtualMachine.class);
    final VirtualMachine vm = pair.getFirst();
    final Datacenter datacenter = pair.getSecond();

    final VirtualMachineConfigSpec config = new VirtualMachineConfigSpec();
    final VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
    final VirtualMachineRelocateSpec location = new VirtualMachineRelocateSpec();

    cloneSpec.setPowerOn(true);
    cloneSpec.setLocation(location);
    cloneSpec.setConfig(config);
    final boolean disableOsCustomization = TeamCityProperties.getBoolean(VmwareConstants.DISABLE_OS_CUSTOMIZATION);
    if (!VmwareConstants.DEFAULT_RESOURCE_POOL.equals(imageDetails.getResourcePoolId())) {
      final ResourcePool pool = findEntityByIdNameNullableOld(imageDetails.getResourcePoolId(), ResourcePool.class, datacenter);
      if (pool != null) {
          location.setPool(pool.getMOR());
      } else {
        LOG.warn(String.format("Unable to find resource pool %s at datacenter %s. Will clone at the image resource pool instead"
          , imageDetails.getResourcePoolId()
          , datacenter == null? "<not provided>":  datacenter.getName()));
      }
    }
    final Map<String, VirtualMachineSnapshotTree> snapshotList = getSnapshotList(vm);
    final VmwareSourceState sourceState = instance.getSourceState();
    if (imageDetails.useCurrentVersion() || StringUtil.isEmptyOrSpaces(sourceState.getSnapshotName())) {
      LOG.info("Snapshot name is not specified. Will clone latest VM state");
    } else {
      final VirtualMachineSnapshotTree obj = snapshotList.get(sourceState.getSnapshotName());
      final ManagedObjectReference snapshot = obj == null ? null : obj.getSnapshot();
      cloneSpec.setSnapshot(snapshot);
      if (snapshot != null) {
        if (TeamCityProperties.getBooleanOrTrue(VmwareConstants.USE_LINKED_CLONE)) {
          LOG.info("Using linked clone. Snapshot name: " + sourceState.getSnapshotName());
          location.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.createNewChildDiskBacking.name());
        } else {
          LOG.info("Using full clone. Snapshot name: " + sourceState.getSnapshotName());
        }
      } else {
        final String errorText = "Unable to find snapshot " + sourceState.getSnapshotName();
        throw new VmwareCheckedCloudException(errorText);
      }
    }

    final VirtualMachineConfigInfo vmConfig = vm.getConfig();
    config.setExtraConfig(new OptionValue[]{
      createOptionValue(TEAMCITY_VMWARE_CLONED_INSTANCE, "true"),
      createOptionValue(TEAMCITY_VMWARE_IMAGE_SOURCE_VM_NAME, imageDetails.getSourceVmName()),
      createOptionValue(TEAMCITY_VMWARE_IMAGE_SOURCE_ID, imageDetails.getSourceId()),
      createOptionValue(TEAMCITY_VMWARE_IMAGE_SOURCE_VM_ID, vm.getMOR().getVal()),
      createOptionValue(TEAMCITY_VMWARE_IMAGE_SNAPSHOT, sourceState.getSnapshotName()),
      createOptionValue(TEAMCITY_VMWARE_IMAGE_CHANGE_VERSION, vmConfig.getChangeVersion()),
      createOptionValue(TEAMCITY_VMWARE_PROFILE_ID, StringUtil.emptyIfNull(myProfileId)),
      createOptionValue(TEAMCITY_VMWARE_SERVER_UUID, StringUtil.emptyIfNull(myServerUUID))
    });

    final GuestInfo guest = vm.getGuest();
    String guestFamily = guest != null ? guest.getGuestFamily() : null;
    if (guestFamily == null){
      final String guestFullName = vmConfig.getGuestFullName();
      if (guestFullName != null && guestFullName.contains("Linux")){
        guestFamily = LINUX_GUEST_FAMILY;
      }
    }

    if (StringUtil.isNotEmpty(imageDetails.getCustomizationSpec())){
      LOG.info(String.format("Will use Customization Spec '%s' to clone %s into %s"
        , imageDetails.getCustomizationSpec(), imageDetails.getSourceVmName(), instance.getName()));
      cloneSpec.setCustomization(getCustomizationSpec(imageDetails.getCustomizationSpec()));
    } else if (!disableOsCustomization && myDomain != null && LINUX_GUEST_FAMILY.equals(guestFamily)){
      LOG.info("Will use basic Linux customization (will customize hostname)");
      // TODO: remove later, after all profiles are updated to use customization spec
      final CustomizationSpec customization = new CustomizationSpec();
      final CustomizationLinuxPrep linuxPrep = new CustomizationLinuxPrep();
      final CustomizationLinuxOptions linuxOptions = new CustomizationLinuxOptions();

      linuxPrep.setHostName(new CustomizationVirtualMachineName());
      linuxPrep.setDomain(myDomain);
      customization.setIdentity(linuxPrep);
      customization.setOptions(linuxOptions);

      customization.setGlobalIPSettings(new CustomizationGlobalIPSettings());
      final CustomizationAdapterMapping mapping = new CustomizationAdapterMapping();
      final CustomizationIPSettings ipSettings = new CustomizationIPSettings();
      mapping.setAdapter(ipSettings);
      ipSettings.setIp(new CustomizationDhcpIpGenerator());
      customization.setNicSettingMap(new CustomizationAdapterMapping[]{mapping});

      cloneSpec.setCustomization(customization);
    }

    try {
      final Folder folder = findEntityByIdNameNullableOld(imageDetails.getFolderId(), Folder.class, datacenter);
      if (folder != null) {
        return vm.cloneVM_Task(folder, instance.getName(), cloneSpec);
      } else {
        String dcName = datacenter == null ? "root" : datacenter.getName();
        throw new VmwareCheckedCloudException(
          String.format("Unable to find folder %s in datacenter %s", imageDetails.getFolderId(), dcName)
        );
      }
    } catch (RemoteException e) {
      instance.setStatus(InstanceStatus.ERROR);
      throw new VmwareCheckedCloudException(e);
    }
  }