autopep8 + a few manual tweaks

This commit is contained in:
Alexandre Aubin 2018-12-13 18:49:20 +00:00
parent fb010765bd
commit 115b557b67
34 changed files with 341 additions and 286 deletions

View file

@ -172,7 +172,7 @@ def app_fetchlist(url=None, name=None):
appslist = appslist_request.text appslist = appslist_request.text
try: try:
json.loads(appslist) json.loads(appslist)
except ValueError, e: except ValueError as e:
logger.error(m18n.n('appslist_retrieve_bad_format', logger.error(m18n.n('appslist_retrieve_bad_format',
appslist=name)) appslist=name))
continue continue
@ -701,7 +701,6 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
from yunohost.log import OperationLogger from yunohost.log import OperationLogger
# Fetch or extract sources # Fetch or extract sources
try: try:
os.listdir(INSTALL_TMP) os.listdir(INSTALL_TMP)
@ -758,7 +757,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
env_dict["YNH_APP_INSTANCE_NUMBER"] = str(instance_number) env_dict["YNH_APP_INSTANCE_NUMBER"] = str(instance_number)
# Start register change on system # Start register change on system
operation_logger.extra.update({'env':env_dict}) operation_logger.extra.update({'env': env_dict})
operation_logger.related_to = [s for s in operation_logger.related_to if s[0] != "app"] operation_logger.related_to = [s for s in operation_logger.related_to if s[0] != "app"]
operation_logger.related_to.append(("app", app_id)) operation_logger.related_to.append(("app", app_id))
operation_logger.start() operation_logger.start()
@ -944,7 +943,6 @@ def app_addaccess(auth, apps, users=[]):
for app in apps: for app in apps:
app_settings = _get_app_settings(app) app_settings = _get_app_settings(app)
if not app_settings: if not app_settings:
continue continue
@ -957,7 +955,7 @@ def app_addaccess(auth, apps, users=[]):
# Start register change on system # Start register change on system
related_to = [('app', app)] related_to = [('app', app)]
operation_logger= OperationLogger('app_addaccess', related_to) operation_logger = OperationLogger('app_addaccess', related_to)
operation_logger.start() operation_logger.start()
allowed_users = set() allowed_users = set()
@ -1020,7 +1018,7 @@ def app_removeaccess(auth, apps, users=[]):
# Start register change on system # Start register change on system
related_to = [('app', app)] related_to = [('app', app)]
operation_logger= OperationLogger('app_removeaccess', related_to) operation_logger = OperationLogger('app_removeaccess', related_to)
operation_logger.start() operation_logger.start()
if remove_all: if remove_all:
@ -1034,7 +1032,7 @@ def app_removeaccess(auth, apps, users=[]):
if allowed_user not in users: if allowed_user not in users:
allowed_users.add(allowed_user) allowed_users.add(allowed_user)
operation_logger.related_to += [ ('user', x) for x in allowed_users ] operation_logger.related_to += [('user', x) for x in allowed_users]
operation_logger.flush() operation_logger.flush()
new_users = ','.join(allowed_users) new_users = ','.join(allowed_users)
app_setting(app, 'allowed_users', new_users) app_setting(app, 'allowed_users', new_users)
@ -1069,7 +1067,7 @@ def app_clearaccess(auth, apps):
# Start register change on system # Start register change on system
related_to = [('app', app)] related_to = [('app', app)]
operation_logger= OperationLogger('app_clearaccess', related_to) operation_logger = OperationLogger('app_clearaccess', related_to)
operation_logger.start() operation_logger.start()
if 'mode' in app_settings: if 'mode' in app_settings:
@ -1126,7 +1124,7 @@ def app_makedefault(operation_logger, auth, app, domain=None):
if domain is None: if domain is None:
domain = app_domain domain = app_domain
operation_logger.related_to.append(('domain',domain)) operation_logger.related_to.append(('domain', domain))
elif domain not in domain_list(auth)['domains']: elif domain not in domain_list(auth)['domains']:
raise YunohostError('domain_unknown') raise YunohostError('domain_unknown')
@ -1218,7 +1216,7 @@ def app_register_url(auth, app, domain, path):
# This line can't be moved on top of file, otherwise it creates an infinite # This line can't be moved on top of file, otherwise it creates an infinite
# loop of import with tools.py... # loop of import with tools.py...
from domain import _get_conflicting_apps, _normalize_domain_path from .domain import _get_conflicting_apps, _normalize_domain_path
domain, path = _normalize_domain_path(domain, path) domain, path = _normalize_domain_path(domain, path)
@ -2185,7 +2183,6 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
elif arg_type == 'password': elif arg_type == 'password':
msignals.display(m18n.n('good_practices_about_user_password')) msignals.display(m18n.n('good_practices_about_user_password'))
try: try:
input_string = msignals.prompt(ask_string, is_password) input_string = msignals.prompt(ask_string, is_password)
except NotImplementedError: except NotImplementedError:
@ -2385,7 +2382,7 @@ def _install_appslist_fetch_cron():
with open(cron_job_file, "w") as f: with open(cron_job_file, "w") as f:
f.write('\n'.join(cron_job)) f.write('\n'.join(cron_job))
_set_permissions(cron_job_file, "root", "root", 0755) _set_permissions(cron_job_file, "root", "root", 0o755)
# FIXME - Duplicate from certificate.py, should be moved into a common helper # FIXME - Duplicate from certificate.py, should be moved into a common helper

View file

@ -52,6 +52,7 @@ from yunohost.monitor import binary_to_human
from yunohost.tools import tools_postinstall from yunohost.tools import tools_postinstall
from yunohost.service import service_regen_conf from yunohost.service import service_regen_conf
from yunohost.log import OperationLogger from yunohost.log import OperationLogger
from functools import reduce
BACKUP_PATH = '/home/yunohost.backup' BACKUP_PATH = '/home/yunohost.backup'
ARCHIVES_PATH = '%s/archives' % BACKUP_PATH ARCHIVES_PATH = '%s/archives' % BACKUP_PATH
@ -63,6 +64,7 @@ logger = getActionLogger('yunohost.backup')
class BackupRestoreTargetsManager(object): class BackupRestoreTargetsManager(object):
""" """
BackupRestoreTargetsManager manage the targets BackupRestoreTargetsManager manage the targets
in BackupManager and RestoreManager in BackupManager and RestoreManager
@ -176,6 +178,7 @@ class BackupRestoreTargetsManager(object):
class BackupManager(): class BackupManager():
""" """
This class collect files to backup in a list and apply one or several This class collect files to backup in a list and apply one or several
backup method on it. backup method on it.
@ -267,9 +270,9 @@ class BackupManager():
self.work_dir = os.path.join(BACKUP_PATH, 'tmp', name) self.work_dir = os.path.join(BACKUP_PATH, 'tmp', name)
self._init_work_dir() self._init_work_dir()
########################################################################### #
# Misc helpers # # Misc helpers #
########################################################################### #
@property @property
def info(self): def info(self):
@ -321,16 +324,16 @@ class BackupManager():
# FIXME replace isdir by exists ? manage better the case where the path # FIXME replace isdir by exists ? manage better the case where the path
# exists # exists
if not os.path.isdir(self.work_dir): if not os.path.isdir(self.work_dir):
filesystem.mkdir(self.work_dir, 0750, parents=True, uid='admin') filesystem.mkdir(self.work_dir, 0o750, parents=True, uid='admin')
elif self.is_tmp_work_dir: elif self.is_tmp_work_dir:
logger.debug("temporary directory for backup '%s' already exists", logger.debug("temporary directory for backup '%s' already exists",
self.work_dir) self.work_dir)
# FIXME May be we should clean the workdir here # FIXME May be we should clean the workdir here
raise YunohostError('backup_output_directory_not_empty') raise YunohostError('backup_output_directory_not_empty')
########################################################################### #
# Backup target management # # Backup target management #
########################################################################### #
def set_system_targets(self, system_parts=[]): def set_system_targets(self, system_parts=[]):
""" """
@ -380,9 +383,9 @@ class BackupManager():
logger.warning(m18n.n('backup_with_no_restore_script_for_app', app=app)) logger.warning(m18n.n('backup_with_no_restore_script_for_app', app=app))
self.targets.set_result("apps", app, "Warning") self.targets.set_result("apps", app, "Warning")
########################################################################### #
# Management of files to backup / "The CSV" # # Management of files to backup / "The CSV" #
########################################################################### #
def _import_to_list_to_backup(self, tmp_csv): def _import_to_list_to_backup(self, tmp_csv):
""" """
@ -465,9 +468,9 @@ class BackupManager():
logger.error(m18n.n('backup_csv_addition_failed')) logger.error(m18n.n('backup_csv_addition_failed'))
self.csv_file.close() self.csv_file.close()
########################################################################### #
# File collection from system parts and apps # # File collection from system parts and apps #
########################################################################### #
def collect_files(self): def collect_files(self):
""" """
@ -602,7 +605,7 @@ class BackupManager():
restore_hooks_dir = os.path.join(self.work_dir, "hooks", "restore") restore_hooks_dir = os.path.join(self.work_dir, "hooks", "restore")
if not os.path.exists(restore_hooks_dir): if not os.path.exists(restore_hooks_dir):
filesystem.mkdir(restore_hooks_dir, mode=0750, filesystem.mkdir(restore_hooks_dir, mode=0o750,
parents=True, uid='admin') parents=True, uid='admin')
restore_hooks = hook_list("restore")["hooks"] restore_hooks = hook_list("restore")["hooks"]
@ -668,7 +671,7 @@ class BackupManager():
logger.debug(m18n.n('backup_running_app_script', app=app)) logger.debug(m18n.n('backup_running_app_script', app=app))
try: try:
# Prepare backup directory for the app # Prepare backup directory for the app
filesystem.mkdir(tmp_app_bkp_dir, 0750, True, uid='admin') filesystem.mkdir(tmp_app_bkp_dir, 0o750, True, uid='admin')
# Copy the app settings to be able to call _common.sh # Copy the app settings to be able to call _common.sh
shutil.copytree(app_setting_path, settings_dir) shutil.copytree(app_setting_path, settings_dir)
@ -702,9 +705,9 @@ class BackupManager():
filesystem.rm(tmp_script, force=True) filesystem.rm(tmp_script, force=True)
filesystem.rm(env_dict["YNH_BACKUP_CSV"], force=True) filesystem.rm(env_dict["YNH_BACKUP_CSV"], force=True)
########################################################################### #
# Actual backup archive creation / method management # # Actual backup archive creation / method management #
########################################################################### #
def add(self, method): def add(self, method):
""" """
@ -776,6 +779,7 @@ class BackupManager():
class RestoreManager(): class RestoreManager():
""" """
RestoreManager allow to restore a past backup archive RestoreManager allow to restore a past backup archive
@ -824,9 +828,9 @@ class RestoreManager():
self.method = BackupMethod.create(method) self.method = BackupMethod.create(method)
self.targets = BackupRestoreTargetsManager() self.targets = BackupRestoreTargetsManager()
########################################################################### #
# Misc helpers # # Misc helpers #
########################################################################### #
@property @property
def success(self): def success(self):
@ -902,9 +906,9 @@ class RestoreManager():
logger.warning(m18n.n('restore_cleaning_failed')) logger.warning(m18n.n('restore_cleaning_failed'))
filesystem.rm(self.work_dir, True, True) filesystem.rm(self.work_dir, True, True)
########################################################################### #
# Restore target manangement # # Restore target manangement #
########################################################################### #
def set_system_targets(self, system_parts=[]): def set_system_targets(self, system_parts=[]):
""" """
@ -980,9 +984,9 @@ class RestoreManager():
self.info['apps'].keys(), self.info['apps'].keys(),
unknown_error) unknown_error)
########################################################################### #
# Archive mounting # # Archive mounting #
########################################################################### #
def mount(self): def mount(self):
""" """
@ -1023,9 +1027,9 @@ class RestoreManager():
self._read_info_files() self._read_info_files()
########################################################################### #
# Space computation / checks # # Space computation / checks #
########################################################################### #
def _compute_needed_space(self): def _compute_needed_space(self):
""" """
@ -1086,9 +1090,9 @@ class RestoreManager():
else: else:
raise YunohostError('restore_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin) raise YunohostError('restore_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin)
########################################################################### #
# "Actual restore" (reverse step of the backup collect part) # # "Actual restore" (reverse step of the backup collect part) #
########################################################################### #
def restore(self): def restore(self):
""" """
@ -1104,7 +1108,6 @@ class RestoreManager():
# Apply dirty patch to redirect php5 file on php7 # Apply dirty patch to redirect php5 file on php7
self._patch_backup_csv_file() self._patch_backup_csv_file()
self._restore_system() self._restore_system()
self._restore_apps() self._restore_apps()
finally: finally:
@ -1130,7 +1133,7 @@ class RestoreManager():
contains_php5 = True contains_php5 = True
row['source'] = row['source'].replace('/etc/php5', '/etc/php/7.0') \ row['source'] = row['source'].replace('/etc/php5', '/etc/php/7.0') \
.replace('/var/run/php5-fpm', '/var/run/php/php7.0-fpm') \ .replace('/var/run/php5-fpm', '/var/run/php/php7.0-fpm') \
.replace('php5','php7') .replace('php5', 'php7')
newlines.append(row) newlines.append(row)
except (IOError, OSError, csv.Error) as e: except (IOError, OSError, csv.Error) as e:
@ -1273,7 +1276,7 @@ class RestoreManager():
app_instance_name) app_instance_name)
app_scripts_new_path = os.path.join(app_settings_new_path, 'scripts') app_scripts_new_path = os.path.join(app_settings_new_path, 'scripts')
shutil.copytree(app_settings_in_archive, app_settings_new_path) shutil.copytree(app_settings_in_archive, app_settings_new_path)
filesystem.chmod(app_settings_new_path, 0400, 0400, True) filesystem.chmod(app_settings_new_path, 0o400, 0o400, True)
filesystem.chown(app_scripts_new_path, 'admin', None, True) filesystem.chown(app_scripts_new_path, 'admin', None, True)
# Copy the app scripts to a writable temporary folder # Copy the app scripts to a writable temporary folder
@ -1281,7 +1284,7 @@ class RestoreManager():
# in the backup method ? # in the backup method ?
tmp_folder_for_app_restore = tempfile.mkdtemp(prefix='restore') tmp_folder_for_app_restore = tempfile.mkdtemp(prefix='restore')
copytree(app_scripts_in_archive, tmp_folder_for_app_restore) copytree(app_scripts_in_archive, tmp_folder_for_app_restore)
filesystem.chmod(tmp_folder_for_app_restore, 0550, 0550, True) filesystem.chmod(tmp_folder_for_app_restore, 0o550, 0o550, True)
filesystem.chown(tmp_folder_for_app_restore, 'admin', None, True) filesystem.chown(tmp_folder_for_app_restore, 'admin', None, True)
restore_script = os.path.join(tmp_folder_for_app_restore, 'restore') restore_script = os.path.join(tmp_folder_for_app_restore, 'restore')
@ -1298,7 +1301,7 @@ class RestoreManager():
raise_on_error=True, raise_on_error=True,
env=env_dict) env=env_dict)
except: except:
msg = m18n.n('restore_app_failed',app=app_instance_name) msg = m18n.n('restore_app_failed', app=app_instance_name)
logger.exception(msg) logger.exception(msg)
operation_logger.error(msg) operation_logger.error(msg)
@ -1359,12 +1362,13 @@ class RestoreManager():
return env_var return env_var
############################################################################### #
# Backup methods # # Backup methods #
############################################################################### #
class BackupMethod(object): class BackupMethod(object):
""" """
BackupMethod is an abstract class that represents a way to backup and BackupMethod is an abstract class that represents a way to backup and
restore a list of files. restore a list of files.
@ -1686,6 +1690,7 @@ class BackupMethod(object):
class CopyBackupMethod(BackupMethod): class CopyBackupMethod(BackupMethod):
""" """
This class just do an uncompress copy of each file in a location, and This class just do an uncompress copy of each file in a location, and
could be the inverse for restoring could be the inverse for restoring
@ -1712,7 +1717,7 @@ class CopyBackupMethod(BackupMethod):
dest_parent = os.path.dirname(dest) dest_parent = os.path.dirname(dest)
if not os.path.exists(dest_parent): if not os.path.exists(dest_parent):
filesystem.mkdir(dest_parent, 0750, True, uid='admin') filesystem.mkdir(dest_parent, 0o750, True, uid='admin')
if os.path.isdir(source): if os.path.isdir(source):
shutil.copytree(source, dest) shutil.copytree(source, dest)
@ -1747,6 +1752,7 @@ class CopyBackupMethod(BackupMethod):
class TarBackupMethod(BackupMethod): class TarBackupMethod(BackupMethod):
""" """
This class compress all files to backup in archive. This class compress all files to backup in archive.
""" """
@ -1777,7 +1783,7 @@ class TarBackupMethod(BackupMethod):
""" """
if not os.path.exists(self.repo): if not os.path.exists(self.repo):
filesystem.mkdir(self.repo, 0750, parents=True, uid='admin') filesystem.mkdir(self.repo, 0o750, parents=True, uid='admin')
# Check free space in output # Check free space in output
self._check_is_enough_free_space() self._check_is_enough_free_space()
@ -1895,6 +1901,7 @@ class BorgBackupMethod(BackupMethod):
class CustomBackupMethod(BackupMethod): class CustomBackupMethod(BackupMethod):
""" """
This class use a bash script/hook "backup_method" to do the This class use a bash script/hook "backup_method" to do the
backup/restore operations. A user can add his own hook inside backup/restore operations. A user can add his own hook inside
@ -1958,9 +1965,9 @@ class CustomBackupMethod(BackupMethod):
self.manager.description] self.manager.description]
############################################################################### #
# "Front-end" # # "Front-end" #
############################################################################### #
def backup_create(name=None, description=None, methods=[], def backup_create(name=None, description=None, methods=[],
output_directory=None, no_compress=False, output_directory=None, no_compress=False,
@ -1980,9 +1987,9 @@ def backup_create(name=None, description=None, methods=[],
# TODO: Add a 'clean' argument to clean output directory # TODO: Add a 'clean' argument to clean output directory
########################################################################### #
# Validate / parse arguments # # Validate / parse arguments #
########################################################################### #
# Validate there is no archive with the same name # Validate there is no archive with the same name
if name and name in backup_list()['archives']: if name and name in backup_list()['archives']:
@ -2017,9 +2024,9 @@ def backup_create(name=None, description=None, methods=[],
system = [] system = []
apps = [] apps = []
########################################################################### #
# Intialize # # Intialize #
########################################################################### #
# Create yunohost archives directory if it does not exists # Create yunohost archives directory if it does not exists
_create_archive_dir() _create_archive_dir()
@ -2044,9 +2051,9 @@ def backup_create(name=None, description=None, methods=[],
backup_manager.set_system_targets(system) backup_manager.set_system_targets(system)
backup_manager.set_apps_targets(apps) backup_manager.set_apps_targets(apps)
########################################################################### #
# Collect files and put them in the archive # # Collect files and put them in the archive #
########################################################################### #
# Collect files to be backup (by calling app backup script / system hooks) # Collect files to be backup (by calling app backup script / system hooks)
backup_manager.collect_files() backup_manager.collect_files()
@ -2074,9 +2081,9 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
apps -- List of application names to restore apps -- List of application names to restore
""" """
########################################################################### #
# Validate / parse arguments # # Validate / parse arguments #
########################################################################### #
# If no --system or --apps given, restore everything # If no --system or --apps given, restore everything
if system is None and apps is None: if system is None and apps is None:
@ -2105,9 +2112,9 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
# TODO Partial app restore could not work if ldap is not restored before # TODO Partial app restore could not work if ldap is not restored before
# TODO repair mysql if broken and it's a complete restore # TODO repair mysql if broken and it's a complete restore
########################################################################### #
# Initialize # # Initialize #
########################################################################### #
restore_manager = RestoreManager(name) restore_manager = RestoreManager(name)
@ -2116,9 +2123,9 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
restore_manager.assert_enough_free_space() restore_manager.assert_enough_free_space()
########################################################################### #
# Mount the archive then call the restore for each system part / app # # Mount the archive then call the restore for each system part / app #
########################################################################### #
restore_manager.mount() restore_manager.mount()
restore_manager.restore() restore_manager.restore()
@ -2156,7 +2163,7 @@ def backup_list(with_info=False, human_readable=False):
except ValueError: except ValueError:
continue continue
result.append(name) result.append(name)
result.sort(key=lambda x: os.path.getctime(os.path.join(ARCHIVES_PATH, x+".tar.gz"))) result.sort(key=lambda x: os.path.getctime(os.path.join(ARCHIVES_PATH, x + ".tar.gz")))
if result and with_info: if result and with_info:
d = OrderedDict() d = OrderedDict()
@ -2277,9 +2284,9 @@ def backup_delete(name):
logger.success(m18n.n('backup_deleted')) logger.success(m18n.n('backup_deleted'))
############################################################################### #
# Misc helpers # # Misc helpers #
############################################################################### #
def _create_archive_dir(): def _create_archive_dir():
@ -2288,7 +2295,7 @@ def _create_archive_dir():
if os.path.lexists(ARCHIVES_PATH): if os.path.lexists(ARCHIVES_PATH):
raise YunohostError('backup_output_symlink_dir_broken', path=ARCHIVES_PATH) raise YunohostError('backup_output_symlink_dir_broken', path=ARCHIVES_PATH)
os.mkdir(ARCHIVES_PATH, 0750) os.mkdir(ARCHIVES_PATH, 0o750)
def _call_for_each_path(self, callback, csv_path=None): def _call_for_each_path(self, callback, csv_path=None):

View file

@ -80,9 +80,9 @@ DNS_RESOLVERS = [
"80.67.188.188" # LDN "80.67.188.188" # LDN
] ]
############################################################################### #
# Front-end stuff # # Front-end stuff #
############################################################################### #
def certificate_status(auth, domain_list, full=False): def certificate_status(auth, domain_list, full=False):
@ -215,10 +215,10 @@ def _certificate_install_selfsigned(domain_list, force=False):
crt_pem.write(ca_pem.read()) crt_pem.write(ca_pem.read())
# Set appropriate permissions # Set appropriate permissions
_set_permissions(new_cert_folder, "root", "root", 0755) _set_permissions(new_cert_folder, "root", "root", 0o755)
_set_permissions(key_file, "root", "ssl-cert", 0640) _set_permissions(key_file, "root", "ssl-cert", 0o640)
_set_permissions(crt_file, "root", "ssl-cert", 0640) _set_permissions(crt_file, "root", "ssl-cert", 0o640)
_set_permissions(conf_file, "root", "root", 0600) _set_permissions(conf_file, "root", "root", 0o600)
# Actually enable the certificate we created # Actually enable the certificate we created
_enable_certificate(domain, new_cert_folder) _enable_certificate(domain, new_cert_folder)
@ -298,6 +298,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
logger.error(msg) logger.error(msg)
operation_logger.error(msg) operation_logger.error(msg)
def certificate_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False): def certificate_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False):
""" """
Renew Let's Encrypt certificate for given domains (all by default) Renew Let's Encrypt certificate for given domains (all by default)
@ -401,9 +402,10 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
logger.error("Sending email with details to root ...") logger.error("Sending email with details to root ...")
_email_renewing_failed(domain, e, stack.getvalue()) _email_renewing_failed(domain, e, stack.getvalue())
############################################################################### #
# Back-end stuff # # Back-end stuff #
############################################################################### #
def _install_cron(): def _install_cron():
cron_job_file = "/etc/cron.daily/yunohost-certificate-renew" cron_job_file = "/etc/cron.daily/yunohost-certificate-renew"
@ -412,7 +414,7 @@ def _install_cron():
f.write("#!/bin/bash\n") f.write("#!/bin/bash\n")
f.write("yunohost domain cert-renew --email\n") f.write("yunohost domain cert-renew --email\n")
_set_permissions(cron_job_file, "root", "root", 0755) _set_permissions(cron_job_file, "root", "root", 0o755)
def _email_renewing_failed(domain, exception_message, stack): def _email_renewing_failed(domain, exception_message, stack):
@ -517,8 +519,8 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
if not os.path.exists(TMP_FOLDER): if not os.path.exists(TMP_FOLDER):
os.makedirs(TMP_FOLDER) os.makedirs(TMP_FOLDER)
_set_permissions(WEBROOT_FOLDER, "root", "www-data", 0650) _set_permissions(WEBROOT_FOLDER, "root", "www-data", 0o650)
_set_permissions(TMP_FOLDER, "root", "root", 0640) _set_permissions(TMP_FOLDER, "root", "root", 0o640)
# Regen conf for dnsmasq if needed # Regen conf for dnsmasq if needed
_regen_dnsmasq_if_needed() _regen_dnsmasq_if_needed()
@ -529,7 +531,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
domain_key_file = "%s/%s.pem" % (TMP_FOLDER, domain) domain_key_file = "%s/%s.pem" % (TMP_FOLDER, domain)
_generate_key(domain_key_file) _generate_key(domain_key_file)
_set_permissions(domain_key_file, "root", "ssl-cert", 0640) _set_permissions(domain_key_file, "root", "ssl-cert", 0o640)
_prepare_certificate_signing_request(domain, domain_key_file, TMP_FOLDER) _prepare_certificate_signing_request(domain, domain_key_file, TMP_FOLDER)
@ -585,12 +587,12 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
os.makedirs(new_cert_folder) os.makedirs(new_cert_folder)
_set_permissions(new_cert_folder, "root", "root", 0655) _set_permissions(new_cert_folder, "root", "root", 0o655)
# Move the private key # Move the private key
domain_key_file_finaldest = os.path.join(new_cert_folder, "key.pem") domain_key_file_finaldest = os.path.join(new_cert_folder, "key.pem")
shutil.move(domain_key_file, domain_key_file_finaldest) shutil.move(domain_key_file, domain_key_file_finaldest)
_set_permissions(domain_key_file_finaldest, "root", "ssl-cert", 0640) _set_permissions(domain_key_file_finaldest, "root", "ssl-cert", 0o640)
# Write the cert # Write the cert
domain_cert_file = os.path.join(new_cert_folder, "crt.pem") domain_cert_file = os.path.join(new_cert_folder, "crt.pem")
@ -599,7 +601,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
f.write(signed_certificate) f.write(signed_certificate)
f.write(intermediate_certificate) f.write(intermediate_certificate)
_set_permissions(domain_cert_file, "root", "ssl-cert", 0640) _set_permissions(domain_cert_file, "root", "ssl-cert", 0o640)
if staging: if staging:
return return
@ -735,15 +737,15 @@ def _get_status(domain):
"ACME_eligible": ACME_eligible "ACME_eligible": ACME_eligible
} }
############################################################################### #
# Misc small stuff ... # # Misc small stuff ... #
############################################################################### #
def _generate_account_key(): def _generate_account_key():
logger.debug("Generating account key ...") logger.debug("Generating account key ...")
_generate_key(ACCOUNT_KEY_FILE) _generate_key(ACCOUNT_KEY_FILE)
_set_permissions(ACCOUNT_KEY_FILE, "root", "root", 0400) _set_permissions(ACCOUNT_KEY_FILE, "root", "root", 0o400)
def _generate_key(destination_path): def _generate_key(destination_path):

View file

@ -3,7 +3,9 @@ import glob
from yunohost.tools import Migration from yunohost.tools import Migration
from moulinette.utils.filesystem import chown from moulinette.utils.filesystem import chown
class MyMigration(Migration): class MyMigration(Migration):
"Change certificates group permissions from 'metronome' to 'ssl-cert'" "Change certificates group permissions from 'metronome' to 'ssl-cert'"
all_certificate_files = glob.glob("/etc/yunohost/certs/*/*.pem") all_certificate_files = glob.glob("/etc/yunohost/certs/*/*.pem")

View file

@ -16,6 +16,7 @@ logger = getActionLogger('yunohost.migration')
class MyMigration(Migration): class MyMigration(Migration):
"Migrate Dyndns stuff from MD5 TSIG to SHA512 TSIG" "Migrate Dyndns stuff from MD5 TSIG to SHA512 TSIG"
def backward(self): def backward(self):
@ -87,4 +88,3 @@ class MyMigration(Migration):
logger.info(m18n.n('migrate_tsig_end')) logger.info(m18n.n('migrate_tsig_end'))
return return

View file

@ -24,6 +24,7 @@ YUNOHOST_PACKAGES = ["yunohost", "yunohost-admin", "moulinette", "ssowat"]
class MyMigration(Migration): class MyMigration(Migration):
"Upgrade the system to Debian Stretch and Yunohost 3.0" "Upgrade the system to Debian Stretch and Yunohost 3.0"
mode = "manual" mode = "manual"
@ -286,7 +287,7 @@ class MyMigration(Migration):
# Create tmp directory if it does not exists # Create tmp directory if it does not exists
tmp_dir = os.path.join("/tmp/", self.name) tmp_dir = os.path.join("/tmp/", self.name)
if not os.path.exists(tmp_dir): if not os.path.exists(tmp_dir):
os.mkdir(tmp_dir, 0700) os.mkdir(tmp_dir, 0o700)
for f in self.files_to_keep: for f in self.files_to_keep:
dest_file = f.strip('/').replace("/", "_") dest_file = f.strip('/').replace("/", "_")

View file

@ -19,6 +19,7 @@ MIGRATION_COMMENT = "; YunoHost note : this file was automatically moved from {}
class MyMigration(Migration): class MyMigration(Migration):
"Migrate php5-fpm 'pool' conf files to php7 stuff" "Migrate php5-fpm 'pool' conf files to php7 stuff"
def migrate(self): def migrate(self):

View file

@ -11,6 +11,7 @@ logger = getActionLogger('yunohost.migration')
class MyMigration(Migration): class MyMigration(Migration):
"Migrate DBs from Postgresql 9.4 to 9.6 after migrating to Stretch" "Migrate DBs from Postgresql 9.4 to 9.6 after migrating to Stretch"
def migrate(self): def migrate(self):

View file

@ -15,7 +15,9 @@ from yunohost.tools import Migration
logger = getActionLogger('yunohost.migration') logger = getActionLogger('yunohost.migration')
SMALL_PWD_LIST = ["yunohost", "olinuxino", "olinux", "raspberry", "admin", "root", "test", "rpi"] SMALL_PWD_LIST = ["yunohost", "olinuxino", "olinux", "raspberry", "admin", "root", "test", "rpi"]
class MyMigration(Migration): class MyMigration(Migration):
"Synchronize admin and root passwords" "Synchronize admin and root passwords"
def migrate(self): def migrate(self):

View file

@ -8,8 +8,10 @@ from moulinette.utils.log import getActionLogger
from moulinette.utils.filesystem import mkdir, rm from moulinette.utils.filesystem import mkdir, rm
from yunohost.tools import Migration from yunohost.tools import Migration
from yunohost.service import service_regen_conf, _get_conf_hashes, \ from yunohost.service import service_regen_conf, \
_calculate_hash, _run_service_command _get_conf_hashes, \
_calculate_hash, \
_run_service_command
from yunohost.settings import settings_set from yunohost.settings import settings_set
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
@ -19,6 +21,7 @@ SSHD_CONF = '/etc/ssh/sshd_config'
class MyMigration(Migration): class MyMigration(Migration):
""" """
This is the first step of a couple of migrations that ensure SSH conf is This is the first step of a couple of migrations that ensure SSH conf is
managed by YunoHost (even if the "from_script" flag is present, which was managed by YunoHost (even if the "from_script" flag is present, which was
@ -48,7 +51,7 @@ class MyMigration(Migration):
# Create sshd_config.d dir # Create sshd_config.d dir
if not os.path.exists(SSHD_CONF + '.d'): if not os.path.exists(SSHD_CONF + '.d'):
mkdir(SSHD_CONF + '.d', 0755, uid='root', gid='root') mkdir(SSHD_CONF + '.d', 0o755, uid='root', gid='root')
# Here, we make it so that /etc/ssh/sshd_config is managed # Here, we make it so that /etc/ssh/sshd_config is managed
# by the regen conf (in particular in the case where the # by the regen conf (in particular in the case where the

View file

@ -3,7 +3,8 @@ import re
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from yunohost.tools import Migration from yunohost.tools import Migration
from yunohost.service import service_regen_conf, _get_conf_hashes, \ from yunohost.service import service_regen_conf, \
_get_conf_hashes, \
_calculate_hash _calculate_hash
from yunohost.settings import settings_set, settings_get from yunohost.settings import settings_set, settings_get
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
@ -12,7 +13,9 @@ logger = getActionLogger('yunohost.migration')
SSHD_CONF = '/etc/ssh/sshd_config' SSHD_CONF = '/etc/ssh/sshd_config'
class MyMigration(Migration): class MyMigration(Migration):
""" """
In this second step, the admin is asked if it's okay to use In this second step, the admin is asked if it's okay to use
the recommended SSH configuration - which also implies the recommended SSH configuration - which also implies

View file

@ -115,8 +115,8 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix']) service_regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix'])
app_ssowatconf(auth) app_ssowatconf(auth)
except Exception, e: except Exception as e:
from sys import exc_info; from sys import exc_info
t, v, tb = exc_info() t, v, tb = exc_info()
# Force domain removal silently # Force domain removal silently

View file

@ -225,7 +225,6 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
'zone %s' % host, 'zone %s' % host,
] ]
old_ipv4 = check_output("dig @%s +short %s" % (dyn_host, domain)).strip() or None old_ipv4 = check_output("dig @%s +short %s" % (dyn_host, domain)).strip() or None
old_ipv6 = check_output("dig @%s +short aaaa %s" % (dyn_host, domain)).strip() or None old_ipv6 = check_output("dig @%s +short aaaa %s" % (dyn_host, domain)).strip() or None
@ -273,7 +272,7 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
# should be muc.the.domain.tld. or the.domain.tld # should be muc.the.domain.tld. or the.domain.tld
if record["value"] == "@": if record["value"] == "@":
record["value"] = domain record["value"] = domain
record["value"] = record["value"].replace(";","\;") record["value"] = record["value"].replace(";", "\;")
action = "update add {name}.{domain}. {ttl} {type} {value}".format(domain=domain, **record) action = "update add {name}.{domain}. {ttl} {type} {value}".format(domain=domain, **record)
action = action.replace(" @.", " ") action = action.replace(" @.", " ")

View file

@ -369,7 +369,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
) )
if stdinfo: if stdinfo:
callbacks = ( callbacks[0], callbacks[1], callbacks = (callbacks[0], callbacks[1],
lambda l: logger.info(l.rstrip())) lambda l: logger.info(l.rstrip()))
logger.debug("About to run the command '%s'" % command) logger.debug("About to run the command '%s'" % command)

View file

@ -283,6 +283,7 @@ def is_unit_operation(entities=['app', 'domain', 'service', 'user'],
class OperationLogger(object): class OperationLogger(object):
""" """
Instances of this class represents unit operation done on the ynh instance. Instances of this class represents unit operation done on the ynh instance.

View file

@ -288,7 +288,7 @@ def monitor_system(units=None, human_readable=False):
else: else:
raise YunohostError('unit_unknown', unit=u) raise YunohostError('unit_unknown', unit=u)
if len(units) == 1 and type(result[units[0]]) is not str: if len(units) == 1 and not isinstance(result[units[0]], str):
return result[units[0]] return result[units[0]]
return result return result

View file

@ -151,6 +151,7 @@ def service_stop(names):
raise YunohostError('service_stop_failed', service=name, logs=_get_journalctl_logs(name)) raise YunohostError('service_stop_failed', service=name, logs=_get_journalctl_logs(name))
logger.debug(m18n.n('service_already_stopped', service=name)) logger.debug(m18n.n('service_already_stopped', service=name))
@is_unit_operation() @is_unit_operation()
def service_enable(operation_logger, names): def service_enable(operation_logger, names):
""" """
@ -377,7 +378,7 @@ def service_regen_conf(operation_logger, names=[], with_diff=False, force=False,
if not names: if not names:
operation_logger.name_parameter_override = 'all' operation_logger.name_parameter_override = 'all'
elif len(names) != 1: elif len(names) != 1:
operation_logger.name_parameter_override = str(len(operation_logger.related_to))+'_services' operation_logger.name_parameter_override = str(len(operation_logger.related_to)) + '_services'
operation_logger.start() operation_logger.start()
# Clean pending conf directory # Clean pending conf directory
@ -389,7 +390,7 @@ def service_regen_conf(operation_logger, names=[], with_diff=False, force=False,
shutil.rmtree(os.path.join(PENDING_CONF_DIR, name), shutil.rmtree(os.path.join(PENDING_CONF_DIR, name),
ignore_errors=True) ignore_errors=True)
else: else:
filesystem.mkdir(PENDING_CONF_DIR, 0755, True) filesystem.mkdir(PENDING_CONF_DIR, 0o755, True)
# Format common hooks arguments # Format common hooks arguments
common_args = [1 if force else 0, 1 if dry_run else 0] common_args = [1 if force else 0, 1 if dry_run else 0]
@ -400,7 +401,7 @@ def service_regen_conf(operation_logger, names=[], with_diff=False, force=False,
def _pre_call(name, priority, path, args): def _pre_call(name, priority, path, args):
# create the pending conf directory for the service # create the pending conf directory for the service
service_pending_path = os.path.join(PENDING_CONF_DIR, name) service_pending_path = os.path.join(PENDING_CONF_DIR, name)
filesystem.mkdir(service_pending_path, 0755, True, uid='root') filesystem.mkdir(service_pending_path, 0o755, True, uid='root')
# return the arguments to pass to the script # return the arguments to pass to the script
return pre_args + [service_pending_path, ] return pre_args + [service_pending_path, ]
@ -637,10 +638,10 @@ def _give_lock(action, service, p):
else: else:
systemctl_PID_name = "ControlPID" systemctl_PID_name = "ControlPID"
cmd_get_son_PID ="systemctl show %s -p %s" % (service, systemctl_PID_name) cmd_get_son_PID = "systemctl show %s -p %s" % (service, systemctl_PID_name)
son_PID = 0 son_PID = 0
# As long as we did not found the PID and that the command is still running # As long as we did not found the PID and that the command is still running
while son_PID == 0 and p.poll() == None: while son_PID == 0 and p.poll() is None:
# Call systemctl to get the PID # Call systemctl to get the PID
# Output of the command is e.g. ControlPID=1234 # Output of the command is e.g. ControlPID=1234
son_PID = subprocess.check_output(cmd_get_son_PID.split()) \ son_PID = subprocess.check_output(cmd_get_son_PID.split()) \
@ -657,11 +658,12 @@ def _give_lock(action, service, p):
return son_PID return son_PID
def _remove_lock(PID_to_remove): def _remove_lock(PID_to_remove):
# FIXME ironically not concurrency safe because it's not atomic... # FIXME ironically not concurrency safe because it's not atomic...
PIDs = filesystem.read_file(MOULINETTE_LOCK).split("\n") PIDs = filesystem.read_file(MOULINETTE_LOCK).split("\n")
PIDs_to_keep = [ PID for PID in PIDs if int(PID) != PID_to_remove ] PIDs_to_keep = [PID for PID in PIDs if int(PID) != PID_to_remove]
filesystem.write_to_file(MOULINETTE_LOCK, '\n'.join(PIDs_to_keep)) filesystem.write_to_file(MOULINETTE_LOCK, '\n'.join(PIDs_to_keep))
@ -775,6 +777,7 @@ def _find_previous_log_file(file):
return None return None
def _get_files_diff(orig_file, new_file, as_string=False, skip_header=True): def _get_files_diff(orig_file, new_file, as_string=False, skip_header=True):
"""Compare two files and return the differences """Compare two files and return the differences
@ -919,7 +922,7 @@ def _process_regen_conf(system_conf, new_conf=None, save=True):
backup_dir = os.path.dirname(backup_path) backup_dir = os.path.dirname(backup_path)
if not os.path.isdir(backup_dir): if not os.path.isdir(backup_dir):
filesystem.mkdir(backup_dir, 0755, True) filesystem.mkdir(backup_dir, 0o755, True)
shutil.copy2(system_conf, backup_path) shutil.copy2(system_conf, backup_path)
logger.debug(m18n.n('service_conf_file_backed_up', logger.debug(m18n.n('service_conf_file_backed_up',
@ -934,7 +937,7 @@ def _process_regen_conf(system_conf, new_conf=None, save=True):
system_dir = os.path.dirname(system_conf) system_dir = os.path.dirname(system_conf)
if not os.path.isdir(system_dir): if not os.path.isdir(system_dir):
filesystem.mkdir(system_dir, 0755, True) filesystem.mkdir(system_dir, 0o755, True)
shutil.copyfile(new_conf, system_conf) shutil.copyfile(new_conf, system_conf)
logger.debug(m18n.n('service_conf_file_updated', logger.debug(m18n.n('service_conf_file_updated',

View file

@ -93,7 +93,7 @@ def settings_set(key, value):
if not isinstance(value, int) or isinstance(value, bool): if not isinstance(value, int) or isinstance(value, bool):
if isinstance(value, str): if isinstance(value, str):
try: try:
value=int(value) value = int(value)
except: except:
raise YunohostError('global_settings_bad_type_for_setting', raise YunohostError('global_settings_bad_type_for_setting',
setting=key, setting=key,

View file

@ -98,7 +98,7 @@ def user_ssh_add_key(auth, username, key, comment):
# create empty file to set good permissions # create empty file to set good permissions
write_to_file(authorized_keys_file, "") write_to_file(authorized_keys_file, "")
chown(authorized_keys_file, uid=user["uid"][0]) chown(authorized_keys_file, uid=user["uid"][0])
chmod(authorized_keys_file, 0600) chmod(authorized_keys_file, 0o600)
authorized_keys_content = read_file(authorized_keys_file) authorized_keys_content = read_file(authorized_keys_file)

View file

@ -7,12 +7,14 @@ sys.path.append("..")
def pytest_addoption(parser): def pytest_addoption(parser):
parser.addoption("--yunodebug", action="store_true", default=False) parser.addoption("--yunodebug", action="store_true", default=False)
############################################################################### #
# Tweak translator to raise exceptions if string keys are not defined # # Tweak translator to raise exceptions if string keys are not defined #
############################################################################### #
old_translate = moulinette.core.Translator.translate old_translate = moulinette.core.Translator.translate
def new_translate(self, key, *args, **kwargs): def new_translate(self, key, *args, **kwargs):
if key not in self._translations[self.default_locale].keys(): if key not in self._translations[self.default_locale].keys():
@ -21,14 +23,15 @@ def new_translate(self, key, *args, **kwargs):
return old_translate(self, key, *args, **kwargs) return old_translate(self, key, *args, **kwargs)
moulinette.core.Translator.translate = new_translate moulinette.core.Translator.translate = new_translate
def new_m18nn(self, key, *args, **kwargs): def new_m18nn(self, key, *args, **kwargs):
return self._namespaces[self._current_namespace].translate(key, *args, **kwargs) return self._namespaces[self._current_namespace].translate(key, *args, **kwargs)
moulinette.core.Moulinette18n.n = new_m18nn moulinette.core.Moulinette18n.n = new_m18nn
############################################################################### #
# Init the moulinette to have the cli loggers stuff # # Init the moulinette to have the cli loggers stuff #
############################################################################### #
def pytest_cmdline_main(config): def pytest_cmdline_main(config):

View file

@ -17,7 +17,7 @@ APPSLISTS_JSON = '/etc/yunohost/appslists.json'
def setup_function(function): def setup_function(function):
# Clear all appslist # Clear all appslist
files = glob.glob(REPO_PATH+"/*") files = glob.glob(REPO_PATH + "/*")
for f in files: for f in files:
os.remove(f) os.remove(f)
@ -42,9 +42,9 @@ def cron_job_is_there():
return r == 0 return r == 0
############################################################################### #
# Test listing of appslists and registering of appslists # # Test listing of appslists and registering of appslists #
############################################################################### #
def test_appslist_list_empty(): def test_appslist_list_empty():
@ -103,9 +103,9 @@ def test_appslist_list_register_conflict_url():
assert "plopette" not in appslist_dict.keys() assert "plopette" not in appslist_dict.keys()
############################################################################### #
# Test fetching of appslists # # Test fetching of appslists #
############################################################################### #
def test_appslist_fetch(): def test_appslist_fetch():
@ -244,9 +244,9 @@ def test_appslist_fetch_timeout():
app_fetchlist() app_fetchlist()
############################################################################### #
# Test remove of appslist # # Test remove of appslist #
############################################################################### #
def test_appslist_remove(): def test_appslist_remove():
@ -274,9 +274,9 @@ def test_appslist_remove_unknown():
app_removelist("dummy") app_removelist("dummy")
############################################################################### #
# Test migration from legacy appslist system # # Test migration from legacy appslist system #
############################################################################### #
def add_legacy_cron(name, url): def add_legacy_cron(name, url):

View file

@ -22,6 +22,7 @@ def setup_function(function):
except: except:
pass pass
def teardown_function(function): def teardown_function(function):
try: try:

View file

@ -22,6 +22,7 @@ AUTH_IDENTIFIER = ('ldap', 'ldap-anonymous')
AUTH_PARAMETERS = {'uri': 'ldap://localhost:389', 'base_dn': 'dc=yunohost,dc=org'} AUTH_PARAMETERS = {'uri': 'ldap://localhost:389', 'base_dn': 'dc=yunohost,dc=org'}
auth = None auth = None
def setup_function(function): def setup_function(function):
global maindomain global maindomain
@ -87,9 +88,9 @@ def teardown_function(function):
shutil.rmtree("/opt/test_backup_output_directory") shutil.rmtree("/opt/test_backup_output_directory")
############################################################################### #
# Helpers # # Helpers #
############################################################################### #
def app_is_installed(app): def app_is_installed(app):
@ -111,6 +112,7 @@ def backup_test_dependencies_are_met():
return True return True
def tmp_backup_directory_is_empty(): def tmp_backup_directory_is_empty():
if not os.path.exists("/home/yunohost.backup/tmp/"): if not os.path.exists("/home/yunohost.backup/tmp/"):
@ -118,6 +120,7 @@ def tmp_backup_directory_is_empty():
else: else:
return len(os.listdir('/home/yunohost.backup/tmp/')) == 0 return len(os.listdir('/home/yunohost.backup/tmp/')) == 0
def clean_tmp_backup_directory(): def clean_tmp_backup_directory():
if tmp_backup_directory_is_empty(): if tmp_backup_directory_is_empty():
@ -125,10 +128,10 @@ def clean_tmp_backup_directory():
mount_lines = subprocess.check_output("mount").split("\n") mount_lines = subprocess.check_output("mount").split("\n")
points_to_umount = [ line.split(" ")[2] points_to_umount = [line.split(" ")[2]
for line in mount_lines for line in mount_lines
if len(line) >= 3 if len(line) >= 3
and line.split(" ")[2].startswith("/home/yunohost.backup/tmp") ] and line.split(" ")[2].startswith("/home/yunohost.backup/tmp")]
for point in reversed(points_to_umount): for point in reversed(points_to_umount):
os.system("umount %s" % point) os.system("umount %s" % point)
@ -138,6 +141,7 @@ def clean_tmp_backup_directory():
shutil.rmtree("/home/yunohost.backup/tmp/") shutil.rmtree("/home/yunohost.backup/tmp/")
def reset_ssowat_conf(): def reset_ssowat_conf():
# Make sure we have a ssowat # Make sure we have a ssowat
@ -191,9 +195,10 @@ def add_archive_system_from_2p4():
os.system("cp ./tests/apps/backup_system_from_2p4/backup.tar.gz \ os.system("cp ./tests/apps/backup_system_from_2p4/backup.tar.gz \
/home/yunohost.backup/archives/backup_system_from_2p4.tar.gz") /home/yunohost.backup/archives/backup_system_from_2p4.tar.gz")
############################################################################### #
# System backup # # System backup #
############################################################################### #
def test_backup_only_ldap(): def test_backup_only_ldap():
@ -220,9 +225,10 @@ def test_backup_system_part_that_does_not_exists(mocker):
m18n.n.assert_any_call('backup_hook_unknown', hook="yolol") m18n.n.assert_any_call('backup_hook_unknown', hook="yolol")
m18n.n.assert_any_call('backup_nothings_done') m18n.n.assert_any_call('backup_nothings_done')
############################################################################### #
# System backup and restore # # System backup and restore #
############################################################################### #
def test_backup_and_restore_all_sys(): def test_backup_and_restore_all_sys():
@ -250,9 +256,9 @@ def test_backup_and_restore_all_sys():
assert os.path.exists("/etc/ssowat/conf.json") assert os.path.exists("/etc/ssowat/conf.json")
############################################################################### #
# System restore from 2.4 # # System restore from 2.4 #
############################################################################### #
@pytest.mark.with_system_archive_from_2p4 @pytest.mark.with_system_archive_from_2p4
def test_restore_system_from_Ynh2p4(monkeypatch, mocker): def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
@ -275,9 +281,10 @@ def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
apps=None, apps=None,
force=True) force=True)
############################################################################### #
# App backup # # App backup #
############################################################################### #
@pytest.mark.with_backup_recommended_app_installed @pytest.mark.with_backup_recommended_app_installed
def test_backup_script_failure_handling(monkeypatch, mocker): def test_backup_script_failure_handling(monkeypatch, mocker):
@ -300,6 +307,7 @@ def test_backup_script_failure_handling(monkeypatch, mocker):
m18n.n.assert_any_call('backup_app_failed', app='backup_recommended_app') m18n.n.assert_any_call('backup_app_failed', app='backup_recommended_app')
@pytest.mark.with_backup_recommended_app_installed @pytest.mark.with_backup_recommended_app_installed
def test_backup_not_enough_free_space(monkeypatch, mocker): def test_backup_not_enough_free_space(monkeypatch, mocker):
@ -385,6 +393,7 @@ def test_backup_with_different_output_directory():
assert len(archives_info["system"].keys()) == 1 assert len(archives_info["system"].keys()) == 1
assert "conf_ssh" in archives_info["system"].keys() assert "conf_ssh" in archives_info["system"].keys()
@pytest.mark.clean_opt_dir @pytest.mark.clean_opt_dir
def test_backup_with_no_compress(): def test_backup_with_no_compress():
# Create the backup # Create the backup
@ -396,9 +405,9 @@ def test_backup_with_no_compress():
assert os.path.exists("/opt/test_backup_output_directory/info.json") assert os.path.exists("/opt/test_backup_output_directory/info.json")
############################################################################### #
# App restore # # App restore #
############################################################################### #
@pytest.mark.with_wordpress_archive_from_2p4 @pytest.mark.with_wordpress_archive_from_2p4
def test_restore_app_wordpress_from_Ynh2p4(): def test_restore_app_wordpress_from_Ynh2p4():
@ -531,9 +540,10 @@ def _test_backup_and_restore_app(app):
assert app_is_installed(app) assert app_is_installed(app)
############################################################################### #
# Some edge cases # # Some edge cases #
############################################################################### #
def test_restore_archive_with_no_json(mocker): def test_restore_archive_with_no_json(mocker):
@ -555,10 +565,9 @@ def test_backup_binds_are_readonly(monkeypatch):
self.manager = backup_manager self.manager = backup_manager
self._organize_files() self._organize_files()
confssh = os.path.join(self.work_dir, "conf/ssh") confssh = os.path.join(self.work_dir, "conf/ssh")
output = subprocess.check_output("touch %s/test 2>&1 || true" % confssh, output = subprocess.check_output("touch %s/test 2>&1 || true" % confssh,
shell=True, env={'LANG' : 'en_US.UTF-8'}) shell=True, env={'LANG': 'en_US.UTF-8'})
assert "Read-only file system" in output assert "Read-only file system" in output

View file

@ -53,6 +53,7 @@ def test_appchangeurl():
check_changeurl_app("/newchangeurl") check_changeurl_app("/newchangeurl")
def test_appchangeurl_sameurl(): def test_appchangeurl_sameurl():
install_changeurl_app("/changeurl") install_changeurl_app("/changeurl")
check_changeurl_app("/changeurl") check_changeurl_app("/changeurl")

View file

@ -18,7 +18,8 @@ def teardown_function(function):
def test_settings_get_bool(): def test_settings_get_bool():
assert settings_get("example.bool") == True assert settings_get("example.bool")
def test_settings_get_full_bool(): def test_settings_get_full_bool():
assert settings_get("example.bool", True) == {"type": "bool", "value": True, "default": True, "description": "Example boolean option"} assert settings_get("example.bool", True) == {"type": "bool", "value": True, "default": True, "description": "Example boolean option"}
@ -27,6 +28,7 @@ def test_settings_get_full_bool():
def test_settings_get_int(): def test_settings_get_int():
assert settings_get("example.int") == 42 assert settings_get("example.int") == 42
def test_settings_get_full_int(): def test_settings_get_full_int():
assert settings_get("example.int", True) == {"type": "int", "value": 42, "default": 42, "description": "Example int option"} assert settings_get("example.int", True) == {"type": "int", "value": 42, "default": 42, "description": "Example int option"}
@ -34,6 +36,7 @@ def test_settings_get_full_int():
def test_settings_get_string(): def test_settings_get_string():
assert settings_get("example.string") == "yolo swag" assert settings_get("example.string") == "yolo swag"
def test_settings_get_full_string(): def test_settings_get_full_string():
assert settings_get("example.string", True) == {"type": "string", "value": "yolo swag", "default": "yolo swag", "description": "Example string option"} assert settings_get("example.string", True) == {"type": "string", "value": "yolo swag", "default": "yolo swag", "description": "Example string option"}
@ -41,6 +44,7 @@ def test_settings_get_full_string():
def test_settings_get_enum(): def test_settings_get_enum():
assert settings_get("example.enum") == "a" assert settings_get("example.enum") == "a"
def test_settings_get_full_enum(): def test_settings_get_full_enum():
assert settings_get("example.enum", True) == {"type": "enum", "value": "a", "default": "a", "description": "Example enum option", "choices": ["a", "b", "c"]} assert settings_get("example.enum", True) == {"type": "enum", "value": "a", "default": "a", "description": "Example enum option", "choices": ["a", "b", "c"]}
@ -152,7 +156,6 @@ def test_reset_all_backup():
assert settings_after_modification == json.load(open(old_settings_backup_path, "r")) assert settings_after_modification == json.load(open(old_settings_backup_path, "r"))
def test_unknown_keys(): def test_unknown_keys():
unknown_settings_path = SETTINGS_PATH_OTHER_LOCATION % "unknown" unknown_settings_path = SETTINGS_PATH_OTHER_LOCATION % "unknown"
unknown_setting = { unknown_setting = {

View file

@ -136,7 +136,7 @@ def tools_adminpw(auth, new_password, check_strength=True):
new_hash = _hash_user_password(new_password) new_hash = _hash_user_password(new_password)
try: try:
auth.update("cn=admin", { "userPassword": new_hash, }) auth.update("cn=admin", {"userPassword": new_hash, })
except: except:
logger.exception('unable to change admin password') logger.exception('unable to change admin password')
raise YunohostError('admin_password_change_failed') raise YunohostError('admin_password_change_failed')
@ -265,7 +265,7 @@ def _is_inside_container():
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
out, _ = p.communicate() out, _ = p.communicate()
container = ['lxc','lxd','docker'] container = ['lxc', 'lxd', 'docker']
return out.split()[0] in container return out.split()[0] in container
@ -323,7 +323,6 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
else: else:
dyndns = False dyndns = False
operation_logger.start() operation_logger.start()
logger.info(m18n.n('yunohost_installing')) logger.info(m18n.n('yunohost_installing'))
@ -575,7 +574,6 @@ def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=Fal
else: else:
logger.info(m18n.n('packages_no_upgrade')) logger.info(m18n.n('packages_no_upgrade'))
if not ignore_apps: if not ignore_apps:
try: try:
app_upgrade(auth) app_upgrade(auth)
@ -815,12 +813,12 @@ def tools_migrations_list(pending=False, done=False):
migrations = [m for m in migrations if m.number > last_migration] migrations = [m for m in migrations if m.number > last_migration]
# Reduce to dictionnaries # Reduce to dictionnaries
migrations = [{ "id": migration.id, migrations = [{"id": migration.id,
"number": migration.number, "number": migration.number,
"name": migration.name, "name": migration.name,
"mode": migration.mode, "mode": migration.mode,
"description": migration.description, "description": migration.description,
"disclaimer": migration.disclaimer } for migration in migrations ] "disclaimer": migration.disclaimer} for migration in migrations]
return {"migrations": migrations} return {"migrations": migrations}
@ -914,7 +912,7 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
accept_disclaimer = False accept_disclaimer = False
# Start register change on system # Start register change on system
operation_logger= OperationLogger('tools_migrations_migrate_' + mode) operation_logger = OperationLogger('tools_migrations_migrate_' + mode)
operation_logger.start() operation_logger.start()
if not skip: if not skip:
@ -967,6 +965,7 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
write_to_json(MIGRATIONS_STATE_PATH, state) write_to_json(MIGRATIONS_STATE_PATH, state)
def tools_migrations_state(): def tools_migrations_state():
""" """
Show current migration state Show current migration state
@ -1009,7 +1008,7 @@ def _get_migrations_list():
migrations = [] migrations = []
try: try:
import data_migrations from . import data_migrations
except ImportError: except ImportError:
# not data migrations present, return empty list # not data migrations present, return empty list
return migrations return migrations
@ -1032,7 +1031,7 @@ def _get_migration_by_name(migration_name):
""" """
try: try:
import data_migrations from . import data_migrations
except ImportError: except ImportError:
raise AssertionError("Unable to find migration with name %s" % migration_name) raise AssertionError("Unable to find migration with name %s" % migration_name)
@ -1066,6 +1065,7 @@ def _load_migration(migration_file):
raise YunohostError('migrations_error_failed_to_load_migration', raise YunohostError('migrations_error_failed_to_load_migration',
number=number, name=name) number=number, name=name)
def _skip_all_migrations(): def _skip_all_migrations():
""" """
Skip all pending migrations. Skip all pending migrations.
@ -1115,4 +1115,3 @@ class Migration(object):
@property @property
def description(self): def description(self):
return m18n.n("migration_description_%s" % self.id) return m18n.n("migration_description_%s" % self.id)

View file

@ -40,6 +40,7 @@ from yunohost.log import is_unit_operation
logger = getActionLogger('yunohost.user') logger = getActionLogger('yunohost.user')
def user_list(auth, fields=None): def user_list(auth, fields=None):
""" """
List users List users
@ -466,18 +467,23 @@ def user_info(auth, username):
# #
import yunohost.ssh import yunohost.ssh
def user_ssh_allow(auth, username): def user_ssh_allow(auth, username):
return yunohost.ssh.user_ssh_allow(auth, username) return yunohost.ssh.user_ssh_allow(auth, username)
def user_ssh_disallow(auth, username): def user_ssh_disallow(auth, username):
return yunohost.ssh.user_ssh_disallow(auth, username) return yunohost.ssh.user_ssh_disallow(auth, username)
def user_ssh_list_keys(auth, username): def user_ssh_list_keys(auth, username):
return yunohost.ssh.user_ssh_list_keys(auth, username) return yunohost.ssh.user_ssh_list_keys(auth, username)
def user_ssh_add_key(auth, username, key, comment): def user_ssh_add_key(auth, username, key, comment):
return yunohost.ssh.user_ssh_add_key(auth, username, key, comment) return yunohost.ssh.user_ssh_add_key(auth, username, key, comment)
def user_ssh_remove_key(auth, username, key): def user_ssh_remove_key(auth, username, key):
return yunohost.ssh.user_ssh_remove_key(auth, username, key) return yunohost.ssh.user_ssh_remove_key(auth, username, key)
@ -485,6 +491,7 @@ def user_ssh_remove_key(auth, username, key):
# End SSH subcategory # End SSH subcategory
# #
def _convertSize(num, suffix=''): def _convertSize(num, suffix=''):
for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']: for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']:
if abs(num) < 1024.0: if abs(num) < 1024.0:
@ -520,6 +527,3 @@ def _hash_user_password(password):
salt = '$6$' + salt + '$' salt = '$6$' + salt + '$'
return '{CRYPT}' + crypt.crypt(str(password), salt) return '{CRYPT}' + crypt.crypt(str(password), salt)

View file

@ -22,12 +22,14 @@
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette import m18n from moulinette import m18n
class YunohostError(MoulinetteError): class YunohostError(MoulinetteError):
"""Yunohost base exception""" """Yunohost base exception"""
def __init__(self, key, __raw_msg__=False, *args, **kwargs): def __init__(self, key, __raw_msg__=False, *args, **kwargs):
if __raw_msg__: if __raw_msg__:
msg = key msg = key
else: else:
msg = m18n.n(key, *args, **kwargs) msg = m18n.n(key, *args, **kwargs)
super(YunohostError, self).__init__(msg, __raw_msg__=True) super(YunohostError, self).__init__(msg, __raw_msg__=True)

View file

@ -20,10 +20,12 @@
""" """
import os import os
def free_space_in_directory(dirpath): def free_space_in_directory(dirpath):
stat = os.statvfs(dirpath) stat = os.statvfs(dirpath)
return stat.f_frsize * stat.f_bavail return stat.f_frsize * stat.f_bavail
def space_used_by_directory(dirpath): def space_used_by_directory(dirpath):
stat = os.statvfs(dirpath) stat = os.statvfs(dirpath)
return stat.f_frsize * stat.f_blocks return stat.f_frsize * stat.f_blocks

View file

@ -71,7 +71,7 @@ def get_gateway():
return addr.popitem()[1] if len(addr) == 1 else None return addr.popitem()[1] if len(addr) == 1 else None
############################################################################### #
def _extract_inet(string, skip_netmask=False, skip_loopback=True): def _extract_inet(string, skip_netmask=False, skip_loopback=True):

View file

@ -33,6 +33,7 @@ logger = logging.getLogger('yunohost.utils.packages')
# Exceptions ----------------------------------------------------------------- # Exceptions -----------------------------------------------------------------
class PackageException(Exception): class PackageException(Exception):
"""Base exception related to a package """Base exception related to a package
Represent an exception related to the package named `pkgname`. If no Represent an exception related to the package named `pkgname`. If no
@ -50,16 +51,19 @@ class PackageException(Exception):
class UnknownPackage(PackageException): class UnknownPackage(PackageException):
"""The package is not found in the cache.""" """The package is not found in the cache."""
message_key = 'package_unknown' message_key = 'package_unknown'
class UninstalledPackage(PackageException): class UninstalledPackage(PackageException):
"""The package is not installed.""" """The package is not installed."""
message_key = 'package_not_installed' message_key = 'package_not_installed'
class InvalidSpecifier(ValueError): class InvalidSpecifier(ValueError):
"""An invalid specifier was found.""" """An invalid specifier was found."""
@ -68,6 +72,7 @@ class InvalidSpecifier(ValueError):
# See: https://github.com/pypa/packaging # See: https://github.com/pypa/packaging
class Specifier(object): class Specifier(object):
"""Unique package version specifier """Unique package version specifier
Restrict a package version according to the `spec`. It must be a string Restrict a package version according to the `spec`. It must be a string
@ -257,6 +262,7 @@ class Specifier(object):
class SpecifierSet(object): class SpecifierSet(object):
"""A set of package version specifiers """A set of package version specifiers
Combine several Specifier separated by a comma. It allows to restrict Combine several Specifier separated by a comma. It allows to restrict

View file

@ -38,9 +38,11 @@ STRENGTH_LEVELS = [
(12, 1, 1, 1, 1), (12, 1, 1, 1, 1),
] ]
def assert_password_is_strong_enough(profile, password): def assert_password_is_strong_enough(profile, password):
PasswordValidator(profile).validate(password) PasswordValidator(profile).validate(password)
class PasswordValidator(object): class PasswordValidator(object):
def __init__(self, profile): def __init__(self, profile):
@ -157,7 +159,7 @@ class PasswordValidator(object):
# and the strength of the password (e.g. [11, 2, 7, 2, 0]) # and the strength of the password (e.g. [11, 2, 7, 2, 0])
# and compare the values 1-by-1. # and compare the values 1-by-1.
# If one False is found, the password does not satisfy the level # If one False is found, the password does not satisfy the level
if False in [s>=c for s, c in zip(strength, level_criterias)]: if False in [s >= c for s, c in zip(strength, level_criterias)]:
break break
# Otherwise, the strength of the password is at least of the current level. # Otherwise, the strength of the password is at least of the current level.
strength_level = level + 1 strength_level = level + 1
@ -186,7 +188,7 @@ if __name__ == '__main__':
if len(sys.argv) < 2: if len(sys.argv) < 2:
import getpass import getpass
pwd = getpass.getpass("") pwd = getpass.getpass("")
#print("usage: password.py PASSWORD") # print("usage: password.py PASSWORD")
else: else:
pwd = sys.argv[1] pwd = sys.argv[1]
status, msg = PasswordValidator('user').validation_summary(pwd) status, msg = PasswordValidator('user').validation_summary(pwd)

View file

@ -5,6 +5,7 @@ import json
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
def yunopaste(data): def yunopaste(data):
paste_server = "https://paste.yunohost.org" paste_server = "https://paste.yunohost.org"