@@ -422,3 +422,100 @@ def instance_get_devices(self, instance_name, caller = None):
422422 rets = "Instance '%s' not found" % instance_name
423423 log .error (rets )
424424 return (False , rets , [])
425+
426+ @exports .export ("ssa{ss}" , "(bs)" )
427+ def instance_create (self , plugin_name , instance_name , options , caller = None ):
428+ """Dynamically create a plugin instance
429+
430+ Parameters:
431+ plugin_name -- name of the plugin
432+ instance_name -- name of the new instance
433+ dict of string-string -- options for the new instance
434+
435+ Return:
436+ bool -- True on success
437+ string -- error message or "OK"
438+ """
439+ if caller == "" :
440+ return (False , "Unauthorized" )
441+ plugins = {p .name : p for p in self ._daemon ._unit_manager .plugins }
442+ if not plugin_name in plugins .keys ():
443+ rets = "Plugin '%s' not found" % plugin_name
444+ log .error (rets )
445+ return (False , rets )
446+ plugin = plugins [plugin_name ]
447+ if not isinstance (plugin , hotplug .Plugin ):
448+ rets = "Plugin '%s' does not support hotplugging or dynamic instances." % plugin .name
449+ log .error (rets )
450+ return (False , rets )
451+ devices = options .pop ("devices" , None )
452+ devices_udev_regex = options .pop ("devices_udev_regex" , None )
453+ script_pre = options .pop ("script_pre" , None )
454+ script_post = options .pop ("script_post" , None )
455+ priority = int (options .pop ("priority" , self ._daemon ._unit_manager ._def_instance_priority ))
456+ try :
457+ instance = plugin .create_instance (instance_name , priority , devices , devices_udev_regex , script_pre , script_post , options )
458+ plugin .initialize_instance (instance )
459+ self ._daemon ._unit_manager .instances .append (instance )
460+ except Exception as e :
461+ rets = "Error creating instance '%s': %s" % (instance_name , str (e ))
462+ log .error (rets )
463+ return (False , rets )
464+ log .info ("Created dynamic instance '%s' of plugin '%s'" % (instance_name , plugin_name ))
465+
466+ plugin .assign_free_devices (instance )
467+ plugin .instance_apply_tuning (instance )
468+ # transfer matching devices from other instances, if the priority of the new
469+ # instance is equal or higher (equal or lower priority value)
470+ for other_instance in self ._daemon ._unit_manager .instances :
471+ if (other_instance == instance or
472+ other_instance .plugin != plugin or
473+ instance .priority > other_instance .priority ):
474+ continue
475+ devs_moving = plugin ._get_matching_devices (instance , other_instance .processed_devices )
476+ if len (devs_moving ):
477+ log .info ("Moving devices '%s' from instance '%s' to instance '%s'." % (str (devs_moving ),
478+ other_instance .name , instance .name ))
479+ plugin ._remove_devices_nocheck (other_instance , devs_moving )
480+ plugin ._add_devices_nocheck (instance , devs_moving )
481+ return (True , "OK" )
482+
483+ @exports .export ("s" , "(bs)" )
484+ def instance_destroy (self , instance_name , caller = None ):
485+ """Destroy a dynamically created plugin instance
486+
487+ Parameters:
488+ instance_name -- name of the new instance
489+
490+ Return:
491+ bool -- True on success
492+ string -- error message or "OK"
493+ """
494+ if caller == "" :
495+ return (False , "Unauthorized" )
496+ try :
497+ instance = [i for i in self ._daemon ._unit_manager .instances if i .name == instance_name ][0 ]
498+ except IndexError :
499+ rets = "Instance '%s' not found" % instance_name
500+ log .error (rets )
501+ return (False , rets )
502+ plugin = instance .plugin
503+ if not isinstance (plugin , hotplug .Plugin ):
504+ rets = "Plugin '%s' does not support hotplugging or dynamic instances." % plugin .name
505+ log .error (rets )
506+ return (False , rets )
507+ devices = instance .processed_devices .copy ()
508+ try :
509+ plugin ._remove_devices_nocheck (instance , devices )
510+ self ._daemon ._unit_manager .instances .remove (instance )
511+ plugin .instance_unapply_tuning (instance )
512+ plugin .destroy_instance (instance )
513+ except Exception as e :
514+ rets = "Error deleting instance '%s': %s" % (instance_name , str (e ))
515+ log .error (rets )
516+ return (False , rets )
517+ log .info ("Deleted instance '%s'" % instance_name )
518+ for device in devices :
519+ # _add_device() will find a suitable plugin instance
520+ plugin ._add_device (device )
521+ return (True , "OK" )
0 commit comments