author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Tue, 06 Jul 2010 17:15:25 +0200 | |
changeset 5909 | 9af8ac182f53 |
parent 5424 | 8ecbcbff9777 |
permissions | -rw-r--r-- |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
1 |
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
3 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
4 |
# This file is part of CubicWeb. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
5 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
9 |
# any later version. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
10 |
# |
5424
8ecbcbff9777
replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5421
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
14 |
# details. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
15 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4835
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
0 | 18 |
"""special management views to manage repository content (initialization and |
19 |
restoration). |
|
20 |
||
21 |
""" |
|
22 |
__docformat__ = "restructuredtext en" |
|
23 |
||
24 |
from os.path import exists, join, abspath |
|
25 |
from pickle import loads, dumps |
|
26 |
||
27 |
from logilab.common.decorators import cached |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
28 |
from logilab.mtconverter import xml_escape |
0 | 29 |
|
692
800592b8d39b
replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
635
diff
changeset
|
30 |
from cubicweb.selectors import none_rset, match_user_groups |
4023
eae23c40627a
drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
31 |
from cubicweb.view import StartupView |
0 | 32 |
from cubicweb.web import Redirect |
33 |
from cubicweb.goa.dbinit import fix_entities, init_persistent_schema, insert_versions |
|
34 |
||
35 |
from google.appengine.api.datastore import Entity, Key, Get, Put, Delete |
|
36 |
from google.appengine.api.datastore_types import Blob |
|
37 |
from google.appengine.api.datastore_errors import EntityNotFoundError |
|
38 |
||
39 |
||
40 |
def _get_status(name, create=True): |
|
41 |
key = Key.from_path('EApplicationStatus', name) |
|
42 |
try: |
|
43 |
status = Get(key) |
|
44 |
except EntityNotFoundError: |
|
45 |
if create: |
|
46 |
status = Entity('EApplicationStatus', name=name) |
|
47 |
else: |
|
48 |
status = None |
|
49 |
return status |
|
50 |
||
51 |
||
52 |
class AuthInfo(StartupView): |
|
53 |
"""special management view to get cookie values to give to laxctl commands |
|
54 |
which are doing datastore administration requests |
|
55 |
""" |
|
56 |
id = 'authinfo' |
|
742
99115e029dca
replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
692
diff
changeset
|
57 |
__select__ = none_rset() & match_user_groups('managers') |
0 | 58 |
|
59 |
def call(self): |
|
60 |
cookie = self.req.get_cookie() |
|
61 |
values = [] |
|
62 |
if self.config['use-google-auth']: |
|
63 |
for param in ('ACSID', 'dev_appserver_login'): |
|
64 |
morsel = cookie.get(param) |
|
65 |
if morsel: |
|
66 |
values.append('%s=%s' % (param, morsel.value)) |
|
67 |
break |
|
68 |
values.append('__session=%s' % cookie['__session'].value) |
|
69 |
self.w(u"<p>pass this flag to the client: --cookie='%s'</p>" |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
70 |
% xml_escape('; '.join(values))) |
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
71 |
|
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
72 |
|
0 | 73 |
|
74 |
class ContentInit(StartupView): |
|
75 |
"""special management view to initialize content of a repository, |
|
76 |
step by step to avoid depassing quotas |
|
77 |
""" |
|
78 |
id = 'contentinit' |
|
742
99115e029dca
replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
692
diff
changeset
|
79 |
__select__ = none_rset() & match_user_groups('managers') |
0 | 80 |
|
81 |
def server_session(self): |
|
82 |
ssession = self.config.repo_session(self.req.cnx.sessionid) |
|
83 |
ssession.set_pool() |
|
84 |
return ssession |
|
85 |
||
86 |
def end_core_step(self, msg, status, stepid): |
|
87 |
status['cpath'] = '' |
|
88 |
status['stepid'] = stepid |
|
89 |
Put(status) |
|
90 |
self.msg(msg) |
|
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
91 |
|
0 | 92 |
def call(self): |
93 |
status = _get_status('creation') |
|
94 |
if status.get('finished'): |
|
95 |
self.redirect('process already completed') |
|
96 |
config = self.config |
|
97 |
# execute cubicweb's post<event> script |
|
98 |
#mhandler.exec_event_script('post%s' % event) |
|
99 |
# execute cubes'post<event> script if any |
|
100 |
paths = [p for p in config.cubes_path() + [config.apphome] |
|
101 |
if exists(join(p, 'migration'))] |
|
102 |
paths = [abspath(p) for p in (reversed(paths))] |
|
103 |
cpath = status.get('cpath') |
|
104 |
if cpath is None and status.get('stepid') is None: |
|
105 |
init_persistent_schema(self.server_session(), self.schema) |
|
106 |
self.end_core_step(u'inserted schema entities', status, 0) |
|
107 |
return |
|
108 |
if cpath == '' and status.get('stepid') == 0: |
|
109 |
fix_entities(self.schema) |
|
110 |
self.end_core_step(u'fixed bootstrap groups and users', status, 1) |
|
111 |
return |
|
112 |
if cpath == '' and status.get('stepid') == 1: |
|
113 |
insert_versions(self.server_session(), self.config) |
|
114 |
self.end_core_step(u'inserted software versions', status, None) |
|
115 |
return |
|
116 |
for i, path in enumerate(paths): |
|
117 |
if not cpath or cpath == path: |
|
118 |
self.info('running %s', path) |
|
119 |
stepid = status.get('stepid') |
|
120 |
context = status.get('context') |
|
121 |
if context is not None: |
|
122 |
context = loads(context) |
|
123 |
else: |
|
124 |
context = {} |
|
125 |
stepid = self._migrhandler.exec_event_script( |
|
126 |
'postcreate', path, 'stepable_postcreate', stepid, context) |
|
127 |
if stepid is None: # finished for this script |
|
128 |
# reset script state |
|
129 |
context = stepid = None |
|
130 |
# next time, go to the next script |
|
131 |
self.msg(u'finished postcreate for %s' % path) |
|
132 |
try: |
|
133 |
path = paths[i+1] |
|
134 |
self.continue_link() |
|
135 |
except IndexError: |
|
136 |
status['finished'] = True |
|
137 |
path = None |
|
138 |
self.redirect('process completed') |
|
139 |
else: |
|
140 |
if context.get('stepidx'): |
|
141 |
self.msg(u'created %s entities for step %s of %s' % ( |
|
142 |
context['stepidx'], stepid, path)) |
|
143 |
else: |
|
144 |
self.msg(u'finished postcreate step %s for %s' % ( |
|
145 |
stepid, path)) |
|
146 |
context = Blob(dumps(context)) |
|
147 |
self.continue_link() |
|
148 |
status['context'] = context |
|
149 |
status['stepid'] = stepid |
|
150 |
status['cpath'] = path |
|
151 |
break |
|
152 |
else: |
|
153 |
if not cpath: |
|
154 |
# nothing to be done |
|
155 |
status['finished'] = True |
|
156 |
self.redirect('process completed') |
|
157 |
else: |
|
158 |
# Note the error: is expected by the laxctl command line tool, |
|
159 |
# deal with this if internationalization is introduced |
|
160 |
self.msg(u'error: strange creation state, can\'t find %s' |
|
161 |
% cpath) |
|
162 |
self.w(u'<div>click <a href="%s?vid=contentclear">here</a> to ' |
|
163 |
'<b>delete all datastore content</b> so process can be ' |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
164 |
'reinitialized</div>' % xml_escape(self.req.base_url())) |
0 | 165 |
Put(status) |
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
166 |
|
0 | 167 |
@property |
168 |
@cached |
|
169 |
def _migrhandler(self): |
|
170 |
return self.config.migration_handler(self.schema, interactive=False, |
|
171 |
cnx=self.req.cnx, |
|
172 |
repo=self.config.repository()) |
|
173 |
||
174 |
def msg(self, msg): |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
175 |
self.w(u'<div class="message">%s</div>' % xml_escape(msg)) |
0 | 176 |
def redirect(self, msg): |
177 |
raise Redirect(self.req.build_url('', msg)) |
|
178 |
def continue_link(self): |
|
2312
af4d8f75c5db
use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
179 |
self.w(u'<a href="%s">continue</a><br/>' % xml_escape(self.req.url())) |
0 | 180 |
|
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
181 |
|
0 | 182 |
class ContentClear(StartupView): |
183 |
id = 'contentclear' |
|
742
99115e029dca
replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
692
diff
changeset
|
184 |
__select__ = none_rset() & match_user_groups('managers') |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
742
diff
changeset
|
185 |
skip_etypes = ('CWGroup', 'CWUser') |
1802
d628defebc17
delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1398
diff
changeset
|
186 |
|
0 | 187 |
def call(self): |
4835
13b0b96d7982
[repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
188 |
# XXX should use unsafe execute with all hooks deactivated |
0 | 189 |
# XXX step by catching datastore errors? |
190 |
for eschema in self.schema.entities(): |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2312
diff
changeset
|
191 |
if eschema.final or eschema in self.skip_etypes: |
0 | 192 |
continue |
193 |
self.req.execute('DELETE %s X' % eschema) |
|
194 |
self.w(u'deleted all %s entities<br/>' % eschema) |
|
195 |
status = _get_status('creation', create=False) |
|
196 |
if status: |
|
197 |
Delete(status) |
|
198 |
self.w(u'done<br/>') |
|
199 |
self.w(u'click <a href="%s?vid=contentinit">here</a> to start the data ' |
|
200 |
'initialization process<br/>' % self.req.base_url()) |