Core OCB Objects Design Information¶
- Node objects encapsulate machine-specific state – they have
unique | programmatically generated names (which must also be the machine’s FQDN | in DNS), track whether OpenCrowbar is allowed to manage the machine, and track | whether the machine is alive and reachable. In the OCB framework, | nodes are things that a jig performs operations on as directed by a | role through a noderole.
- Roles are the primary unit of functionality in OCB – they
provide | the code that the jigs use to effect change on the nodes in accordance | with the desired state stored in the noderole graph. Roles form a | dependency graph of their own (roles must declare what other roles | they depend on), each role must declare the jig that will be used to | do things to a node, and roles can have flags that affect how the | annealer will handle certian aspects of building the noderole graph | and initial node bootstrap.
- Noderoles represent a binding of a role to a node. Each
noderole | tracks any state that needs to communicated from the user or the | OpenCrowbar framework to a node (and vice versa), and the overall noderole | graph determines both the order in which roles are enacted on nodes | and what attributes are visible from other noderoles when the noderole | runs.
- A deployment is an administratively convenient logical grouping of nodes along with a set of default role configurations (the deployment roles) relevant to whatever workload is being run in the deployment. Deployments all have a parent deployment except for the system deployment, which OpenCrowbar manages and which is where all newly-discovered nodes wind up. Nodes belong to deployments, which helps control how the noderole graph is built. Deployments can be either proposed (when the user needs to make deployment-wide configuration changes), or committed (where the annealer is allowed to work, and user-level changes are Not Allowed)
any | jig-specific files that the roles require.
Roles, in a little detail:¶
stored in the | noderole graph, but there are some (primarily those provided by the | network, dns, and provisioner barclamps) that need to maintain a | significant amout of state outside the noderole graph or that need to | be able to react to noderole and node state transitions. To give them | a formal method of doing so, you can override the base Role model with | one that responds to several events that happen in the noderole and | node lifecycles.
The Two Rules for Events:¶
Events run synchronously, so they must be fast.
If your event takes more than a few milliseconds to run, or youwant to do something on a remote machine, you should make it arole of its own and bind it to that node as a noderole instead.
again.
How To Respond to Events:¶
class BarclampFoo::RoleName < Role
class BarclampFoo::Role < Role
Noderole Events:¶
- on_proposed
- on_todo
- on_blocked
- on_transition
- on_error
- on_active
Node Events:¶
- on_node_create will be called after the node is created and the default set of noderoles has been bound to it.
- on_node_delete will be called just before the node is destroyed.
Role Flags:¶
to | handle:
- Discovery, which means that this role will be automatically bound to all non-admin nodes when the node is freshly-created if the role’s jig is active.
- Bootstrap, which means that this role will be automatically bound to all freshly-created admin nodes. This flag is primarily used by the OpenCrowbar framework to bootstrap the initial OpenCrowbar admin node into existence.
- Implicit, which signals that this role can be implicitly created and bound to a node as part of the dependency resolution process, and that it must be bound to the same node as the role that depends on it is being bound to.
- Library, which is not used by anything right now and may be removed.
Role dependency rules:¶
Noderoles:¶
How the noderole graph is built:¶
it a | node and a deployment, and it either creates a node role bound to an | appropriate place in the graph or dies with an exception. In detail:
Verify that the jig that implements the role is active.
Check to see if this role has already been bound to this node. If it has, return that noderole.
- Check that all our parent roles have been bound into the noderole
graph. If they have not, bind them on the same node we are binding to.
Create a new noderole binding this role to the requested node in the deployment, and create parent/child relationships between the new noderole and the parents we found. The noderole will be created in the PROPOSED state.
Call the on_proposed event hook for this role with the new noderole.
Return the new noderole to the caller.
OpenCrowbar | framework – it determines the shape and connectedness of the noderole | graph, and hence it plays a large part in determining whether what we | are deploying makes sense.
What is in a noderole:¶
- Pointers to its parents and children in the noderole graph.
- The state of the noderole.
- A blob of JSON that the user can edit. This blob is seeded from the deployment role data, which in turn is seeded from the role template
- A blob of data that the OpenCrowbar framework can edit. This is used by the roles to pass system-generated data to the jigs, and is usually seeded by one of the noderole events.
- A blob of data that we get back at the end of a jig run.
What happens in OCB to create a node:¶
an API request come in with the requested name of the new node, and a flag that indicates whether it is an admin node.
The requested name is checked to see it is a valid FQDN in the cluster’s administrative DNS domain and that it is unique. If neither of those are true, the request fails, otherwise we create the node object. The new node object will not be alive or available, and it will not have any roles bound to it.
- (optional) API calls come in to hint to the system (via the
hint-admin-mac and hint-admin-v4addr attribs) what MAC address should be used for DHCP purposes and what IP address should be assigned to the node from the admin network. Nodes booting via Sledgehammer use hint-admin-mac to ensure that the provisioner-dhcp-database role runs, which allows Sledgehammer to get a proper in-range DHCP address.
- API calls come in that bind the crowbar-managed-node role to the
freshly-created node. This will have the side effect of pullng in all the roles we need to properly discover a node and bind them to the node-role graph as well.
(optional) API calls come in that modify the default values of the freshly-bound noderoles.
The node is committed via the node API, which automatically commits all the noderoles bound to the node.
The node is marked as alive by the node API. After that, the annealer takes over to discover the node.
role.
The NodeRole state machine, the framework-driven parts:¶
- The jig that is associated with the noderole via the role half of the binding is active,
- The deployment that the noderole belongs to is COMMITTED,
- The node that the noderole binds to is alive and available,
- There is no noderole for that node that is in TRANSITION
How we determine what information is visible to a node during a jig run:¶
Aliveness and availability:¶
Delayed Jobs and Queuing:¶
is | running on a node at any given time. For now, we limit ourselves to | having up to 10 tasks running in the background at any given time, | which should be enough for the immediate future until we come up with | proper tuning guidelines or auto-tuning code for significantly larger | clusters.
Postgresql 9.3:¶
Deployment tree:¶
Provisioner Installing Ubuntu 12.04:¶
- Create a new deployment, and add the provisioner-os-install role to that deployment. In the future you will be able to edit the deployment role information to change what the default OS for a deployment should be.
- Drag one of the non-admin nodes onto the provisioner-os-install role. This will create a proposed noderole binding the provisioner-os-install role to that node, and in the future you would be able to change what OS would be installed on that node by editing that noderole before committing the deployment.
- Commit the deployment. This will cause several things to happen:
- The freshly-bound noderoles will transition to TODO, which will
trigger an annealer pass on the noderoles.
- The annealer will grab all the provisioner-os-install roles that
are in TODO, set them in TRANSITION, and hand them off to delayed_jobs via the queuing system.
- The delayed_jobs handlers will use the script jig to schedule a
reboot of the nodes for 60 seconds in the future and then return, which will transition the noderole to ACTIVE.
- In the crowbar framework, the provisioner-os-install role has an
on_active hook which will change the boot environment of the node passed to it via the noderole to the appropriate os install state for the OS we want to install, and mark the node as not alive so that the annealer will ignore the node while it is being installed.
- The provisioner-dhcp-database role has an on_node_change handler
that watches for changes in the boot environment of a node. It will see the bootenv change, update the provisioner-dhcp-database noderoles with the new bootenv for the node, and then enqueue a run of all of the provisioner-dhcp-database roles.
- delayed_jobs will see the enqueued runs, and run them in the order
they were submitted. All the runs sholuld happen before the 60 seconds has elapsed.
- When the nodes finally reboot, the DHCP databases should have been
updated and the nodes will boot into the Uubntu OS installer, install, and then set their bootenv to local, which will tell the provisioner (via the provisioner-dhcp-database on_node_change hook) to not PXE boot the node anymore.
- When the nodes reboot off their freshly-installed hard drive, they
will mark themselves as alive, and the annealer will rerun all of the usual discovery roles.
Bootstrapping OpenCrowbar:¶
Put docs here.