docs: Fix headers formating
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#mgmt
|
||||
# mgmt
|
||||
|
||||
<!--
|
||||
Mgmt
|
||||
@@ -19,13 +19,13 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
##mgmt resource guide by [James](https://ttboj.wordpress.com/)
|
||||
####Available from:
|
||||
####[https://github.com/purpleidea/mgmt/](https://github.com/purpleidea/mgmt/)
|
||||
## mgmt resource guide by [James](https://ttboj.wordpress.com/)
|
||||
#### Available from:
|
||||
#### [https://github.com/purpleidea/mgmt/](https://github.com/purpleidea/mgmt/)
|
||||
|
||||
####This documentation is available in: [Markdown](https://github.com/purpleidea/mgmt/blob/master/docs/resource-guide.md) or [PDF](https://pdfdoc-purpleidea.rhcloud.com/pdf/https://github.com/purpleidea/mgmt/blob/master/docs/resource-guide.md) format.
|
||||
#### This documentation is available in: [Markdown](https://github.com/purpleidea/mgmt/blob/master/docs/resource-guide.md) or [PDF](https://pdfdoc-purpleidea.rhcloud.com/pdf/https://github.com/purpleidea/mgmt/blob/master/docs/resource-guide.md) format.
|
||||
|
||||
####Table of Contents
|
||||
#### Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Theory - Resource theory in mgmt](#theory)
|
||||
@@ -49,7 +49,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
10. [Suggestions - API change suggestions](#suggestions)
|
||||
11. [Authors - Authors and contact information](#authors)
|
||||
|
||||
##Overview
|
||||
## Overview
|
||||
|
||||
The `mgmt` tool has built-in resource primitives which make up the building
|
||||
blocks of any configuration. Each instance of a resource is mapped to a single
|
||||
@@ -58,7 +58,7 @@ This guide is meant to instruct developers on how to write a brand new resource.
|
||||
Since `mgmt` and the core resources are written in golang, some prior golang
|
||||
knowledge is assumed.
|
||||
|
||||
##Theory
|
||||
## Theory
|
||||
|
||||
Resources in `mgmt` are similar to resources in other systems in that they are
|
||||
[idempotent](https://en.wikipedia.org/wiki/Idempotence). Our resources are
|
||||
@@ -68,14 +68,14 @@ on this design, please read the
|
||||
[original article](https://ttboj.wordpress.com/2016/01/18/next-generation-configuration-mgmt/)
|
||||
on the subject.
|
||||
|
||||
##Resource API
|
||||
## Resource API
|
||||
|
||||
To implement a resource in `mgmt` it must satisfy the
|
||||
[`Res`](https://github.com/purpleidea/mgmt/blob/master/resources/resources.go)
|
||||
interface. What follows are each of the method signatures and a description of
|
||||
each.
|
||||
|
||||
###Default
|
||||
### Default
|
||||
```golang
|
||||
Default() Res
|
||||
```
|
||||
@@ -84,7 +84,7 @@ This returns a populated resource struct as a `Res`. It shouldn't populate any
|
||||
values which already have the correct default as the golang zero value. In
|
||||
general it is preferable if the zero values make for the correct defaults.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// Default returns some sensible defaults for this resource.
|
||||
func (obj *FooRes) Default() Res {
|
||||
@@ -94,7 +94,7 @@ func (obj *FooRes) Default() Res {
|
||||
}
|
||||
```
|
||||
|
||||
###Validate
|
||||
### Validate
|
||||
```golang
|
||||
Validate() error
|
||||
```
|
||||
@@ -105,7 +105,7 @@ specifications, it should generate an error. If you notice that this method is
|
||||
quite large, it might be an indication that you should reconsider the parameter
|
||||
list and interface to this resource. This method is called _before_ `Init`.
|
||||
|
||||
###Init
|
||||
### Init
|
||||
```golang
|
||||
Init() error
|
||||
```
|
||||
@@ -114,7 +114,7 @@ This is called to initialize the resource. If something goes wrong, it should
|
||||
return an error. It should set the resource `kind`, do any resource specific
|
||||
work, and finish by calling the `Init` method of the base resource.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// Init initializes the Foo resource.
|
||||
func (obj *FooRes) Init() error {
|
||||
@@ -133,7 +133,7 @@ this. In other words, you should expect `Validate` to have run first, but you
|
||||
shouldn't allow `Init` to dangerously `rm -rf /$the_world` if your code only
|
||||
checks `$the_world` in `Validate`. Remember to always program safely!
|
||||
|
||||
###CheckApply
|
||||
### CheckApply
|
||||
```golang
|
||||
CheckApply(apply bool) (checkOK bool, err error)
|
||||
```
|
||||
@@ -158,7 +158,7 @@ resource isn't now converged. This is not a bug, as the resources `Watch`
|
||||
facility will detect the change, ultimately resulting in a subsequent call to
|
||||
`CheckApply`.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// CheckApply does the idempotent work of checking and applying resource state.
|
||||
func (obj *FooRes) CheckApply(apply bool) (bool, error) {
|
||||
@@ -179,7 +179,7 @@ skipped. This is an engine optimization, and not a bug. It is mentioned here in
|
||||
the documentation in case you are confused as to why a debug message you've
|
||||
added to the code isn't always printed.
|
||||
|
||||
####Refresh notifications
|
||||
#### Refresh notifications
|
||||
Some resources may choose to support receiving refresh notifications. In general
|
||||
these should be avoided if possible, but nevertheless, they do make sense in
|
||||
certain situations. Resources that support these need to verify if one was sent
|
||||
@@ -192,7 +192,7 @@ action is applied by that resource and are transmitted through graph edges which
|
||||
have enabled their propagation. Resources that currently perform some refresh
|
||||
action include `svc`, `timer`, and `password`.
|
||||
|
||||
####Paired execution
|
||||
#### Paired execution
|
||||
For many resources it is not uncommon to see `CheckApply` run twice in rapid
|
||||
succession. This is usually not a pathological occurrence, but rather a healthy
|
||||
pattern which is a consequence of the event system. When the state of the
|
||||
@@ -201,14 +201,14 @@ having just changed the state, it is usually the case that this repair will
|
||||
trigger the `Watch` code! In response, a second `CheckApply` is triggered, which
|
||||
will likely find the state to now be correct.
|
||||
|
||||
####Summary
|
||||
#### Summary
|
||||
* Anytime an error occurs during `CheckApply`, you should return `(false, err)`.
|
||||
* If the state is correct and no changes are needed, return `(true, nil)`.
|
||||
* You should only make changes to the system if `apply` is set to `true`.
|
||||
* After checking the state and possibly applying the fix, return `(false, nil)`.
|
||||
* Returning `(true, err)` is a programming error and will cause a `Fatal`.
|
||||
|
||||
###Watch
|
||||
### Watch
|
||||
```golang
|
||||
Watch(chan Event) error
|
||||
```
|
||||
@@ -237,7 +237,7 @@ If the resource is activated in `polling` mode, the `Watch` method will not get
|
||||
executed. As a result, the resource must still work even if the main loop is not
|
||||
running.
|
||||
|
||||
####Select
|
||||
#### Select
|
||||
The lifetime of most resources `Watch` method should be spent in an infinite
|
||||
loop that is bounded by a `select` call. The `select` call is the point where
|
||||
our method hands back control to the engine (and the kernel) so that we can
|
||||
@@ -246,7 +246,7 @@ events from the engine via the `<-obj.Events()` call, wait for the converged
|
||||
timeout with `<-cuid.ConvergedTimer()`, and receive events for our resource
|
||||
itself!
|
||||
|
||||
####Events
|
||||
#### Events
|
||||
If we receive an internal event from the `<-obj.Events()` method, we can read it
|
||||
with the ReadEvent helper function. This function tells us if we should shutdown
|
||||
our resource, and if we should generate an event. When we want to send an event,
|
||||
@@ -254,14 +254,14 @@ we use the `DoSend` helper function. It is also important to mark the resource
|
||||
state as `dirty` if we believe it might have changed. We do this with the
|
||||
`StateOK(false)` function.
|
||||
|
||||
####Startup
|
||||
#### Startup
|
||||
Once the `Watch` function has finished starting up successfully, it is important
|
||||
to generate one event to notify the `mgmt` engine that we're now listening
|
||||
successfully, so that it can run an initial `CheckApply` to ensure we're safely
|
||||
tracking a healthy state and that we didn't miss anything when `Watch` was down
|
||||
or from before `mgmt` was running. It does this by calling the `Running` method.
|
||||
|
||||
####Converged
|
||||
#### Converged
|
||||
The engine might be asked to shutdown when the entire state of the system has
|
||||
not seen any changes for some duration of time. In order for the engine to be
|
||||
able to make this determination, each resource must report its converged state.
|
||||
@@ -275,7 +275,7 @@ Instead of interacting with the `ConvergedUID` with these two methods, we can
|
||||
instead use the `StartTimer` and `ResetTimer` methods which accomplish the same
|
||||
thing, but provide a `select`-free interface for different coding situations.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// Watch is the listener and main loop for this resource.
|
||||
func (obj *FooRes) Watch(processChan chan event.Event) error {
|
||||
@@ -334,14 +334,14 @@ func (obj *FooRes) Watch(processChan chan event.Event) error {
|
||||
}
|
||||
```
|
||||
|
||||
####Summary
|
||||
#### Summary
|
||||
* Remember to call the appropriate `converger` methods throughout the resource.
|
||||
* Remember to call `Startup` when the `Watch` is running successfully.
|
||||
* Remember to process internal events and shutdown promptly if asked to.
|
||||
* Ensure the design of your resource is well thought out.
|
||||
* Have a look at the existing resources for a rough idea of how this all works.
|
||||
|
||||
###Compare
|
||||
### Compare
|
||||
```golang
|
||||
Compare(Res) bool
|
||||
```
|
||||
@@ -358,7 +358,7 @@ need to be changed. On occasion, not all of them need to be compared, in
|
||||
particular if they store some generated state, or if they aren't significant in
|
||||
some way.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// Compare two resources and return if they are equivalent.
|
||||
func (obj *FooRes) Compare(res Res) bool {
|
||||
@@ -384,7 +384,7 @@ func (obj *FooRes) Compare(res Res) bool {
|
||||
}
|
||||
```
|
||||
|
||||
###GetUIDs
|
||||
### GetUIDs
|
||||
```golang
|
||||
GetUIDs() []ResUID
|
||||
```
|
||||
@@ -393,7 +393,7 @@ The `GetUIDs` method returns a list of `ResUID` interfaces that represent the
|
||||
particular resource uniquely. This is used with the AutoEdges API to determine
|
||||
if another resource can match a dependency to this one.
|
||||
|
||||
###AutoEdges
|
||||
### AutoEdges
|
||||
```golang
|
||||
AutoEdges() AutoEdge
|
||||
```
|
||||
@@ -402,14 +402,14 @@ This returns a struct that implements the `AutoEdge` interface. This struct
|
||||
is used to match other resources that might be relevant dependencies for this
|
||||
resource.
|
||||
|
||||
###CollectPattern
|
||||
### CollectPattern
|
||||
```golang
|
||||
CollectPattern() string
|
||||
```
|
||||
|
||||
This is currently a stub and will be updated once the DSL is further along.
|
||||
|
||||
###UnmarshalYAML
|
||||
### UnmarshalYAML
|
||||
```golang
|
||||
UnmarshalYAML(unmarshal func(interface{}) error) error // optional
|
||||
```
|
||||
@@ -422,7 +422,7 @@ someone writes to use with `libmgmt`) would have to implement this needlessly.
|
||||
The signature intentionally matches what is required to satisfy the `go-yaml`
|
||||
[Unmarshaler](https://godoc.org/gopkg.in/yaml.v2#Unmarshaler) interface.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
// UnmarshalYAML is the custom unmarshal handler for this struct.
|
||||
// It is primarily useful for setting the defaults.
|
||||
@@ -445,18 +445,18 @@ func (obj *FooRes) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
}
|
||||
```
|
||||
|
||||
##Further considerations
|
||||
## Further considerations
|
||||
There is some additional information that any resource writer will need to know.
|
||||
Each issue is listed separately below!
|
||||
|
||||
###Resource struct
|
||||
### Resource struct
|
||||
Each resource will implement methods as pointer receivers on a resource struct.
|
||||
The resource struct must include an anonymous reference to the `BaseRes` struct.
|
||||
The naming convention for resources is that they end with a `Res` suffix. If
|
||||
you'd like your resource to be accessible by the `YAML` graph API (GAPI), then
|
||||
you'll need to include the appropriate YAML fields as shown below.
|
||||
|
||||
####Example
|
||||
#### Example
|
||||
```golang
|
||||
type FooRes struct {
|
||||
BaseRes `yaml:",inline"` // base properties
|
||||
@@ -469,7 +469,7 @@ type FooRes struct {
|
||||
}
|
||||
```
|
||||
|
||||
###YAML
|
||||
### YAML
|
||||
In addition to labelling your resource struct with YAML fields, you must also
|
||||
add an entry to the internal `GraphConfig` struct. It is a fairly straight
|
||||
forward one line patch.
|
||||
@@ -489,7 +489,7 @@ type GraphConfig struct {
|
||||
It's also recommended that you add the [UnmarshalYAML](#unmarshalyaml) method to
|
||||
your resources so that unspecified values are given sane defaults.
|
||||
|
||||
###Gob registration
|
||||
### Gob registration
|
||||
All resources must be registered with the `golang` _gob_ module so that they can
|
||||
be encoded and decoded. Make sure to include the following code snippet for this
|
||||
to work.
|
||||
@@ -501,14 +501,14 @@ func init() { // special golang method that runs once
|
||||
}
|
||||
```
|
||||
|
||||
##Automatic edges
|
||||
## Automatic edges
|
||||
Automatic edges in `mgmt` are well described in [this article](https://ttboj.wordpress.com/2016/03/14/automatic-edges-in-mgmt/).
|
||||
The best example of this technique can be seen in the `svc` resource.
|
||||
Unfortunately no further documentation about this subject has been written. To
|
||||
expand this section, please send a patch! Please contact us if you'd like to
|
||||
work on a resource that uses this feature, or to add it to an existing one!
|
||||
|
||||
##Automatic grouping
|
||||
## Automatic grouping
|
||||
Automatic grouping in `mgmt` is well described in [this article](https://ttboj.wordpress.com/2016/03/30/automatic-grouping-in-mgmt/).
|
||||
The best example of this technique can be seen in the `pkg` resource.
|
||||
Unfortunately no further documentation about this subject has been written. To
|
||||
@@ -516,7 +516,7 @@ expand this section, please send a patch! Please contact us if you'd like to
|
||||
work on a resource that uses this feature, or to add it to an existing one!
|
||||
|
||||
|
||||
##Send/Recv
|
||||
## Send/Recv
|
||||
In `mgmt` there is a novel concept called _Send/Recv_. For some background,
|
||||
please [read the introductory article](https://ttboj.wordpress.com/2016/12/07/sendrecv-in-mgmt/).
|
||||
When using this feature, the engine will automatically send the user specified
|
||||
@@ -559,7 +559,7 @@ such as for cache invalidation.
|
||||
|
||||
Remember, `Send/Recv` only changes your resource code if you cache state.
|
||||
|
||||
##Composite resources
|
||||
## Composite resources
|
||||
Composite resources are resources which embed one or more existing resources.
|
||||
This is useful to prevent code duplication in higher level resource scenarios.
|
||||
The best example of this technique can be seen in the `nspawn` resource which
|
||||
@@ -568,30 +568,30 @@ Unfortunately no further documentation about this subject has been written. To
|
||||
expand this section, please send a patch! Please contact us if you'd like to
|
||||
work on a resource that uses this feature, or to add it to an existing one!
|
||||
|
||||
##Frequently asked questions
|
||||
## Frequently asked questions
|
||||
(Send your questions as a patch to this FAQ! I'll review it, merge it, and
|
||||
respond by commit with the answer.)
|
||||
|
||||
###Can I write resources in a different language?
|
||||
### Can I write resources in a different language?
|
||||
Currently `golang` is the only supported language for built-in resources. We
|
||||
might consider allowing external resources to be imported in the future. This
|
||||
will likely require a language that can expose a C-like API, such as `python` or
|
||||
`ruby`. Custom `golang` resources are already possible when using mgmt as a lib.
|
||||
Higher level resource collections will be possible once the `mgmt` DSL is ready.
|
||||
|
||||
###What new resource primitives need writing?
|
||||
### What new resource primitives need writing?
|
||||
There are still many ideas for new resources that haven't been written yet. If
|
||||
you'd like to contribute one, please contact us and tell us about your idea!
|
||||
|
||||
###Where can I find more information about mgmt?
|
||||
### Where can I find more information about mgmt?
|
||||
Additional blog posts, videos and other material [is available!](https://github.com/purpleidea/mgmt/#on-the-web).
|
||||
|
||||
##Suggestions
|
||||
## Suggestions
|
||||
If you have any ideas for API changes or other improvements to resource writing,
|
||||
please let us know! We're still pre 1.0 and pre 0.1 and happy to break API in
|
||||
order to get it right!
|
||||
|
||||
##Authors
|
||||
## Authors
|
||||
|
||||
Copyright (C) 2013-2016+ James Shubin and the project contributors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user