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, ""); } } }
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() { 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 != null) { if (Helpers.ClearwaterOrGreater(host)) { Host.apply_edition(host.Connection.Session, host.opaque_ref, Host.GetEditionText(_edition), false); } else { 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); } }