Skip to content

Cluster Coordinator for deployable & controllable resources (such as VMs & containers)

License

Notifications You must be signed in to change notification settings

sippeproject/vagoth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vagoth Cluster Coordinator

Vagoth provides a cluster management framework that you can build upon to create interesting applications where you have the concept of nodes which can have relationships to one another, finite resources that must be tracked, and a lifecycle which starts with provisioning and ends with deprovisioning. What they do along the way is up to the specific implementation, but it can make use of a job scheduler and actions to perform tasks in the background. Is that abstract enough for you?

A more concrete example is managing a cluster of virtual machines and the servers they run upon. In fact, Vagoth comes with a set of components to do just that.

You can find more documentation under doc/

Command line example

Vagoth comes with a VM-management focused CLI which wraps around the Python API.

In this example, I'm using the Geats driver to provision an LXC container according to a definition that's created by a custom provisioner plugin. The provisioner adds an entry to DHCP and DNS for the new node before saving it using the registry plugin.

Here I'm using the included synchronous job scheduler plugin which runs the action immediately. The messages prefixed by 'vagoth:' are the logging.info() messages generated by the actions.

# ask the provisioner to create a new VM called 'devnode1' using the 'debian' template
$ vagoth new devnode1 template=debian
new: OK (devnode1)

# list the new node.  It doesn't yet have a state or a parent assigned.
$ vagoth list devnode1
devnode1    state=unknown    type=vm  parent=

# Call devnode1.start(), which triggers the 'start' action. It also
# sees that it's not defined (deployed) anywhere yet, so it calls the
# define action first, to assign the 'devnode1' node to a server.
$ vagoth start devnode1
vagoth: txid=6e2bc0fb source=myuser action=start vm=devnode1
vagoth: txid=6e2bc0fb source=myuser action=define vm=devnode1
start: OK (devnode1)

# The action has set the state 'starting'
$ vagoth list devnode1
devnode1    state=starting    type=vm  parent=hyper1

# Call the monitor plugin to poll all the hv nodes for the latest state.
$ vagoth poll 

# It picked up the new running state
$ vagoth list devnode1
devnode1    state=running    type=vm  parent=hyper1

$ ssh root@devnode1
root@devnode1:~# ip route ls
default via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.46 
root@devnode1:~# exit
Connection to devnode1 closed.

$ vagoth
usage: vagoth [-h] [-v]
              
              {list,tree,listvm,listhv,start,stop,shutdown,info,undefine,define,provision,deprovision,new,delete,rename,poll}
              ...
vagoth: error: too few arguments

# call devnode1.deprovision(), which for the geats driver will wipe the filesystem too
$ vagoth deprovision devnode1
vagoth: txid=d01ca1bc source=myuser action=deprovision vm=devnode1
deprovision: OK (devnode1)

$ vagoth list devnode1
devnode1         state=unassigned  type=vm  parent=

$ vagoth delete devnode1
delete: OK (devnode1)

Python shell example

One of Vagoth's goals is to represent distributed state via a simple API. Individual plugins may become complicated, but the API should remain simple. Normally, the state updates with manager.action('poll') would happen in a background process or even via another mechanism completely, but in this example we call it explicitly.

>>> import vagoth
>>> manager = vagoth.get_manager()
>>> dir(manager)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_instantiate_node', 'action', 'cleanup', 'config', 'get_node', 'get_node_by_key', 'get_node_by_name', 'get_nodes', 'get_nodes_with_parent', 'get_nodes_with_tag', 'get_nodes_with_type', 'list_nodes', 'provisioner', 'registry', 'scheduler']
>>> manager.list_nodes()
['hyper1']
>>> manager.get_node('hyper1')
<Hypervisor hyper1 at 2ce8fd0>
>>> manager.provisioner.provision("devnode1", node_name="devnode1", node_type="vm", definition={"template": "debian"})
>>> node = manager.get_node('devnode1')
>>> node
<VirtualMachine devnode1 at 1d66450>
>>> node.state
'unknown'
>>> node.start()
>>> manager.action('poll'); node.refresh(); node.state
'running'
>>> node.stop()
>>> manager.action('poll'); node.refresh(); node.state
'stopped'
>>> manager.provisioner.deprovision('devnode1')
Traceback:
  <snip>
vagoth.exceptions.ProvisioningException: Cannot deprovision node while it's still assigned to a parent
>>> node.deprovision()
>>> manager.action('poll')
>>> node.refresh(); node.state, node.parent
('unassigned', None)
>>> manager.provisioner.deprovision('devnode1')
>>> node.refresh()
Traceback:
  <snip>
vagoth.exceptions.NodeNotFoundException: Node devnode1 not found in registry.

What about a REST API or web interface?

A REST or other remote API is a great idea! I'd build a web interface around the REST API, however, to make it easy to support multiple clusters.

I haven't implemented a REST API myself because it starts to delve into authentication and authorization aspects, which is something I'd like to avoid in Vagoth itself.

About

Cluster Coordinator for deployable & controllable resources (such as VMs & containers)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published