vCenter Cluster Placement


#1

Hello, I have a requirement to place vms on certain vcenter cluster based on their role. After that I am hoping to use the standard vmware_best_fit_least_utilized to place the vm on the least loaded host and datastore. I copied out vmware_best_fit_least_utilized to my domain and updated it with what I believe should set the cluster, as per attached. Its erroring, as per attached.

Would be good to get the set cluster code to work, perhaps it needs to be done at a diffrent stage? Once I get that working I am hoping the rest of the method will also work…

Thankscluster.txt (836 Bytes)
cluster_err.txt (1.9 KB)


#2

Hi Dan,

I believe set_cluster only takes a cluster object, not the string of the cluster name. You’ll want to find the cluster object and then pass it to set_cluster. Here is an example I have used:

cluster = $evm.vmdb(:ems_cluster).find_by_id(cluster_id)
prov.set_cluster(cluster)

You could also find by name, though that could be less specific if you have multiple clusters with the same name.

cluster = $evm.vmdb(:ems_cluster).find_by_name(cluster_name)
prov.set_cluster(cluster)

HTH,
-Jeff


#3

Oh, if memory serves correctly, if you also intend to specify a specific host prov.eligible_hosts may choose hosts outside the cluster, you may want to use cluster.hosts.each do |h| and check that they are on with something like next unless h.power_state == "on".

-Jeff


#4

Thanks Jeffery @jcutter I’ll give it a try.

I only need to do custom cluster selection and also network (aka vlan). I had my network selection method as part of the VMProvision_VM statemachine. That worked for requests coming from a service catalog (services > catalog), but not requests coming from provision dialogs (compute > infra > vm > Lifecycle).

Been trying to add a check context to the method, ie check if the request is from a service catalog, if so do, otherwise ignore. Cant get that going, maybe because at VMProvision_VM we can do this sort of check anymore?

Have tried:
if $evm.root[‘automation_task’] then
if $evm.root[‘service_template_provision_task’] then
if $evm.root[‘service_template_provision_request’] then

Maybe need to move the network and cluster selection code to CatalogInitializationItem?

Asked the question here and thought I got it going, but alas not yet…


#5

Tried using the cluster name way and modifing my vmware_best_fit_least_utilized. Different error. Why would it say not eligible? The name doesn’t exist or some other preset is disqualifing the selection?

ERROR – : Q-task_id([miq_provision_51000000001219]) MiqAeServiceModelBase.ar_method raised: : <Resource <EmsCluster

<51000000000004:IMC3_NonProd_DMZ_Clus> is not an eligible resource for this provisioning instance.>


#6

Made a change to the vmdb call, appended the .name method, still an error (the correct value is desplayed in the cluster variable)…

cluster = $evm.vmdb(:ems_cluster).find_by_name(cluster_name).name
$evm.log(“info”, “Cluster Variables: #{cluster} #{data_center} #{envname} #{dmzzone} #{datazone} #{os_name}”)
@task.set_cluster(cluster)

[----] E, [2017-05-25T12:20:36.219535 #997:9e6e48] ERROR – : Q-task_id([miq_provision_51000000001252]) MiqAeServiceModelBase.ar_method raised: : <undefined method bas e_class' for String:Class> [----] E, [2017-05-25T12:20:36.219767 #997:9e6e48] ERROR -- : Q-task_id([miq_provision_51000000001252]) /var/www/miq/vmdb/app/models/mixins/miq_provision_mixin.rb:323:inresource_cla
ss’
/var/www/miq/vmdb/app/models/mixins/miq_provision_mixin.rb:112:in set_resource' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:270:inpublic_send’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:270:in block in object_send' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:289:inar_method’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:299:in ar_method' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:268:inobject_send’
/var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:44:in set_resource' /var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:16:inblock (2 levels) in expose_eligible_resources’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:289:in ar_method' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:299:inar_method’
/var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:15:in block in expose_eligible_resources' /opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1624:inperform_without_block’
/opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1584:in perform' /opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1657:inblock (2 levels) in main_loop’
/opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1653:in loop' /opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1653:inblock in main_loop’
[----] E, [2017-05-25T12:20:36.220242 #997:9e6e48] ERROR – : Q-task_id([miq_provision_51000000001252]) MiqAeServiceModelBase.ar_method raised: : <undefined method base_class' for String:Class> [----] E, [2017-05-25T12:20:36.220410 #997:9e6e48] ERROR -- : Q-task_id([miq_provision_51000000001252]) /var/www/miq/vmdb/app/models/mixins/miq_provision_mixin.rb:323:inresource_class’
/var/www/miq/vmdb/app/models/mixins/miq_provision_mixin.rb:112:in set_resource' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:270:inpublic_send’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:270:in block in object_send' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:289:inar_method’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:299:in ar_method' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:268:inobject_send’
/var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:44:in set_resource' /var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:16:inblock (2 levels) in expose_eligible_resources’
/var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:289:in ar_method' /var/www/miq/vmdb/lib/miq_automation_engine/engine/miq_ae_service_model_base.rb:299:inar_method’
/var/www/miq/vmdb/lib/miq_automation_engine/service_models/mixins/miq_ae_service_miq_provision_mixin.rb:15:in block in expose_eligible_resources' /opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1624:inperform_without_block’
/opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1584:in perform' /opt/rh/rh-ruby23/root/usr/share/ruby/drb/drb.rb:1657:inblock (2 levels) in main_loop’


#7

Also tried moving the code to the CatalogInitialzationItem, but the same results.

Think my issue is with undrstanding “is not an eligible resource for this provisioning instance” Why is this happening? Is this tied down to the source os template perhaps? I have found that the code “works” if the cluster selected is the same as where the os template is hsoted. I then removed the Auto Select from the Environment catalog item, but still get the not eligible error…


#8

So looks like its not necessarily the os template’s cluster but the required datastore and cluster selections of the service catalog’s catalog item’s environment?

How do I overwrite/customise the cluster?

@gmccullough hi greg, you mention how the eligible lists are created or exist here but how do I get around them?

thanks


#9

@jcutter @gmccullough @itewk @pemcg bit of an all call, sorry. sure its something documented somewhere but i am not finding it…

My placement method is erroring (“is not an eligible resource for this provisioning instance”) when trying to set the cluster. So the set_cluster is getting the right object (not string), but…

It feels like I need to get my environment selection sequence right. This is driven by what is originally selected in the Service Catalog’s Catalog Item’s Environment. I have tried to switch the flieds to not required via the vmware yamls (miq_provision_vmware_dialogs_template.yaml, miq_provision_vmware_dialogs_clone_to_template.yaml & miq_provision_vmware_dialogs_clone_to_template.yaml, didn’t have any effect (evm/ae restart required?).

There is a lot of goodness in the background inherritance and I am looking to just make costum selection on one particularly, ie cluster. From there hopefully the normal inheritance (dc) and eligibility filters will kick in and out of the box selection like least utilized hosts and datastore will work.

I was thinking this could be achieved by setting the environment catalog item to not auto and selecting the minimum fields (arbitrary since placement will change it), copying vmware_best_fit_least_utilized and adding the set_cluster, before the host & storage selections…?

Thanks


#10

Hey @dan,

The error you are seeing is, as you expect, because some other resource selection is causing the filtering of the clusters to exclude the cluster you are trying to set.

If you are trying to do auto-placement I would expect the placement fields to have nil values like this: :placement_cluster_name=>[nil, nil] when the method starts.

Two suggests:

  1. Log the provisioning placement options when the script starts to help determine what filtering is already in place.
placement_options = @task.options.select {|x,y| x.to_s.starts_with?('placement')}
placement_options[:vlan] = @task.options[:vlan]
$evm.log(:info, "Placement Options: #{placement_options}")
  1. Use the eligible_clusters method to log what clusters the task considers eligible:
@task.eligible_clusters { |c| $evm.log(:info, "eligible cluster: #{c.id}:#{c.name}") }

Let see what information we get from the adding these to your placement method.


#11

Hi @gmccullough Greg, the eligible_clusters log entries did come through…?:confused: The cluster variable after it did log…

I have attached the results
autolog_placement.log (1.2 KB)
objwalker_rd.log (131.8 KB)

$evm.log(“info”, “Args: #{MIQ_ARGS.inspect}”)

Get variables

prov = $evm.root[“miq_provision”]
@task = $evm.root[‘miq_provision_request’] || $evm.root[‘miq_provision’] || $evm.root[‘miq_request_task’]
vm = @task.vm_template
$evm.instantiate(’/ObjectWalker/ObjectWalker/objectwalker’)

placement_options = @task.options.select {|x,y| x.to_s.starts_with?(‘placement’)}
placement_options[:vlan] = @task.options[:vlan]
$evm.log(:info, “Placement Options: #{placement_options}”)

@task.eligible_clusters { |c| $evm.log(:info, “eligible cluster: #{c.id}:#{c.name}”) }

dmzzone = @task.options[:dmzzone]
datazone = @task.options[:datazone]
data_center = @task.options[:data_center]
envname = @task.options[:envname]
os_name = @task.source.platform

cluster = $evm.vmdb(:ems_cluster).find_by_name(cluster_name)
$evm.log(“info”, “Cluster Variables: #{cluster} #{data_center} #{envname} #{dmzzone} #{datazone} #{os_name}”)
prov.set_cluster(cluster)

Thanks


#12

Hi All, been working on this a bit more. A suggested approach is to switch to a Generic Catalog Item. This approach would mean that all the Request Info tabs (Template selection, Environment, Network, Cust Spec, etc) will have to be coded. The only thing I really need to change is the vcenter cluster, just seems heavy handed if I am only looking to change the vcenter selection.

Is the generic catalog item the only approach available to me?

Thanks