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_VIFs != 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);
                        }

                        string oldmac = VIF.get_MAC(Session, vif);

                        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_VIFs.FirstOrDefault(proxyVIF => proxyVIF.device == vifObj.device);
                            if (matchingProxyVif != null && matchingProxyVif.MAC == oldmac)
                            {
                                // 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_VIFs.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 (VIF vif in m_VIFs)
                    {
                        vif.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.Error($"Exception while deleting network {network.Name()}. Squashing.", 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;
        }
Ejemplo n.º 2
0
        public void ImpXvaFile()
        {
            log.InfoFormat("开始导入WinCenter xva文件:{0}", ConnectManager.FilePath);
            string vmRef = GetVmRef(applyFile());

            if (string.IsNullOrEmpty(vmRef))
            {
                return;
            }
            log.InfoFormat("WinCenter xva文件导入完成");

            try {
                log.InfoFormat("导入后的WinCenter VM:[{0}]", vmRef);
                List <XenRef <VIF> > vifRefs = VM.get_VIFs(ConnectManager.session, vmRef);
                foreach (XenRef <VIF> vifRef in vifRefs)
                {
                    log.InfoFormat("删除原有的VIF:[{0}]", vifRef.opaque_ref);
                    VIF.destroy(ConnectManager.session, vifRef);
                }
                HTTPHelper.progressInfo     = "删除原有VIF";
                HTTPHelper.progressPercent += 1;

                bool isTemplate = VM.get_is_a_template(ConnectManager.session, vmRef);
                if (isTemplate)
                {
                    log.InfoFormat("导入的xva是模板,删除VM:[{0}]", vmRef);
                    VM.destroy(ConnectManager.session, vmRef);
                    return;
                }

                VIF newVif = ConnectManager.VIF;
                newVif.VM = new XenRef <VM>(vmRef);
                XenRef <VIF> newVifRef = VIF.create(ConnectManager.session, newVif);
                log.InfoFormat("重新创建VIF:[{0}]", newVifRef.opaque_ref);
                string mac = VIF.get_MAC(ConnectManager.session, newVifRef);
                log.InfoFormat("新的MAC地址为:[{0}]", mac);
                string newVifUuid = VIF.get_uuid(ConnectManager.session, newVifRef);
                log.InfoFormat("新的VIF UUID为:[{0}]", newVifUuid);

                HTTPHelper.progressInfo     = "创建新的VIF";
                HTTPHelper.progressPercent += 1;

                DefaultVMName(ConnectManager.VMName);
                log.InfoFormat("检查WinCenter VM的名称,VM名称为:{0}", ConnectManager.VMName);
                VM.set_name_label(ConnectManager.session, vmRef, ConnectManager.VMName);
                HTTPHelper.progressInfo     = "检查VM名称";
                HTTPHelper.progressPercent += 1;

                /**
                 * BUG:AE方式设置IP之后,由于ISO没有弹出,在控制台修改IP重启以后,AE会重新设置ISO配置中的IP
                 * 故不再使用AE这种方式,而是改成在VM启动后使用xenstore-write方式动态修改IP
                 */
                //初始化AE
                //initVmByAe(vmRef, mac);

                XenRef <Host> hostRef = Host.get_by_uuid(ConnectManager.session, ConnectManager.TargetHost.uuid);
                log.InfoFormat("设置WinCenter VM的所属主机:[{0}]", ConnectManager.TargetHostName);
                HTTPHelper.progressInfo = "设置主机";
                VM.set_affinity(ConnectManager.session, vmRef, hostRef);
                HTTPHelper.progressPercent += 1;

                setAutoPoweron(vmRef);
                HTTPHelper.progressInfo = "启动VM";
                VM.start(ConnectManager.session, vmRef, false, false);
                Thread.Sleep(2 * 60 * 1000);                 //休眠2分钟,等待虚拟机启动完成
                HTTPHelper.progressPercent += 2;
                log.InfoFormat("启动WinCenter VM:[{0}]成功", vmRef);

                //去掉AE方式设置IP,VM启动后使用xenstore-write方式动态设置IP
                HTTPHelper.progressInfo = "设置网络信息";
                setActiveVifIp(newVifUuid);
                HTTPHelper.progressPercent = 100;
                log.InfoFormat("设置IP信息成功");
            }
            catch (Exception ex) {
                log.ErrorFormat("安装失败: {0}", ex.Message);
                log.ErrorFormat("开始删除WinCenter VM:[{0}]", vmRef);
                try {
                    vm_power_state power_state = VM.get_power_state(ConnectManager.session, vmRef);
                    if (!vm_power_state.Halted.ToString().Equals(power_state.ToString()))
                    {
                        VM.shutdown(ConnectManager.session, vmRef);
                    }
                }
                catch (Exception ex1) {
                    log.ErrorFormat("WinCenter VM关机失败:{0}", ex1.Message);
                }

                try {
                    VM.destroy(ConnectManager.session, vmRef);
                }
                catch (Exception ex1) {
                    log.ErrorFormat("删除WinCenter VM失败:{0}", ex1.Message);
                    throw ex1;
                }
                throw;
            }
        }