Ejemplo n.º 1
0
        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;
        }