mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
autopep8 + a few manual tweaks
This commit is contained in:
parent
fb010765bd
commit
115b557b67
34 changed files with 341 additions and 286 deletions
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
@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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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" #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
@property
|
||||
def success(self):
|
||||
|
@ -902,9 +906,9 @@ class RestoreManager():
|
|||
logger.warning(m18n.n('restore_cleaning_failed'))
|
||||
filesystem.rm(self.work_dir, True, True)
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Restore target manangement #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
def set_system_targets(self, system_parts=[]):
|
||||
"""
|
||||
|
@ -980,9 +984,9 @@ class RestoreManager():
|
|||
self.info['apps'].keys(),
|
||||
unknown_error)
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Archive mounting #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
def mount(self):
|
||||
"""
|
||||
|
@ -1023,9 +1027,9 @@ class RestoreManager():
|
|||
|
||||
self._read_info_files()
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Space computation / checks #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
def _compute_needed_space(self):
|
||||
"""
|
||||
|
@ -1086,9 +1090,9 @@ class RestoreManager():
|
|||
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) #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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:
|
||||
|
@ -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)
|
||||
|
||||
|
@ -1359,12 +1362,13 @@ class RestoreManager():
|
|||
|
||||
return env_var
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Backup methods #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
class BackupMethod(object):
|
||||
|
||||
"""
|
||||
BackupMethod is an abstract class that represents a way to backup and
|
||||
restore a list of files.
|
||||
|
@ -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" #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
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 there is no archive with the same name
|
||||
if name and name in backup_list()['archives']:
|
||||
|
@ -2017,9 +2024,9 @@ def backup_create(name=None, description=None, methods=[],
|
|||
system = []
|
||||
apps = []
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# 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 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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
# 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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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 #
|
||||
###########################################################################
|
||||
#
|
||||
|
||||
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()
|
||||
|
@ -2277,9 +2284,9 @@ def backup_delete(name):
|
|||
|
||||
logger.success(m18n.n('backup_deleted'))
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# 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):
|
||||
|
|
|
@ -80,9 +80,9 @@ DNS_RESOLVERS = [
|
|||
"80.67.188.188" # LDN
|
||||
]
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Front-end stuff #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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())
|
||||
|
||||
# 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)
|
||||
|
@ -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)
|
||||
|
@ -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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -735,15 +737,15 @@ def _get_status(domain):
|
|||
"ACME_eligible": ACME_eligible
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# 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):
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -16,6 +16,7 @@ logger = getActionLogger('yunohost.migration')
|
|||
|
||||
|
||||
class MyMigration(Migration):
|
||||
|
||||
"Migrate Dyndns stuff from MD5 TSIG to SHA512 TSIG"
|
||||
|
||||
def backward(self):
|
||||
|
@ -87,4 +88,3 @@ class MyMigration(Migration):
|
|||
|
||||
logger.info(m18n.n('migrate_tsig_end'))
|
||||
return
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -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("/", "_")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -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(" @.", " ")
|
||||
|
|
|
@ -369,7 +369,7 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
|||
)
|
||||
|
||||
if stdinfo:
|
||||
callbacks = ( callbacks[0], callbacks[1],
|
||||
callbacks = (callbacks[0], callbacks[1],
|
||||
lambda l: logger.info(l.rstrip()))
|
||||
|
||||
logger.debug("About to run the command '%s'" % command)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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, ]
|
||||
|
@ -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,7 +922,7 @@ 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',
|
||||
|
@ -934,7 +937,7 @@ def _process_regen_conf(system_conf, new_conf=None, save=True):
|
|||
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',
|
||||
|
|
|
@ -93,7 +93,7 @@ def settings_set(key, value):
|
|||
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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
def pytest_cmdline_main(config):
|
||||
|
|
|
@ -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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
def test_appslist_fetch():
|
||||
|
@ -244,9 +244,9 @@ def test_appslist_fetch_timeout():
|
|||
app_fetchlist()
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# 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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
def add_legacy_cron(name, url):
|
||||
|
|
|
@ -22,6 +22,7 @@ def setup_function(function):
|
|||
except:
|
||||
pass
|
||||
|
||||
|
||||
def teardown_function(function):
|
||||
|
||||
try:
|
||||
|
|
|
@ -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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
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]
|
||||
points_to_umount = [line.split(" ")[2]
|
||||
for line in mount_lines
|
||||
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):
|
||||
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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
|
||||
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 #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
@pytest.mark.with_system_archive_from_2p4
|
||||
def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
|
||||
|
@ -275,9 +281,10 @@ def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
|
|||
apps=None,
|
||||
force=True)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# 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,9 +405,9 @@ def test_backup_with_no_compress():
|
|||
assert os.path.exists("/opt/test_backup_output_directory/info.json")
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# App restore #
|
||||
###############################################################################
|
||||
#
|
||||
|
||||
@pytest.mark.with_wordpress_archive_from_2p4
|
||||
def test_restore_app_wordpress_from_Ynh2p4():
|
||||
|
@ -531,9 +540,10 @@ def _test_backup_and_restore_app(app):
|
|||
|
||||
assert app_is_installed(app)
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# 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
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ def test_appchangeurl():
|
|||
|
||||
check_changeurl_app("/newchangeurl")
|
||||
|
||||
|
||||
def test_appchangeurl_sameurl():
|
||||
install_changeurl_app("/changeurl")
|
||||
check_changeurl_app("/changeurl")
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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'))
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
migrations = [{"id": migration.id,
|
||||
"number": migration.number,
|
||||
"name": migration.name,
|
||||
"mode": migration.mode,
|
||||
"description": migration.description,
|
||||
"disclaimer": migration.disclaimer } for migration in migrations ]
|
||||
"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:
|
||||
|
@ -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)
|
||||
|
||||
|
@ -1066,6 +1065,7 @@ def _load_migration(migration_file):
|
|||
raise YunohostError('migrations_error_failed_to_load_migration',
|
||||
number=number, name=name)
|
||||
|
||||
|
||||
def _skip_all_migrations():
|
||||
"""
|
||||
Skip all pending migrations.
|
||||
|
@ -1115,4 +1115,3 @@ class Migration(object):
|
|||
@property
|
||||
def description(self):
|
||||
return m18n.n("migration_description_%s" % self.id)
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ from yunohost.log import is_unit_operation
|
|||
|
||||
logger = getActionLogger('yunohost.user')
|
||||
|
||||
|
||||
def user_list(auth, fields=None):
|
||||
"""
|
||||
List users
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -5,6 +5,7 @@ import json
|
|||
|
||||
from yunohost.utils.error import YunohostError
|
||||
|
||||
|
||||
def yunopaste(data):
|
||||
|
||||
paste_server = "https://paste.yunohost.org"
|
||||
|
|
Loading…
Add table
Reference in a new issue