Changeset 193 for cleverbox/trunk/cleverbox
- Timestamp:
- 08/16/07 08:49:44 (5 years ago)
- Location:
- cleverbox/trunk/cleverbox
- Files:
-
- 2 added
- 6 modified
-
client.py (modified) (9 diffs)
-
environment.py (modified) (4 diffs)
-
log.py (added)
-
project.py (modified) (2 diffs)
-
scripts/admin.py (modified) (14 diffs)
-
tests/client.py (modified) (3 diffs)
-
tests/environment.py (modified) (1 diff)
-
utils/styles.py (added)
Legend:
- Unmodified
- Added
- Removed
-
cleverbox/trunk/cleverbox/client.py
r187 r193 3 3 """ 4 4 5 import os6 from cleverbox.utils import filesystem 5 import logging, os 6 from cleverbox.utils import filesystem, styles 7 7 8 8 client_dir_layout = ('htdocs', 'logs', 'tmp', 'uploads', 'var/svn', 'var/trac') … … 62 62 # Client name cannot contain strokes 63 63 if client_name.count('-') != 0: 64 print "** Client's identifier can not contain the '-' character." 65 return 64 raise Exception, "Client's identifier can not contain the '-' character." 66 65 67 66 # Information collection … … 76 75 dir_is_ok = os.access(parent_dir, os.W_OK) and not os.access(collected_infos['home_dir'], os.R_OK) 77 76 if not dir_is_ok: 78 print "Directory %s is not writable or already exists, aborting." % collected_infos['home_dir'] 79 raise os.error 80 81 82 print 83 print "Creating a new client." 84 print "Let's collect some informations about him : " 85 print 86 print " Please enter client's full name." 87 print " This will be used in several interface screens and in emails." 88 print 89 90 dfn = client_name.capitalize() 91 collected_infos['full_name'] = raw_input('Full Name [%s]> ' % dfn).strip() or dfn 92 93 print 94 print "Supplied informations verified." 95 print "Let's proceed with client creation :" 96 print 77 raise os.error, "Directory %s is not writable or already exists, aborting." % collected_infos['home_dir'] 97 78 98 79 # Client creation … … 103 84 map(os.makedirs, homedir_layout) 104 85 105 print " Directory layout created in %s\n" % collected_infos['home_dir'] 86 print styles.style.SUCCESSNORESET('') 87 logging.info(" Directory layout created in %s" % collected_infos['home_dir']) 88 print 106 89 107 90 # -- Apache configuration … … 114 97 115 98 # -- Write conf to filesystem 116 apache_conf_filepath = os.path.join( environment.path, 'clients-available', client_name)99 apache_conf_filepath = os.path.join(environment.path, 'clients-available', client_name) 117 100 f = file(apache_conf_filepath, 'w+') 118 101 f.write(apache_conf) 119 102 f.close() 120 103 121 print " Apache configuration written to %s\n" % apache_conf_filepath104 logging.info(" Apache configuration written to %s\n" % apache_conf_filepath) 122 105 123 106 # -- Fix permissions 124 """125 chown -R dev:dev /$CLIENTSROOT/$CLIENTNAME126 chown dev:www-data /$CLIENTSROOT/$CLIENTNAME/logs127 chmod g+w /$CLIENTSROOT/$CLIENTNAME/logs128 chown dev:www-data /$CLIENTSROOT/$CLIENTNAME/uploads129 chmod g+w /$CLIENTSROOT/$CLIENTNAME/uploads130 """131 107 filesystem.chowntree(collected_infos['home_dir'], 132 108 filesystem.get_uid_from_name(environment.config.get('general', 'ssh_user')), … … 145 121 os.chmod(os.path.join(collected_infos['home_dir'], 'uploads'), 0775) 146 122 147 print " Fixed permissions in %s\n" % collected_infos['home_dir']123 logging.info(" Fixed permissions in %s" % collected_infos['home_dir']) 148 124 149 125 # Final steps 150 126 # -- Enable client ? 151 print "Client has been created. Do you want to enable it ?" 152 print 127 print styles.style.RESET('') 153 128 enable_client = raw_input('Enable client ? [y/N]> ').strip() or False 154 129 … … 156 131 enable(environment,client_name) 157 132 133 print styles.style.SUCCESSNORESET('') 134 logging.info(" Client %s was successfully created." % collected_infos['full_name']) 135 print " Apache configuration need to be reloaded for this to be effective." 158 136 print 159 print "Client %s was successfully created." % collected_infos['full_name'] 160 print "Apache configuration need to be reloaded for this to be effective." 161 print 162 print "You may want create some projects now. Try 'help project' for some documentation." 163 print 137 print " You may want create some projects now. Try 'help project' for some documentation." 138 print styles.style.RESET('') 164 139 165 140 def remove(environment, client_name): 166 141 """ 167 142 Deletes client from supplied environment. 168 """ 143 144 TODO : tunr that into an "archive" command to avoid complete loss of data 145 """ 146 147 raise NotImplementedError, "More work needed on this" 169 148 170 149 if not exists(environment, client_name): … … 217 196 os.symlink(target, linkname) 218 197 219 print "Client '%s' has been enabled" % client_name 220 print "Apache configuration needs to be reloaded for this to be effective." 198 print styles.style.SUCCESSNORESET('') 199 logging.info(" Client '%s' has been enabled" % client_name) 200 print " Apache configuration needs to be reloaded for this to be effective." 201 print styles.style.RESET('') 221 202 222 203 def disable(environment, client_name): 223 204 """ 224 205 Disables a client in supplied environment. 225 TODO : disable client's projects.226 206 """ 227 207 if not exists(environment, client_name): … … 229 209 230 210 if client_name in get(environment, 'disabled'): 231 raise Exception, 'Client "%s" is already enabled.' % client_name 211 raise Exception, 'Client "%s" is already disabled.' % client_name 212 213 import cleverbox.project 214 client_projects = get_projects(environment, client_name, 'enabled') 215 if len(client_projects): 216 print 217 for project_name in client_projects: 218 cleverbox.project.disable(environment, client_name, project_name) 232 219 233 220 linkname = os.path.join(environment.path, 'clients-enabled', client_name) 234 221 os.unlink(linkname) 235 222 236 print "Client '%s' has been disabled" % client_name 237 print "Apache configuration needs to be reloaded for this to be effective." 223 print styles.style.SUCCESSNORESET('') 224 logging.info(" Client '%s' has been disabled" % client_name) 225 print " Apache configuration needs to be reloaded for this to be effective." 226 print styles.style.RESET('') 238 227 239 228 def get_projects(environment, client_name, status=None): -
cleverbox/trunk/cleverbox/environment.py
r189 r193 1 import os, shutil, stat1 import logging, os, shutil, stat 2 2 import ConfigParser 3 3 from pkg_resources import parse_version … … 44 44 try: 45 45 # Create directory structure 46 print "\n\tCreating directory layout\n" 46 print 47 logging.info(" Creating directory layout") 48 print 47 49 env_dirs = [] 48 50 for dirname in layout: … … 59 61 60 62 # Create default configuration profile 61 print "\n\tCreating default configuration profile\n" 63 print 64 logging.info(" Creating default configuration profile") 65 print 66 62 67 for filename in profile_files: 63 68 shutil.copy( … … 84 89 85 90 except Exception, exception: 86 print exception 87 print "** Environment couldn't be initialized in %(env_dir)s\n" % {'env_dir' : self.path} 88 print "Rolling back changes" 91 92 logging.error(exception) 93 logging.error(" Environment couldn't be initialized in %(env_dir)s" % {'env_dir' : self.path}) 94 logging.info("Rolling back changes") 95 89 96 for entry in os.listdir(self.path): 90 97 path = os.path.join(self.path, entry) -
cleverbox/trunk/cleverbox/project.py
r189 r193 4 4 5 5 import os, re, ConfigParser, traceback 6 from cleverbox.utils import filesystem 6 from cleverbox.utils import filesystem, styles 7 7 8 8 def exists(environment, client_name, project_name, project_status = None): … … 57 57 try: 58 58 os.unlink(os.path.join(environment.get_path('projects-enabled'), '%s-%s' % (client_name, project_name))) 59 print "Project '%s' has been disabled. Apache needs to be reloaded." % project_name59 print styles.style.SUCCESS(" Project '%s' has been disabled. Apache needs to be reloaded." % project_name) 60 60 except (IOError, os.error), exception: 61 raise Exception, 'Project "%s" is already disabled' 61 raise Exception, 'Project "%s" is already disabled' % project_name 62 62 63 63 def enable(environment, client_name, project_name): -
cleverbox/trunk/cleverbox/scripts/admin.py
r189 r193 1 1 # -*- coding: utf-8 -*- 2 2 3 import cmd, os, shlex, sys3 import cmd, logging, os, shlex, sys 4 4 from trac import util 5 5 from trac.scripts.admin import TracAdmin 6 from cleverbox.utils import termcolors 6 from cleverbox.utils import termcolors, styles 7 7 from cleverbox.environment import Environment 8 8 from cleverbox import client, project 9 import cleverbox.log 9 10 10 11 _version = '0.5dev' 11 12 # Set up the terminal color scheme.13 class dummy: pass14 style = dummy()15 style.ERROR = termcolors.make_style(fg='red', opts=('bold',))16 style.WARN = termcolors.make_style(fg='yellow', opts=('bold',))17 style.SUCCESS = termcolors.make_style(fg='green', opts=('bold',))18 style.H1 = termcolors.make_style(fg='white', opts=('bold', 'underline'))19 style.ENABLED = termcolors.make_style(fg='green')20 style.DISABLED = termcolors.make_style(fg='red')21 del dummy22 23 def disable_termcolors():24 class dummy:25 def __getattr__(self, attr):26 return lambda x: x27 global style28 style = dummy()29 30 # Disable terminal coloring on Windows, Pocket PC, or if somebody's piping the output.31 if sys.platform == 'win32' or sys.platform == 'Pocket PC' or not sys.stdout.isatty():32 disable_termcolors()33 12 34 13 class CleverboxAdmin(cmd.Cmd): … … 38 17 'Available Commands:\n' 39 18 ruler = '' 40 prompt = style .H1("Cleverbox > ")19 prompt = styles.style.H1("Cleverbox > ") 41 20 _date_format = '%Y-%m-%d' 42 21 _datetime_format = '%Y-%m-%d %H:%M:%S' … … 50 29 self.env_set(os.path.abspath(envdir)) 51 30 self.interactive = False 31 32 # Setup logging 33 screen = logging.StreamHandler(sys.stdout) 34 screen.setFormatter(cleverbox.log.TermcolorsFormatter('%(message)s')) 35 logging.getLogger('').setLevel(logging.DEBUG) 36 logging.getLogger('').addHandler(screen) 52 37 53 38 ## … … 59 44 # Load environment 60 45 self.env = Environment(env_path) 61 46 62 47 # Check if environment needs an upgrade 63 48 try: 64 49 if check_upgrade and self.env.needs_upgrade(_version): 65 print style.ERROR("\nCleverbox environment needs to be upgraded. Please run :") 66 print style.ERROR(" cleverbox-admin %s upgrade\n" % self.env.path) 50 print 51 logging.warn(" Cleverbox environment needs to be upgraded.\n" \ 52 " Please run : cleverbox-admin %s upgrade" % self.env.path) 53 print 67 54 sys.exit(1) 68 elif not self.env.needs_upgrade(_version): 69 print style.SUCCESS("\nCleverbox environment is up to date.\n") 55 elif not self.env.needs_upgrade(_version): 56 print 57 logging.info(styles.style.SUCCESS(" Cleverbox environment is up to date.")) 58 print 70 59 except IOError, e: 71 60 # no VERSION file means user wants to create an environment … … 84 73 raise 85 74 except Exception, e: 86 print >> sys.stderr, style.ERROR('Command failed: %s' % e) 75 print 76 logging.error(' Command failed: %s' % e) 77 print 87 78 rv = 2 88 79 if not self.interactive: … … 91 82 def run(self): 92 83 self.interactive = True 93 print style .H1('Welcome to cleverbox-admin\n'\94 'Interactive Cleverbox administration console.\n'\95 "Type: '?' or 'help' for help on commands.\n")84 print styles.style.H1('Welcome to cleverbox-admin\n' \ 85 'Interactive Cleverbox administration console.\n' \ 86 "Type: '?' or 'help' for help on commands.\n") 96 87 self.cmdloop() 97 88 … … 99 90 _help_initenv = [('initenv', 'Environment initialisation')] 100 91 def do_initenv(self, line=None): 101 print "Environment initialisation in %(env_dir)s" % {'env_dir' : self.env.path}92 logging.info("Environment initialisation in %(env_dir)s" % {'env_dir' : self.env.path}) 102 93 103 94 # Collect local configuration info … … 115 106 os.makedirs(collected_infos['general']['clients_root'], 0775) 116 107 except IOError, ioexception : 117 print ioexception118 print "** Projects storage dir could not be created."108 logging.error(ioexception) 109 logging.error("Projects storage dir could not be created.") 119 110 120 111 # Apache user & group … … 150 141 151 142 print 152 print "Environment successfully initialized\n" 153 print "You need to add this statement to your apache configuration : \n" \ 154 "\t'Include %(env_dir)s/clients-enabled/*'\n" % {'env_dir' : self.env.path} 143 print termcolors.colorize('', fg='green', opts=('noreset',)) 144 logging.info("Environment successfully initialized\n" \ 145 "You need to add this statement to your apache configuration : \n" \ 146 "\t'Include %(env_dir)s/clients-enabled/*'\n" % {'env_dir' : self.env.path}) 147 print termcolors.colorize('') 155 148 156 149 _help_upgrade = [('upgrade', 'Executes necessary operation to make environment up to date')] … … 167 160 TracAdmin.print_doc(doc) 168 161 except AttributeError: 169 print "No documentation found for %s" % arg[0]162 logging.error("No documentation found for %s" % arg[0]) 170 163 else: 171 164 docs = (self._help_client + self._help_project + self._help_initenv + self._help_upgrade) … … 184 177 _help_client = [('client list', 'Lists available clients'), 185 178 ('client add <name>', 'Adds a client'), 186 ('client remove <name>', 'Deletes a client'),187 179 ('client enable <name>', 'Enables a client'), 188 180 ('client disable <name>', 'Disables a client')] … … 227 219 ''' 228 220 229 print "Enabled :\n" \ 230 "%s\n\n" \ 231 "Disabled : \n" \ 232 "%s\n" % (client.get(self.env, 'enabled'), client.get(self.env, 'disabled')) 221 all_clients = client.get(self.env) 222 if len(all_clients): 223 print 224 all_clients.sort() 225 en_clients = client.get(self.env, 'enabled') 226 dis_clients = client.get(self.env, 'disabled') 227 for client_name in all_clients: 228 if client_name in en_clients: 229 print styles.style.ENABLED(' [E] %s' % client_name) 230 else: 231 print styles.style.DISABLED(' [D] %s' % client_name) 232 print 233 233 234 234 def _do_client_add(self, client_name): 235 235 client.add(self.env, client_name) 236 237 def _do_client_remove(self, client_name):238 client.remove(self.env, client_name)239 236 240 237 def _do_client_enable(self, client_name): … … 266 263 do_func = getattr(self, '_do_project_' + parts[0]) 267 264 # Python __call__() signature changed in Python2.4 268 if ( sys.version[:3] == '2.4'): 269 do_func.__call__(parts[1:]) 270 else: 271 do_func.__call__(self, parts[1:]) 265 do_func.__call__(parts[1:]) 272 266 except AttributeError, e: 273 print e267 logging.error(e) 274 268 self.do_help('project') 275 269 276 def _do_project_list(self, line=None ):270 def _do_project_list(self, line=None, misc=None): 277 271 278 272 client_projects = {} 279 273 280 274 clients = client.get(self.env) 281 clients.sort() 275 clients.sort() 276 282 277 for client_name in clients: 283 print style.H1("\n%s :" % client_name) 284 enabled_projects = project.get(self.env, client_name, 'enabled') 278 279 all_projects = project.get(self.env, client_name) 280 if not len(all_projects): continue 281 282 all_projects.sort() 283 284 print styles.style.H1("\n%s :" % client_name) 285 286 enabled_projects = project.get(self.env, client_name, 'enabled') 285 287 disabled_projects = project.get(self.env, client_name, 'disabled') 286 all_projects = project.get(self.env, client_name) 287 all_projects.sort()288 for project_name in all_projects:289 if project_name in enabled_projects:290 printstyle.ENABLED("[E] %s" % project_name)291 else:292 printstyle.DISABLED("[D] %s" % project_name)288 289 290 for project_name in all_projects: 291 if project_name in enabled_projects: 292 print styles.style.ENABLED("[E] %s" % project_name) 293 else: 294 print styles.style.DISABLED("[D] %s" % project_name) 293 295 294 296 def _do_project_disable(self, args): … … 310 312 311 313 (client_name, project_name) = args 312 project.enable( environment, client_name, project_name)314 project.enable(self.env, client_name, project_name) 313 315 314 316 def _do_project_add(self, args): -
cleverbox/trunk/cleverbox/tests/client.py
r177 r193 1 1 import unittest 2 2 3 import shutil3 import logging, os, shutil, tempfile 4 4 from cleverbox.environment import Environment 5 5 from cleverbox.scripts.admin import CleverboxAdmin 6 7 logging.basicConfig(stream=open('/dev/null', 'w+')) 6 8 7 9 class ClientTestCase(unittest.TestCase): … … 13 15 def setUp(self): 14 16 env_path = os.path.join(tempfile.gettempdir(), 'cleverbox-tempenv') 17 os.mkdir(env_path) 15 18 self.env = Environment(env_path) 16 self.env.create() 17 self.admin = CleverboxAdmin(self.env) 19 parameters = {'general' : 20 {'clients_root' : os.path.join(env_path, 'var', 'cleverbox'), 21 'assets_dir' : os.path.join('/home/trivoallan/workspace/cleverbox-trunk/assets'), 22 'apache_group' : 'www-data'}} 23 self.env.create('0.5test', parameters) 18 24 19 25 def tearDown(self): … … 22 28 # client add 23 29 def test_client_add_generates_expected_apache_configuration(self): 24 self.admin.onecmd('client add cogip')30 pass 25 31 26 32 def test_client_add_fails_on_existing_client(self): -
cleverbox/trunk/cleverbox/tests/environment.py
r192 r193 2 2 from cleverbox.environment import Environment 3 3 4 # Don't bother with output from scrip s4 # Don't bother with output from scripts 5 5 logging.basicConfig(stream=open('/dev/null', 'w+')) 6 6
