Pluggable protection provider doc
Change-Id: I64dce168322cf607951bada5ac0eb19f80c4b09e
This commit is contained in:
parent
70a97bea74
commit
ef71a5b311
57
doc/images/available_protectables.svg
Normal file
57
doc/images/available_protectables.svg
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="370px" style="width:612px;height:370px;" version="1.1" viewBox="0 0 612 370" width="612px">
|
||||
<defs>
|
||||
<filter height="300%" id="f1" width="300%" x="-1" y="-1">
|
||||
<feGaussianBlur result="blurOut" stdDeviation="2.0" />
|
||||
<feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0" />
|
||||
<feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut3" mode="normal" />
|
||||
</filter>
|
||||
</defs>
|
||||
<g>
|
||||
<text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacingAndGlyphs" textLength="175" x="223" y="16.708">Smaug Protectables</text>
|
||||
<polygon fill="#DDDDDD" points="43.5,28.9531,43.5,104.1406,576.5,104.1406,576.5,28.9531,43.5,28.9531" style="stroke: #000000; stroke-width: 1.0;" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="474" x="49.5" y="46.9482">This file contains the dependecy between protectables in the default</text>
|
||||
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="514" x="49.5" y="63.2451">distribution of Smaug. The arrows, similar to inheritance point to the parent</text>
|
||||
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="521" x="49.5" y="79.542">since Protectables define what types they depend on so this reflects who is</text>
|
||||
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="216" x="49.5" y="95.8389">responsible for the connection.</text>
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="120" x="6" y="321.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="114" x="9" y="337.2793">OS::Glance::Image</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="7" x2="125" y1="345.1094" y2="345.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="7" x2="125" y1="353.1094" y2="353.1094" />
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="110" x="90" y="221.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="104" x="93" y="237.2793">OS::Nova::Server</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="91" x2="199" y1="245.1094" y2="245.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="91" x2="199" y1="253.1094" y2="253.1094" />
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="140" x="183" y="121.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="134" x="186" y="137.2793">OS::Keystone::Project</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="184" x2="322" y1="145.1094" y2="145.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="184" x2="322" y1="153.1094" y2="153.1094" />
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="125" x="175.5" y="321.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="119" x="178.5" y="337.2793">OS::Cinder::Volume</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="176.5" x2="299.5" y1="345.1094" y2="345.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="176.5" x2="299.5" y1="353.1094" y2="353.1094" />
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="146" x="306" y="221.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="140" x="309" y="237.2793">OS::Neutron::Topology</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="307" x2="451" y1="245.1094" y2="245.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="307" x2="451" y1="253.1094" y2="253.1094" />
|
||||
<rect fill="#FEFECE" filter="url(#f1)" height="39.9688" style="stroke: #A80036; stroke-width: 1.5;" width="116" x="487" y="221.1406" />
|
||||
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="110" x="490" y="237.2793">OS::Manila::Share</text>
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="488" x2="602" y1="245.1094" y2="245.1094" />
|
||||
<line style="stroke: #A80036; stroke-width: 1.5;" x1="488" x2="602" y1="253.1094" y2="253.1094" />
|
||||
<path d="M116.496,277.4996 C104.7183,292.1104 91.5229,308.4793 81.5754,320.8192 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="111.39,272.6798,129.392,261.5022,122.29,281.4662,111.39,272.6798" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M163.291,160.0376 C129.059,171.5966 93.2034,190.4656 72,221.1406 C51.416,250.9196 56.1704,295.5937 61.2398,320.883 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="161.414,153.2916,182.585,154.1916,165.474,166.6906,161.414,153.2916" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M177.204,276.0761 C191.403,291.0385 207.572,308.0769 219.664,320.8192 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="172.063,280.8282,163.374,261.5022,182.219,271.1911,172.063,280.8282" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M250.003,181.6976 C246.806,223.8996 241.875,288.9852 239.449,321.008 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="243.044,180.9006,251.534,161.4866,257.004,181.9576,243.044,180.9006" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M217.053,174.7586 C200.12,190.1246 180.51,207.9186 166.027,221.0606 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="212.405,169.5246,231.92,161.2686,221.813,179.8926,212.405,169.5246" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M293.425,173.5816 C313.517,189.2086 337.139,207.5816 354.469,221.0606 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="289.083,179.0726,277.593,161.2686,297.678,168.0216,289.083,179.0726" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<path d="M328.634,167.5246 C378.412,184.2306 442.531,205.7506 488.013,221.0146 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
<polygon fill="none" points="326.38,174.1516,309.647,161.1526,330.835,160.8796,326.38,174.1516" style="stroke: #A80036; stroke-width: 1.0;" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.2 KiB |
1
doc/images/pluggable_protection_provider.svg
Normal file
1
doc/images/pluggable_protection_provider.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 36 KiB |
26
doc/source/specs/available_protectables.pu
Normal file
26
doc/source/specs/available_protectables.pu
Normal file
@ -0,0 +1,26 @@
|
||||
@startuml
|
||||
|
||||
title Smaug Protectables
|
||||
|
||||
hide circle
|
||||
|
||||
legend top
|
||||
This file contains the dependecy between protectables in the default
|
||||
distribution of Smaug. The arrows, similar to inheritance point to the parent
|
||||
since Protectables define what types they depend on so this reflects who is
|
||||
responsible for the connection.
|
||||
endlegend
|
||||
|
||||
class OS::Glance::Image extends OS::Nova::Server, OS::Keystone::Project
|
||||
|
||||
class OS::Cinder::Volume extends OS::Nova::Server, OS::Keystone::Project
|
||||
|
||||
class OS::Nova::Server extends OS::Keystone::Project
|
||||
|
||||
class OS::Keystone::Project
|
||||
|
||||
class OS::Neutron::Topology extends OS::Keystone::Project
|
||||
|
||||
class OS::Manila::Share extends OS::Keystone::Project
|
||||
|
||||
@enduml
|
@ -31,9 +31,10 @@ Spec Template
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
bank-plugin-lease
|
||||
pluggable_protection_provider
|
||||
skeleton
|
||||
template
|
||||
bank-plugin-lease
|
||||
|
||||
|
||||
Indices and tables
|
||||
|
126
doc/source/specs/pluggable_protection_provider.pu
Normal file
126
doc/source/specs/pluggable_protection_provider.pu
Normal file
@ -0,0 +1,126 @@
|
||||
@startuml
|
||||
|
||||
title Pluggable Protection Provider
|
||||
|
||||
class ResourceType extends String {
|
||||
|
||||
}
|
||||
|
||||
class Resource {
|
||||
+type: ResourceType
|
||||
+id: UUID
|
||||
}
|
||||
|
||||
class ResourceGraphNode {
|
||||
resource: Resource
|
||||
dependent_resources: []ResourceGraphNode
|
||||
}
|
||||
|
||||
ResourceGraphNode "1" o- "0..*" ResourceGraphNode
|
||||
|
||||
class ResourceGraphWalker {
|
||||
+constructor(sources: []ResourceGraphNode)
|
||||
+add_listener(listener: ResourceGraphWalkerListener)
|
||||
+walk()
|
||||
}
|
||||
|
||||
ResourceGraphWalker -- ResourceGraphWalkerListener
|
||||
|
||||
interface ResourceGraphWalkerListener {
|
||||
on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)
|
||||
on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)
|
||||
}
|
||||
|
||||
ResourceGraphNode *- Resource
|
||||
|
||||
class ProtectableRegistry {
|
||||
+ {static} fetch_dependant_resources(resource: Resource): []Resource
|
||||
+ {static} register(resource_type: ResourceType, protectable: Protectable)
|
||||
+ {static} list_resources(resource_type: ResourceType): [] Resource
|
||||
}
|
||||
|
||||
ProtectableRegistry --> Resource: <<creates>>
|
||||
|
||||
ProtectableRegistry "1" *- "*" Protectable
|
||||
|
||||
interface Protectable {
|
||||
+ possible_parent_types(resource_type: ResourceType): []ResourceType
|
||||
+ fetch_child_resources(resource: Resource): []Resource
|
||||
+ list_resources(resource_type: ResourceType): []Resource
|
||||
}
|
||||
|
||||
Resource *- ResourceType
|
||||
|
||||
enum Operation {
|
||||
protect
|
||||
start
|
||||
suspend
|
||||
restore
|
||||
delete
|
||||
}
|
||||
|
||||
class Context {
|
||||
+plan: ProtectionPlan
|
||||
+operation: Operation
|
||||
+parameters: dict
|
||||
+resource: ResourceGraphNode
|
||||
+bank_section: BankSection
|
||||
+is_first_visit: boolean
|
||||
+task_builder: TaskBuilder
|
||||
}
|
||||
|
||||
interface BankPlugin {
|
||||
|
||||
}
|
||||
|
||||
interface BankSection extends BankPluginInterface {
|
||||
is_writeable(): bool
|
||||
}
|
||||
|
||||
Context *-- TaskBuilder
|
||||
Context *-- BankSection
|
||||
|
||||
interface Task {
|
||||
|
||||
}
|
||||
|
||||
note left of Task
|
||||
Opaque object
|
||||
end note
|
||||
|
||||
interface TaskBuilder {
|
||||
add_task(target: function, args=collection): Task
|
||||
link_tasks(a: Task, b: Task)
|
||||
}
|
||||
|
||||
TaskBuilder --> Task: Creates
|
||||
|
||||
Context -- Operation
|
||||
|
||||
interface ProtectionPlugin {
|
||||
..metadata functions..
|
||||
get_supported_resources_types(): []ResourceType
|
||||
..graph walk functions..
|
||||
+on_resource_start(context: Context)
|
||||
+on_resource_end(context: Context)
|
||||
..schema functions..
|
||||
+get_options_schema(resource_type: ResourceType)
|
||||
+get_saved_info_schema(resource_type: ResourceType)
|
||||
+get_restore_schema(resource_type: ResourceType)
|
||||
+get_saved_info(metadata_store: MetadataStore, resource: Resource)
|
||||
}
|
||||
|
||||
ProtectionPlugin -- Context
|
||||
|
||||
interface ProtectionProvider {
|
||||
}
|
||||
|
||||
class PluggableProtectionProvider extends ProtectionProvider {
|
||||
-plugins: [ResourceType]ProtectionPlugin
|
||||
}
|
||||
|
||||
PluggableProtectionProvider *-- "1..*" ProtectionPlugin: Uses for functionality
|
||||
PluggableProtectionProvider -> ResourceGraphWalker: uses it to iterate over graph
|
||||
ResourceGraphWalker - ResourceGraphNode
|
||||
|
||||
@enduml
|
62
doc/source/specs/pluggable_protection_provider.rst
Normal file
62
doc/source/specs/pluggable_protection_provider.rst
Normal file
@ -0,0 +1,62 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
==========================================
|
||||
Pluggable Protection Provider
|
||||
==========================================
|
||||
|
||||
https://blueprints.launchpad.net/smaug/+spec/operation-engine-design
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
Even though we allow each provider to be implemented in any way it pleases we
|
||||
foresee that most providers will want to be able share code between them.
|
||||
We would also like for a user to be able to easily extend the ProtectionProvider
|
||||
that will be provided by default.
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
As as solution we propose the *Pluggable Protection Provider*.
|
||||
|
||||
The *Pluggable Protection Provider* will be the reference implementation
|
||||
protection provider. It's purpose is to be fully pluggable and extandable so
|
||||
that only extream use cases will need to implement their own Protection Provider
|
||||
from scratch.
|
||||
|
||||
The protection provider will contain internally a map between any registered
|
||||
*Protectable* and a corrosponding *Protection Plugin*. When the pluggable
|
||||
protection provider is asked to perform an action, it will walk over the
|
||||
graph and pass a context object to the appropriate plugin whenever a node is
|
||||
encountered.
|
||||
|
||||
The resource graph is traversed in with DFS. When a node is first encountered
|
||||
the protection manager gets the plugin for the appropriate resource type, builds
|
||||
a context and passes it to the plugins `get_pre_task()` method. The plugin can
|
||||
return any tasks that it wants added to the task list. When all of a node
|
||||
childrens have been visited the `get_pre_task()` is called. The task returned
|
||||
from this method will also be added to the task list but is also guranteed to
|
||||
execute after all the child node's tasks have finished. Any of the methods can
|
||||
return `None` if they don't want any action performed.
|
||||
|
||||
After the entire grap has been traversed the Protection Provider will return
|
||||
the task lists which will be queued and than executed according to the
|
||||
executor's policy. When all the tasks are done the operation is considered
|
||||
complete.
|
||||
|
||||
This scheme decouples the tree structure form the task execution. A plugin that
|
||||
handles multiple resources or that aggregates mutiple resources to one task can
|
||||
use this mechanism to only return tasks when appropriate for it's scheme.
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/openstack/smaug/master/doc/images/pluggable_protection_provider.svg
|
||||
:alt: Smaug
|
||||
:align: center
|
||||
|
||||
References
|
||||
==========
|
||||
1. `Class Diagram Source <http://raw.githubusercontent.com/openstack/smaug/master/doc/images/specs/pluggable_protection_provider.pu>`_
|
||||
2. `Dependency graph building algorithm <https://docs.google.com/document/d/1Mkd9RgUVdiRL6iei8Nqzzx4xteKIcd-yjMLEkV4Jc9s/edit#>`_
|
Loading…
Reference in New Issue
Block a user