8 __docformat__ = "restructuredtext en" |
8 __docformat__ = "restructuredtext en" |
9 |
9 |
10 import sys |
10 import sys |
11 import os |
11 import os |
12 |
12 |
13 from logilab.common.configuration import REQUIRED, Configuration, ini_format_section |
13 from logilab.common.configuration import Configuration |
14 from logilab.common.clcommands import register_commands, cmd_run, pop_arg |
14 from logilab.common.clcommands import register_commands, cmd_run, pop_arg |
15 |
15 |
16 from cubicweb import AuthenticationError, ExecutionError, ConfigurationError |
16 from cubicweb import AuthenticationError, ExecutionError, ConfigurationError |
17 from cubicweb.toolsutils import (Command, CommandHandler, confirm, |
17 from cubicweb.toolsutils import Command, CommandHandler, confirm |
18 restrict_perms_to_user) |
18 from cubicweb.server import SOURCE_TYPES |
19 from cubicweb.server.serverconfig import ServerConfiguration |
19 from cubicweb.server.utils import ask_source_config |
|
20 from cubicweb.server.serverconfig import USER_OPTIONS, ServerConfiguration |
20 |
21 |
21 |
22 |
22 # utility functions ########################################################### |
23 # utility functions ########################################################### |
23 |
24 |
24 def source_cnx(source, dbname=None, special_privs=False, verbose=True): |
25 def source_cnx(source, dbname=None, special_privs=False, verbose=True): |
90 except AttributeError: |
91 except AttributeError: |
91 # set_isolation_level() is psycopg specific |
92 # set_isolation_level() is psycopg specific |
92 pass |
93 pass |
93 return cnx |
94 return cnx |
94 |
95 |
95 def generate_sources_file(sourcesfile, sourcescfg, keys=None): |
|
96 """serialize repository'sources configuration into a INI like file |
|
97 |
|
98 the `keys` parameter may be used to sort sections |
|
99 """ |
|
100 from cubicweb.server.sources import SOURCE_TYPES |
|
101 if keys is None: |
|
102 keys = sourcescfg.keys() |
|
103 else: |
|
104 for key in sourcescfg: |
|
105 if not key in keys: |
|
106 keys.append(key) |
|
107 stream = open(sourcesfile, 'w') |
|
108 for uri in keys: |
|
109 sconfig = sourcescfg[uri] |
|
110 if isinstance(sconfig, dict): |
|
111 # get a Configuration object |
|
112 _sconfig = Configuration(options=SOURCE_TYPES[sconfig['adapter']].options) |
|
113 for attr, val in sconfig.items(): |
|
114 if attr == 'uri': |
|
115 continue |
|
116 if attr == 'adapter': |
|
117 _sconfig.adapter = val |
|
118 else: |
|
119 _sconfig.set_option(attr, val) |
|
120 sconfig = _sconfig |
|
121 optsbysect = list(sconfig.options_by_section()) |
|
122 assert len(optsbysect) == 1, 'all options for a source should be in the same group' |
|
123 ini_format_section(stream, uri, optsbysect[0][1]) |
|
124 if hasattr(sconfig, 'adapter'): |
|
125 print >> stream |
|
126 print >> stream, '# adapter for this source (YOU SHOULD NOT CHANGE THIS)' |
|
127 print >> stream, 'adapter=%s' % sconfig.adapter |
|
128 print >> stream |
|
129 |
|
130 def repo_cnx(config): |
96 def repo_cnx(config): |
131 """return a in-memory repository and a db api connection it""" |
97 """return a in-memory repository and a db api connection it""" |
132 from cubicweb.dbapi import in_memory_cnx |
98 from cubicweb.dbapi import in_memory_cnx |
133 from cubicweb.server.utils import manager_userpasswd |
99 from cubicweb.server.utils import manager_userpasswd |
134 try: |
100 try: |
168 sourcesfile = config.sources_file() |
133 sourcesfile = config.sources_file() |
169 sconfig = Configuration(options=SOURCE_TYPES['native'].options) |
134 sconfig = Configuration(options=SOURCE_TYPES['native'].options) |
170 sconfig.adapter = 'native' |
135 sconfig.adapter = 'native' |
171 sconfig.input_config(inputlevel=inputlevel) |
136 sconfig.input_config(inputlevel=inputlevel) |
172 sourcescfg = {'system': sconfig} |
137 sourcescfg = {'system': sconfig} |
|
138 for cube in cubes: |
|
139 # if a source is named as the cube containing it, we need the |
|
140 # source to use the cube, so add it. |
|
141 if cube in SOURCE_TYPES: |
|
142 sourcescfg[cube] = ask_source_config(cube, inputlevel) |
173 while raw_input('enter another source [y/N]: ').strip().lower() == 'y': |
143 while raw_input('enter another source [y/N]: ').strip().lower() == 'y': |
174 sourcetype = raw_input('source type (%s): ' % ', '.join(SOURCE_TYPES.keys())) |
144 available = sorted(stype for stype in SOURCE_TYPES |
175 sconfig = Configuration(options=SOURCE_TYPES[sourcetype].options) |
145 if not stype in cubes) |
176 sconfig.adapter = sourcetype |
146 while True: |
177 sourceuri = raw_input('source uri: ').strip() |
147 sourcetype = raw_input('source type (%s): ' % ', '.join(available)) |
178 assert not sourceuri in sourcescfg |
148 if sourcetype in available: |
179 sconfig.input_config(inputlevel=inputlevel) |
149 break |
180 sourcescfg[sourceuri] = sconfig |
150 print 'unknown source type, use one of the available type' |
181 # module names look like cubes.mycube.themodule |
151 while True: |
182 sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1] |
152 sourceuri = raw_input('source uri: ').strip() |
183 # if the source adapter is coming from an external component, ensure |
153 if sourceuri != 'admin' and sourceuri not in sourcescfg: |
184 # it's specified in used cubes |
154 break |
185 if sourcecube != 'cubicweb' and not sourcecube in cubes: |
155 print 'uri already used, choose another one' |
186 cubes.append(sourcecube) |
156 sourcescfg[sourceuri] = ask_source_config(sourcetype) |
|
157 sourcemodule = SOURCE_TYPES[sourcetype].module |
|
158 if not sourcemodule.startswith('cubicweb.'): |
|
159 # module names look like cubes.mycube.themodule |
|
160 sourcecube = SOURCE_TYPES[sourcetype].module.split('.', 2)[1] |
|
161 # if the source adapter is coming from an external component, |
|
162 # ensure it's specified in used cubes |
|
163 if not sourcecube in cubes: |
|
164 cubes.append(sourcecube) |
187 sconfig = Configuration(options=USER_OPTIONS) |
165 sconfig = Configuration(options=USER_OPTIONS) |
188 sconfig.input_config(inputlevel=inputlevel) |
166 sconfig.input_config(inputlevel=inputlevel) |
189 sourcescfg['admin'] = sconfig |
167 sourcescfg['admin'] = sconfig |
190 generate_sources_file(sourcesfile, sourcescfg, ['admin', 'system']) |
168 config.write_sources_file(sourcescfg) |
191 restrict_perms_to_user(sourcesfile) |
|
192 # remember selected cubes for later initialization of the database |
169 # remember selected cubes for later initialization of the database |
193 config.write_bootstrap_cubes_file(cubes) |
170 config.write_bootstrap_cubes_file(cubes) |
194 |
171 |
195 def postcreate(self): |
172 def postcreate(self): |
196 if confirm('do you want to create repository\'s system database?'): |
173 if confirm('do you want to create repository\'s system database?'): |
197 verbosity = (self.config.mode == 'installed') and 'y' or 'n' |
174 verbosity = (self.config.mode == 'installed') and 'y' or 'n' |
198 cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity) |
175 cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity) |
199 else: |
176 else: |
200 print 'nevermind, you can do it later using the db-create command' |
177 print 'nevermind, you can do it later using the db-create command' |
201 |
|
202 USER_OPTIONS = ( |
|
203 ('login', {'type' : 'string', |
|
204 'default': REQUIRED, |
|
205 'help': "cubicweb manager account's login " |
|
206 '(this user will be created)', |
|
207 'inputlevel': 0, |
|
208 }), |
|
209 ('password', {'type' : 'password', |
|
210 'help': "cubicweb manager account's password", |
|
211 'inputlevel': 0, |
|
212 }), |
|
213 ) |
|
214 |
178 |
215 |
179 |
216 class RepositoryDeleteHandler(CommandHandler): |
180 class RepositoryDeleteHandler(CommandHandler): |
217 cmdname = 'delete' |
181 cmdname = 'delete' |
218 cfgname = 'repository' |
182 cfgname = 'repository' |
433 """run the command with its specific arguments""" |
397 """run the command with its specific arguments""" |
434 from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX |
398 from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX |
435 from cubicweb.server.utils import crypt_password, manager_userpasswd |
399 from cubicweb.server.utils import crypt_password, manager_userpasswd |
436 appid = pop_arg(args, 1, msg="No application specified !") |
400 appid = pop_arg(args, 1, msg="No application specified !") |
437 config = ServerConfiguration.config_for(appid) |
401 config = ServerConfiguration.config_for(appid) |
438 sourcescfg = config.sources() |
402 sourcescfg = config.read_sources_file() |
439 try: |
403 try: |
440 adminlogin = sourcescfg['admin']['login'] |
404 adminlogin = sourcescfg['admin']['login'] |
441 except KeyError: |
405 except KeyError: |
442 print 'could not get cubicweb administrator login' |
406 print 'could not get cubicweb administrator login' |
443 sys.exit(1) |
407 sys.exit(1) |
452 cursor, withpb=False) |
416 cursor, withpb=False) |
453 sconfig = Configuration(options=USER_OPTIONS) |
417 sconfig = Configuration(options=USER_OPTIONS) |
454 sconfig['login'] = adminlogin |
418 sconfig['login'] = adminlogin |
455 sconfig['password'] = passwd |
419 sconfig['password'] = passwd |
456 sourcescfg['admin'] = sconfig |
420 sourcescfg['admin'] = sconfig |
457 sourcesfile = config.sources_file() |
421 config.write_sources_file(sourcescfg) |
458 generate_sources_file(sourcesfile, sourcescfg) |
|
459 restrict_perms_to_user(sourcesfile) |
|
460 except Exception, ex: |
422 except Exception, ex: |
461 cnx.rollback() |
423 cnx.rollback() |
462 import traceback |
424 import traceback |
463 traceback.print_exc() |
425 traceback.print_exc() |
464 print 'An error occured:', ex |
426 print 'An error occured:', ex |