moulinette/lib/yunohost/tools.py

278 lines
8.9 KiB
Python

# -*- coding: utf-8 -*-
""" License
Copyright (C) 2013 YunoHost
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, see http://www.gnu.org/licenses
"""
""" yunohost_tools.py
Specific tools
"""
import logging
logging.warning('the module yunohost.tools has not been revisited and updated yet')
import os
import sys
import yaml
import re
import getpass
import subprocess
import requests
import json
from domain import domain_add, domain_list
from dyndns import dyndns_subscribe
from backup import backup_init
from app import app_ssowatconf
from moulinette.helpers import YunoHostError, YunoHostLDAP, validate, colorize, get_required_args, win_msg
def tools_ldapinit(password=None):
"""
YunoHost LDAP initialization
"""
with YunoHostLDAP() as yldap:
with open('ldap_scheme.yml') as f:
ldap_map = yaml.load(f)
for rdn, attr_dict in ldap_map['parents'].items():
try: yldap.add(rdn, attr_dict)
except: pass
for rdn, attr_dict in ldap_map['children'].items():
try: yldap.add(rdn, attr_dict)
except: pass
admin_dict = {
'cn': 'admin',
'uid': 'admin',
'description': 'LDAP Administrator',
'gidNumber': '1007',
'uidNumber': '1007',
'homeDirectory': '/home/admin',
'loginShell': '/bin/bash',
'objectClass': ['organizationalRole', 'posixAccount', 'simpleSecurityObject'],
'userPassword': 'yunohost'
}
yldap.update('cn=admin', admin_dict)
win_msg(_("LDAP has been successfully initialized"))
def tools_adminpw(old_password, new_password):
"""
Change admin password
Keyword argument:
new_password
old_password
"""
# Validate password length
if len(new_password) < 4:
raise YunoHostError(22, _("Password is too short"))
old_password.replace('"', '\\"')
old_password.replace('&', '\\&')
new_password.replace('"', '\\"')
new_password.replace('&', '\\&')
result = os.system('ldappasswd -h localhost -D cn=admin,dc=yunohost,dc=org -w "'+ old_password +'" -a "'+ old_password +'" -s "' + new_password + '"')
if result == 0:
win_msg(_("Admin password has been changed"))
else:
raise YunoHostError(22, _("Invalid password"))
def tools_maindomain(old_domain, new_domain, dyndns=False):
"""
Main domain change tool
Keyword argument:
new_domain
old_domain
"""
if not old_domain:
with open('/etc/yunohost/current_host', 'r') as f:
old_domain = f.readline().rstrip()
validate(r'^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$', old_domain)
config_files = [
'/etc/postfix/main.cf',
'/etc/metronome/metronome.cfg.lua',
'/etc/dovecot/dovecot.conf',
'/usr/share/yunohost/yunohost-config/others/startup',
'/home/yunohost.backup/tahoe/tahoe.cfg'
'/etc/amavis/conf.d/05-node_id'
]
config_dir = []
for dir in config_dir:
for file in os.listdir(dir):
config_files.append(dir + '/' + file)
for file in config_files:
with open(file, "r") as sources:
lines = sources.readlines()
with open(file, "w") as sources:
for line in lines:
sources.write(re.sub(r''+ old_domain +'', new_domain, line))
domain_add([new_domain], main=True)
os.system('rm /etc/ssl/private/yunohost_key.pem')
os.system('rm /etc/ssl/certs/yunohost_crt.pem')
command_list = [
'ln -s /etc/yunohost/certs/'+ new_domain +'/key.pem /etc/ssl/private/yunohost_key.pem',
'ln -s /etc/yunohost/certs/'+ new_domain +'/crt.pem /etc/ssl/certs/yunohost_crt.pem',
'echo '+ new_domain +' > /etc/yunohost/current_host',
'service nginx restart',
'service metronome restart',
'service postfix restart',
'service dovecot restart'
]
try:
with open('/etc/yunohost/light') as f: pass
except IOError:
command_list.append('service amavis restart')
#command_list.append('service tahoe-lafs restart')
for command in command_list:
if os.system(command) != 0:
raise YunoHostError(17, _("There were a problem during domain changing"))
if dyndns: dyndns_subscribe(domain=new_domain)
elif len(new_domain.split('.')) >= 3:
r = requests.get('http://dyndns.yunohost.org/domains')
dyndomains = json.loads(r.text)
dyndomain = '.'.join(new_domain.split('.')[1:])
if dyndomain in dyndomains:
dyndns_subscribe(domain=new_domain)
win_msg(_("Main domain has been successfully changed"))
def tools_postinstall(domain, password, dyndns=False):
"""
YunoHost post-install
Keyword argument:
domain -- YunoHost main domain
dyndns -- Subscribe domain to a DynDNS service
password -- YunoHost admin password
"""
try:
with open('/etc/yunohost/installed') as f: pass
except IOError:
print('Installing YunoHost')
else:
raise YunoHostError(17, _("YunoHost is already installed"))
if len(domain.split('.')) >= 3:
r = requests.get('http://dyndns.yunohost.org/domains')
dyndomains = json.loads(r.text)
dyndomain = '.'.join(domain.split('.')[1:])
if dyndomain in dyndomains:
if requests.get('http://dyndns.yunohost.org/test/'+ domain).status_code == 200:
dyndns=True
else:
raise YunoHostError(17, _("Domain is already taken"))
# Create required folders
folders_to_create = [
'/etc/yunohost/apps',
'/etc/yunohost/certs',
'/var/cache/yunohost/repo',
'/home/yunohost.backup',
'/home/yunohost.app'
]
for folder in folders_to_create:
try: os.listdir(folder)
except OSError: os.makedirs(folder)
# Set hostname to avoid amavis bug
if os.system('hostname -d') != 0:
os.system('hostname yunohost.yunohost.org')
# Activate "full" mode if RAM >= 512MB
for L in open("/proc/meminfo"):
if "MemTotal" in L:
if int(L.split(" ")[-2]) < 500000 or not requests.get('http://ip.yunohost.org/'):
os.system('touch /etc/yunohost/light')
else:
os.system('service dspam stop')
os.system('chmod -x /etc/cron.daily/dspam')
os.system('update-rc.d dspam remove')
os.system('sed -i "s/yes/no/g" /etc/default/dspam')
os.system('sed -i "s/dspam=no/dspam=yes/" /etc/yunohost/yunohost.conf')
os.system('apt-get install -y -qq yunohost-config-amavis')
os.system('service amavis start')
os.system('apt-get install --reinstall -y -qq yunohost-config-postfix yunohost-config-dovecot')
# Create SSL CA
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
command_list = [
'echo "01" > '+ ssl_dir +'/serial',
'rm '+ ssl_dir +'/index.txt',
'touch '+ ssl_dir +'/index.txt',
'cp '+ ssl_dir +'/openssl.cnf '+ ssl_dir +'/openssl.ca.cnf ',
'sed -i "s/yunohost.org/'+ domain +'/g" '+ ssl_dir +'/openssl.ca.cnf ',
'openssl req -x509 -new -config '+ ssl_dir +'/openssl.ca.cnf -days 3650 -out '+ ssl_dir +'/ca/cacert.pem -keyout '+ ssl_dir +'/ca/cakey.pem -nodes -batch',
'cp '+ ssl_dir +'/ca/cacert.pem /etc/ssl/certs/ca-yunohost_crt.pem',
'update-ca-certificates'
]
for command in command_list:
if os.system(command) != 0:
raise YunoHostError(17, _("There were a problem during CA creation"))
with YunoHostLDAP(password='yunohost') as yldap:
# Initialize YunoHost LDAP base
tools_ldapinit(password)
# Initialize backup system
backup_init()
# New domain config
tools_maindomain(old_domain='yunohost.org', new_domain=domain, dyndns=dyndns)
# Generate SSOwat configuration file
app_ssowatconf()
# Change LDAP admin password
tools_adminpw(old_password='yunohost', new_password=password)
os.system('touch /etc/yunohost/installed')
os.system('service yunohost-api restart &')
win_msg(_("YunoHost has been successfully configured"))