protected override void Run()
        {
            List<LicenseFailure> licenseFailures = new List<LicenseFailure>();

            // 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;
                                if (host != null && host.uuid == alert.HostUuid)
                                {
                                    if (alert.Title == PropertyManager.GetFriendlyName("Message.name-license_not_available"))
                                    {
                                        // the license server reported there were no licenses available.
                                        alertText = string.Format(PropertyManager.GetFriendlyName("Message.body-license_not_available"), xoClosure.Name);
                                    }
                                    else if (alert.Title == PropertyManager.GetFriendlyName("Message.name-license_server_unreachable"))
                                    {
                                        // couldn't check out license because couldn't contact license server
                                        alertText = string.Format(PropertyManager.GetFriendlyName("Message.body-license_server_unreachable"), xoClosure.Name);
                                    }
                                    else if (alert.Title == PropertyManager.GetFriendlyName("Message.name-grace_license"))
                                    {
                                        alertText = string.Empty;
                                    }
                                }
                            }
                        }
                    };

                    Alert.XenCenterAlerts.CollectionChanged += 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.apply_edition(host.Connection.Session, host.opaque_ref, Host.GetEditionText(_edition));
                        // PR-1102: populate the list of updated hosts
                        updatedHosts.Add(host, previousLicenseData);
                    }

                    if (xo is Pool)
                    {
                        if(!Helpers.ClearwaterOrGreater(xo.Connection))
                        {
                            foreach (Host poolHost in xo.Connection.Cache.Hosts)
                            {
                                Host.apply_edition(host.Connection.Session, poolHost.opaque_ref, Host.GetEditionText(_edition));
                            }
                        }
                        else
                        {
                            Pool.apply_edition(xo.Connection.Session, pool.opaque_ref, Host.GetEditionText(_edition));
                            //TODO: Look into why this is required. Event.Next returning late? XAPI returning before updated?
                            Thread.Sleep(200);
                        }

                        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.XenCenterAlerts.CollectionChanged -= 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);
            }
        }
Beispiel #2
0
        protected override void Run()
        {
            SafeToExit = false;
            if (Connection.IsConnected)
            {
                if (!File.Exists(Filepath))
                {
                    throw new Exception(Messages.LICENSE_FILE_DOES_NOT_EXIST);
                }
                if (new FileInfo(Filepath).Length > 1048576)
                {
                    throw new Exception(Messages.LICENSE_FILE_TOO_LARGE);
                }

                string encodedContent = Convert.ToBase64String(File.ReadAllBytes(Filepath));

                // 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(this.Host);

                this.Description = string.Format(Messages.APPLYLICENSE_APPLYING, Filepath);
                log.DebugFormat("Applying license to server {0}", this.Host.Name);
                RelatedTask = XenAPI.Host.async_license_apply(this.Session, this.Host.opaque_ref, encodedContent);
                PollToCompletion();
                this.Description = Messages.APPLYLICENSE_APPLIED;

                // PR-1102: send licensing data to the activation server
                Dictionary<Host, LicensingHelper.LicenseDataStruct> hosts = new Dictionary<Host, LicensingHelper.LicenseDataStruct>();
                hosts.Add(this.Host, previousLicenseData);
                if (ActivateFreeLicense)
                    LicensingHelper.SendActivationData(hosts);
                else
                    LicensingHelper.SendLicenseEditionData(hosts, "");
            }
        }