root/cleverbox/trunk/cleverbox/model/client.py

Revision 260, 9.2 KB (checked in by trivoallan, 4 years ago)

cleverbox :

  • Added licence information to all project's file. Fixes #28
  • Fixed version number in O.4's setup.py
Line 
1# This file is part of the "Cleverbox" program.
2#
3# Cleverbox is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# Cleverbox is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with Cleverbox.  If not, see <http://www.gnu.org/licenses/>.
15#
16# Copyright 2008, Tristan Rivoallan
17
18"""
19This module regroups all the logic for manipulating client data in a given environment.
20"""
21
22import logging, os
23from cleverbox.utils import filesystem, styles
24
25client_dir_layout = ('htdocs', 'logs', 'tmp', 'var/svn', 'var/trac')
26
27def exists(environment, client_name):
28    """
29    Returns true if requested client exists in supplied environment.
30    """
31    return client_name in get(environment)
32
33def get(environment, only = False):
34    '''
35    Returns a list of clients in supplied environment.
36    The "only" parameter is used to restrict returned clients list. Recognized values are "enabled" and "disabled".
37    '''
38
39    list_clients = []
40
41    # Each client
42    if not only:
43        list_clients = os.listdir(environment.get_path('clients-available'))
44
45    # Only enabled clients
46    elif only == 'enabled':
47        list_clients = os.listdir(environment.get_path('clients-enabled'))
48
49    # Only disabled clients (ie. not enabled)
50    elif only == 'disabled':
51
52        disabled_clients = []
53        available_clients = os.listdir(environment.get_path('clients-available'))
54        enabled_clients = os.listdir(environment.get_path('clients-enabled'))
55
56        # Expect poor performances for this intersection algorithm
57        # see http://python.project.cwi.nl/search/hypermail/python-recent/0159.html
58        for e in available_clients:
59            if e not in enabled_clients:
60                disabled_clients.append(e)
61
62        list_clients = disabled_clients
63
64    return list_clients
65
66def add(environment, client_name, parameters = {}):
67    """
68    Creates a new client in supplied environment.
69      * Checks if client not already exists
70      * Collects informations about client
71      * Checks informations are correct
72      * Create clients environment directory layout
73      * Creates apache configuration fragment
74    """
75
76    if (exists(environment, client_name)):
77        raise Exception, 'Client "%s" already exists' % client_name
78
79    # Client name cannot contain strokes
80    if client_name.count('-') != 0:
81        raise Exception, "Client's identifier can not contain the '-' character."
82
83    # Information collection
84    collected_infos = {'full_name' : None,
85                       'home_dir'  : None}
86   
87    collected_infos['home_dir'] = os.path.join(environment.config.get('general', 'clients_root'), client_name)
88    client_dir = collected_infos['home_dir']
89
90    # Client creation
91    # -- Homedir layout
92    homedir_layout = []
93    for d in client_dir_layout:
94        homedir_layout.append(os.path.join(collected_infos['home_dir'], d))
95    map(os.makedirs, homedir_layout)
96
97    print styles.style.SUCCESSNORESET('')
98    logging.info("  Directory layout created in %s" % collected_infos['home_dir'])
99    print
100
101    # -- Apache configuration
102    apache_conf = """
103# -- Include enabled projects configuration files
104Include %(env_dir)s/projects-enabled/%(client_name)s-*
105""" % { 'client_name' : client_name,
106'home_dir'    : collected_infos['home_dir'],
107'env_dir'     : environment.path }
108
109    # -- Write conf to filesystem
110    apache_conf_filepath = os.path.join(environment.path, 'clients-available', client_name)
111    f = file(apache_conf_filepath, 'w+')
112    f.write(apache_conf)
113    f.close()
114
115    logging.info("  Apache configuration written to %s\n" % apache_conf_filepath)
116
117    # -- Set permissions
118    user  = environment.config.get('general', 'ssh_user')
119    group = environment.config.get('general', 'apache_group')
120   
121    permissions = {os.path.join(environment.path, 'clients-available', client_name)    : (0640, user, group),
122                   os.path.join(client_dir)                                            : (0750, user, group),
123                   os.path.join(client_dir, 'htdocs')                                  : (0770, user, group),
124                   os.path.join(client_dir, 'logs')                                    : (0770, user, group),
125                   os.path.join(client_dir, 'tmp')                                     : (0770, user, group),
126                   os.path.join(client_dir, 'var')                                     : (0750, user, group),
127                   os.path.join(client_dir, 'var', 'svn')                              : (0750, user, group),
128                   os.path.join(client_dir, 'var', 'trac')                             : (0750, user, group)}
129   
130    filesystem.set_permissions(permissions)
131   
132    logging.info("  Fixed permissions in %s" % collected_infos['home_dir'])
133
134    #  Final steps
135    # -- Enable client ?
136    print styles.style.RESET('')
137    try:
138        enable_client = parameters['enable']
139    except KeyError:
140        enable_client = raw_input('Enable client ? [y/N]> ').strip() or False
141
142    if str(enable_client).find('y') == 0:
143        enable(environment,client_name)
144
145    print styles.style.SUCCESSNORESET('')
146    logging.info("  Client %s was successfully created." % collected_infos['full_name'])
147    print "  Apache configuration need to be reloaded for this to be effective."
148    print
149    print "  You may want create some projects now. Try 'help project' for some documentation."
150    print styles.style.RESET('')
151
152def remove(environment, client_name):
153    """
154    Deletes client from supplied environment.
155   
156    TODO : turn that into an "archive" command to avoid complete loss of data
157    """
158   
159    raise NotImplementedError, "More work needed on this"
160   
161    if not exists(environment, client_name):
162        raise Exception, 'Client "%s" does not exists.'
163
164    continue_removal = False
165    print "You are about to remove client '%s'." % client_name
166    confirm_removal = raw_input('Remove client ? [y/N]> ').strip() or False
167    if confirm_removal == 'y':
168        continue_removal = True
169
170    if not continue_removal:
171        print "Client '%s' was *not* removed" % client_name
172        return
173
174    # Client is enabled, propose disabling it
175    client_disabled = True
176    if client_name in get(environment, 'enabled'):
177        client_disabled = False
178        print "You can not remove an enabled client. Disabling it."
179        try:
180            disable(environment, client_name)
181        except Exception, e:
182            print e
183
184    # Disable client's projects
185    for project_name in get_projects(environment, client_name, 'enabled'):
186        project.disable(environment, (client_name, project_name))
187
188    # Disable client
189    client_apacheconf = os.path.join(environment.path, 'clients-available', client_name)
190    os.unlink(client_apacheconf)
191   
192    print "Client '%s' has been removed." % client_name
193    print "Apache configuration needs to be reloaded for this to be effective."
194
195def enable(environment, client_name):
196    """
197    Enables client in supplied environment.
198    """
199   
200    if not exists(environment, client_name):
201        raise Exception, 'Client "%s" does not exist.' % client_name
202
203    if client_name in get(environment, 'enabled'):
204        raise Exception, 'Client "%s" is already enabled.' % client_name
205
206    target = os.path.join(environment.path, 'clients-available', client_name)
207    linkname = os.path.join(environment.path, 'clients-enabled', client_name)
208    os.symlink(target, linkname)
209
210    print styles.style.SUCCESSNORESET('')
211    logging.info("  Client '%s' has been enabled" % client_name)
212    print "  Apache configuration needs to be reloaded for this to be effective."
213    print styles.style.RESET('')
214
215def disable(environment, client_name):
216    """
217    Disables a client in supplied environment.
218    """
219    if not exists(environment, client_name):
220        raise Exception, 'Client "%s" does not exist.' % client_name
221
222    if client_name in get(environment, 'disabled'):
223        raise Exception, 'Client "%s" is already disabled.' % client_name
224
225    from cleverbox.model import project
226    client_projects = get_projects(environment, client_name, 'enabled')
227    if len(client_projects):
228        print
229        for project_name in client_projects:
230            project.disable(environment, client_name, project_name)
231
232    linkname = os.path.join(environment.path, 'clients-enabled', client_name)
233    os.unlink(linkname)
234   
235    print styles.style.SUCCESSNORESET('')
236    logging.info("  Client '%s' has been disabled" % client_name)
237    print "  Apache configuration needs to be reloaded for this to be effective."
238    print styles.style.RESET('')
239
240def get_projects(environment, client_name, status=None):
241    """
242    Returns client's projects in environment.
243    If "status" parameter is supplied, returned list is limited to projects with this status.
244    """
245
246    # Having the import here avoids a circular import problem with project.py
247    from cleverbox.model import project
248    return project.get(environment, client_name, status)
Note: See TracBrowser for help on using the browser.