Show
Ignore:
Timestamp:
08/16/07 08:49:44 (5 years ago)
Author:
trivoallan
Message:

cleverbox :

  • added logging capabilities
  • implemented nicer client and environment command output
Location:
cleverbox/trunk/cleverbox
Files:
2 added
6 modified

Legend:

Unmodified
Added
Removed
  • cleverbox/trunk/cleverbox/client.py

    r187 r193  
    33""" 
    44 
    5 import os 
    6 from cleverbox.utils import filesystem 
     5import logging, os 
     6from cleverbox.utils import filesystem, styles 
    77 
    88client_dir_layout = ('htdocs', 'logs', 'tmp', 'uploads', 'var/svn', 'var/trac') 
     
    6262    # Client name cannot contain strokes 
    6363    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." 
    6665 
    6766    # Information collection 
     
    7675    dir_is_ok = os.access(parent_dir, os.W_OK) and not os.access(collected_infos['home_dir'], os.R_OK) 
    7776    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'] 
    9778 
    9879    # Client creation 
     
    10384    map(os.makedirs, homedir_layout) 
    10485 
    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 
    10689 
    10790    # -- Apache configuration 
     
    11497 
    11598    # -- 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) 
    117100    f = file(apache_conf_filepath, 'w+') 
    118101    f.write(apache_conf) 
    119102    f.close() 
    120103 
    121     print "  Apache configuration written to %s\n" % apache_conf_filepath 
     104    logging.info("  Apache configuration written to %s\n" % apache_conf_filepath) 
    122105 
    123106    # -- Fix permissions 
    124     """ 
    125     chown -R dev:dev /$CLIENTSROOT/$CLIENTNAME 
    126     chown dev:www-data /$CLIENTSROOT/$CLIENTNAME/logs 
    127     chmod g+w /$CLIENTSROOT/$CLIENTNAME/logs 
    128     chown dev:www-data /$CLIENTSROOT/$CLIENTNAME/uploads 
    129     chmod g+w /$CLIENTSROOT/$CLIENTNAME/uploads 
    130     """ 
    131107    filesystem.chowntree(collected_infos['home_dir'], 
    132108                         filesystem.get_uid_from_name(environment.config.get('general', 'ssh_user')), 
     
    145121    os.chmod(os.path.join(collected_infos['home_dir'], 'uploads'), 0775) 
    146122 
    147     print "  Fixed permissions in %s\n" % collected_infos['home_dir'] 
     123    logging.info("  Fixed permissions in %s" % collected_infos['home_dir']) 
    148124 
    149125    #  Final steps 
    150126    # -- Enable client ? 
    151     print "Client has been created. Do you want to enable it ?" 
    152     print 
     127    print styles.style.RESET('') 
    153128    enable_client = raw_input('Enable client ? [y/N]> ').strip() or False 
    154129 
     
    156131        enable(environment,client_name) 
    157132 
     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." 
    158136    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('') 
    164139 
    165140def remove(environment, client_name): 
    166141    """ 
    167142    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" 
    169148     
    170149    if not exists(environment, client_name): 
     
    217196    os.symlink(target, linkname) 
    218197 
    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('') 
    221202 
    222203def disable(environment, client_name): 
    223204    """ 
    224205    Disables a client in supplied environment. 
    225     TODO : disable client's projects. 
    226206    """ 
    227207    if not exists(environment, client_name): 
     
    229209 
    230210    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) 
    232219 
    233220    linkname = os.path.join(environment.path, 'clients-enabled', client_name) 
    234221    os.unlink(linkname) 
    235222     
    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('') 
    238227 
    239228def get_projects(environment, client_name, status=None): 
  • cleverbox/trunk/cleverbox/environment.py

    r189 r193  
    1 import os, shutil, stat 
     1import logging, os, shutil, stat 
    22import ConfigParser 
    33from pkg_resources import parse_version 
     
    4444        try: 
    4545            # Create directory structure 
    46             print "\n\tCreating directory layout\n" 
     46            print 
     47            logging.info("  Creating directory layout") 
     48            print 
    4749            env_dirs = [] 
    4850            for dirname in layout: 
     
    5961 
    6062            # Create default configuration profile 
    61             print "\n\tCreating default configuration profile\n" 
     63            print 
     64            logging.info("  Creating default configuration profile") 
     65            print 
     66             
    6267            for filename in profile_files: 
    6368                shutil.copy( 
     
    8489 
    8590        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             
    8996            for entry in os.listdir(self.path): 
    9097                path = os.path.join(self.path, entry) 
  • cleverbox/trunk/cleverbox/project.py

    r189 r193  
    44 
    55import os, re, ConfigParser, traceback 
    6 from cleverbox.utils import filesystem 
     6from cleverbox.utils import filesystem, styles 
    77 
    88def exists(environment, client_name, project_name, project_status = None): 
     
    5757    try: 
    5858        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_name 
     59        print styles.style.SUCCESS("  Project '%s' has been disabled. Apache needs to be reloaded." % project_name) 
    6060    except (IOError, os.error), exception: 
    61             raise Exception, 'Project "%s" is already disabled' 
     61            raise Exception, 'Project "%s" is already disabled' % project_name 
    6262 
    6363def enable(environment, client_name, project_name): 
  • cleverbox/trunk/cleverbox/scripts/admin.py

    r189 r193  
    11# -*- coding: utf-8 -*- 
    22 
    3 import cmd, os, shlex, sys 
     3import cmd, logging, os, shlex, sys 
    44from trac import util 
    55from trac.scripts.admin import TracAdmin 
    6 from cleverbox.utils import termcolors 
     6from cleverbox.utils import termcolors, styles 
    77from cleverbox.environment import Environment 
    88from cleverbox import client, project 
     9import cleverbox.log 
    910 
    1011_version = '0.5dev' 
    11  
    12 # Set up the terminal color scheme. 
    13 class dummy: pass 
    14 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 dummy 
    22  
    23 def disable_termcolors(): 
    24     class dummy: 
    25         def __getattr__(self, attr): 
    26             return lambda x: x 
    27     global style 
    28     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() 
    3312 
    3413class CleverboxAdmin(cmd.Cmd): 
     
    3817                 'Available Commands:\n' 
    3918    ruler = '' 
    40     prompt = style.H1("Cleverbox > ") 
     19    prompt = styles.style.H1("Cleverbox > ") 
    4120    _date_format = '%Y-%m-%d' 
    4221    _datetime_format = '%Y-%m-%d %H:%M:%S' 
     
    5029            self.env_set(os.path.abspath(envdir)) 
    5130        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) 
    5237 
    5338    ## 
     
    5944        # Load environment 
    6045        self.env = Environment(env_path) 
    61          
     46 
    6247        # Check if environment needs an upgrade 
    6348        try: 
    6449            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 
    6754                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 
    7059        except IOError, e: 
    7160            # no VERSION file means user wants to create an environment 
     
    8473            raise 
    8574        except Exception, e: 
    86             print >> sys.stderr, style.ERROR('Command failed: %s' % e) 
     75            print 
     76            logging.error('  Command failed: %s' % e) 
     77            print 
    8778            rv = 2 
    8879        if not self.interactive: 
     
    9182    def run(self): 
    9283        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") 
    9687        self.cmdloop() 
    9788 
     
    9990    _help_initenv = [('initenv', 'Environment initialisation')] 
    10091    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}) 
    10293 
    10394        # Collect local configuration info 
     
    115106            os.makedirs(collected_infos['general']['clients_root'], 0775) 
    116107        except IOError, ioexception : 
    117             print ioexception 
    118             print "** Projects storage dir could not be created." 
     108            logging.error(ioexception) 
     109            logging.error("Projects storage dir could not be created.") 
    119110 
    120111        # Apache user & group 
     
    150141         
    151142        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('') 
    155148 
    156149    _help_upgrade = [('upgrade', 'Executes necessary operation to make environment up to date')] 
     
    167160                TracAdmin.print_doc(doc) 
    168161            except AttributeError: 
    169                 print "No documentation found for %s" % arg[0] 
     162                logging.error("No documentation found for %s" % arg[0]) 
    170163        else: 
    171164            docs = (self._help_client + self._help_project + self._help_initenv + self._help_upgrade) 
     
    184177    _help_client = [('client list', 'Lists available clients'), 
    185178                    ('client add <name>', 'Adds a client'), 
    186                     ('client remove <name>', 'Deletes a client'), 
    187179                    ('client enable <name>', 'Enables a client'), 
    188180                    ('client disable <name>', 'Disables a client')] 
     
    227219        ''' 
    228220         
    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 
    233233 
    234234    def _do_client_add(self, client_name): 
    235235        client.add(self.env, client_name) 
    236  
    237     def _do_client_remove(self, client_name): 
    238         client.remove(self.env, client_name) 
    239236 
    240237    def _do_client_enable(self, client_name): 
     
    266263            do_func = getattr(self, '_do_project_' + parts[0]) 
    267264            # 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:]) 
    272266        except AttributeError, e: 
    273             print e 
     267            logging.error(e) 
    274268            self.do_help('project') 
    275269 
    276     def _do_project_list(self, line=None): 
     270    def _do_project_list(self, line=None, misc=None): 
    277271 
    278272        client_projects = {} 
    279273 
    280274        clients = client.get(self.env) 
    281         clients.sort() 
     275        clients.sort() 
     276         
    282277        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') 
    285287            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                     print style.ENABLED("[E] %s" % project_name) 
    291                 else: 
    292                     print style.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) 
    293295 
    294296    def _do_project_disable(self, args): 
     
    310312             
    311313        (client_name, project_name) = args 
    312         project.enable(environment, client_name, project_name) 
     314        project.enable(self.env, client_name, project_name) 
    313315 
    314316    def _do_project_add(self, args): 
  • cleverbox/trunk/cleverbox/tests/client.py

    r177 r193  
    11import unittest 
    22 
    3 import shutil 
     3import logging, os, shutil, tempfile 
    44from cleverbox.environment import Environment 
    55from cleverbox.scripts.admin import CleverboxAdmin 
     6 
     7logging.basicConfig(stream=open('/dev/null', 'w+')) 
    68 
    79class ClientTestCase(unittest.TestCase): 
     
    1315    def setUp(self): 
    1416        env_path = os.path.join(tempfile.gettempdir(), 'cleverbox-tempenv') 
     17        os.mkdir(env_path) 
    1518        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) 
    1824     
    1925    def tearDown(self): 
     
    2228    # client add 
    2329    def test_client_add_generates_expected_apache_configuration(self): 
    24         self.admin.onecmd('client add cogip') 
     30        pass 
    2531     
    2632    def test_client_add_fails_on_existing_client(self): 
  • cleverbox/trunk/cleverbox/tests/environment.py

    r192 r193  
    22from cleverbox.environment import Environment 
    33 
    4 # Don't bother with output from scrips 
     4# Don't bother with output from scripts 
    55logging.basicConfig(stream=open('/dev/null', 'w+')) 
    66