Newer
Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Script to set the domain of an existing MediaServer, Miris Manager or Monitor
'''
import os
import re
import subprocess
import sys
import utils
from utils import log
class SetAppDomain():
USAGE = '''USAGE: %s [-d] [-f] [-h] <app> <domain>
-d: Debug mode (can be started with non root users).
-f: Force mode (to force replacement of configuration even if there are warnings).
-h: Show this message.
app: The application for which the new domain should be set.
Possible values:
"ms" (MediaServer), "mm" (Miris Manager), "mon" (Monitor).
It is possible to specify which MediaServer instance should be targetted
by using this format: ms-<instance name> (for example ms-msuser).
domain: The new domain.''' % __file__
UNIX_USER_PATTERN = r'[a-z0-9\-]+'
DOMAIN_PATTERN = r'([a-z0-9\-]+\.)*[a-z0-9\-]+(\.[a-z]+){0,1}'
def __init__(self, *args):
args = list(args)
# Check if help is required
if '-h' in args:
sys.exit(0)
# Check current dir
root_dir = utils.get_dir(__file__)
if root_dir != '':
os.chdir(root_dir)
self.root_dir = root_dir
# Add to python path
if root_dir not in sys.path:
sys.path.append(root_dir)
# Check if force mode is enabled
self.force = '-f' in args
if self.force:
args.remove('-f')
# Check that this script is run by root
self.debug = '-d' in args
if self.debug:
args.remove('-d')
whoami = subprocess.check_output(['whoami']).decode('utf-8').strip()
if whoami != 'root' and not self.debug:
log('This script should be run as root user.')
sys.exit(1)
# Parse args
if not args:
log('Not enough arguments.')
sys.exit(1)
new_domain = args.pop()
if not re.match(self.DOMAIN_PATTERN, new_domain):
log('The given domain "%s" does not match the expected pattern (%s).\n' % (new_domain, self.DOMAIN_PATTERN))
log(self.USAGE)
sys.exit(1)
if args:
app = args.pop()
# Get Nginx conf path and instance user
key = None
nginx_conf = '/etc/nginx/sites-available/skyreach.conf'
elif app == 'mon':
nginx_conf = '/etc/nginx/sites-available/msmonitor.conf'
key = 'MONITOR_SERVER_NAME'
elif app == 'ms' or app.startswith('ms-'):
if app.startswith('ms-'):
instance = app[3:].strip('. -\t\n')
if not re.match(self.UNIX_USER_PATTERN, instance):
log('Invalid MediaServer instance requested. Validation reg exp is: %s' % self.UNIX_USER_PATTERN)
sys.exit(1)
else:
instance = 'msuser'
nginx_conf = '/etc/nginx/sites-available/mediaserver-%s.conf' % instance
if instance == 'msuser':
key = 'MS_SERVER_NAME'
else:
log('Invalid app name requested.')
self.change_nginx_domain(nginx_conf, new_domain)
self.change_hosts_file(new_domain)
if key:
self.change_envsetup_conf(key, new_domain)
if app == 'mm':
warning = self.change_mm_domain(new_domain)
elif app == 'mon':
warning = None
else:
warning = self.change_ms_domain(new_domain, instance)
log('\033[92mDone\033[0m')
if warning:
log('\033[93mWarning:\033[0m')
log(warning)
sys.exit(0)
def change_nginx_domain(self, path, new_domain):
log('Checking Nginx configuration file "%s".' % path)
if not os.path.exists(path):
log('The configuration file does not exist.')
sys.exit(1)
with open(path, 'r') as fo:
vhost = fo.read()
new_vhost = ''
changed_lines = 0
for line in vhost.split('\n'):
if re.match(r'\s*server_name\s+([\w\-\_\.\ ]+);', line):
line = re.sub(r'server_name\s+([\w\-\_\.\ ]+);', 'server_name %s;' % new_domain, line)
changed_lines += 1
new_vhost += line + '\n'
if changed_lines != 2:
log('Warning the number of server_name occurence changed in Nginx configuration is not the expected number (2) but is %s.' % changed_lines)
if not self.force:
log('New configuration will be:')
log(new_vhost)
log('Use -f to force the replacement of the configuration.')
sys.exit(1)
new_vhost = new_vhost.strip() + '\n'
if new_vhost != vhost:
if self.debug:
log('New Nginx conf:')
log(new_vhost)
else:
with open(path, 'w') as fo:
fo.write(new_vhost)
log('The configuration file "%s" has been update.' % path)
utils.run_commands(['service nginx restart'])
else:
log('The configuration file "%s" is already up to date.' % path)
def change_hosts_file(self, new_domain):
with open('/etc/hosts', 'r') as fo:
hosts = fo.read()
if ' ' + new_domain in hosts:
hosts = hosts.replace(' ' + new_domain, '')
elif '\t' + new_domain in hosts:
hosts = hosts.replace('\t' + new_domain, '')
hosts = hosts.strip()
new_hosts = ''
for line in hosts.split('\n'):
new_hosts += '\n' + line
if line.startswith('127.0.0.1'):
new_hosts += ' ' + new_domain
if new_hosts != ori_hosts:
if self.debug:
log('New hosts:')
log(new_hosts)
else:
with open('/etc/hosts', 'w') as fo:
fo.write(new_hosts)
log('The "/etc/hosts" file has been update.')
try:
utils.run_commands(['service nscd restart'])
except Exception as nscd_err:
log(nscd_err)
log('The "/etc/hosts" file is already up to date.')
def change_envsetup_conf(self, key, new_domain):
confs = (
'conf.sh',
'auto-generated-conf.sh',
)
replaced = False
for path in confs:
if os.path.exists(path):
with open(path, 'r') as fo:
content = fo.read()
if key in content:
content = re.sub(r'%s=.*' % key, '%s=\'%s\'' % (key, new_domain), content)
with open(path, 'w') as fo:
fo.write(content)
replaced = True
log('Envsetup configration file "%s" updated.' % path)
break
if not replaced:
with open(confs[0], 'a') as fo:
fo.write('\n%s=\'%s\'' % (key, new_domain))
log('Envsetup configration file "%s" updated.' % confs[0])
def change_ms_domain(self, new_domain, instance):
import mediaserver
ms_path = mediaserver.__path__[0]
new_url = 'https://%s' % new_domain
log('Assuming that the new url is using HTTPS: "%s"' % new_url)
cmds = [
# set site url in site settings
'python3 %s %s site_url="%s"' % (os.path.join(ms_path, 'scripts', 'mssiteconfig.py'), instance, new_url),
# reset all local resources managers
'python3 %s %s local' % (os.path.join(ms_path, 'scripts', 'reset_service_resources.py'), instance),
# change configuration of celerity in MS and in workers
'python3 %s update %s' % (os.path.join(ms_path, 'scripts', 'celerity_config_updater.py'), instance),
# restart ms
'mscontroller.py restart -u %s' % instance,
]
utils.run_commands(cmds)
log('Unable to set domain in MediaServer database and Celerity config:\n%s' % e)
log('Domain changed in MediaServer database and Celerity config.')
msg = 'Some steps to change the domain should be done manually:'
msg += '\n - Change the domain of MediaServer used in Miris Manager stations configuration.'
def change_mm_domain(self, new_domain):
try:
new_url = 'https://%s' % new_domain
log('Assuming that the new url is using HTTPS: "%s"' % new_url)
cmds = [
# set site url in site settings
'echo \'from skyreach_site.base.models import SiteSettings; ss = SiteSettings.get_singleton(); ss.url = "%s"; ss.save(); print("Site settings saved.")\' | su skyreach -c "python3 /home/skyreach/htdocs/skyreach_site/manage.py shell -i python"' % new_url,
]
utils.run_commands(cmds)
except Exception as e:
log('Unable to set domain in Miris Manager database:\n%s' % e)
sys.exit(1)
else:
log('Domain changed in Miris Manager database.')
msg = 'Some steps to change the domain should be done manually:'
msg += '\n - Change the url of Miris Manager in the related MediaServer.'
if __name__ == '__main__':
SetAppDomain(*sys.argv[1:])