do not fail when generating documentation
[slapos.git] / stack / resilient / README.txt
1
2 Base resilient stack
3 ====================
4
5 This stack is meant to be extended by SR profiles, or other stacks, that need to provide
6 automated backup/restore, election of backup candidates, and instance failover.
7
8 As reference implementations, both stack/lamp and stack/lapp define resilient behavior for
9 MySQL and Postgres respectively.
10
11 This involves three different software_types:
12
13  * pull-backup
14  * {mysoftware}_export
15  * {mysoftware}_import
16
17 where 'mysoftware' is the component that needs resiliency (can be postgres, mysql, erp5, and so on).
18
19
20 pull-backup
21 -----------
22
23 This software type is defined in
24
25     http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/stack/resilient/instance-pull-backup.cfg.in?js=1
26
27 and there should be no reason to modify or extend it.
28
29 An instance of type 'pull-backup' will receive data from an 'export' instance and immediately populate an 'import' instance.
30 The backup data is automatically used to build an historical, incremental archive in srv/backup/pbs.
31
32
33 export
34 ------
35
36 example:
37     http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/stack/lapp/postgres/instance-postgres-export.cfg.in?js=1
38
39 This is the *active* instance - the one providing live data to the application.
40
41 A backup is run via the bin/exporter script: it will
42      1) run bin/{mysoftware}-backup
43  and 2) notify the pull-backup instance that data is ready.
44
45 The pull-backup, upon receiving the notification, will make a copy of the data and transmit it to the 'import' instances.
46
47 You should provide the bin/{mysoftware}-exporter script, see for instance
48   http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/slapos/recipe/postgres/__init__.py?js=1#l207
49   http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/slapos/recipe/mydumper.py?js=1#l71
50
51 By default, as defined in
52   http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/stack/resilient/pbsready-export.cfg.in?js=1#l27
53 the bin/exporter script is run every 60 minutes.
54
55
56
57 import
58 ------
59
60 example:
61     http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/stack/lapp/postgres/instance-postgres-import.cfg.in?js=1
62
63 This is the *fallback* instance - the one that can be activated and thus become active.
64 Any number of import instances can be used. Deciding which one should take over can be done manually
65 or through a monitoring + election script.
66
67
68 You should provide the bin/{mysoftware}-importer script, see for instance
69
70   http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/slapos/recipe/postgres/__init__.py?js=1#l233
71   http://git.erp5.org/gitweb/slapos.git/blob/HEAD:/slapos/recipe/mydumper.py?js=1#l71
72
73
74
75
76 In practice
77 -----------
78
79 Add resilience to your software
80
81 Let's say you already have a file instance-mysoftware.cfg.in that instantiates your
82 software. In which there is a part [mysoftware] where there is the main recipe
83 that instantiates the program.
84
85 You need to create two new files, instance-mysoftware-import.cfg.in and
86 instance-mysoftware-export.cfg.in, following this layout:
87
88
89 IMPORT:
90
91 [buildout]
92 extends = ${instance-mysoftware:output}
93           ${pbsready-import:output}
94
95 parts +=
96     mysoftware
97     import-on-notification
98
99 [importer]
100 recipe = YourImportRecipe
101 wrapper = $${rootdirectory:bin}/$${slap-parameter:namebase}-importer
102 backup-directory = $${directory:backup}
103 ...
104
105
106
107 EXPORT:
108
109 [buildout]
110 extends = ${instance-mysoftware:output}
111           ${pbsready-export:output}
112
113 parts +=
114     mysoftware
115     cron-entry-backup
116
117 [exporter]
118 recipe = YourExportRecipe
119 wrapper = $${rootdirectory:bin}/$${slap-parameter:namebase}-exporter
120 backup-directory = $${directory:backup}
121 ...
122
123
124 In the [exporter] / [importer] part, you are free to do whatever you want, but
125 you need to dump / import your data from $${directory:backup} and specify a
126 wrapper. I suggest you only add options and specify your export/import recipe.
127
128
129
130 -----------------------------------------------------------------------------------------
131
132 Finally, instance-mysoftware-import.cfg.in and
133 instance-mysoftware-export.cfg.in need to be downloaded and accessible by
134 switch_softwaretype, and you need to extend stack/resilient/buildout.cfg and
135 stack/resilient/switchsoftware.cfg to download the whole resiliency bundle.
136
137 Here is how it's done in the mariadb case for the lamp stack:
138
139
140
141  ** buildout.cfg **
142
143 extends =
144    ../resilient/buildout.cfg
145
146 [instance-mariadb-import]
147 recipe = slapos.recipe.template
148 url = ${:_profile_base_location_}/mariadb/instance-mariadb-import.cfg.in
149 output = ${buildout:directory}/instance-mariadb-import.cfg
150 md5sum = ...
151 mode = 0644
152
153 [instance-mariadb-export]
154 recipe = slapos.recipe.template
155 url = ${:_profile_base_location_}/mariadb/instance-mariadb-export.cfg.in
156 output = ${buildout:directory}/instance-mariadb-export.cfg
157 md5sum = ...
158 mode = 0644
159
160
161
162  ** instance.cfg.in **
163
164 extends =
165   ../resilient/switchsoftware.cfg
166
167 [switch-softwaretype]
168 ...
169 mariadb = ${instance-mariadb:output}
170 mariadb-import = ${instance-mariadb-import:output}
171 mariadb-export = ${instance-mariadb-export:output}
172 ...
173
174
175
176 Then, in the .cfg file where you want to instantiate your software, you can do, instead of requesting your software
177
178  * template-resilient.cfg.in *
179
180 [buildout]
181 ...
182 parts +=
183   {{ parts.replicate("Name","3") }}
184   ...
185
186 [...]
187 ...
188 [ArgLeader]
189 ...
190
191 [ArgBackup]
192 ...
193
194 {{ replicated.replicate("Name", "3",
195                         "mysoftware-export", "mysoftware-import",
196                         "ArgLeader","ArgBackup") }}
197
198 and it'll expend into the sections require to request Name0, Name1 and Name2,
199 backuped and resilient. The leader will expend the section [ArgLeader], backups
200 will expend [ArgBackup]. If you don't need to specify any options, you can
201 omit the last two arguments in replicate().
202
203 Since you will compile your template with jinja2, there should be no $${},
204 because it is not yet possible to use jinja2 -> buildout template.
205
206 To compile with jinja2, see jinja2's recipe.
207
208