89 lines
3.9 KiB
Python
89 lines
3.9 KiB
Python
import os
|
|
import sys
|
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
from django.db import connection, transaction
|
|
|
|
from hobo.multitenant.middleware import TenantMiddleware, get_tenant_model
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Create tenant(s) by hostname(s)'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument('hostnames', metavar='HOSTNAME', nargs='+')
|
|
parser.add_argument('--legacy-hostname', dest='legacy_hostname')
|
|
|
|
def handle(self, hostnames, legacy_hostname, **options):
|
|
verbosity = int(options.get('verbosity'))
|
|
if not hostnames:
|
|
raise CommandError('you must give at least one tenant hostname')
|
|
|
|
if '-' in hostnames: # get additional list of hostnames from stdin
|
|
hostnames = list(hostnames)
|
|
hostnames.remove('-')
|
|
hostnames.extend([x.strip() for x in sys.stdin.readlines()])
|
|
|
|
if legacy_hostname and len(hostnames) > 1:
|
|
raise CommandError('You must specify only hostname when using --legacy-hostname')
|
|
|
|
for hostname in hostnames:
|
|
try:
|
|
tenant_base = TenantMiddleware.base()
|
|
except AttributeError:
|
|
raise CommandError('you must configure TENANT_BASE in your settings')
|
|
if not tenant_base:
|
|
raise CommandError('you must set a value to TENANT_BASE in your settings')
|
|
tenant_dir = os.path.join(tenant_base, hostname)
|
|
if os.path.exists(tenant_dir):
|
|
raise CommandError('tenant already exists')
|
|
|
|
tenant_dir_tmp = os.path.join(tenant_base, hostname + '__CREATION_IN_PROGRESS.invalid')
|
|
if legacy_hostname:
|
|
legacy_tenant_dir = os.path.join(tenant_base, legacy_hostname)
|
|
if not os.path.exists(legacy_tenant_dir):
|
|
raise CommandError('legacy tenant does not exists')
|
|
try:
|
|
os.rename(legacy_tenant_dir, tenant_dir_tmp)
|
|
except OSError as e:
|
|
raise CommandError('cannot change legacy tenant (%s)' % str(e))
|
|
else:
|
|
try:
|
|
os.mkdir(tenant_dir_tmp, 0o755)
|
|
except OSError as e:
|
|
raise CommandError('cannot start tenant creation (%s)' % str(e))
|
|
|
|
# tenant creation in database
|
|
try:
|
|
connection.set_schema_to_public()
|
|
schema = TenantMiddleware.hostname2schema(hostname)
|
|
legacy_schema = None
|
|
if legacy_hostname:
|
|
legacy_schema = TenantMiddleware.hostname2schema(legacy_hostname)
|
|
tenant = get_tenant_model()(schema_name=schema, domain_url=hostname)
|
|
if verbosity >= 1:
|
|
msg = self.style.NOTICE('=== Creating schema ') + self.style.SQL_TABLE(tenant.schema_name)
|
|
if legacy_schema:
|
|
msg = (
|
|
self.style.NOTICE('=== Renamin schema ')
|
|
+ self.style.SQL_TABLE(legacy_schema)
|
|
+ ' to '
|
|
+ self.style.SQL_TABLE(tenant.schema_name)
|
|
)
|
|
print()
|
|
print(msg)
|
|
with transaction.atomic():
|
|
tenant.create_schema(check_if_exists=True, legacy_schema_name=legacy_schema)
|
|
except Exception as e:
|
|
if legacy_hostname:
|
|
os.rename(tenant_dir_tmp, legacy_tenant_dir)
|
|
else:
|
|
os.rmdir(tenant_dir_tmp)
|
|
raise CommandError('tenant creation failed (%s)' % str(e))
|
|
if not legacy_hostname:
|
|
for folder in ('media', 'static', 'templates'):
|
|
path = os.path.join(tenant_dir_tmp, folder)
|
|
os.mkdir(path, 0o755)
|
|
# activate the tenant by creating its directory
|
|
os.rename(tenant_dir_tmp, tenant_dir)
|