root / docs / upgrade-0.13.rst @ 6c931e8b
History | View | Annotate | Download (19.1 kB)
1 |
Upgrade to Synnefo v0.13 |
---|---|
2 |
^^^^^^^^^^^^^^^^^^^^^^^^ |
3 |
|
4 |
The bulk of the upgrade to v0.13 is about user and quota migrations. |
5 |
In summary, the migration process has 3 steps: |
6 |
|
7 |
1. Run some commands and scripts to diagnose and extract some migration data |
8 |
while the OLD code is running, and BEFORE any changes are made. |
9 |
|
10 |
2. Bring down services, upgrade packages, configure services, and perform |
11 |
django database migrations. These migrations do not need any interaction |
12 |
between services. |
13 |
|
14 |
3. Initialize the Astakos quota system and bring the Astakos service up, since |
15 |
it will be needed during a second-phase of UUID and quota migrations, that |
16 |
also uses data extracted from step 1. |
17 |
|
18 |
|
19 |
.. warning:: |
20 |
|
21 |
It is strongly suggested that you keep separate database backups |
22 |
for each service after the completion of each of step. |
23 |
|
24 |
1. Bring web services down, backup databases |
25 |
============================================ |
26 |
|
27 |
1. All web services must be brought down so that the database maintains a |
28 |
predictable and consistent state during the migration process. |
29 |
|
30 |
2. Backup databases for recovery to a pre-migration state. |
31 |
|
32 |
3. Keep the database servers running during the migration process |
33 |
|
34 |
|
35 |
2. Prepare astakos user migration to case insensitive emails |
36 |
============================================================ |
37 |
|
38 |
It is possible that two or more users have been registered with emails that |
39 |
differ only in the case of its letters. There can only be one of those |
40 |
accounts after the migration, so the rest must be deleted. |
41 |
|
42 |
Note that even if the users are deleted in Astakos, there still are duplicate |
43 |
entries in Cyclades and Pithos. For each service we need to reduce those |
44 |
multiple accounts into one, either merging them together, or deleting and |
45 |
discarding data from all but one. |
46 |
|
47 |
.. _find_duplicate_emails: |
48 |
|
49 |
2.1 Find duplicate email entries in Astakos |
50 |
------------------------------------------- |
51 |
(script: ``find_astakos_users_with_conflicting_emails.py``):: |
52 |
|
53 |
astakos-host$ cat << EOF > find_astakos_users_with_conflicting_emails.py |
54 |
#!/usr/bin/env python |
55 |
import os |
56 |
import sys |
57 |
|
58 |
os.environ['DJANGO_SETTINGS_MODULE'] = 'synnefo.settings' |
59 |
|
60 |
import astakos |
61 |
from astakos.im.models import AstakosUser as A |
62 |
|
63 |
|
64 |
def user_filter(user): |
65 |
return A.objects.filter(email__iexact=user.email).count() > 1 |
66 |
|
67 |
all_users = list(A.objects.all()) |
68 |
userlist = [(str(u.pk) + ': ' + str(u.email) + ' (' + str(u.is_active) + ', ' + |
69 |
str(u.date_joined) + ')') for u in filter(user_filter, all_users)] |
70 |
|
71 |
sys.stderr.write("id email (is_active, creation date)\n") |
72 |
print "\n".join(userlist) |
73 |
EOF |
74 |
|
75 |
astakos-host$ python ./find_astakos_users_with_conflicting_emails.py |
76 |
|
77 |
.. _remove_astakos_duplicate: |
78 |
|
79 |
2.1 Remove duplicate users in Astakos by their id |
80 |
------------------------------------------------- |
81 |
(script: ``delete_astakos_users.py``):: |
82 |
|
83 |
astakos-host$ cat << EOF > delete_astakos_users.py |
84 |
#!/usr/bin/env python |
85 |
|
86 |
import os |
87 |
import sys |
88 |
from time import sleep |
89 |
|
90 |
os.environ['DJANGO_SETTINGS_MODULE'] = 'synnefo.settings' |
91 |
|
92 |
import astakos |
93 |
from astakos.im.models import AstakosUser as A |
94 |
|
95 |
|
96 |
def user_filter(user): |
97 |
return A.objects.filter(email__iexact=user.email).count() > 1 |
98 |
|
99 |
argv = sys.argv |
100 |
argc = len(sys.argv) |
101 |
|
102 |
if argc < 2: |
103 |
print "Usage: ./delete_astakos_users.py <id>..." |
104 |
raise SystemExit() |
105 |
|
106 |
id_list = [int(x) for x in argv[1:]] |
107 |
|
108 |
print "" |
109 |
print "This will permanently delete the following users:\n" |
110 |
print "id email (is_active, creation date)" |
111 |
print "-- --------------------------------" |
112 |
|
113 |
users = A.objects.filter(id__in=id_list) |
114 |
for user in users: |
115 |
print "%s: %s (%s, %s)" % (user.id, user.email, user.is_active, |
116 |
user.date_joined) |
117 |
|
118 |
print "\nExecute? (yes/no): ", |
119 |
line = raw_input().rstrip() |
120 |
if line != 'yes': |
121 |
print "\nCancelled" |
122 |
raise SystemExit() |
123 |
|
124 |
print "\nConfirmed." |
125 |
sleep(2) |
126 |
for user in users: |
127 |
print "deleting %s: %s" % (user.id, user.email) |
128 |
user.delete() |
129 |
|
130 |
EOF |
131 |
|
132 |
astakos-host$ python ./delete_astakos_users.py 30 40 |
133 |
|
134 |
.. warning:: |
135 |
|
136 |
After deleting users with the ``delete_astakos_users.py`` script, |
137 |
check again with ``find_astakos_users_with_conflicting_emails.py`` |
138 |
(as in :ref:`find_duplicate_emails`) |
139 |
to make sure that no duplicate email conflicts remain. |
140 |
|
141 |
|
142 |
3. Upgrade Synnefo and configure settings |
143 |
========================================= |
144 |
|
145 |
3.1 Install the new versions of packages |
146 |
---------------------------------------- |
147 |
|
148 |
:: |
149 |
|
150 |
astakos.host$ apt-get install \ |
151 |
snf-common \ |
152 |
snf-webproject \ |
153 |
snf-quotaholder-app \ |
154 |
snf-astakos-app \ |
155 |
kamaki \ |
156 |
|
157 |
|
158 |
cyclades.host$ apt-get install \ |
159 |
snf-common \ |
160 |
snf-webproject |
161 |
snf-pithos-backend \ |
162 |
snf-cyclades-app \ |
163 |
kamaki \ |
164 |
|
165 |
|
166 |
pithos.host$ apt-get install \ |
167 |
snf-common \ |
168 |
snf-webproject |
169 |
snf-pithos-backend \ |
170 |
snf-pithos-app \ |
171 |
snf-pithos-webclient \ |
172 |
kamaki \ |
173 |
|
174 |
|
175 |
ganeti.node$ apt-get install \ |
176 |
snf-cyclades-gtools \ |
177 |
snf-pithos-backend \ |
178 |
kamaki \ |
179 |
|
180 |
.. note:: |
181 |
|
182 |
If you get questioned about stale content types during the |
183 |
migration process, answer ``no`` and let the migration finish. |
184 |
|
185 |
|
186 |
3.2 Sync and migrate Django DB |
187 |
------------------------------ |
188 |
|
189 |
.. note:: |
190 |
|
191 |
If you are asked about stale content types during the migration process, |
192 |
answer 'no' and let the migration finish. |
193 |
|
194 |
:: |
195 |
|
196 |
astakos-host$ snf-manage syncdb |
197 |
astakos-host$ snf-manage migrate |
198 |
|
199 |
cyclades-host$ snf-manage syncdb |
200 |
cyclades-host$ snf-manage migrate |
201 |
|
202 |
.. note:: |
203 |
|
204 |
After the migration, Astakos has created uuids for all users, |
205 |
and has set the uuid as the public identifier of a user. |
206 |
This uuid is to be used both at other services (Cyclades, Pithos) |
207 |
and at the clientside (kamaki client settings). |
208 |
|
209 |
Duplicate-email users have been deleted earlier in |
210 |
:ref:`remove_astakos_duplicate` |
211 |
|
212 |
3.3 Setup quota settings for all services |
213 |
----------------------------------------- |
214 |
|
215 |
Generally: |
216 |
|
217 |
:: |
218 |
|
219 |
# Service Setting Value |
220 |
# quotaholder: QUOTAHOLDER_TOKEN = <random string> |
221 |
|
222 |
# astakos: ASTAKOS_QUOTAHOLDER_TOKEN = <the same random string> |
223 |
# astakos: ASTAKOS_QUOTAHOLDER_URL = https://quotaholder.host/quotaholder/v |
224 |
|
225 |
# cyclades: CYCLADES_QUOTAHOLDER_TOKEN = <the same random string> |
226 |
# cyclades: CYCLADES_QUOTAHOLDER_URL = http://quotaholder.host/quotaholder/v |
227 |
# cyclades: CYCLADES_USE_QUOTAHOLDER = True |
228 |
|
229 |
|
230 |
# pithos: PITHOS_QUOTAHOLDER_TOKEN = <the same random string> |
231 |
# pithos: PITHOS_QUOTAHOLDER_URL = http://quotaholder.host/quotaholder/v |
232 |
# pithos: PITHOS_USE_QUOTAHOLDER = True |
233 |
# All services must match the quotaholder token and url configured for quotaholder. |
234 |
|
235 |
Specifically: |
236 |
|
237 |
On the Astakos host, edit ``/etc/synnefo/20-snf-astakos-app-settings.conf``: |
238 |
|
239 |
:: |
240 |
|
241 |
QUOTAHOLDER_TOKEN = 'aExampleTokenJbFm12w' |
242 |
ASTAKOS_QUOTAHOLDER_TOKEN = 'aExampleTokenJbFm12w' |
243 |
ASTAKOS_QUOTAHOLDER_URL = 'https://accounts.synnefo.local/quotaholder/v' |
244 |
|
245 |
On the Cyclades host, edit ``/etc/synnefo/20-snf-cyclades-app-quotas.conf``: |
246 |
|
247 |
:: |
248 |
|
249 |
CYCLADES_USE_QUOTAHOLDER = True |
250 |
CYCLADES_QUOTAHOLDER_URL = 'https://accounts.synnefo.local/quotaholder/v' |
251 |
CYCLADES_QUOTAHOLDER_TOKEN = 'aExampleTokenJbFm12w' |
252 |
|
253 |
On the Pithos host, edit ``/etc/synnefo/20-snf-pithos-app-settings.conf``: |
254 |
|
255 |
:: |
256 |
|
257 |
PITHOS_QUOTAHOLDER_URL = 'https://accounts.synnefo.local/quotaholder/v' |
258 |
PITHOS_QUOTAHOLDER_TOKEN = 'aExampleTokenJbFm12w' |
259 |
PITHOS_USE_QUOTAHOLDER = True |
260 |
|
261 |
3.4 Setup astakos |
262 |
----------------- |
263 |
|
264 |
- **Remove** this redirection from astakos front-end web server :: |
265 |
|
266 |
RewriteRule ^/login(.*) /im/login/redirect$1 [PT,NE] |
267 |
|
268 |
(see `<http://docs.dev.grnet.gr/synnefo/latest/quick-install-admin-guide.html#apache2-setup>`_) |
269 |
|
270 |
- Enable users to change their contact email. Edit |
271 |
``/etc/synnefo/20-snf-astakos-app-settings.conf`` :: |
272 |
|
273 |
ASTAKOS_EMAILCHANGE_ENABLED = True |
274 |
|
275 |
3.5 Setup Cyclades |
276 |
------------------ |
277 |
|
278 |
- Run on the Astakos host :: |
279 |
|
280 |
# snf-manage service-list |
281 |
|
282 |
- Set the Cyclades service token in ``/etc/synnefo/20-snf-cyclades-app-api.conf`` :: |
283 |
|
284 |
CYCLADES_ASTAKOS_SERVICE_TOKEN = 'asfasdf_CycladesServiceToken_iknl' |
285 |
|
286 |
- Since version 0.13, Synnefo uses **VMAPI** in order to prevent sensitive data |
287 |
needed by 'snf-image' to be stored in Ganeti configuration (e.g. VM |
288 |
password). This is achieved by storing all sensitive information to a CACHE |
289 |
backend and exporting it via VMAPI. The cache entries are invalidated after |
290 |
the first request. Synnefo uses **memcached** as a django cache backend. |
291 |
To install, run on the Cyclades host:: |
292 |
|
293 |
apt-get install memcached |
294 |
apt-get install python-memcache |
295 |
|
296 |
You will also need to configure Cyclades to use the memcached cache backend. |
297 |
Namely, you need to set IP address and port of the memcached daemon, and the |
298 |
default timeout (seconds tha value is stored in the cache). Edit |
299 |
``/etc/synnefo/20-snf-cyclades-app-vmapi.conf`` :: |
300 |
|
301 |
VMAPI_CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=3600" |
302 |
|
303 |
|
304 |
Finally, set the BASE_URL for the VMAPI, which is actually the base URL of |
305 |
Cyclades, again in ``/etc/synnefo/20-snf-cyclades-app-vmapi.conf``. Make sure |
306 |
the domain is exaclty the same, so that no re-directs happen :: |
307 |
|
308 |
VMAPI_BASE_URL = "https://cyclades.synnefo.local" |
309 |
|
310 |
.. note:: |
311 |
|
312 |
- These settings are needed in all Cyclades workers. |
313 |
|
314 |
- VMAPI_CACHE_BACKEND just overrides django's CACHE_BACKEND setting |
315 |
|
316 |
- memcached must be reachable from all Cyclades workers. |
317 |
|
318 |
- For more information about configuring django to use memcached: |
319 |
https://docs.djangoproject.com/en/1.2/topics/cache |
320 |
|
321 |
3.6 Setup Pithos |
322 |
---------------- |
323 |
|
324 |
- Pithos forwards user catalog services to Astakos so that web clients may |
325 |
access them for uuid-displayname translations. Edit on the Pithos host |
326 |
``/etc/synnefo/20-snf-pithos-app-settings.conf`` :: |
327 |
|
328 |
PITHOS_USER_CATALOG_URL = https://accounts.synnefo.local/user_catalogs/ |
329 |
PITHOS_USER_FEEDBACK_URL = https://accounts.synnefo.local/feedback/ |
330 |
PITHOS_USER_LOGIN_URL = https://accounts.synnefo.local/login/ |
331 |
#PITHOS_PROXY_USER_SERVICES = True # Set False if astakos & pithos are on the same host |
332 |
|
333 |
|
334 |
4. Start astakos and quota services |
335 |
=================================== |
336 |
Start the webserver and gunicorn on the Astakos host. E.g.:: |
337 |
|
338 |
# service apache2 start |
339 |
# service gunicorn start |
340 |
|
341 |
.. warning:: |
342 |
|
343 |
To ensure consistency, prevent public access to astakos during migrations. |
344 |
This can be done via firewall or webserver access control. |
345 |
|
346 |
.. _astakos-load-resources: |
347 |
|
348 |
5. Load resource definitions into Astakos |
349 |
========================================= |
350 |
|
351 |
First, set the corresponding values on the following dict in |
352 |
``/etc/synnefo/20-snf-astakos-app-settings.conf`` :: |
353 |
|
354 |
# Set the cloud service properties |
355 |
ASTAKOS_SERVICES = { |
356 |
'cyclades': { |
357 |
# # Specifying the key 'url' will overwrite it. |
358 |
# # Use this to (re)set service URL. |
359 |
# 'url': 'https://cyclades.synnefo.local/ui/', |
360 |
# # order services in listings, cloudbar, etc. |
361 |
# 'order' : 1 |
362 |
'resources': [{ |
363 |
'name': 'disk', |
364 |
'group': 'compute', |
365 |
'uplimit': 30*1024*1024*1024, |
366 |
'unit': 'bytes', |
367 |
'desc': 'Virtual machine disk size' |
368 |
}, { |
369 |
'name': 'cpu', |
370 |
'group': 'compute', |
371 |
'uplimit': 6, |
372 |
'desc': 'Number of virtual machine processors' |
373 |
}, { |
374 |
'name': 'ram', |
375 |
'group': 'compute', |
376 |
'uplimit': 6*1024*1024*1024, |
377 |
'unit': 'bytes', |
378 |
'desc': 'Virtual machines' |
379 |
}, { |
380 |
'name': 'vm', |
381 |
'group': 'compute', |
382 |
'uplimit': 2, |
383 |
'desc': 'Number of virtual machines' |
384 |
}, { |
385 |
'name': 'network.private', |
386 |
'group': 'network', |
387 |
'uplimit': 1, |
388 |
'desc': 'Private networks' |
389 |
} |
390 |
] |
391 |
}, |
392 |
'pithos+': { |
393 |
# # Use this to (re)set service URL. |
394 |
# 'url': 'https://pithos.synnefo.local/ui/', |
395 |
# # order services in listings, cloudbar, etc. |
396 |
# 'order' : 2 |
397 |
'resources':[{ |
398 |
'name': 'diskspace', |
399 |
'group': 'storage', |
400 |
'uplimit': 5*1024*1024*1024, |
401 |
'unit': 'bytes', |
402 |
'desc': 'Pithos account diskspace' |
403 |
}] |
404 |
} |
405 |
} |
406 |
|
407 |
Then, configure and load the available resources per service |
408 |
and associated default limits into Astakos. On the Astakos host run :: |
409 |
|
410 |
# snf-manage astakos-init --load-service-resources |
411 |
|
412 |
|
413 |
.. note:: |
414 |
|
415 |
Before v0.13, only `cyclades.vm`, `cyclades.network.private`, |
416 |
and `pithos+.diskspace` existed (not with this names, of course). |
417 |
However, limits to the new resources must also be set. |
418 |
|
419 |
If the intetion is to keep a resource unlimited, (counting on that VM |
420 |
creation will be limited by other resources' limit) it is best to calculate |
421 |
a value that is too large to be reached because of other limits (and |
422 |
available flavours), but not much larger than needed because this might |
423 |
confuse users who do not readily understand that multiple limits apply and |
424 |
flavors are limited. |
425 |
|
426 |
|
427 |
6. Migrate Services user names to uuids |
428 |
======================================= |
429 |
|
430 |
|
431 |
6.1 Double-check cyclades before user case/uuid migration |
432 |
--------------------------------------------------------- |
433 |
|
434 |
:: |
435 |
|
436 |
cyclades.host$ snf-manage cyclades-astakos-migrate-013 --validate |
437 |
|
438 |
Duplicate user found? |
439 |
|
440 |
- either *merge* (merge will merge all resources to one user):: |
441 |
|
442 |
cyclades.host$ snf-manage cyclades-astakos-migrate-013 --merge-user=kpap@grnet.gr |
443 |
|
444 |
- or *delete* :: |
445 |
|
446 |
cyclades.host$ snf-manage cyclades-astakos-migrate-013 --delete-user=KPap@grnet.gr |
447 |
# (only KPap will be deleted not kpap) |
448 |
|
449 |
6.2 Double-check pithos before user case/uuid migration |
450 |
--------------------------------------------------------- |
451 |
|
452 |
:: |
453 |
|
454 |
pithos.host$ snf-manage pithos-manage-accounts --list-duplicate |
455 |
|
456 |
Duplicate user found? |
457 |
|
458 |
If you want to migrate files first: |
459 |
|
460 |
- *merge* (merge will merge all resources to one user):: |
461 |
|
462 |
pithos.host$ snf-manage pithos-manage-accounts --merge-accounts --src-account=SPapagian@grnet.gr --dest-account=spapagian@grnet.gr |
463 |
# (SPapagian@grnet.gr's contents will be merged into spapagian@grnet.gr, but SPapagian@grnet.gr account will still exist) |
464 |
|
465 |
- and then *delete* :: |
466 |
|
467 |
pithos.host$ snf-manage pithos-manage-accounts --delete-account=SPapagian@grnet.gr |
468 |
# (only SPapagian@grnet.gr will be deleted not spapagian@grnet.gr) |
469 |
|
470 |
If you do *NOT* want to migrate files just run the second step and delete |
471 |
the duplicate account. |
472 |
|
473 |
6.3 Migrate Cyclades users (email case/uuid) |
474 |
-------------------------------------------- |
475 |
|
476 |
:: |
477 |
|
478 |
cyclades.host$ snf-manage cyclades-astakos-migrate-013 --migrate-users |
479 |
|
480 |
- if invalid usernames are found, verify that they do not exist in astakos:: |
481 |
|
482 |
astakos.host$ snf-manage user-list |
483 |
|
484 |
- if no user exists:: |
485 |
|
486 |
cyclades.host$ snf-manage cyclades-astakos-migrate-013 --delete-user=<userid> |
487 |
|
488 |
Finally, if you have set manually quotas for specific users inside |
489 |
``/etc/synnefo/20-snf-cyclades-app-api.conf`` (in ``VMS_USER_QUOTA``, |
490 |
``NETWORKS_USER_QUOTA`` make sure to update them so that: |
491 |
|
492 |
1. There are no double entries wrt case sensitivity |
493 |
2. Replace all user email addresses with the corresponding UUIDs |
494 |
|
495 |
To find the UUIDs for step 2 run on the Astakos host :: |
496 |
|
497 |
# snf-manage user-list |
498 |
|
499 |
6.4 Migrate Pithos user names |
500 |
----------------------------- |
501 |
|
502 |
Check if alembic has not been initialized :: |
503 |
|
504 |
pithos.host$ pithos-migrate current |
505 |
|
506 |
- If alembic current is None (e.g. okeanos.io) :: |
507 |
|
508 |
pithos.host$ pithos-migrate stamp 3dd56e750a3 |
509 |
|
510 |
Finally, migrate pithos account name to uuid:: |
511 |
|
512 |
pithos.host$ pithos-migrate upgrade head |
513 |
|
514 |
7. Migrate old quota limits |
515 |
=========================== |
516 |
|
517 |
7.1 Migrate Pithos quota limits to Astakos |
518 |
------------------------------------------ |
519 |
|
520 |
Migrate from pithos native to astakos/quotaholder. |
521 |
This requires a file to be transfered from Cyclades to Astakos:: |
522 |
|
523 |
pithos.host$ snf-manage pithos-export-quota --location=pithos-quota.txt |
524 |
pithos.host$ rsync -avP pithos-quota.txt astakos.host: |
525 |
astakos.host$ snf-manage user-set-initial-quota pithos-quota.txt |
526 |
|
527 |
.. _export-quota-note: |
528 |
|
529 |
.. note:: |
530 |
|
531 |
`pithos-export-quota` will only export quotas that are not equal to the |
532 |
defaults in Pithos. Therefore, it is possible to both change or maintain |
533 |
the default quotas across the migration. To maintain quotas the new default |
534 |
pithos+.diskpace limit in Astakos must be equal to the (old) default quota |
535 |
limit in Pithos. Change either one of them make them equal. |
536 |
|
537 |
see :ref:`astakos-load-resources` on how to set the (new) default quotas in Astakos. |
538 |
|
539 |
7.2 Migrate Cyclades quota limits to Astakos |
540 |
-------------------------------------------- |
541 |
|
542 |
:: |
543 |
|
544 |
cyclades.host$ snf-manage cyclades-export-quota --location=cyclades-quota.txt |
545 |
cyclades.host$ rsync -avP cyclades-quota.txt astakos.host: |
546 |
astakos.host$ snf-manage user-set-initial-quota cyclades-quota.txt |
547 |
|
548 |
`cyclades-export-quota` will only export quotas that are not equal to the defaults. |
549 |
See :ref:`note above <export-quota-note>`. |
550 |
|
551 |
8. Enforce the new quota limits migrated to Astakos |
552 |
=================================================== |
553 |
The following should report all users not having quota limits set |
554 |
because the effective quota database has not been initialized yet. :: |
555 |
|
556 |
astakos.host$ snf-manage astakos-quota --verify |
557 |
|
558 |
Initialize the effective quota database:: |
559 |
|
560 |
astakos.host$ snf-manage astakos-quota --sync |
561 |
|
562 |
This procedure may be used to verify and re-synchronize the effective quota |
563 |
database with the quota limits that are derived from policies in Astakos |
564 |
(initial quotas, project memberships, etc.) |
565 |
|
566 |
9. Initialize resource usage |
567 |
============================ |
568 |
|
569 |
The effective quota database (quotaholder) has just been initialized and knows |
570 |
nothing of the current resource usage. Therefore, each service must send it in. |
571 |
|
572 |
9.1 Initialize Pithos resource usage |
573 |
------------------------------------ |
574 |
|
575 |
:: |
576 |
|
577 |
pithos.host$ snf-manage pithos-reset-usage |
578 |
|
579 |
9.2 Initialize Cyclades resource usage |
580 |
-------------------------------------- |
581 |
|
582 |
:: |
583 |
|
584 |
cyclades.host$ snf-manage cyclades-reset-usage |
585 |
|
586 |
10. Install periodic project maintainance checks |
587 |
================================================ |
588 |
In order to detect and effect project expiration, |
589 |
a management command has to be run periodically |
590 |
(depending on the required granularity, e.g. once a day/hour):: |
591 |
|
592 |
astakos.host$ snf-manage project-control --terminate-expired |
593 |
|
594 |
A list of expired projects can be extracted with:: |
595 |
|
596 |
astakos.host$ snf-manage project-control --list-expired |
597 |
|