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); }
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())); }
/// <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") }); } }
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); }
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); }