package org.ovirt.engine.core.vdsbroker.vdsbroker; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.ovirt.engine.core.common.businessentities.DiskImage; import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmInterfaceType; import org.ovirt.engine.core.common.businessentities.VmType; import org.ovirt.engine.core.common.businessentities.network; import org.ovirt.engine.core.common.businessentities.network_cluster; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.vdscommands.CreateVmVDSCommandParameters; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.core.compat.TimeZoneInfo; import org.ovirt.engine.core.compat.WindowsJavaTimezoneMapping; import org.ovirt.engine.core.dal.comparators.DiskImageByBootComparator; import org.ovirt.engine.core.dal.comparators.DiskImageByDriveMappingComparator; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.vmproperties.VmPropertiesUtils; import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcStruct; public class CreateVDSCommand<P extends CreateVmVDSCommandParameters> extends VmReturnVdsBrokerCommand<P> { protected VM mVm; protected XmlRpcStruct mCreateInfo = new XmlRpcStruct(); public CreateVDSCommand(P parameters) { super(parameters, parameters.getVm().getvm_guid()); mVm = parameters.getVm(); } @Override protected void ExecuteVdsBrokerCommand() { InitData(); mVmReturn = getBroker().create(mCreateInfo); LogCommandInfo(); ProceedProxyReturnValue(); VdsBrokerObjectsBuilder.updateVMDynamicData(mVm.getDynamicData(), mVmReturn.mVm); } /** * Logs the command info. */ private void LogCommandInfo() { final char EQUAL = '='; final char SEP = ','; StringBuilder info = new StringBuilder(); String sep = ""; for (String o : mCreateInfo.getKeys()) { info.append(sep); info.append(o); info.append(EQUAL); info.append(mCreateInfo.getItem(o)); sep = (new Character(SEP)).toString(); } log.infoFormat("{0} {1}", getClass().getName(), info.toString()); } private void InitDesktopSoundDevice(){ final String OS_REGEX = "^.*%1s,([^,]*).*$"; final String DEFAULT_TYPE = "default"; String soundDeviceTypeConfig = Config.<String> GetValue(ConfigValues.DesktopAudioDeviceType,mVm.getvds_group_compatibility_version().toString()); String vmOS = mVm.getos().name(); Pattern regexPattern = Pattern.compile(String.format(OS_REGEX, vmOS)); Matcher regexMatcher = regexPattern.matcher(soundDeviceTypeConfig); if (regexMatcher.find()) { mCreateInfo.add(VdsProperties.soundDevice, regexMatcher.group(1)); } else { regexPattern = Pattern.compile(String.format(OS_REGEX, DEFAULT_TYPE)); regexMatcher = regexPattern.matcher(soundDeviceTypeConfig); if (regexMatcher.find()) { mCreateInfo.add(VdsProperties.soundDevice, regexMatcher.group(1)); } } } private void InitData() { mCreateInfo.add(VdsProperties.vm_guid, mVm.getvm_guid().toString()); mCreateInfo.add(VdsProperties.vm_name, mVm.getvm_name()); mCreateInfo.add(VdsProperties.mem_size_mb, mVm.getvm_mem_size_mb()); mCreateInfo.add(VdsProperties.num_of_monitors, (new Integer(mVm.getnum_of_monitors())).toString()); mCreateInfo.add(VdsProperties.num_of_cpus, (new Integer(mVm.getnum_of_cpus())).toString()); if (Config.<Boolean> GetValue(ConfigValues.SendSMPOnRunVm)) { mCreateInfo.add(VdsProperties.cores_per_socket, (new Integer(mVm.getcpu_per_socket())).toString()); } mCreateInfo.add(VdsProperties.emulatedMachine, Config.<String> GetValue(ConfigValues.EmulatedMachine, mVm .getvds_group_compatibility_version().toString())); // send cipher suite and spice secure channels parameters only if ssl // enabled. if (Config.<Boolean> GetValue(ConfigValues.SSLEnabled)) { mCreateInfo.add(VdsProperties.spiceSslCipherSuite, Config.<String> GetValue(ConfigValues.CipherSuite)); mCreateInfo.add(VdsProperties.SpiceSecureChannels, Config.<String> GetValue(ConfigValues.SpiceSecureChannels)); } if (!StringHelper.isNullOrEmpty(mVm.getCdPath())) { mCreateInfo.add(VdsProperties.CDRom, mVm.getCdPath()); } if (!StringHelper.isNullOrEmpty(mVm.getFloppyPath())) { mCreateInfo.add(VdsProperties.Floppy, mVm.getFloppyPath()); } mCreateInfo.add(VdsProperties.kvmEnable, mVm.getkvm_enable().toString().toLowerCase()); mCreateInfo.add(VdsProperties.acpiEnable, mVm.getacpi_enable().toString().toLowerCase()); mCreateInfo.add(VdsProperties.Custom, VmPropertiesUtils.getVMProperties(mVm.getStaticData())); InitDrivesData(); // netowrk StringBuilder macs = new StringBuilder(); StringBuilder nics = new StringBuilder(); StringBuilder networks = new StringBuilder(); for (int i = 0; i < mVm.getInterfaces().size(); i++) { macs.append(mVm.getInterfaces().get(i).getMacAddress()); networks.append(mVm.getInterfaces().get(i).getNetworkName()); VmInterfaceType ifaceType = VmInterfaceType.rtl8139; if (mVm.getInterfaces().get(i).getType() != null) { ifaceType = VmInterfaceType.forValue(mVm.getInterfaces().get(i).getType()); } if (ifaceType == VmInterfaceType.rtl8139_pv) { Boolean useRtl8139_pv = Config.<Boolean> GetValue(ConfigValues.UseRtl8139_pv, mVm.getvds_group_compatibility_version().toString()); if (!useRtl8139_pv) { if (mVm.getHasAgent()) { nics.append("pv"); } else { nics.append("rtl8139"); } } else { nics.append("rtl8139,pv"); macs.append(","); macs.append(mVm.getInterfaces().get(i).getMacAddress()); networks.append(","); networks.append(mVm.getInterfaces().get(i).getNetworkName()); } } else { nics.append(ifaceType.toString()); } if (i < mVm.getInterfaces().size() - 1) { macs.append(","); nics.append(","); networks.append(","); } } // set Display network List<network_cluster> all = DbFacade.getInstance().getNetworkClusterDAO().getAllForCluster( mVm.getvds_group_id()); // LINQ 29456 // network_cluster networkCluster = all.FirstOrDefault(n => // n.is_display); network_cluster networkCluster = null; for (network_cluster tempNetworkCluster : all) { if (tempNetworkCluster.getis_display()) { networkCluster = tempNetworkCluster; break; } } // LINQ 29456 if (networkCluster != null) { // LINQ 29456 // network net = DbFacade.Instance.getAllNetworks().FirstOrDefault(n // => n.id == networkCluster.network_id); network net = null; List<network> allNetworks = DbFacade.getInstance().getNetworkDAO().getAll(); for (network tempNetwork : allNetworks) { if (tempNetwork.getId().equals(networkCluster.getnetwork_id())) { net = tempNetwork; break; } } // LINQ 29456 if (net != null) { mCreateInfo.add(VdsProperties.displaynetwork, net.getname()); } } if (!StringHelper.isNullOrEmpty(macs.toString().trim())) { mCreateInfo.add(VdsProperties.mac_addr, macs.toString()); mCreateInfo.add(VdsProperties.nic_type, nics.toString()); mCreateInfo.add(VdsProperties.bridge, networks.toString()); } mCreateInfo.add(VdsProperties.display, mVm.getdisplay_type().toString()); // vnc, // qxl mCreateInfo.add(VdsProperties.vm_type, "kvm"); // "qemu", "kvm" if (mVm.getRunAndPause()) { mCreateInfo.add(VdsProperties.launch_paused_param, "true"); } mCreateInfo.add(VdsProperties.Boot, mVm.getboot_sequence().toString().toLowerCase()); // send vm_dynamic.utc_diff if exist, if not send vm_static.time_zone if (mVm.getutc_diff() != null) { mCreateInfo.add(VdsProperties.utc_diff, mVm.getutc_diff().toString()); } else { // get vm timezone String timeZone = TimeZoneInfo.Local.getId(); if (!StringHelper.isNullOrEmpty(mVm.gettime_zone())) { timeZone = mVm.gettime_zone(); } // convert to java & calculate offset String javaZoneId = WindowsJavaTimezoneMapping.windowsToJava.get(timeZone); int offset = 0; if (javaZoneId != null) { offset = (TimeZone.getTimeZone(javaZoneId).getOffset(new Date().getTime()) / 1000); } mCreateInfo.add(VdsProperties.utc_diff, "" + offset); } if (mVm.getvm_type() == VmType.Desktop) { InitDesktopSoundDevice(); } if (mVm.getvds_group_cpu_flags_data() != null) { mCreateInfo.add(VdsProperties.cpuType, mVm.getvds_group_cpu_flags_data()); } mCreateInfo.add(VdsProperties.niceLevel, (new Integer(mVm.getnice_level())).toString()); if (mVm.getstatus() == VMStatus.Suspended && !StringHelper.isNullOrEmpty(mVm.gethibernation_vol_handle())) { mCreateInfo.add(VdsProperties.hiberVolHandle, mVm.gethibernation_vol_handle()); } mCreateInfo.add(VdsProperties.KeyboardLayout, Config.<String> GetValue(ConfigValues.VncKeyboardLayout)); if (mVm.getvm_os().isLinux()) { mCreateInfo.add(VdsProperties.PitReinjection, "false"); } if (mVm.getdisplay_type() == DisplayType.vnc) { mCreateInfo.add(VdsProperties.TabletEnable, "true"); } // Boot Options if (!StringHelper.isNullOrEmpty(mVm.getinitrd_url())) { mCreateInfo.add(VdsProperties.InitrdUrl, mVm.getinitrd_url()); } if (!StringHelper.isNullOrEmpty(mVm.getkernel_url())) { mCreateInfo.add(VdsProperties.KernelUrl, mVm.getkernel_url()); if (!StringHelper.isNullOrEmpty(mVm.getkernel_params())) { mCreateInfo.add(VdsProperties.KernelParams, mVm.getkernel_params()); } } mCreateInfo.add(VdsProperties.transparent_huge_pages, mVm.getTransparentHugePages() ? "true" : "false"); } private void InitDrivesData() { int[] ideIndexSlots = new int[] { 0, 1, 3 }; Map[] drives = new Map[mVm.getDiskMap().size()]; int ideCount = 0, pciCount = 0; int i = 0; // LINQ 29456 // order first by drive numbers and then order by boot for the bootable // drive to be first (important for IDE to be index 0) ! // foreach (DiskImage disk in mVm.DiskMap.Values.OrderBy(a => // int.Parse(a.internal_drive_mapping)).OrderByDescending(a => a.boot)) List<DiskImage> diskImages = new ArrayList<DiskImage>(mVm.getDiskMap().values()); Collections.sort(diskImages, new DiskImageByDriveMappingComparator()); Collections.sort(diskImages, Collections.reverseOrder(new DiskImageByBootComparator())); for (DiskImage disk : diskImages) // LINQ 29456 { Map drive = new HashMap(); drive.put("domainID", disk.getstorage_id().toString()); drive.put("poolID", disk.getstorage_pool_id().toString()); drive.put("volumeID", disk.getId().toString()); drive.put("imageID", disk.getimage_group_id().toString()); drive.put("format", disk.getvolume_format().toString().toLowerCase()); drive.put("propagateErrors", disk.getpropagate_errors().toString().toLowerCase()); switch (disk.getdisk_interface()) { case IDE: drive.put("if", "ide"); drive.put("index", String.valueOf(ideIndexSlots[ideCount])); ideCount++; break; case VirtIO: drive.put("if", "virtio"); drive.put("index", String.valueOf(pciCount)); drive.put("boot", String.valueOf(disk.getboot()).toLowerCase()); pciCount++; break; default: // ISCI not supported break; } drives[i] = drive; i++; } mCreateInfo.add("drives", drives); } private static LogCompat log = LogFactoryCompat.getLog(CreateVDSCommand.class); }