PROJECT_MOVED -> https://lab.nexedi.com/nexedi/slapos
[slapos.git] / stack / resilient / template-replicated.cfg.in
1 {% macro replicate(namebase, nbbackup, typeexport, typeimport, heriteLeader='', heriteBackup='', slapparameter_dict={}) %}
2
3 {% set sla_parameter_dict = {} -%}
4 # prepare sla-parameters
5 {% if slapparameter_dict is defined -%}
6 {%   for key in slapparameter_dict.keys() -%}
7 {%     if key.startswith('-sla-') -%}
8 {%       do sla_parameter_dict.__setitem__(key, slapparameter_dict.pop(key)) -%}
9 {%     endif -%}
10 {%   endfor -%}
11 {% endif -%}
12
13
14 [resilient-directory]
15 recipe = slapos.cookbook:mkdirectory
16 home = ${buildout:directory}
17 etc = ${:home}/etc
18 promise = ${:etc}/promise
19
20
21 ## Tells the Backupable recipe that we want a backup
22 [resilient]
23 recipe = slapos.cookbook:request
24 config-namebase = {{namebase}}
25 software-url = ${slap-connection:software-release-url}
26
27 [request-{{namebase}}]
28 <= resilient
29    slap-connection
30    {{heriteLeader}}
31 software-type = {{typeexport}}
32 name = {{namebase}}0
33 return = ssh-public-key ssh-url notification-id ip
34 config-number = 0
35 config-authorized-key = {% for id in range(1,nbbackup|int) %} ${request-pbs-{{namebase}}-{{id}}:connection-ssh-key}{% endfor %}
36 config-notify = {% for id in range(1,nbbackup|int) %} ${request-pbs-{{namebase}}-{{id}}:connection-notification-url}{% endfor %}
37 # Bubble up all the instance parameters to the requested export instance.
38 {% if slapparameter_dict is defined %}
39 {% for parameter_name, parameter_value in slapparameter_dict.items() %}config-{{parameter_name}} = {{parameter_value}}
40 {% endfor %}
41 {% endif %}
42 {% if sla_parameter_dict == {} -%}
43 sla-mode = unique_by_network
44 {% else %}
45 {%   set sla_key_main = "-sla-%s%s-" % (namebase, 0) -%}
46 {%   set sla_key_secondary = "-sla-%s-" % (0) -%}
47 {%   set sla_key_main_length = sla_key_main | length -%}
48 {%   set sla_key_secondary_length = sla_key_secondary | length -%}
49 {%   set sla_dict = {} -%}
50 {%   for key in sla_parameter_dict.keys() -%}
51 {%     if key.startswith(sla_key_main) -%}
52 {%       do sla_dict.__setitem__(key[sla_key_main_length:], sla_parameter_dict.get(key)) -%}
53 {%     elif key.startswith(sla_key_secondary) and not sla_dict.has_key(key[sla_key_secondary_length:]) -%}
54 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
55 {%     endif -%}
56 {%   endfor -%}
57 {%   for key, value in sla_dict.iteritems() -%}
58 sla-{{ key }} = {{ value }}
59 {%   endfor -%}
60 {% endif -%}
61
62 {% for id in range(1,nbbackup|int) %}
63
64 [request-{{namebase}}-pseudo-replicating-{{id}}]
65 <= slap-connection
66    resilient
67    {{heriteBackup}}
68 recipe = slapos.cookbook:request
69 name = {{namebase}}{{id}}
70
71 software-url = ${slap-connection:software-release-url}
72 software-type = {{typeimport}}
73 return = ssh-public-key ssh-url notification-url ip takeover-url takeover-password
74
75 pbs-notification-id = ${slap-connection:computer-id}-${slap-connection:partition-id}-{{namebase}}-{{id}}-push
76
77 config-number = {{id}}
78 config-authorized-key = ${request-pbs-{{namebase}}-{{id}}:connection-ssh-key}
79 config-on-notification = ${request-pbs-{{namebase}}-{{id}}:connection-feeds-url}${:pbs-notification-id}
80 {% if sla_parameter_dict == {} -%}
81 sla-mode = unique_by_network
82 {% else %}
83 {%   set sla_key_main = "-sla-%s%s-" % (namebase, id) -%}
84 {%   set sla_key_secondary = "-sla-%s-" % (id) -%}
85 {%   set sla_key_main_length = sla_key_main | length -%}
86 {%   set sla_key_secondary_length = sla_key_secondary | length -%}
87 {%   set sla_dict = {} -%}
88 {%   for key in sla_parameter_dict.keys() -%}
89 {%     if key.startswith(sla_key_main) -%}
90 {%       do sla_dict.__setitem__(key[sla_key_main_length:], sla_parameter_dict.get(key)) -%}
91 {%     elif key.startswith(sla_key_secondary) and not sla_dict.has_key(key[sla_key_secondary_length:]) -%}
92 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
93 {%     endif -%}
94 {%   endfor -%}
95 {%   for key, value in sla_dict.iteritems() -%}
96 sla-{{ key }} = {{ value }}
97 {%   endfor -%}
98 {% endif %}
99
100 [publish-connection-information]
101 feed-url-{{namebase}}-{{id}}-push = ${request-pbs-{{namebase}}-{{id}}:connection-feeds-url}${request-{{namebase}}-pseudo-replicating-{{id}}:pbs-notification-id}
102 takeover-{{namebase}}-{{id}}-url = ${request-{{namebase}}-pseudo-replicating-{{id}}:connection-takeover-url}
103 takeover-{{namebase}}-{{id}}-password = ${request-{{namebase}}-pseudo-replicating-{{id}}:connection-takeover-password}
104
105 {% endfor -%}
106
107
108
109 [resilient-request-{{namebase}}-public-key-promise]
110 # Check that public-key-value parameter exists and is not empty
111 # XXX: maybe we should consider empty values to be non-nexistent.
112 recipe = collective.recipe.template
113 # XXX: don't use system executable
114 input = inline:#!/bin/sh
115   PUBLIC_KEY_CONTENT="${request-{{namebase}}:connection-ssh-public-key})"
116   if [[ ! -n "$PUBLIC_KEY_CONTENT" || "$PUBLIC_KEY_CONTENT" == *None* ]]; then
117     exit 1
118   fi
119 output = ${resilient-directory:promise}/resilient-request-{{namebase}}-public-key
120 mode = 700
121
122 {% for id in range(1,nbbackup|int) %}
123
124 [resilient-request-{{namebase}}-pseudo-replicating-{{id}}-public-key-promise]
125 # Check that public-key-value parameter exists and is not empty
126 # XXX: maybe we should consider empty values to be non-nexistent.
127 recipe = collective.recipe.template
128 # XXX: don't use system executable
129 input = inline:#!/bin/sh
130   PUBLIC_KEY_CONTENT="${request-{{namebase}}-pseudo-replicating-{{id}}:connection-ssh-public-key})"
131   if [[ ! -n "$PUBLIC_KEY_CONTENT" || "$PUBLIC_KEY_CONTENT" == *None* ]]; then
132     exit 1
133   fi
134 output = ${resilient-directory:promise}/resilient-request-{{namebase}}-pseudo-replicating-{{id}}-public-key
135 mode = 700
136
137 {% endfor %}
138
139
140
141 ## The PBS and their push / pull slaves
142 ## Adding a PBS provides resiliency
143 ## Adding a backup server provides availability
144
145 ## Having 3 backups pulling from the same PBS provides
146 ##only availability, not resiliency
147
148 [request-pbs-common]
149 <= slap-connection
150 recipe = slapos.cookbook:request
151 software-url = ${slap-connection:software-release-url}
152 software-type = pull-backup
153
154 {% for id in range(1,nbbackup|int) %}
155
156 [request-pbs-{{namebase}}-{{id}}]
157 <= request-pbs-common
158 name = PBS ({{namebase}} / {{id}})
159 config-ignore-known-hosts-file = ${slap-parameter:ignore-known-hosts-file}
160 return = ssh-key notification-url feeds-url
161 slave = false
162 {% if sla_parameter_dict == {} -%}
163 sla-mode = unique_by_network
164 {% else %}
165 {%   set sla_key_main = "-sla-%s%s-" % ("pbs", id) -%}
166 {%   set sla_key_secondary = "-sla-%s-" % (id) -%}
167 {%   set sla_key_main_length = sla_key_main | length -%}
168 {%   set sla_key_secondary_length = sla_key_secondary | length -%}
169 {%   set sla_dict = {} -%}
170 {%   for key in sla_parameter_dict.keys() -%}
171 {%     if key.startswith(sla_key_main) -%}
172 {%       do sla_dict.__setitem__(key[sla_key_main_length:], sla_parameter_dict.get(key)) -%}
173 {%     elif key.startswith(sla_key_secondary) and not sla_dict.has_key(key[sla_key_secondary_length:]) -%}
174 {%         do sla_dict.__setitem__(key[sla_key_secondary_length:], sla_parameter_dict.get(key)) -%}
175 {%     endif -%}
176 {%   endfor -%}
177 {%   for key, value in sla_dict.iteritems() -%}
178 sla-{{ key }} = {{ value }}
179 {%   endfor %}
180 {% endif %}
181
182 [resilient-request-pbs-{{namebase}}-{{id}}-public-key-promise]
183 # Check that public-key-value parameter exists and is not empty
184 # XXX: maybe we should consider empty values to be non-nexistent.
185 recipe = collective.recipe.template
186 # XXX: don't use system executable
187 input = inline:#!/bin/sh
188   PUBLIC_KEY_CONTENT="${request-pbs-{{namebase}}-{{id}}:connection-ssh-key}:connection-ssh-key})"
189   if [[ ! -n "$PUBLIC_KEY_CONTENT" || "$PUBLIC_KEY_CONTENT" == *None* ]]; then
190     exit 1
191   fi
192 output = ${resilient-directory:promise}/resilient-request-{{namebase}}-pseudo-replicating-{{id}}-public-key
193 mode = 700
194
195
196 [request-pull-backup-server-{{namebase}}-{{id}}]
197 <= request-pbs-common
198 name = PBS {{id}} pulling from ${request-{{namebase}}:name}
199 config-url = ${request-{{namebase}}:connection-ssh-url}
200 config-type = pull
201 config-server-key = ${request-{{namebase}}:connection-ssh-public-key}
202 config-on-notification = ${request-{{namebase}}:connection-notification-id}
203 config-notify = ${request-pbs-{{namebase}}-{{id}}:connection-notification-url}
204 config-notification-id = ${slap-connection:computer-id}-${slap-connection:partition-id}-{{namebase}}-{{id}}-pull
205 config-name = ${slap-connection:computer-id}-${slap-connection:partition-id}-{{namebase}}-{{id}}
206 config-title = Pulling from {{namebase}}
207 config-remove-backup-older-than = {{ slapparameter_dict.get('remove-backup-older-than', '2W') }}
208 slave = true
209 sla-instance_guid = ${request-pbs-{{namebase}}-{{id}}:instance_guid}
210
211 [publish-connection-information]
212 feed-url-{{namebase}}-{{id}}-pull = ${request-pbs-{{namebase}}-{{id}}:connection-feeds-url}${request-pull-backup-server-{{namebase}}-{{id}}:config-notification-id}
213
214
215 [request-pull-backup-server-{{namebase}}-backup-{{id}}]
216 <= request-pbs-common
217 name = PBS pushing on ${request-{{namebase}}-pseudo-replicating-{{id}}:name}
218 config-url = ${request-{{namebase}}-pseudo-replicating-{{id}}:connection-ssh-url}
219 config-type = push
220 config-server-key = ${request-{{namebase}}-pseudo-replicating-{{id}}:connection-ssh-public-key}
221 config-on-notification = ${request-pbs-{{namebase}}-{{id}}:connection-feeds-url}${request-pull-backup-server-{{namebase}}-{{id}}:config-notification-id}
222 config-notify = ${request-{{namebase}}-pseudo-replicating-{{id}}:connection-notification-url}
223 config-notification-id = ${request-{{namebase}}-pseudo-replicating-{{id}}:pbs-notification-id}
224 config-name = ${slap-connection:computer-id}-${slap-connection:partition-id}-{{namebase}}-{{id}}
225 config-title = Pushing to {{namebase}} backup {{id}}
226 slave = true
227 sla-instance_guid = ${request-pbs-{{namebase}}-{{id}}:instance_guid}
228 {% endfor %}
229
230 [slap-parameter]
231 # Default parameters for distributed deployment
232 # I.e state "backup1 of maria should go there, ..."
233 {% for id in range(1,nbbackup|int) %}
234 {{namebase}}{{id}}-computer-guid =
235 pbs-{{namebase}}{{id}}-computer-guid =
236 {% endfor %}
237 ignore-known-hosts-file = false
238
239 {% endmacro %}
240