protected override void Run() { SafeToExit = false; bool isTemplate; try { string vmRef; if (m_filename.EndsWith("ova.xml")) //importing version 1 from of VM { m_filename = m_filename.Replace("ova.xml", ""); vmRef = GetVmRef(applyVersionOneFiles()); } else //importing current format of VM { vmRef = GetVmRef(applyFile()); } if (Cancelling) { throw new CancelledException(); } // Now lets try and set the affinity and start the VM if (string.IsNullOrEmpty(vmRef)) { return; } while (!Cancelling && (VM = Connection.Resolve(new XenRef <VM>(vmRef))) == null) { Thread.Sleep(100); } if (Cancelling) { throw new CancelledException(); } isTemplate = VM.get_is_a_template(Session, vmRef); if (isTemplate && Helpers.FalconOrGreater(Connection) && VM.get_is_default_template(Session, vmRef)) { var otherConfig = VM.get_other_config(Session, vmRef); if (!otherConfig.ContainsKey(IMPORT_TASK) || otherConfig[IMPORT_TASK] != RelatedTask.opaque_ref) { throw new Exception(Messages.IMPORT_TEMPLATE_ALREADY_EXISTS); } } Description = isTemplate ? Messages.IMPORT_TEMPLATE_UPDATING_TEMPLATE : Messages.IMPORTVM_UPDATING_VM; VM.set_name_label(Session, vmRef, DefaultVMName(VM.get_name_label(Session, vmRef))); if (!isTemplate && m_affinity != null) { VM.set_affinity(Session, vmRef, m_affinity.opaque_ref); } // Wait here for the wizard to finish Description = isTemplate ? Messages.IMPORT_TEMPLATE_WAITING_FOR_WIZARD : Messages.IMPORTVM_WAITING_FOR_WIZARD; lock (monitor) { while (!(m_wizardDone || Cancelling)) { Monitor.Wait(monitor); } } if (Cancelling) { throw new CancelledException(); } if (m_proxyVIFs != null) { Description = isTemplate ? Messages.IMPORT_TEMPLATE_UPDATING_NETWORKS : Messages.IMPORTVM_UPDATING_NETWORKS; // For ElyOrGreater hosts, we can move the VIFs to another network, // but for older hosts we need to destroy all vifs and recreate them List <XenRef <VIF> > vifs = VM.get_VIFs(Session, vmRef); List <XenAPI.Network> networks = new List <XenAPI.Network>(); bool canMoveVifs = Helpers.ElyOrGreater(Connection); foreach (XenRef <VIF> vif in vifs) { // Save the network as we may have to delete it later XenAPI.Network network = Connection.Resolve(VIF.get_network(Session, vif)); if (network != null) { networks.Add(network); } if (canMoveVifs) { var vifObj = Connection.Resolve(vif); if (vifObj == null) { continue; } // try to find a matching VIF in the m_proxyVIFs list, based on the device field var matchingProxyVif = m_proxyVIFs.FirstOrDefault(proxyVIF => proxyVIF.device == vifObj.device); if (matchingProxyVif != null) { // move the VIF to the desired network VIF.move(Session, vif, matchingProxyVif.network); // remove matchingProxyVif from the list, so we don't create the VIF again later m_proxyVIFs.Remove(matchingProxyVif); continue; } } // destroy the VIF, if we haven't managed to move it VIF.destroy(Session, vif); } // recreate VIFs if needed (m_proxyVIFs can be empty, if we moved all the VIFs in the previous step) foreach (Proxy_VIF proxyVIF in m_proxyVIFs) { VIF vif = new VIF(proxyVIF) { VM = new XenRef <VM>(vmRef) }; VIF.create(Session, vif); } // now delete any Networks associated with this task if they have no VIFs foreach (XenAPI.Network network in networks) { if (!network.other_config.ContainsKey(IMPORT_TASK)) { continue; } if (network.other_config[IMPORT_TASK] != RelatedTask.opaque_ref) { continue; } try { if (XenAPI.Network.get_VIFs(Session, network.opaque_ref).Count > 0) { continue; } if (XenAPI.Network.get_PIFs(Session, network.opaque_ref).Count > 0) { continue; } XenAPI.Network.destroy(Session, network.opaque_ref); } catch (Exception e) { log.ErrorFormat("Exception while deleting network {0}. Squashing.", network.Name()); log.Error(e, e); } } } if (!VM.get_is_a_template(Session, vmRef)) { if (m_startAutomatically) { Description = Messages.IMPORTVM_STARTING; VM.start(Session, vmRef, false, false); } } } catch (CancelledException) { Description = Messages.CANCELLED_BY_USER; throw; } Description = isTemplate ? Messages.IMPORT_TEMPLATE_IMPORTCOMPLETE : Messages.IMPORTVM_IMPORTCOMPLETE; }