mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[fix] Repository list, add, remove
This commit is contained in:
parent
6eca4bff69
commit
04f85eb860
5 changed files with 49 additions and 32 deletions
|
@ -90,7 +90,8 @@
|
|||
"backup_archive_system_part_not_available": "System part '{part}' unavailable in this backup",
|
||||
"backup_archive_writing_error": "Could not add the files '{source}' (named in the archive '{dest}') to be backed up into the compressed archive '{archive}'",
|
||||
"backup_ask_for_copying_if_needed": "Do you want to perform the backup using {size}MB temporarily? (This way is used since some files could not be prepared using a more efficient method.)",
|
||||
"backup_borg_init_error": "Unable initialize the borg repository",
|
||||
"backup_borg_init_error": "Unable initialize the borg repository: {error}",
|
||||
"backup_borg_already_initialized": "The borg repository '{repository}' already exists, it has been properly added to repositories managed by YunoHost cli.",
|
||||
"backup_cant_mount_uncompress_archive": "Could not mount the uncompressed archive as write protected",
|
||||
"backup_cleaning_failed": "Could not clean up the temporary backup folder",
|
||||
"backup_copying_to_organize_the_archive": "Copying {size}MB to organize the archive",
|
||||
|
@ -116,6 +117,8 @@
|
|||
"backup_output_directory_required": "You must provide an output directory for the backup",
|
||||
"backup_output_symlink_dir_broken": "Your archive directory '{path}' is a broken symlink. Maybe you forgot to re/mount or plug in the storage medium it points to.",
|
||||
"backup_permission": "Backup permission for {app}",
|
||||
"backup_repository_exists": "Backup repository '{backup_repository}' already exists",
|
||||
"backup_repository_unknown": "Backup repository '{backup_repository}' unknown",
|
||||
"backup_running_hooks": "Running backup hooks...",
|
||||
"backup_system_part_failed": "Could not backup the '{part}' system part",
|
||||
"backup_unable_to_organize_files": "Could not use the quick method to organize files in the archive",
|
||||
|
|
|
@ -1099,6 +1099,9 @@ backup:
|
|||
--full:
|
||||
help: Show more details
|
||||
action: store_true
|
||||
--space-used:
|
||||
help: Display size used
|
||||
action: store_true
|
||||
|
||||
### backup_repository_info()
|
||||
info:
|
||||
|
@ -1111,13 +1114,9 @@ backup:
|
|||
pattern: &pattern_backup_repository_shortname
|
||||
- !!str ^[a-zA-Z0-9-_\.]+$
|
||||
- "pattern_backup_repository_shortname"
|
||||
-H:
|
||||
full: --human-readable
|
||||
help: Print sizes in human readable format
|
||||
action: store_true
|
||||
--space-used:
|
||||
help: Display size used
|
||||
action: store_false
|
||||
action: store_true
|
||||
|
||||
### backup_repository_add()
|
||||
add:
|
||||
|
|
|
@ -1871,12 +1871,12 @@ def backup_delete(name, repository):
|
|||
#
|
||||
|
||||
|
||||
def backup_repository_list(full=False):
|
||||
def backup_repository_list(space_used=False, full=False):
|
||||
"""
|
||||
List available repositories where put archives
|
||||
"""
|
||||
|
||||
return {"repositories": BackupRepository.list(full)}
|
||||
return {"repositories": BackupRepository.list(space_used, full)}
|
||||
|
||||
|
||||
def backup_repository_info(shortname, space_used=False):
|
||||
|
|
|
@ -24,6 +24,7 @@ import json
|
|||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from moulinette import m18n
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
from yunohost.utils.error import YunohostError
|
||||
|
@ -37,7 +38,7 @@ class BorgBackupRepository(LocalBackupRepository):
|
|||
method_name = "borg"
|
||||
|
||||
# TODO logs
|
||||
def _run_borg_command(self, cmd, stdout=None):
|
||||
def _run_borg_command(self, cmd, stdout=None, stderr=None):
|
||||
""" Call a submethod of borg with the good context
|
||||
"""
|
||||
env = dict(os.environ)
|
||||
|
@ -59,15 +60,16 @@ class BorgBackupRepository(LocalBackupRepository):
|
|||
# Authorize to move the repository (borgbase do this)
|
||||
env["BORG_RELOCATED_REPO_ACCESS_IS_OK"] = "yes"
|
||||
|
||||
return subprocess.Popen(cmd, env=env, stdout=stdout)
|
||||
return subprocess.Popen(cmd, env=env,
|
||||
stdout=stdout, stderr=stderr)
|
||||
|
||||
def _call(self, action, cmd, json_output=False):
|
||||
borg = self._run_borg_command(cmd)
|
||||
return_code = borg.wait()
|
||||
if return_code:
|
||||
raise YunohostError(f"backup_borg_{action}_error")
|
||||
borg = self._run_borg_command(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = borg.communicate()
|
||||
if borg.returncode:
|
||||
raise YunohostError(f"backup_borg_{action}_error", error=err)
|
||||
|
||||
out, _ = borg.communicate()
|
||||
if json_output:
|
||||
try:
|
||||
return json.loads(out)
|
||||
|
@ -117,8 +119,20 @@ class BorgBackupRepository(LocalBackupRepository):
|
|||
|
||||
if "quota" in self.future_values and self.future_values["quota"]:
|
||||
cmd += ['--storage-quota', self.quota]
|
||||
try:
|
||||
self._call('init', cmd)
|
||||
except YunohostError as e:
|
||||
if e.key != "backup_borg_init_error":
|
||||
raise
|
||||
else:
|
||||
# Check if it's possible to read the borg repo with current settings
|
||||
try:
|
||||
cmd = ["borg", "info", self.location]
|
||||
self._call('info', cmd)
|
||||
except YunohostError:
|
||||
raise e
|
||||
|
||||
self._call('init', cmd)
|
||||
logger.info(m18n.n("backup_borg_already_initialized", repository=self.location))
|
||||
|
||||
def update(self):
|
||||
raise NotImplementedError()
|
||||
|
@ -148,12 +162,11 @@ class BorgBackupRepository(LocalBackupRepository):
|
|||
return [archive["name"] for archive in response['archives']]
|
||||
|
||||
def compute_space_used(self):
|
||||
if not self.is_remote:
|
||||
return super().purge()
|
||||
else:
|
||||
cmd = ["borg", "info", "--json", self.location]
|
||||
response = self._call('info', cmd)
|
||||
return response["cache"]["stats"]["unique_size"]
|
||||
""" Return the size of this repo on the disk"""
|
||||
# FIXME this size could be unrelevant, comparison between du and borg sizes doesn't match !
|
||||
cmd = ["borg", "info", "--json", self.location]
|
||||
response = self._call('info', cmd, json_output=True)
|
||||
return response["cache"]["stats"]["unique_size"]
|
||||
|
||||
def prune(self, prefix=None, **kwargs):
|
||||
|
||||
|
|
|
@ -104,13 +104,14 @@ class BackupRepository(ConfigPanel):
|
|||
if not full:
|
||||
return repositories
|
||||
|
||||
full_repositories = {}
|
||||
for repo in repositories:
|
||||
try:
|
||||
repositories[repo] = BackupRepository(repo).info(space_used)
|
||||
except Exception:
|
||||
logger.error(f"Unable to open repository {repo}")
|
||||
full_repositories.update(BackupRepository(repo).info(space_used))
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to open repository {repo}: {e}")
|
||||
|
||||
return repositories
|
||||
return full_repositories
|
||||
|
||||
# =================================================
|
||||
# Config Panel Hooks
|
||||
|
@ -232,18 +233,19 @@ class BackupRepository(ConfigPanel):
|
|||
self.purge()
|
||||
|
||||
rm(self.save_path, force=True)
|
||||
logger.success(m18n.n("repository_removed", repository=self.shortname))
|
||||
logger.success(m18n.n("repository_removed", repository=self.entity))
|
||||
|
||||
def info(self, space_used=False):
|
||||
result = super().get(mode="export")
|
||||
|
||||
if self.__class__ == BackupRepository and space_used is True:
|
||||
if space_used is True:
|
||||
result["space_used"] = self.compute_space_used()
|
||||
|
||||
return {self.shortname: result}
|
||||
return {self.entity: result}
|
||||
|
||||
def list_archives(self, with_info):
|
||||
archives = self.list_archive_name()
|
||||
self._cast_by_method()
|
||||
archives = self.list_archives_names()
|
||||
if with_info:
|
||||
d = {}
|
||||
for archive in archives:
|
||||
|
@ -267,7 +269,7 @@ class BackupRepository(ConfigPanel):
|
|||
|
||||
# List archives with creation date
|
||||
archives = {}
|
||||
for archive_name in self.list_archive_name(prefix):
|
||||
for archive_name in self.list_archives_names(prefix):
|
||||
archive = BackupArchive(repo=self, name=archive_name)
|
||||
created_at = archive.info()["created_at"]
|
||||
archives[created_at] = archive
|
||||
|
@ -314,7 +316,7 @@ class BackupRepository(ConfigPanel):
|
|||
def purge(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def list_archives_names(self):
|
||||
def list_archives_names(self, prefix=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def compute_space_used(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue