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

@ -137,7 +137,7 @@ def app_fetchlist(url=None, name=None):
else:
appslists_to_be_fetched = appslists.keys()
import requests # lazy loading this module for performance reasons
import requests # lazy loading this module for performance reasons
# Fetch all appslists to be fetched
for name in appslists_to_be_fetched:
@ -172,7 +172,7 @@ def app_fetchlist(url=None, name=None):
appslist = appslist_request.text
try:
json.loads(appslist)
except ValueError, e:
except ValueError as e:
logger.error(m18n.n('appslist_retrieve_bad_format',
appslist=name))
continue
@ -542,7 +542,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
raise YunohostError("app_change_url_failed_nginx_reload", nginx_errors=nginx_errors)
logger.success(m18n.n("app_change_url_success",
app=app, domain=domain, path=path))
app=app, domain=domain, path=path))
hook_callback('post_app_change_url', args=args_list, env=env_dict)
@ -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.log import OperationLogger
# Fetch or extract sources
try:
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)
# 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.append(("app", app_id))
operation_logger.start()
@ -816,8 +815,8 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
# Execute remove script
operation_logger_remove = OperationLogger('remove_on_failed_install',
[('app', app_instance_name)],
env=env_dict_remove)
[('app', app_instance_name)],
env=env_dict_remove)
operation_logger_remove.start()
remove_retcode = hook_exec(
@ -944,7 +943,6 @@ def app_addaccess(auth, apps, users=[]):
for app in apps:
app_settings = _get_app_settings(app)
if not app_settings:
continue
@ -957,7 +955,7 @@ def app_addaccess(auth, apps, users=[]):
# Start register change on system
related_to = [('app', app)]
operation_logger= OperationLogger('app_addaccess', related_to)
operation_logger = OperationLogger('app_addaccess', related_to)
operation_logger.start()
allowed_users = set()
@ -1020,7 +1018,7 @@ def app_removeaccess(auth, apps, users=[]):
# Start register change on system
related_to = [('app', app)]
operation_logger= OperationLogger('app_removeaccess', related_to)
operation_logger = OperationLogger('app_removeaccess', related_to)
operation_logger.start()
if remove_all:
@ -1034,7 +1032,7 @@ def app_removeaccess(auth, apps, users=[]):
if allowed_user not in users:
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()
new_users = ','.join(allowed_users)
app_setting(app, 'allowed_users', new_users)
@ -1069,7 +1067,7 @@ def app_clearaccess(auth, apps):
# Start register change on system
related_to = [('app', app)]
operation_logger= OperationLogger('app_clearaccess', related_to)
operation_logger = OperationLogger('app_clearaccess', related_to)
operation_logger.start()
if 'mode' in app_settings:
@ -1126,7 +1124,7 @@ def app_makedefault(operation_logger, auth, app, domain=None):
if domain is None:
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']:
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
# 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)
@ -1569,10 +1567,10 @@ def app_config_show_panel(app):
parsed_values[key] = value
return_code = hook_exec(config_script,
args=["show"],
env=env,
stdout_callback=parse_stdout,
)
args=["show"],
env=env,
stdout_callback=parse_stdout,
)
if return_code != 0:
raise Exception("script/config show return value code: %s (considered as an error)", return_code)
@ -1656,9 +1654,9 @@ def app_config_apply(app, args):
logger.warning("Ignore key '%s' from arguments because it is not in the config", key)
return_code = hook_exec(config_script,
args=["apply"],
env=env,
)
args=["apply"],
env=env,
)
if return_code != 0:
raise Exception("'script/config apply' return value code: %s (considered as an error)", return_code)
@ -2185,7 +2183,6 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
elif arg_type == 'password':
msignals.display(m18n.n('good_practices_about_user_password'))
try:
input_string = msignals.prompt(ask_string, is_password)
except NotImplementedError:
@ -2385,7 +2382,7 @@ def _install_appslist_fetch_cron():
with open(cron_job_file, "w") as f:
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
@ -2431,7 +2428,7 @@ def _write_appslist_list(appslist_lists):
json.dump(appslist_lists, f)
except Exception as e:
raise YunohostError("Error while writing list of appslist %s: %s" %
(APPSLISTS_JSON, str(e)), __raw_msg__=True)
(APPSLISTS_JSON, str(e)), __raw_msg__=True)
def _register_new_appslist(url, name):
@ -2541,7 +2538,7 @@ def _patch_php5(app_folder):
continue
c = "sed -i -e 's@/etc/php5@/etc/php/7.0@g' " \
"-e 's@/var/run/php5-fpm@/var/run/php/php7.0-fpm@g' " \
"-e 's@php5@php7.0@g' " \
"%s" % filename
"-e 's@/var/run/php5-fpm@/var/run/php/php7.0-fpm@g' " \
"-e 's@php5@php7.0@g' " \
"%s" % filename
os.system(c)

View file

@ -52,6 +52,7 @@ from yunohost.monitor import binary_to_human
from yunohost.tools import tools_postinstall
from yunohost.service import service_regen_conf
from yunohost.log import OperationLogger
from functools import reduce
BACKUP_PATH = '/home/yunohost.backup'
ARCHIVES_PATH = '%s/archives' % BACKUP_PATH
@ -63,6 +64,7 @@ logger = getActionLogger('yunohost.backup')
class BackupRestoreTargetsManager(object):
"""
BackupRestoreTargetsManager manage the targets
in BackupManager and RestoreManager
@ -176,6 +178,7 @@ class BackupRestoreTargetsManager(object):
class BackupManager():
"""
This class collect files to backup in a list and apply one or several
backup method on it.
@ -267,9 +270,9 @@ class BackupManager():
self.work_dir = os.path.join(BACKUP_PATH, 'tmp', name)
self._init_work_dir()
###########################################################################
# Misc helpers #
###########################################################################
#
# Misc helpers #
#
@property
def info(self):
@ -321,16 +324,16 @@ class BackupManager():
# FIXME replace isdir by exists ? manage better the case where the path
# exists
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:
logger.debug("temporary directory for backup '%s' already exists",
self.work_dir)
# FIXME May be we should clean the workdir here
raise YunohostError('backup_output_directory_not_empty')
###########################################################################
# Backup target management #
###########################################################################
#
# Backup target management #
#
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))
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):
"""
@ -465,9 +468,9 @@ class BackupManager():
logger.error(m18n.n('backup_csv_addition_failed'))
self.csv_file.close()
###########################################################################
# File collection from system parts and apps #
###########################################################################
#
# File collection from system parts and apps #
#
def collect_files(self):
"""
@ -602,7 +605,7 @@ class BackupManager():
restore_hooks_dir = os.path.join(self.work_dir, "hooks", "restore")
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')
restore_hooks = hook_list("restore")["hooks"]
@ -668,7 +671,7 @@ class BackupManager():
logger.debug(m18n.n('backup_running_app_script', app=app))
try:
# 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
shutil.copytree(app_setting_path, settings_dir)
@ -702,9 +705,9 @@ class BackupManager():
filesystem.rm(tmp_script, 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):
"""
@ -776,6 +779,7 @@ class BackupManager():
class RestoreManager():
"""
RestoreManager allow to restore a past backup archive
@ -824,9 +828,9 @@ class RestoreManager():
self.method = BackupMethod.create(method)
self.targets = BackupRestoreTargetsManager()
###########################################################################
# Misc helpers #
###########################################################################
#
# Misc helpers #
#
@property
def success(self):
@ -876,7 +880,7 @@ class RestoreManager():
domain = f.readline().rstrip()
except IOError:
logger.debug("unable to retrieve current_host from the backup",
exc_info=1)
exc_info=1)
# FIXME include the current_host by default ?
raise YunohostError('backup_invalid_archive')
@ -902,9 +906,9 @@ class RestoreManager():
logger.warning(m18n.n('restore_cleaning_failed'))
filesystem.rm(self.work_dir, True, True)
###########################################################################
# Restore target manangement #
###########################################################################
#
# Restore target manangement #
#
def set_system_targets(self, system_parts=[]):
"""
@ -980,9 +984,9 @@ class RestoreManager():
self.info['apps'].keys(),
unknown_error)
###########################################################################
# Archive mounting #
###########################################################################
#
# Archive mounting #
#
def mount(self):
"""
@ -1023,9 +1027,9 @@ class RestoreManager():
self._read_info_files()
###########################################################################
# Space computation / checks #
###########################################################################
#
# Space computation / checks #
#
def _compute_needed_space(self):
"""
@ -1082,13 +1086,13 @@ class RestoreManager():
return True
elif free_space > needed_space:
# TODO Add --force options to avoid the error raising
raise YunohostError('restore_may_be_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin)
raise YunohostError('restore_may_be_not_enough_disk_space', free_space=free_space, needed_space=needed_space, margin=margin)
else:
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):
"""
@ -1104,7 +1108,6 @@ class RestoreManager():
# Apply dirty patch to redirect php5 file on php7
self._patch_backup_csv_file()
self._restore_system()
self._restore_apps()
finally:
@ -1130,7 +1133,7 @@ class RestoreManager():
contains_php5 = True
row['source'] = row['source'].replace('/etc/php5', '/etc/php/7.0') \
.replace('/var/run/php5-fpm', '/var/run/php/php7.0-fpm') \
.replace('php5','php7')
.replace('php5', 'php7')
newlines.append(row)
except (IOError, OSError, csv.Error) as e:
@ -1260,7 +1263,7 @@ class RestoreManager():
# Check if the app has a restore script
app_restore_script_in_archive = os.path.join(app_scripts_in_archive,
'restore')
'restore')
if not os.path.isfile(app_restore_script_in_archive):
logger.warning(m18n.n('unrestore_app', app=app_instance_name))
self.targets.set_result("apps", app_instance_name, "Warning")
@ -1273,7 +1276,7 @@ class RestoreManager():
app_instance_name)
app_scripts_new_path = os.path.join(app_settings_new_path, 'scripts')
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)
# Copy the app scripts to a writable temporary folder
@ -1281,7 +1284,7 @@ class RestoreManager():
# in the backup method ?
tmp_folder_for_app_restore = tempfile.mkdtemp(prefix='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)
restore_script = os.path.join(tmp_folder_for_app_restore, 'restore')
@ -1298,7 +1301,7 @@ class RestoreManager():
raise_on_error=True,
env=env_dict)
except:
msg = m18n.n('restore_app_failed',app=app_instance_name)
msg = m18n.n('restore_app_failed', app=app_instance_name)
logger.exception(msg)
operation_logger.error(msg)
@ -1314,8 +1317,8 @@ class RestoreManager():
env_dict_remove["YNH_APP_INSTANCE_NUMBER"] = str(app_instance_nb)
operation_logger = OperationLogger('remove_on_failed_restore',
[('app', app_instance_name)],
env=env_dict_remove)
[('app', app_instance_name)],
env=env_dict_remove)
operation_logger.start()
# Execute remove script
@ -1359,12 +1362,13 @@ class RestoreManager():
return env_var
###############################################################################
# Backup methods #
###############################################################################
#
# Backup methods #
#
class BackupMethod(object):
"""
BackupMethod is an abstract class that represents a way to backup and
restore a list of files.
@ -1637,7 +1641,7 @@ class BackupMethod(object):
if size > MB_ALLOWED_TO_ORGANIZE:
try:
i = msignals.prompt(m18n.n('backup_ask_for_copying_if_needed',
answers='y/N', size=str(size)))
answers='y/N', size=str(size)))
except NotImplemented:
raise YunohostError('backup_unable_to_organize_files')
else:
@ -1646,7 +1650,7 @@ class BackupMethod(object):
# Copy unbinded path
logger.debug(m18n.n('backup_copying_to_organize_the_archive',
size=str(size)))
size=str(size)))
for path in paths_needed_to_be_copied:
dest = os.path.join(self.work_dir, path['dest'])
if os.path.isdir(path['source']):
@ -1686,6 +1690,7 @@ class BackupMethod(object):
class CopyBackupMethod(BackupMethod):
"""
This class just do an uncompress copy of each file in a location, and
could be the inverse for restoring
@ -1712,7 +1717,7 @@ class CopyBackupMethod(BackupMethod):
dest_parent = os.path.dirname(dest)
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):
shutil.copytree(source, dest)
@ -1747,6 +1752,7 @@ class CopyBackupMethod(BackupMethod):
class TarBackupMethod(BackupMethod):
"""
This class compress all files to backup in archive.
"""
@ -1777,7 +1783,7 @@ class TarBackupMethod(BackupMethod):
"""
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
self._check_is_enough_free_space()
@ -1895,6 +1901,7 @@ class BorgBackupMethod(BackupMethod):
class CustomBackupMethod(BackupMethod):
"""
This class use a bash script/hook "backup_method" to do the
backup/restore operations. A user can add his own hook inside
@ -1958,9 +1965,9 @@ class CustomBackupMethod(BackupMethod):
self.manager.description]
###############################################################################
# "Front-end" #
###############################################################################
#
# "Front-end" #
#
def backup_create(name=None, description=None, methods=[],
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
###########################################################################
# Validate / parse arguments #
###########################################################################
#
# Validate / parse arguments #
#
# Validate there is no archive with the same name
if name and name in backup_list()['archives']:
@ -1995,7 +2002,7 @@ def backup_create(name=None, description=None, methods=[],
# Check for forbidden folders
if output_directory.startswith(ARCHIVES_PATH) or \
re.match(r'^/(|(bin|boot|dev|etc|lib|root|run|sbin|sys|usr|var)(|/.*))$',
output_directory):
output_directory):
raise YunohostError('backup_output_directory_forbidden')
# Check that output directory is empty
@ -2017,9 +2024,9 @@ def backup_create(name=None, description=None, methods=[],
system = []
apps = []
###########################################################################
# Intialize #
###########################################################################
#
# Intialize #
#
# Create yunohost archives directory if it does not exists
_create_archive_dir()
@ -2044,9 +2051,9 @@ def backup_create(name=None, description=None, methods=[],
backup_manager.set_system_targets(system)
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)
backup_manager.collect_files()
@ -2074,9 +2081,9 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
apps -- List of application names to restore
"""
###########################################################################
# Validate / parse arguments #
###########################################################################
#
# Validate / parse arguments #
#
# If no --system or --apps given, restore everything
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 repair mysql if broken and it's a complete restore
###########################################################################
# Initialize #
###########################################################################
#
# Initialize #
#
restore_manager = RestoreManager(name)
@ -2116,9 +2123,9 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
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.restore()
@ -2156,7 +2163,7 @@ def backup_list(with_info=False, human_readable=False):
except ValueError:
continue
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:
d = OrderedDict()
@ -2194,7 +2201,7 @@ def backup_info(name, with_details=False, human_readable=False):
# Raise exception if link is broken (e.g. on unmounted external storage)
if not os.path.exists(archive_file):
raise YunohostError('backup_archive_broken_link',
path=archive_file)
path=archive_file)
info_file = "%s/%s.info.json" % (ARCHIVES_PATH, name)
@ -2259,7 +2266,7 @@ def backup_delete(name):
"""
if name not in backup_list()["archives"]:
raise YunohostError('backup_archive_name_unknown',
name=name)
name=name)
hook_callback('pre_backup_delete', args=[name])
@ -2277,9 +2284,9 @@ def backup_delete(name):
logger.success(m18n.n('backup_deleted'))
###############################################################################
# Misc helpers #
###############################################################################
#
# Misc helpers #
#
def _create_archive_dir():
@ -2288,7 +2295,7 @@ def _create_archive_dir():
if os.path.lexists(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):

View file

@ -80,9 +80,9 @@ DNS_RESOLVERS = [
"80.67.188.188" # LDN
]
###############################################################################
# Front-end stuff #
###############################################################################
#
# Front-end stuff #
#
def certificate_status(auth, domain_list, full=False):
@ -149,7 +149,7 @@ def _certificate_install_selfsigned(domain_list, force=False):
for domain in domain_list:
operation_logger = OperationLogger('selfsigned_cert_install', [('domain', domain)],
args={'force': force})
args={'force': force})
# Paths of files and folder we'll need
date_tag = datetime.utcnow().strftime("%Y%m%d.%H%M%S")
@ -215,10 +215,10 @@ def _certificate_install_selfsigned(domain_list, force=False):
crt_pem.write(ca_pem.read())
# Set appropriate permissions
_set_permissions(new_cert_folder, "root", "root", 0755)
_set_permissions(key_file, "root", "ssl-cert", 0640)
_set_permissions(crt_file, "root", "ssl-cert", 0640)
_set_permissions(conf_file, "root", "root", 0600)
_set_permissions(new_cert_folder, "root", "root", 0o755)
_set_permissions(key_file, "root", "ssl-cert", 0o640)
_set_permissions(crt_file, "root", "ssl-cert", 0o640)
_set_permissions(conf_file, "root", "root", 0o600)
# Actually enable the certificate we created
_enable_certificate(domain, new_cert_folder)
@ -273,8 +273,8 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
for domain in domain_list:
operation_logger = OperationLogger('letsencrypt_cert_install', [('domain', domain)],
args={'force': force, 'no_checks': no_checks,
'staging': staging})
args={'force': force, 'no_checks': no_checks,
'staging': staging})
logger.info(
"Now attempting install of certificate for domain %s!", domain)
@ -298,6 +298,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
logger.error(msg)
operation_logger.error(msg)
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)
@ -367,8 +368,8 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
for domain in domain_list:
operation_logger = OperationLogger('letsencrypt_cert_renew', [('domain', domain)],
args={'force': force, 'no_checks': no_checks,
'staging': staging, 'email': email})
args={'force': force, 'no_checks': no_checks,
'staging': staging, 'email': email})
logger.info(
"Now attempting renewing of certificate for domain %s !", domain)
@ -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 ...")
_email_renewing_failed(domain, e, stack.getvalue())
###############################################################################
# Back-end stuff #
###############################################################################
#
# Back-end stuff #
#
def _install_cron():
cron_job_file = "/etc/cron.daily/yunohost-certificate-renew"
@ -412,7 +414,7 @@ def _install_cron():
f.write("#!/bin/bash\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):
@ -517,8 +519,8 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
if not os.path.exists(TMP_FOLDER):
os.makedirs(TMP_FOLDER)
_set_permissions(WEBROOT_FOLDER, "root", "www-data", 0650)
_set_permissions(TMP_FOLDER, "root", "root", 0640)
_set_permissions(WEBROOT_FOLDER, "root", "www-data", 0o650)
_set_permissions(TMP_FOLDER, "root", "root", 0o640)
# Regen conf for 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)
_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)
@ -563,7 +565,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
raise YunohostError('certmanager_cert_signing_failed')
import requests # lazy loading this module for performance reasons
import requests # lazy loading this module for performance reasons
try:
intermediate_certificate = requests.get(INTERMEDIATE_CERTIFICATE_URL, timeout=30).text
except requests.exceptions.Timeout as e:
@ -585,12 +587,12 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
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
domain_key_file_finaldest = os.path.join(new_cert_folder, "key.pem")
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
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(intermediate_certificate)
_set_permissions(domain_cert_file, "root", "ssl-cert", 0640)
_set_permissions(domain_cert_file, "root", "ssl-cert", 0o640)
if staging:
return
@ -614,7 +616,7 @@ def _fetch_and_enable_new_certificate(domain, staging=False, no_checks=False):
def _prepare_certificate_signing_request(domain, key_file, output_folder):
from OpenSSL import crypto # lazy loading this module for performance reasons
from OpenSSL import crypto # lazy loading this module for performance reasons
# Init a request
csr = crypto.X509Req()
@ -645,7 +647,7 @@ def _get_status(domain):
if not os.path.isfile(cert_file):
raise YunohostError('certmanager_no_cert_file', domain=domain, file=cert_file)
from OpenSSL import crypto # lazy loading this module for performance reasons
from OpenSSL import crypto # lazy loading this module for performance reasons
try:
cert = crypto.load_certificate(
crypto.FILETYPE_PEM, open(cert_file).read())
@ -735,19 +737,19 @@ def _get_status(domain):
"ACME_eligible": ACME_eligible
}
###############################################################################
# Misc small stuff ... #
###############################################################################
#
# Misc small stuff ... #
#
def _generate_account_key():
logger.debug("Generating account key ...")
_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):
from OpenSSL import crypto # lazy loading this module for performance reasons
from OpenSSL import crypto # lazy loading this module for performance reasons
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, KEY_SIZE)
@ -836,7 +838,7 @@ def _dns_ip_match_public_ip(public_ip, domain):
def _domain_is_accessible_through_HTTP(ip, domain):
import requests # lazy loading this module for performance reasons
import requests # lazy loading this module for performance reasons
try:
requests.head("http://" + ip, headers={"Host": domain}, timeout=10)
except requests.exceptions.Timeout as e:

View file

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

View file

@ -16,6 +16,7 @@ logger = getActionLogger('yunohost.migration')
class MyMigration(Migration):
"Migrate Dyndns stuff from MD5 TSIG to SHA512 TSIG"
def backward(self):
@ -70,7 +71,7 @@ class MyMigration(Migration):
os.system("mv /etc/yunohost/dyndns/*+165* /tmp")
raise YunohostError('migrate_tsig_failed', domain=domain,
error_code=str(r.status_code), error=error)
error_code=str(r.status_code), error=error)
# remove old certificates
os.system("mv /etc/yunohost/dyndns/*+157* /tmp")
@ -87,4 +88,3 @@ class MyMigration(Migration):
logger.info(m18n.n('migrate_tsig_end'))
return

View file

@ -24,6 +24,7 @@ YUNOHOST_PACKAGES = ["yunohost", "yunohost-admin", "moulinette", "ssowat"]
class MyMigration(Migration):
"Upgrade the system to Debian Stretch and Yunohost 3.0"
mode = "manual"
@ -168,11 +169,11 @@ class MyMigration(Migration):
# - switch yunohost's repo to forge
for f in sources_list:
command = "sed -i -e 's@ jessie @ stretch @g' " \
"-e '/backports/ s@^#*@#@' " \
"-e 's@ jessie/updates @ stretch/updates @g' " \
"-e 's@ jessie-updates @ stretch-updates @g' " \
"-e 's@repo.yunohost@forge.yunohost@g' " \
"{}".format(f)
"-e '/backports/ s@^#*@#@' " \
"-e 's@ jessie/updates @ stretch/updates @g' " \
"-e 's@ jessie-updates @ stretch-updates @g' " \
"-e 's@repo.yunohost@forge.yunohost@g' " \
"{}".format(f)
os.system(command)
def get_apps_equivs_packages(self):
@ -286,7 +287,7 @@ class MyMigration(Migration):
# Create tmp directory if it does not exists
tmp_dir = os.path.join("/tmp/", self.name)
if not os.path.exists(tmp_dir):
os.mkdir(tmp_dir, 0700)
os.mkdir(tmp_dir, 0o700)
for f in self.files_to_keep:
dest_file = f.strip('/').replace("/", "_")

View file

@ -19,6 +19,7 @@ MIGRATION_COMMENT = "; YunoHost note : this file was automatically moved from {}
class MyMigration(Migration):
"Migrate php5-fpm 'pool' conf files to php7 stuff"
def migrate(self):
@ -58,7 +59,7 @@ class MyMigration(Migration):
_run_service_command("enable", "php7.0-fpm")
os.system("systemctl stop php5-fpm")
os.system("systemctl disable php5-fpm")
os.system("rm /etc/logrotate.d/php5-fpm") # We remove this otherwise the logrotate cron will be unhappy
os.system("rm /etc/logrotate.d/php5-fpm") # We remove this otherwise the logrotate cron will be unhappy
# Get list of nginx conf file
nginx_conf_files = glob.glob("/etc/nginx/conf.d/*.d/*.conf")

View file

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

View file

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

View file

@ -8,8 +8,10 @@ from moulinette.utils.log import getActionLogger
from moulinette.utils.filesystem import mkdir, rm
from yunohost.tools import Migration
from yunohost.service import service_regen_conf, _get_conf_hashes, \
_calculate_hash, _run_service_command
from yunohost.service import service_regen_conf, \
_get_conf_hashes, \
_calculate_hash, \
_run_service_command
from yunohost.settings import settings_set
from yunohost.utils.error import YunohostError
@ -19,6 +21,7 @@ SSHD_CONF = '/etc/ssh/sshd_config'
class MyMigration(Migration):
"""
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
@ -48,7 +51,7 @@ class MyMigration(Migration):
# Create sshd_config.d dir
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
# 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 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
from yunohost.settings import settings_set, settings_get
from yunohost.utils.error import YunohostError
@ -12,7 +13,9 @@ logger = getActionLogger('yunohost.migration')
SSHD_CONF = '/etc/ssh/sshd_config'
class MyMigration(Migration):
"""
In this second step, the admin is asked if it's okay to use
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'])
app_ssowatconf(auth)
except Exception, e:
from sys import exc_info;
except Exception as e:
from sys import exc_info
t, v, tb = exc_info()
# Force domain removal silently

View file

@ -104,7 +104,7 @@ def _dyndns_available(provider, domain):
except MoulinetteError as e:
logger.error(str(e))
raise YunohostError('dyndns_could_not_check_available',
domain=domain, provider=provider)
domain=domain, provider=provider)
return r == u"Domain %s is available" % domain
@ -149,7 +149,7 @@ def dyndns_subscribe(operation_logger, subscribe_host="dyndns.yunohost.org", dom
with open(key_file) as f:
key = f.readline().strip().split(' ', 6)[-1]
import requests # lazy loading this module for performance reasons
import requests # lazy loading this module for performance reasons
# Send subscription
try:
r = requests.post('https://%s/key/%s?key_algo=hmac-sha512' % (subscribe_host, base64.b64encode(key)), data={'subdomain': domain}, timeout=30)
@ -211,7 +211,7 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
exception=e,
number=migration.number,
name=migration.name),
exc_info=1)
exc_info=1)
return
# Extract 'host', e.g. 'nohost.me' from 'foo.nohost.me'
@ -225,7 +225,6 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
'zone %s' % host,
]
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
@ -252,7 +251,7 @@ def dyndns_update(operation_logger, dyn_host="dyndns.yunohost.org", domain=None,
logger.info("Updated needed, going on...")
dns_conf = _build_dns_conf(domain)
del dns_conf["extra"] # Ignore records from the 'extra' category
del dns_conf["extra"] # Ignore records from the 'extra' category
# Delete the old records for all domain/subdomains
@ -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
if record["value"] == "@":
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 = action.replace(" @.", " ")

View file

@ -374,10 +374,10 @@ def firewall_upnp(action='status', no_refresh=False):
try:
# Add new port mapping
upnpc.addportmapping(port, protocol, upnpc.lanaddr,
port, 'yunohost firewall: port %d' % port, '')
port, 'yunohost firewall: port %d' % port, '')
except:
logger.debug('unable to add port %d using UPnP',
port, exc_info=1)
port, exc_info=1)
enabled = False
if enabled != firewall['uPnP']['enabled']:

View file

@ -354,7 +354,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
# prepend environment variables
cmd = '{0} {1}'.format(
' '.join(['{0}={1}'.format(k, shell_quote(v))
for k, v in env.items()]), cmd)
for k, v in env.items()]), cmd)
command.append(cmd.format(script=cmd_script, args=cmd_args))
if logger.isEnabledFor(log.DEBUG):
@ -369,8 +369,8 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
)
if stdinfo:
callbacks = ( callbacks[0], callbacks[1],
lambda l: logger.info(l.rstrip()))
callbacks = (callbacks[0], callbacks[1],
lambda l: logger.info(l.rstrip()))
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):
"""
Instances of this class represents unit operation done on the ynh instance.
@ -423,7 +424,7 @@ class OperationLogger(object):
else:
if is_api:
msg = "<strong>" + m18n.n('log_link_to_failed_log',
name=self.name, desc=desc) + "</strong>"
name=self.name, desc=desc) + "</strong>"
else:
msg = m18n.n('log_help_to_get_failed_log', name=self.name,
desc=desc)

View file

@ -288,7 +288,7 @@ def monitor_system(units=None, human_readable=False):
else:
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
@ -404,7 +404,7 @@ def monitor_enable(with_stats=False):
"""
from yunohost.service import (service_status, service_enable,
service_start)
service_start)
glances = service_status('glances')
if glances['status'] != 'running':
@ -414,7 +414,7 @@ def monitor_enable(with_stats=False):
# Install crontab
if with_stats:
# day: every 5 min # week: every 1 h # month: every 4 h #
# day: every 5 min # week: every 1 h # month: every 4 h #
rules = ('*/5 * * * * root {cmd} day >> /dev/null\n'
'3 * * * * root {cmd} week >> /dev/null\n'
'6 */4 * * * root {cmd} month >> /dev/null').format(
@ -431,7 +431,7 @@ def monitor_disable():
"""
from yunohost.service import (service_status, service_disable,
service_stop)
service_stop)
glances = service_status('glances')
if glances['status'] != 'inactive':

View file

@ -151,6 +151,7 @@ def service_stop(names):
raise YunohostError('service_stop_failed', service=name, logs=_get_journalctl_logs(name))
logger.debug(m18n.n('service_already_stopped', service=name))
@is_unit_operation()
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:
operation_logger.name_parameter_override = 'all'
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()
# 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),
ignore_errors=True)
else:
filesystem.mkdir(PENDING_CONF_DIR, 0755, True)
filesystem.mkdir(PENDING_CONF_DIR, 0o755, True)
# Format common hooks arguments
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):
# create the pending conf directory for the service
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 pre_args + [service_pending_path, ]
@ -418,7 +419,7 @@ def service_regen_conf(operation_logger, names=[], with_diff=False, force=False,
if not names:
raise YunohostError('service_regenconf_failed',
services=', '.join(pre_result['failed']))
services=', '.join(pre_result['failed']))
# Set the processing method
_regen = _process_regen_conf if not dry_run else lambda *a, **k: True
@ -603,7 +604,7 @@ def _run_service_command(action, service):
cmd = 'systemctl %s %s' % (action, service)
need_lock = services[service].get('need_lock', False) \
and action in ['start', 'stop', 'restart', 'reload']
and action in ['start', 'stop', 'restart', 'reload']
try:
# Launch the command
@ -637,10 +638,10 @@ def _give_lock(action, service, p):
else:
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
# 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
# Output of the command is e.g. ControlPID=1234
son_PID = subprocess.check_output(cmd_get_son_PID.split()) \
@ -657,11 +658,12 @@ def _give_lock(action, service, p):
return son_PID
def _remove_lock(PID_to_remove):
# FIXME ironically not concurrency safe because it's not atomic...
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))
@ -775,6 +777,7 @@ def _find_previous_log_file(file):
return None
def _get_files_diff(orig_file, new_file, as_string=False, skip_header=True):
"""Compare two files and return the differences
@ -919,22 +922,22 @@ def _process_regen_conf(system_conf, new_conf=None, save=True):
backup_dir = os.path.dirname(backup_path)
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)
logger.debug(m18n.n('service_conf_file_backed_up',
conf=system_conf, backup=backup_path))
conf=system_conf, backup=backup_path))
try:
if not new_conf:
os.remove(system_conf)
logger.debug(m18n.n('service_conf_file_removed',
conf=system_conf))
conf=system_conf))
else:
system_dir = os.path.dirname(system_conf)
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)
logger.debug(m18n.n('service_conf_file_updated',

View file

@ -88,12 +88,12 @@ def settings_set(key, value):
if key_type == "bool":
if not isinstance(value, bool):
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
received_type=type(value).__name__, expected_type=key_type)
received_type=type(value).__name__, expected_type=key_type)
elif key_type == "int":
if not isinstance(value, int) or isinstance(value, bool):
if isinstance(value, str):
try:
value=int(value)
value = int(value)
except:
raise YunohostError('global_settings_bad_type_for_setting',
setting=key,
@ -101,19 +101,19 @@ def settings_set(key, value):
expected_type=key_type)
else:
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
received_type=type(value).__name__, expected_type=key_type)
received_type=type(value).__name__, expected_type=key_type)
elif key_type == "string":
if not isinstance(value, basestring):
raise YunohostError('global_settings_bad_type_for_setting', setting=key,
received_type=type(value).__name__, expected_type=key_type)
received_type=type(value).__name__, expected_type=key_type)
elif key_type == "enum":
if value not in settings[key]["choices"]:
raise YunohostError('global_settings_bad_choice_for_enum', setting=key,
received_type=type(value).__name__,
expected_type=", ".join(settings[key]["choices"]))
received_type=type(value).__name__,
expected_type=", ".join(settings[key]["choices"]))
else:
raise YunohostError('global_settings_unknown_type', setting=key,
unknown_type=key_type)
unknown_type=key_type)
settings[key]["value"] = value

View file

@ -98,7 +98,7 @@ def user_ssh_add_key(auth, username, key, comment):
# create empty file to set good permissions
write_to_file(authorized_keys_file, "")
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)

View file

@ -7,12 +7,14 @@ sys.path.append("..")
def pytest_addoption(parser):
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
def new_translate(self, key, *args, **kwargs):
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)
moulinette.core.Translator.translate = new_translate
def new_m18nn(self, key, *args, **kwargs):
return self._namespaces[self._current_namespace].translate(key, *args, **kwargs)
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):

View file

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

View file

@ -22,6 +22,7 @@ def setup_function(function):
except:
pass
def teardown_function(function):
try:
@ -50,18 +51,18 @@ def test_urlavailable():
def test_registerurl():
app_install(auth, "./tests/apps/register_url_app_ynh",
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
assert not domain_url_available(auth, maindomain, "/urlregisterapp")
# Try installing at same location
with pytest.raises(YunohostError):
app_install(auth, "./tests/apps/register_url_app_ynh",
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"))
def test_registerurl_baddomain():
with pytest.raises(YunohostError):
app_install(auth, "./tests/apps/register_url_app_ynh",
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"))
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"))

View file

@ -22,6 +22,7 @@ AUTH_IDENTIFIER = ('ldap', 'ldap-anonymous')
AUTH_PARAMETERS = {'uri': 'ldap://localhost:389', 'base_dn': 'dc=yunohost,dc=org'}
auth = None
def setup_function(function):
global maindomain
@ -87,9 +88,9 @@ def teardown_function(function):
shutil.rmtree("/opt/test_backup_output_directory")
###############################################################################
# Helpers #
###############################################################################
#
# Helpers #
#
def app_is_installed(app):
@ -111,6 +112,7 @@ def backup_test_dependencies_are_met():
return True
def tmp_backup_directory_is_empty():
if not os.path.exists("/home/yunohost.backup/tmp/"):
@ -118,6 +120,7 @@ def tmp_backup_directory_is_empty():
else:
return len(os.listdir('/home/yunohost.backup/tmp/')) == 0
def clean_tmp_backup_directory():
if tmp_backup_directory_is_empty():
@ -125,10 +128,10 @@ def clean_tmp_backup_directory():
mount_lines = subprocess.check_output("mount").split("\n")
points_to_umount = [ line.split(" ")[2]
for line in mount_lines
if len(line) >= 3
and line.split(" ")[2].startswith("/home/yunohost.backup/tmp") ]
points_to_umount = [line.split(" ")[2]
for line in mount_lines
if len(line) >= 3
and line.split(" ")[2].startswith("/home/yunohost.backup/tmp")]
for point in reversed(points_to_umount):
os.system("umount %s" % point)
@ -138,6 +141,7 @@ def clean_tmp_backup_directory():
shutil.rmtree("/home/yunohost.backup/tmp/")
def reset_ssowat_conf():
# 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 \
/home/yunohost.backup/archives/backup_system_from_2p4.tar.gz")
###############################################################################
# System backup #
###############################################################################
#
# System backup #
#
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_nothings_done')
###############################################################################
# System backup and restore #
###############################################################################
#
# System backup and restore #
#
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")
###############################################################################
# System restore from 2.4 #
###############################################################################
#
# System restore from 2.4 #
#
@pytest.mark.with_system_archive_from_2p4
def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
@ -265,19 +271,20 @@ def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
# Restore system archive from 2.4
try:
backup_restore(auth, name=backup_list()["archives"][1],
system=[],
apps=None,
force=True)
system=[],
apps=None,
force=True)
finally:
# Restore system as it was
backup_restore(auth, name=backup_list()["archives"][0],
system=[],
apps=None,
force=True)
system=[],
apps=None,
force=True)
#
# App backup #
#
###############################################################################
# App backup #
###############################################################################
@pytest.mark.with_backup_recommended_app_installed
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')
@pytest.mark.with_backup_recommended_app_installed
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 "conf_ssh" in archives_info["system"].keys()
@pytest.mark.clean_opt_dir
def test_backup_with_no_compress():
# Create the backup
@ -396,15 +405,15 @@ def test_backup_with_no_compress():
assert os.path.exists("/opt/test_backup_output_directory/info.json")
###############################################################################
# App restore #
###############################################################################
#
# App restore #
#
@pytest.mark.with_wordpress_archive_from_2p4
def test_restore_app_wordpress_from_Ynh2p4():
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["wordpress"])
apps=["wordpress"])
@pytest.mark.with_wordpress_archive_from_2p4
@ -422,7 +431,7 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
with pytest.raises(YunohostError):
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["wordpress"])
apps=["wordpress"])
m18n.n.assert_any_call('restore_app_failed', app='wordpress')
m18n.n.assert_any_call('restore_nothings_done')
@ -443,12 +452,12 @@ def test_restore_app_not_enough_free_space(monkeypatch, mocker):
with pytest.raises(YunohostError):
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["wordpress"])
apps=["wordpress"])
m18n.n.assert_any_call('restore_not_enough_disk_space',
free_space=0,
margin=ANY,
needed_space=ANY)
free_space=0,
margin=ANY,
needed_space=ANY)
assert not _is_installed("wordpress")
@ -462,7 +471,7 @@ def test_restore_app_not_in_backup(mocker):
with pytest.raises(YunohostError):
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["yoloswag"])
apps=["yoloswag"])
m18n.n.assert_any_call('backup_archive_app_not_found', app="yoloswag")
assert not _is_installed("wordpress")
@ -475,14 +484,14 @@ def test_restore_app_already_installed(mocker):
assert not _is_installed("wordpress")
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["wordpress"])
apps=["wordpress"])
assert _is_installed("wordpress")
mocker.spy(m18n, "n")
with pytest.raises(YunohostError):
backup_restore(auth, system=None, name=backup_list()["archives"][0],
apps=["wordpress"])
apps=["wordpress"])
m18n.n.assert_any_call('restore_already_installed_app', app="wordpress")
m18n.n.assert_any_call('restore_nothings_done')
@ -531,9 +540,10 @@ def _test_backup_and_restore_app(app):
assert app_is_installed(app)
###############################################################################
# Some edge cases #
###############################################################################
#
# Some edge cases #
#
def test_restore_archive_with_no_json(mocker):
@ -555,10 +565,9 @@ def test_backup_binds_are_readonly(monkeypatch):
self.manager = backup_manager
self._organize_files()
confssh = os.path.join(self.work_dir, "conf/ssh")
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
@ -568,7 +577,7 @@ def test_backup_binds_are_readonly(monkeypatch):
self.clean()
monkeypatch.setattr("yunohost.backup.BackupMethod.mount_and_backup",
custom_mount_and_backup)
custom_mount_and_backup)
# Create the backup
backup_create(system=[])

View file

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

View file

@ -18,7 +18,8 @@ def teardown_function(function):
def test_settings_get_bool():
assert settings_get("example.bool") == True
assert settings_get("example.bool")
def test_settings_get_full_bool():
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():
assert settings_get("example.int") == 42
def test_settings_get_full_int():
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():
assert settings_get("example.string") == "yolo swag"
def test_settings_get_full_string():
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():
assert settings_get("example.enum") == "a"
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"]}
@ -152,7 +156,6 @@ def test_reset_all_backup():
assert settings_after_modification == json.load(open(old_settings_backup_path, "r"))
def test_unknown_keys():
unknown_settings_path = SETTINGS_PATH_OTHER_LOCATION % "unknown"
unknown_setting = {

View file

@ -136,7 +136,7 @@ def tools_adminpw(auth, new_password, check_strength=True):
new_hash = _hash_user_password(new_password)
try:
auth.update("cn=admin", { "userPassword": new_hash, })
auth.update("cn=admin", {"userPassword": new_hash, })
except:
logger.exception('unable to change admin password')
raise YunohostError('admin_password_change_failed')
@ -265,7 +265,7 @@ def _is_inside_container():
stderr=subprocess.STDOUT)
out, _ = p.communicate()
container = ['lxc','lxd','docker']
container = ['lxc', 'lxd', 'docker']
return out.split()[0] in container
@ -323,7 +323,6 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
else:
dyndns = False
operation_logger.start()
logger.info(m18n.n('yunohost_installing'))
@ -539,7 +538,7 @@ def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=Fal
# If API call
if is_api:
critical_packages = ("moulinette", "yunohost",
"yunohost-admin", "ssowat", "python")
"yunohost-admin", "ssowat", "python")
critical_upgrades = set()
for pkg in cache.get_changes():
@ -575,7 +574,6 @@ def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=Fal
else:
logger.info(m18n.n('packages_no_upgrade'))
if not ignore_apps:
try:
app_upgrade(auth)
@ -719,7 +717,7 @@ def _check_if_vulnerable_to_meltdown():
try:
call = subprocess.Popen("bash %s --batch json --variant 3" %
SCRIPT_PATH, shell=True,
stdout=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output, _ = call.communicate()
@ -815,12 +813,12 @@ def tools_migrations_list(pending=False, done=False):
migrations = [m for m in migrations if m.number > last_migration]
# Reduce to dictionnaries
migrations = [{ "id": migration.id,
"number": migration.number,
"name": migration.name,
"mode": migration.mode,
"description": migration.description,
"disclaimer": migration.disclaimer } for migration in migrations ]
migrations = [{"id": migration.id,
"number": migration.number,
"name": migration.name,
"mode": migration.mode,
"description": migration.description,
"disclaimer": migration.disclaimer} for migration in migrations]
return {"migrations": migrations}
@ -914,7 +912,7 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
accept_disclaimer = False
# Start register change on system
operation_logger= OperationLogger('tools_migrations_migrate_' + mode)
operation_logger = OperationLogger('tools_migrations_migrate_' + mode)
operation_logger.start()
if not skip:
@ -934,9 +932,9 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
# migration failed, let's stop here but still update state because
# we managed to run the previous ones
msg = m18n.n('migrations_migration_has_failed',
exception=e,
number=migration.number,
name=migration.name)
exception=e,
number=migration.number,
name=migration.name)
logger.error(msg, exc_info=1)
operation_logger.error(msg)
break
@ -967,6 +965,7 @@ def tools_migrations_migrate(target=None, skip=False, auto=False, accept_disclai
write_to_json(MIGRATIONS_STATE_PATH, state)
def tools_migrations_state():
"""
Show current migration state
@ -1009,7 +1008,7 @@ def _get_migrations_list():
migrations = []
try:
import data_migrations
from . import data_migrations
except ImportError:
# not data migrations present, return empty list
return migrations
@ -1032,7 +1031,7 @@ def _get_migration_by_name(migration_name):
"""
try:
import data_migrations
from . import data_migrations
except ImportError:
raise AssertionError("Unable to find migration with name %s" % migration_name)
@ -1051,7 +1050,7 @@ def _load_migration(migration_file):
number, name = migration_id.split("_", 1)
logger.debug(m18n.n('migrations_loading_migration',
number=number, name=name))
number=number, name=name))
try:
# this is python builtin method to import a module using a name, we
@ -1064,7 +1063,8 @@ def _load_migration(migration_file):
traceback.print_exc()
raise YunohostError('migrations_error_failed_to_load_migration',
number=number, name=name)
number=number, name=name)
def _skip_all_migrations():
"""
@ -1115,4 +1115,3 @@ class Migration(object):
@property
def description(self):
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')
def user_list(auth, fields=None):
"""
List users
@ -98,7 +99,7 @@ def user_list(auth, fields=None):
@is_unit_operation([('username', 'user')])
def user_create(operation_logger, auth, username, firstname, lastname, mail, password,
mailbox_quota="0"):
mailbox_quota="0"):
"""
Create user
@ -262,8 +263,8 @@ def user_delete(operation_logger, auth, username, purge=False):
@is_unit_operation([('username', 'user')], exclude=['auth', 'change_password'])
def user_update(operation_logger, auth, username, firstname=None, lastname=None, mail=None,
change_password=None, add_mailforward=None, remove_mailforward=None,
add_mailalias=None, remove_mailalias=None, mailbox_quota=None):
change_password=None, add_mailforward=None, remove_mailforward=None,
add_mailalias=None, remove_mailalias=None, mailbox_quota=None):
"""
Update user informations
@ -466,18 +467,23 @@ def user_info(auth, username):
#
import yunohost.ssh
def user_ssh_allow(auth, username):
return yunohost.ssh.user_ssh_allow(auth, username)
def user_ssh_disallow(auth, username):
return yunohost.ssh.user_ssh_disallow(auth, username)
def user_ssh_list_keys(auth, username):
return yunohost.ssh.user_ssh_list_keys(auth, username)
def 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):
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
#
def _convertSize(num, suffix=''):
for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']:
if abs(num) < 1024.0:
@ -520,6 +527,3 @@ def _hash_user_password(password):
salt = '$6$' + salt + '$'
return '{CRYPT}' + crypt.crypt(str(password), salt)

View file

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

View file

@ -20,10 +20,12 @@
"""
import os
def free_space_in_directory(dirpath):
stat = os.statvfs(dirpath)
return stat.f_frsize * stat.f_bavail
def space_used_by_directory(dirpath):
stat = os.statvfs(dirpath)
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
###############################################################################
#
def _extract_inet(string, skip_netmask=False, skip_loopback=True):

View file

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

View file

@ -38,9 +38,11 @@ STRENGTH_LEVELS = [
(12, 1, 1, 1, 1),
]
def assert_password_is_strong_enough(profile, password):
PasswordValidator(profile).validate(password)
class PasswordValidator(object):
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 compare the values 1-by-1.
# 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
# Otherwise, the strength of the password is at least of the current level.
strength_level = level + 1
@ -186,7 +188,7 @@ if __name__ == '__main__':
if len(sys.argv) < 2:
import getpass
pwd = getpass.getpass("")
#print("usage: password.py PASSWORD")
# print("usage: password.py PASSWORD")
else:
pwd = sys.argv[1]
status, msg = PasswordValidator('user').validation_summary(pwd)

View file

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