|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 3 | +# not use this file except in compliance with the License. You may obtain |
| 4 | +# a copy of the License at |
| 5 | +# |
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 7 | +# |
| 8 | +# Unless required by applicable law or agreed to in writing, software |
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 10 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 11 | +# License for the specific language governing permissions and limitations |
| 12 | +# under the License. |
| 13 | + |
| 14 | +from __future__ import print_function |
| 15 | + |
| 16 | +from optparse import make_option # noqa |
| 17 | +import os |
| 18 | +import socket |
| 19 | +import sys |
| 20 | +import warnings |
| 21 | + |
| 22 | +from django.conf import settings |
| 23 | +from django.core.management.base import BaseCommand # noqa |
| 24 | +from django.template import Context, Template # noqa |
| 25 | + |
| 26 | +# Suppress DeprecationWarnings which clutter the output to the point of |
| 27 | +# rendering it unreadable. |
| 28 | +warnings.simplefilter('ignore') |
| 29 | + |
| 30 | +cmd_name = __name__.split('.')[-1] |
| 31 | + |
| 32 | +CURDIR = os.path.realpath(os.path.dirname(__file__)) |
| 33 | +PROJECT_PATH = os.path.realpath(os.path.join(CURDIR, '../..')) |
| 34 | +STATIC_PATH = os.path.realpath(os.path.join(PROJECT_PATH, '../static')) |
| 35 | + |
| 36 | +# Known apache log directory locations |
| 37 | +APACHE_LOG_DIRS = ( |
| 38 | + '/var/log/httpd', # RHEL / Red Hat / CentOS / Fedora Linux |
| 39 | + '/var/log/apache2', # Debian / Ubuntu Linux |
| 40 | +) |
| 41 | +# Default log directory |
| 42 | +DEFAULT_LOG_DIR = '/var/log' |
| 43 | + |
| 44 | + |
| 45 | +def _getattr(obj, name, default): |
| 46 | + """Like getattr but return `default` if None or False. |
| 47 | +
|
| 48 | + By default, getattr(obj, name, default) returns default only if |
| 49 | + attr does not exist, here, we return `default` even if attr evaluates to |
| 50 | + None or False. |
| 51 | + """ |
| 52 | + value = getattr(obj, name, default) |
| 53 | + if value: |
| 54 | + return value |
| 55 | + else: |
| 56 | + return default |
| 57 | + |
| 58 | + |
| 59 | +context = Context({ |
| 60 | + 'DJANGO_SETTINGS_MODULE': os.environ['DJANGO_SETTINGS_MODULE'], |
| 61 | + 'HOSTNAME': socket.getfqdn(), |
| 62 | + 'PROJECT_PATH': os.path.realpath( |
| 63 | + _getattr(settings, 'ROOT_PATH', PROJECT_PATH)), |
| 64 | + 'STATIC_PATH': os.path.realpath( |
| 65 | + _getattr(settings, 'STATIC_ROOT', STATIC_PATH)), |
| 66 | + 'SSLCERT': '/etc/pki/tls/certs/ca.crt', |
| 67 | + 'SSLKEY': '/etc/pki/tls/private/ca.key', |
| 68 | + 'CACERT': None, |
| 69 | +}) |
| 70 | + |
| 71 | +context['PROJECT_ROOT'] = os.path.dirname(context['PROJECT_PATH']) |
| 72 | +context['PROJECT_DIR_NAME'] = os.path.basename( |
| 73 | + context['PROJECT_PATH'].split(context['PROJECT_ROOT'])[1]) |
| 74 | +context['PROJECT_NAME'] = context['PROJECT_DIR_NAME'] |
| 75 | + |
| 76 | +context['WSGI_FILE'] = os.path.join( |
| 77 | + context['PROJECT_PATH'], 'wsgi/horizon.wsgi') |
| 78 | + |
| 79 | +VHOSTNAME = context['HOSTNAME'].split('.') |
| 80 | +VHOSTNAME[0] = context['PROJECT_NAME'] |
| 81 | +context['VHOSTNAME'] = '.'.join(VHOSTNAME) |
| 82 | + |
| 83 | +if len(VHOSTNAME) > 1: |
| 84 | + context['DOMAINNAME'] = '.'.join(VHOSTNAME[1:]) |
| 85 | +else: |
| 86 | + context['DOMAINNAME'] = 'openstack.org' |
| 87 | +context['ADMIN'] = 'webmaster@%s' % context['DOMAINNAME'] |
| 88 | + |
| 89 | +context['ACTIVATE_THIS'] = None |
| 90 | +virtualenv = os.environ.get('VIRTUAL_ENV') |
| 91 | +if virtualenv: |
| 92 | + activate_this = os.path.join( |
| 93 | + virtualenv, 'bin/activate_this.py') |
| 94 | + if os.path.exists(activate_this): |
| 95 | + context['ACTIVATE_THIS'] = activate_this |
| 96 | + |
| 97 | + |
| 98 | +def find_apache_log_dir(): |
| 99 | + for log_dir in APACHE_LOG_DIRS: |
| 100 | + if os.path.exists(log_dir) and os.path.isdir(log_dir): |
| 101 | + return log_dir |
| 102 | + return DEFAULT_LOG_DIR |
| 103 | +context['LOGDIR'] = find_apache_log_dir() |
| 104 | + |
| 105 | + |
| 106 | +class Command(BaseCommand): |
| 107 | + |
| 108 | + args = '' |
| 109 | + help = """Create %(wsgi_file)s |
| 110 | +or the contents of an apache %(p_name)s.conf file (on stdout). |
| 111 | +The apache configuration is generated on stdout because the place of this |
| 112 | +file is distribution dependent. |
| 113 | +
|
| 114 | +examples:: |
| 115 | +
|
| 116 | + manage.py %(cmd_name)s --wsgi # creates %(wsgi_file)s |
| 117 | + manage.py %(cmd_name)s --apache # creates an apache vhost conf file (on \ |
| 118 | +stdout). |
| 119 | + manage.py %(cmd_name)s --apache --ssl --mail=%(admin)s \ |
| 120 | +--project=%(p_name)s --hostname=%(hostname)s |
| 121 | +
|
| 122 | +To create an acpache configuration file, redirect the output towards the |
| 123 | +location you desire, e.g.:: |
| 124 | +
|
| 125 | + manage.py %(cmd_name)s --apache > \ |
| 126 | +/etc/httpd/conf.d/openstack_dashboard.conf |
| 127 | +
|
| 128 | + """ % { |
| 129 | + 'cmd_name': cmd_name, |
| 130 | + 'p_name': context['PROJECT_NAME'], |
| 131 | + 'wsgi_file': context['WSGI_FILE'], |
| 132 | + 'admin': context['ADMIN'], |
| 133 | + 'hostname': context['VHOSTNAME'], } |
| 134 | + |
| 135 | + option_list = BaseCommand.option_list + ( |
| 136 | + # TODO(ygbo): Add an --nginx option. |
| 137 | + make_option("-a", "--apache", |
| 138 | + default=False, action="store_true", dest="apache", |
| 139 | + help="generate an apache vhost configuration"), |
| 140 | + make_option("--cacert", |
| 141 | + dest="cacert", |
| 142 | + help=("Use with the --apache and --ssl option to define " |
| 143 | + "the path to the SSLCACertificateFile" |
| 144 | + ), |
| 145 | + metavar="CACERT"), |
| 146 | + make_option("-f", "--force", |
| 147 | + default=False, action="store_true", dest="force", |
| 148 | + help="force overwriting of an existing %s file" % |
| 149 | + context['WSGI_FILE']), |
| 150 | + make_option("-H", "--hostname", |
| 151 | + dest="hostname", |
| 152 | + help=("Use with the --apache option to define the server's" |
| 153 | + " hostname (default : %s)") % context['VHOSTNAME'], |
| 154 | + metavar="HOSTNAME"), |
| 155 | + make_option("--logdir", |
| 156 | + dest="logdir", |
| 157 | + help=("Use with the --apache option to define the path to " |
| 158 | + "the apache log directory(default : %s)" |
| 159 | + % context['LOGDIR']), |
| 160 | + metavar="CACERT"), |
| 161 | + make_option("-m", "--mail", |
| 162 | + dest="mail", |
| 163 | + help=("Use with the --apache option to define the web site" |
| 164 | + " administrator's email (default : %s)") % |
| 165 | + context['ADMIN'], |
| 166 | + metavar="MAIL"), |
| 167 | + make_option("-n", "--namedhost", |
| 168 | + default=False, action="store_true", dest="namedhost", |
| 169 | + help=("Use with the --apache option. The apache vhost " |
| 170 | + "configuration will work only when accessed with " |
| 171 | + "the proper hostname (see --hostname).")), |
| 172 | + make_option("-p", "--project", |
| 173 | + dest="project", |
| 174 | + help=("Use with the --apache option to define the project " |
| 175 | + "name (default : %s)") % context['PROJECT_NAME'], |
| 176 | + metavar="PROJECT"), |
| 177 | + make_option("-s", "--ssl", |
| 178 | + default=False, action="store_true", dest="ssl", |
| 179 | + help=("Use with the --apache option. The apache vhost " |
| 180 | + "configuration will use an SSL configuration")), |
| 181 | + make_option("--sslcert", |
| 182 | + dest="sslcert", |
| 183 | + help=("Use with the --apache and --ssl option to define " |
| 184 | + "the path to the SSLCertificateFile (default : %s)" |
| 185 | + ) % context['SSLCERT'], |
| 186 | + metavar="SSLCERT"), |
| 187 | + make_option("--sslkey", |
| 188 | + dest="sslkey", |
| 189 | + help=("Use with the --apache and --ssl option to define " |
| 190 | + "the path to the SSLCertificateKeyFile " |
| 191 | + "(default : %s)") % context['SSLKEY'], |
| 192 | + metavar="SSLKEY"), |
| 193 | + make_option("-w", "--wsgi", |
| 194 | + default=False, action="store_true", dest="wsgi", |
| 195 | + help="generate the horizon.wsgi file"), |
| 196 | + ) |
| 197 | + |
| 198 | + def handle(self, *args, **options): |
| 199 | + force = options.get('force') |
| 200 | + context['SSL'] = options.get('ssl') |
| 201 | + |
| 202 | + if options.get('mail'): |
| 203 | + context['ADMIN'] = options['mail'] |
| 204 | + if options.get('cacert'): |
| 205 | + context['CACERT'] = options['cacert'] |
| 206 | + if options.get('logdir'): |
| 207 | + context['LOGDIR'] = options['logdir'].rstrip('/') |
| 208 | + if options.get('project'): |
| 209 | + context['PROJECT_NAME'] = options['project'] |
| 210 | + if options.get('hostname'): |
| 211 | + context['VHOSTNAME'] = options['hostname'] |
| 212 | + if options.get('sslcert'): |
| 213 | + context['SSLCERT'] = options['sslcert'] |
| 214 | + if options.get('sslkey'): |
| 215 | + context['SSLKEY'] = options['sslkey'] |
| 216 | + |
| 217 | + if options.get('namedhost'): |
| 218 | + context['NAMEDHOST'] = context['VHOSTNAME'] |
| 219 | + else: |
| 220 | + context['NAMEDHOST'] = '*' |
| 221 | + |
| 222 | + # Generate the WSGI. |
| 223 | + if options.get('wsgi'): |
| 224 | + with open( |
| 225 | + os.path.join(CURDIR, 'horizon.wsgi.template'), 'r' |
| 226 | + ) as fp: |
| 227 | + wsgi_template = Template(fp.read()) |
| 228 | + if not os.path.exists(context['WSGI_FILE']) or force: |
| 229 | + with open(context['WSGI_FILE'], 'w') as fp: |
| 230 | + fp.write(wsgi_template.render(context)) |
| 231 | + print('Generated "%s"' % context['WSGI_FILE']) |
| 232 | + else: |
| 233 | + sys.exit('"%s" already exists, use --force to overwrite' % |
| 234 | + context['WSGI_FILE']) |
| 235 | + |
| 236 | + # Generate the apache configuration. |
| 237 | + elif options.get('apache'): |
| 238 | + with open( |
| 239 | + os.path.join(CURDIR, 'apache_vhost.conf.template'), 'r' |
| 240 | + ) as fp: |
| 241 | + wsgi_template = Template(fp.read()) |
| 242 | + sys.stdout.write(wsgi_template.render(context)) |
| 243 | + else: |
| 244 | + self.print_help('manage.py', cmd_name) |
0 commit comments