Example #1
0
        public ExportApplianceWizard(IXenConnection con, SelectedItemCollection selection)
            : base(con)
        {
            InitializeComponent();

            m_pageExportAppliance = new ExportAppliancePage();
            m_pageRbac            = new RBACWarningPage();
            m_pageExportSelectVMs = new ExportSelectVMsPage();
            m_pageExportEula      = new ExportEulaPage();
            m_pageExportOptions   = new ExportOptionsPage();
            m_pageTvmIp           = new TvmIpPage();
            m_pageFinish          = new ExportFinishPage();

            m_selectedObject = selection.FirstAsXenObject;

            if (selection.Count == 1 && (m_selectedObject is VM || m_selectedObject is VM_appliance))
            {
                m_pageExportAppliance.ApplianceFileName = m_selectedObject.Name();
            }

            m_pageExportAppliance.OvfModeOnly   = m_selectedObject is VM_appliance;
            m_pageTvmIp.IsExportMode            = true;
            m_pageFinish.SummaryRetreiver       = GetSummary;
            m_pageExportSelectVMs.SelectedItems = selection;

            AddPages(m_pageExportAppliance, m_pageExportSelectVMs, m_pageFinish);
        }
Example #2
0
        public int CompareTo(object obj)
        {
            S other = obj as S;

            if (other != null)
            {
                return(CompareTo(other));
            }

            IXenObject o = obj as IXenObject;

            if (o == null)
            {
                return(-1);
            }

            return(StringUtility.NaturalCompare(Name(), o.Name()));
        }
Example #3
0
        /// <summary>
        /// Replaces all placeholders (e.g. {$ip_address}, {$session_id} in the specified text for the specified obj.
        /// Since ip_address can take several values over different Networks, this method returns a list of Uri for
        /// each of the different IP addresses.
        /// </summary>
        /// <param name="uri">The text that contains the placeholders to be replaced.</param>
        /// <param name="obj">The object that the placeholder replacements are for.</param>
        /// <returns>A List of Uris.</returns>
        public static List <Uri> SubstituteUri(string uri, IXenObject obj)
        {
            Util.ThrowIfParameterNull(uri, "uri");
            string ipAddressName = Enum.GetName(typeof(PropertyNames), PropertyNames.ip_address);

            try
            {
                if (!uri.Contains(string.Format(PlaceholderFormat, ipAddressName)))
                {
                    return new List <Uri> {
                               new Uri(Substitute(uri, obj))
                    }
                }
                ;

                var ips = (List <ComparableAddress>)PropertyAccessors.Get(PropertyNames.ip_address)(obj);
                if (ips == null || ips.Count == 0)
                {
                    log.DebugFormat("Object {0} (opaque_ref {1}) has no IPs.", obj.Name(), obj.opaque_ref);

                    return(new List <Uri> {
                        new Uri("about:blank")
                    });
                }

                string u = Substitute(uri, obj, s => s != ipAddressName);

                return(ips.ConvertAll(ip =>
                {
                    var ipstring = ip.AddressIP != null && ip.AddressIP.AddressFamily == AddressFamily.InterNetworkV6
                        ? string.Format("[{0}]", ip)
                        : ip.ToString();

                    return new Uri(u.Replace(string.Format(PlaceholderFormat, ipAddressName), ipstring));
                }));
            }
            catch (UriFormatException ex)
            {
                log.Warn("Failed to parse url.", ex);
                return(new List <Uri> {
                    new Uri("about:blank")
                });
            }
        }
Example #4
0
 protected override void Run()
 {
     Description = Messages.ACTION_DR_RECOVER_STATUS;
     if (MetadataSession != null)
     {
         if (xenObject is VM)
         {
             RelatedTask = VM.async_recover(MetadataSession, xenObject.opaque_ref, Session.opaque_ref, true);
         }
         if (xenObject is VM_appliance)
         {
             // if appliance already exists in target pool, it will be replaced during recovery and the uuid is preserved
             RelatedTask = VM_appliance.async_recover(MetadataSession, xenObject.opaque_ref, Session.opaque_ref, true);
         }
         PollToCompletion();
     }
     else
     {
         log.DebugFormat("Metadata session is NULL. Cannot recover {0} to Pool {1}",
                         Helpers.GetName(xenObject), Helpers.GetName(Pool));
     }
     Description = String.Format(Messages.ACTION_DR_RECOVER_DONE, xenObject.Name());
 }
            public DataGridViewRowRecover(IXenObject xenObject)
                : this()
            {
                XenObject      = xenObject;
                taskCell.Value = XenObject is VM
                                     ? string.Format(Messages.ACTION_DR_RECOVER_VM_TITLE, XenObject.Name())
                                     : string.Format(Messages.ACTION_DR_RECOVER_APPLIANCE_TITLE, XenObject.Name());

                UpdateStatus(RecoverState.NotRecovered, Messages.DR_WIZARD_RECOVERPAGE_STATUS_PENDING);
            }
Example #6
0
        public DrRecoverAction(IXenConnection connection, IXenObject xenObject)
            : base(connection, xenObject is VM
                                   ? string.Format(Messages.ACTION_DR_RECOVER_VM_TITLE, xenObject.Name())
                                   : string.Format(Messages.ACTION_DR_RECOVER_APPLIANCE_TITLE, xenObject.Name()))
        {
            this.xenObject = xenObject;

            Pool = Helpers.GetPoolOfOne(connection);
            #region RBAC Dependencies
            if (xenObject is VM)
            {
                ApiMethodsToRoleCheck.Add("VM.async_recover");
            }
            if (xenObject is VM_appliance)
            {
                ApiMethodsToRoleCheck.Add("VM_appliance.async_recover");
            }
            #endregion
        }
        protected override void Run()
        {
            // PR-1102: hosts that have been updated, plus the previous edition information - this data will be sent to the licensing server
            Dictionary <Host, LicensingHelper.LicenseDataStruct> updatedHosts = new Dictionary <Host, LicensingHelper.LicenseDataStruct>();

            this.Description = Messages.LICENSE_UPDATING_LICENSES;
            foreach (IXenObject xo in xos)
            {
                Connection = xo.Connection;

                if (!Connection.IsConnected)
                {
                    continue;
                }

                Host host = null;
                Pool pool = null;

                if (xo is Host)
                {
                    host = xo as Host;
                }
                if (xo is Pool)
                {
                    pool = xo as Pool;
                    host = xo.Connection.Resolve(pool.master);
                }

                string previousLicenseServerAddress = null;
                string previousLicenseServerPort    = null;
                CollectionChangeEventHandler alertsChangeHandler = null;
                string alertText = null;
                object lck       = new object();

                if (host != null && host.license_server.ContainsKey("address"))
                {
                    previousLicenseServerAddress = host.license_server["address"];
                }

                if (host != null && host.license_server.ContainsKey("port"))
                {
                    previousLicenseServerPort = host.license_server["port"];
                }

                try
                {
                    if (pool != null)
                    {
                        pool.Connection.Cache.Hosts.ToList().ForEach(h => SetLicenseServer(h, _licenseServerAddress, _licenseServerPort));
                    }
                    else
                    {
                        SetLicenseServer(host, _licenseServerAddress, _licenseServerPort);
                    }

                    IXenObject xoClosure = xo;
                    alertsChangeHandler = delegate(object sender, CollectionChangeEventArgs e)
                    {
                        if (e.Action == CollectionChangeAction.Add)
                        {
                            lock (lck)
                            {
                                Alert alert = (Alert)e.Element;
                                Message.MessageType messageType;
                                // if this is a message alert, its Name property will contain the MessageType
                                if (host != null && host.uuid == alert.HostUuid && Enum.TryParse(alert.Name, out messageType))
                                {
                                    switch (messageType)
                                    {
                                    case Message.MessageType.LICENSE_NOT_AVAILABLE:
                                    case Message.MessageType.LICENSE_SERVER_UNREACHABLE:
                                    case Message.MessageType.LICENSE_SERVER_VERSION_OBSOLETE:
                                        alertText = string.Format(Message.FriendlyBody(alert.Name), xoClosure.Name());
                                        break;

                                    case Message.MessageType.GRACE_LICENSE:
                                        alertText = string.Empty;
                                        break;
                                    }
                                }
                            }
                        }
                    };

                    Alert.RegisterAlertCollectionChanged(alertsChangeHandler);

                    // PR-1102: catch the host's license data, before applying the new one, so it can be sent later to the licensing server
                    LicensingHelper.LicenseDataStruct previousLicenseData = new LicensingHelper.LicenseDataStruct(host);

                    if (xo is Host && host != null)
                    {
                        Host.apply_edition(host.Connection.Session, host.opaque_ref, Host.GetEditionText(_edition), false);

                        // PR-1102: populate the list of updated hosts
                        updatedHosts.Add(host, previousLicenseData);
                    }

                    if (xo is Pool)
                    {
                        Pool.apply_edition(xo.Connection.Session, pool.opaque_ref, Host.GetEditionText(_edition));

                        xo.Connection.Cache.Hosts.ToList().ForEach(h => updatedHosts.Add(h, previousLicenseData));
                    }

                    Description = Messages.APPLYLICENSE_UPDATED;
                }
                catch (Failure e)
                {
                    for (int i = 0; i < 50; i++)
                    {
                        Thread.Sleep(100);

                        lock (lck)
                        {
                            if (alertText != null)
                            {
                                break;
                            }
                        }
                    }

                    LicenseFailures.Add(new LicenseFailure(host, alertText ?? e.Message));

                    if (pool != null)
                    {
                        pool.Connection.Cache.Hosts.ToList().ForEach(h => SetLicenseServer(h, previousLicenseServerAddress, previousLicenseServerPort));
                    }
                    else
                    {
                        SetLicenseServer(host, previousLicenseServerAddress, previousLicenseServerPort);
                    }
                }
                finally
                {
                    Alert.DeregisterAlertCollectionChanged(alertsChangeHandler);
                }
            }

            // PR-1102: Send licensing data to the activation server
            if (updatedHosts.Count > 0)
            {
                LicensingHelper.SendLicenseEditionData(updatedHosts, Host.GetEditionText(_edition));
            }

            if (LicenseFailures.Count > 0)
            {
                string exceptionText = LicenseFailures.Count == 1 ? string.Format(Messages.LICENSE_ERROR_1, LicenseFailures[0].Host.Name()) : string.Format(Messages.LICENSE_ERROR_MANY, LicenseFailures.Count, new List <IXenObject>(xos).Count);

                if (DoOnLicensingFailure != null)
                {
                    DoOnLicensingFailure(LicenseFailures, exceptionText);
                }
                throw new InvalidOperationException(exceptionText);
            }
        }
        protected override void Run()
        {
            Description = Messages.LICENSE_UPDATING_LICENSES;
            foreach (IXenObject xo in xos)
            {
                Connection = xo.Connection;

                if (!Connection.IsConnected)
                {
                    continue;
                }

                Host host = null;
                Pool pool = null;

                if (xo is Host)
                {
                    host = xo as Host;
                }
                if (xo is Pool)
                {
                    pool = xo as Pool;
                    host = xo.Connection.Resolve(pool.master);
                }

                string previousLicenseServerAddress = null;
                string previousLicenseServerPort    = null;
                CollectionChangeEventHandler alertsChangeHandler = null;
                string alertText = null;
                object lck       = new object();

                if (host != null && host.license_server.ContainsKey("address"))
                {
                    previousLicenseServerAddress = host.license_server["address"];
                }

                if (host != null && host.license_server.ContainsKey("port"))
                {
                    previousLicenseServerPort = host.license_server["port"];
                }

                try
                {
                    if (pool != null)
                    {
                        pool.Connection.Cache.Hosts.ToList().ForEach(h => SetLicenseServer(h, _licenseServerAddress, _licenseServerPort));
                    }
                    else
                    {
                        SetLicenseServer(host, _licenseServerAddress, _licenseServerPort);
                    }

                    IXenObject xoClosure = xo;
                    alertsChangeHandler = delegate(object sender, CollectionChangeEventArgs e)
                    {
                        if (e.Action == CollectionChangeAction.Add)
                        {
                            lock (lck)
                            {
                                Alert alert = (Alert)e.Element;
                                Message.MessageType messageType;
                                // if this is a message alert, its Name property will contain the MessageType
                                if (host != null && host.uuid == alert.HostUuid && Enum.TryParse(alert.Name, out messageType))
                                {
                                    switch (messageType)
                                    {
                                    case Message.MessageType.LICENSE_NOT_AVAILABLE:
                                    case Message.MessageType.LICENSE_SERVER_UNREACHABLE:
                                    case Message.MessageType.LICENSE_SERVER_VERSION_OBSOLETE:
                                        alertText = string.Format(Message.FriendlyBody(alert.Name), xoClosure.Name());
                                        break;

                                    case Message.MessageType.GRACE_LICENSE:
                                        alertText = string.Empty;
                                        break;
                                    }
                                }
                            }
                        }
                    };

                    Alert.RegisterAlertCollectionChanged(alertsChangeHandler);

                    if (xo is Host && host != null)
                    {
                        Host.apply_edition(host.Connection.Session, host.opaque_ref, host.GetEditionText(_edition), false);
                    }

                    if (xo is Pool)
                    {
                        var firstHost = xo.Connection.Cache.Hosts.FirstOrDefault();
                        if (firstHost != null)
                        {
                            Pool.apply_edition(xo.Connection.Session, pool.opaque_ref, firstHost.GetEditionText(_edition));
                        }
                    }

                    Description = Messages.APPLYLICENSE_UPDATED;
                }
                catch (Failure e)
                {
                    for (int i = 0; i < 50; i++)
                    {
                        Thread.Sleep(100);

                        lock (lck)
                        {
                            if (alertText != null)
                            {
                                break;
                            }
                        }
                    }

                    LicenseFailures.Add(new LicenseFailure(host, alertText ?? e.Message));

                    if (pool != null)
                    {
                        pool.Connection.Cache.Hosts.ToList().ForEach(h => SetLicenseServer(h, previousLicenseServerAddress, previousLicenseServerPort));
                    }
                    else
                    {
                        SetLicenseServer(host, previousLicenseServerAddress, previousLicenseServerPort);
                    }
                }
                finally
                {
                    Alert.DeregisterAlertCollectionChanged(alertsChangeHandler);
                }
            }

            if (LicenseFailures.Count > 0)
            {
                string exceptionText = LicenseFailures.Count == 1 ? string.Format(Messages.LICENSE_ERROR_1, LicenseFailures[0].Host.Name()) : string.Format(Messages.LICENSE_ERROR_MANY, LicenseFailures.Count, new List <IXenObject>(xos).Count);

                DoOnLicensingFailure?.Invoke(LicenseFailures, exceptionText);
                throw new InvalidOperationException(exceptionText);
            }
        }
        protected override Problem RunCheck()
        {
            if (MetadataSession == null)
            {
                return(null);
            }

            try
            {
                if (xenObject is VM)
                {
                    VM.assert_can_be_recovered(MetadataSession, xenObject.opaque_ref, Pool.Connection.Session.opaque_ref);
                }
                if (xenObject is VM_appliance)
                {
                    VM_appliance.assert_can_be_recovered(MetadataSession, xenObject.opaque_ref,
                                                         Pool.Connection.Session.opaque_ref);
                }
            }
            catch (Failure f)
            {
                if (f.ErrorDescription.Count > 2 && f.ErrorDescription[0] == Failure.VM_REQUIRES_SR)
                {
                    List <SR> requiredSRs = GetRequiredSRs(xenObject) ?? new List <SR>();

                    SR sr = RetrieveSR(new XenRef <SR>(f.ErrorDescription[2]));
                    if (!requiredSRs.Contains(sr))
                    {
                        requiredSRs.Add(sr);
                    }

                    //search for local SRs
                    SR localSR = requiredSRs.Find(item => !item.shared);
                    if (localSR != null)
                    {
                        // there is local SR which means the VM cannot be recovered
                        return(new MissingSRProblem(this, Pool, localSR, null));
                    }

                    //search for FibreChannel SRs
                    List <SRDeviceConfig> srDeviceConfigList = GetFCSRDeviceConfigList(requiredSRs);
                    if (srDeviceConfigList.Count == 0)
                    {
                        return(new MissingSRProblem(this, Pool, requiredSRs[0], null));
                    }

                    if (srDeviceConfigList.Count == 1)
                    {
                        return(new MissingSRProblem(this, Pool, srDeviceConfigList[0].SR,
                                                    srDeviceConfigList[0].DeviceConfig));
                    }

                    return(new MissingMultipleFCSRsProblem(this, Pool, srDeviceConfigList));
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("There was an error calling assert_can_be_recovered for object {0}", xenObject.Name());
                log.Error(e, e);
            }
            return(null);
        }
        public override bool FailureFoundFor(IXenObject itemToFilterOn)
        {
            Pool        targetPool;
            List <Host> targets = CollateHosts(itemToFilterOn, out targetPool);

            foreach (VM vm in preSelectedVMs)
            {
                log.InfoFormat("Asserting can migrate VM {0} to {1}...", vm.Name(), itemToFilterOn);
                bool vmIsMigratable = false;
                foreach (Host host in targets)
                {
                    if (canceled)
                    {
                        return(false);
                    }

                    // obtain the cache data for a vm
                    IDictionary <string, string> vmCache;
                    lock (cacheLock)
                    {
                        if (!cache.ContainsKey(vm.opaque_ref))
                        {
                            cache.Add(vm.opaque_ref, new Dictionary <string, string>());
                        }
                        vmCache = cache[vm.opaque_ref];
                    }

                    try
                    {
                        //CA-220218: for intra-pool motion of halted VMs we do a move, so no need to assert we can migrate
                        Pool vmPool = Helpers.GetPoolOfOne(vm.Connection);
                        if (_wizardMode == WizardMode.Move && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
                        {
                            // vm is migratable, no need to itearate through all the pool members
                            vmIsMigratable = true;
                            break;
                        }

                        //Skip the resident host as there's a filter for it and
                        //if not then you could exclude intrapool migration
                        //CA-205799: do not offer the host the VM is currently on
                        Host homeHost = vm.Home();
                        if (homeHost != null && homeHost.opaque_ref == host.opaque_ref)
                        {
                            continue;
                        }

                        if (vmCache.ContainsKey(host.opaque_ref))
                        {
                            disableReason = vmCache[host.opaque_ref];
                            if (string.IsNullOrEmpty(disableReason))
                            {
                                // vm is migratable to at least one host in the pool, no need to itearate through all the pool members
                                vmIsMigratable = true;
                                break;
                            }
                            continue;
                        }

                        //if pool_migrate can be done, then we will allow it in the wizard, even if storage migration is not allowed (i.e. users can use the wizard to live-migrate a VM inside the pool)
                        if (_wizardMode == WizardMode.Migrate && vmPool != null && targetPool != null && vmPool.opaque_ref == targetPool.opaque_ref)
                        {
                            var reason = VMOperationHostCommand.GetVmCannotBootOnHostReason(vm, host, vm.Connection.Session, vm_operations.pool_migrate);
                            if (string.IsNullOrEmpty(reason))
                            {
                                lock (cacheLock)
                                {
                                    vmCache[host.opaque_ref] = reason;
                                }
                                // vm is migratable to at least one host in the pool, no need to itearate through all the pool members
                                vmIsMigratable = true;
                                break;
                            }
                        }

                        //check if the destination host is older than the source host
                        var destinationVersion = Helpers.HostPlatformVersion(host);
                        var sourceVersion      = Helpers.HostPlatformVersion(vm.Home() ?? Helpers.GetMaster(vmPool));
                        if (Helpers.productVersionCompare(destinationVersion, sourceVersion) < 0)
                        {
                            throw new Failure(Messages.OLDER_THAN_CURRENT_SERVER);
                        }

                        PIF            managementPif     = host.Connection.Cache.PIFs.First(p => p.management);
                        XenAPI.Network managementNetwork = host.Connection.Cache.Resolve(managementPif.network);

                        Session session = host.Connection.DuplicateSession();
                        Dictionary <string, string> receiveMapping = Host.migrate_receive(session, host.opaque_ref, managementNetwork.opaque_ref, new Dictionary <string, string>());

                        var targetSrs     = host.Connection.Cache.SRs.Where(sr => sr.SupportsStorageMigration()).ToList();
                        var targetNetwork = GetANetwork(host);

                        VM.assert_can_migrate(vm.Connection.Session,
                                              vm.opaque_ref,
                                              receiveMapping,
                                              true,
                                              GetVdiMap(vm, targetSrs),
                                              vm.Connection == host.Connection ? new Dictionary <XenRef <VIF>, XenRef <XenAPI.Network> >() : GetVifMap(vm, targetNetwork),
                                              new Dictionary <string, string>());
                        lock (cacheLock)
                        {
                            vmCache[host.opaque_ref] = string.Empty;
                        }
                        // vm is migratable to at least one host in the pool, no need to itearate through all the pool members
                        vmIsMigratable = true;
                        break;
                    }
                    catch (Failure failure)
                    {
                        if (failure.ErrorDescription.Count > 0 && failure.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
                        {
                            disableReason = failure.Message.Split('\n')[0].TrimEnd('\r'); // we want the first line only
                        }
                        else
                        {
                            disableReason = failure.Message;
                        }

                        lock (cacheLock)
                        {
                            vmCache[host.opaque_ref] = disableReason.Clone().ToString();
                        }

                        log.InfoFormat("VM {0} cannot be migrated to {1}. Reason: {2};", vm.Name(), host.Name(), failure.Message);

                        vmIsMigratable = false;
                    }
                    catch (Exception e)
                    {
                        log.Error($"There was an error while asserting the VM {vm.Name()} can be migrated to {itemToFilterOn.Name()}:", e);
                        disableReason  = Messages.HOST_MENU_UNKNOWN_ERROR;
                        vmIsMigratable = false;
                    }
                }

                // if at least one VM is not migratable to the target pool, then there is no point checking the remaining VMs
                if (!vmIsMigratable)
                {
                    return(true);
                }
            }
            return(false);
        }