Add option to restore using syncoid
This commit is contained in:
parent
599dd490ee
commit
7e6021d2ab
@ -6,50 +6,73 @@ import subprocess
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
def load_and_validate_config_dir(config_dir):
|
class BatchManager:
|
||||||
if not os.path.isdir(config_dir):
|
|
||||||
raise ValueError(f"{config_dir} is not a directory")
|
|
||||||
|
|
||||||
return [
|
def __init__(self, config_dir):
|
||||||
load_and_validate_config_file(os.path.join(config_dir, file))
|
self.__config_list = BatchManager.__load_and_validate_config_dir(config_dir)
|
||||||
for file in os.listdir(config_dir)
|
|
||||||
]
|
@staticmethod
|
||||||
|
def __load_and_validate_config_dir(config_dir):
|
||||||
|
if not os.path.isdir(config_dir):
|
||||||
|
raise ValueError(f"{config_dir} is not a directory")
|
||||||
|
|
||||||
|
return [
|
||||||
|
BatchManager.__load_and_validate_config_file(os.path.join(config_dir, file))
|
||||||
|
for file in os.listdir(config_dir)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def load_and_validate_config_file(config_file_path):
|
@staticmethod
|
||||||
if not os.path.isfile(config_file_path):
|
def __load_and_validate_config_file(config_file_path):
|
||||||
raise ValueError(f"{config_file_path} is not a file")
|
if not os.path.isfile(config_file_path):
|
||||||
|
raise ValueError(f"{config_file_path} is not a file")
|
||||||
|
|
||||||
with open(config_file_path, encoding="utf-8") as config_file:
|
with open(config_file_path, encoding="utf-8") as config_file:
|
||||||
config = yaml.safe_load(config_file)
|
config = yaml.safe_load(config_file)
|
||||||
|
|
||||||
for key in ["dataset", "backup_dataset"]:
|
for key in ["dataset", "backup_dataset"]:
|
||||||
if key not in config:
|
if key not in config:
|
||||||
raise KeyError(f"{key} must be present in {config_file_path}")
|
raise KeyError(f"{key} must be present in {config_file_path}")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
def __exec(self, source_key, destination_key):
|
||||||
|
for config in self.__config_list:
|
||||||
|
syncoid_cmd = ["/usr/sbin/syncoid", "--no-sync-snap", "--preserve-properties"]
|
||||||
|
if config.get("recursive", False):
|
||||||
|
syncoid_cmd.append("--recursive")
|
||||||
|
if config.get("skip_parent", False):
|
||||||
|
syncoid_cmd.append("--skip-parent")
|
||||||
|
syncoid_cmd.append(config[source_key])
|
||||||
|
syncoid_cmd.append(config[destination_key])
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(syncoid_cmd, check=True,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
print(err.stdout.decode("ascii"), flush=True)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def backup(self):
|
||||||
|
self.__exec("dataset", "backup_dataset")
|
||||||
|
|
||||||
|
def restore(self):
|
||||||
|
self.__exec("backup_dataset", "dataset")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Backup service data using syncoid")
|
parser = argparse.ArgumentParser(description="Backup service data using syncoid")
|
||||||
parser.add_argument("--config-dir", type=str, default="/etc/syncoid-batch.d",
|
parser.add_argument("--config-dir", type=str, default="/etc/syncoid-batch.d",
|
||||||
help="Path to directory with YAML config files")
|
help="Path to directory with YAML config files")
|
||||||
|
|
||||||
|
subparsers = parser.add_subparsers()
|
||||||
|
|
||||||
|
backup_parser = subparsers.add_parser("backup")
|
||||||
|
backup_parser.set_defaults(func=BatchManager.backup)
|
||||||
|
|
||||||
|
restore_parser = subparsers.add_parser("restore")
|
||||||
|
restore_parser.set_defaults(func=BatchManager.restore)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
config_list = load_and_validate_config_dir(args.config_dir)
|
args.func(BatchManager(args.config_dir))
|
||||||
|
|
||||||
for config in config_list:
|
|
||||||
syncoid_cmd = ["/usr/sbin/syncoid", "--no-sync-snap"]
|
|
||||||
if config.get("recursive", False):
|
|
||||||
syncoid_cmd.append("--recursive")
|
|
||||||
if config.get("skip_parent", False):
|
|
||||||
syncoid_cmd.append("--skip-parent")
|
|
||||||
syncoid_cmd.append(config["dataset"])
|
|
||||||
syncoid_cmd.append(config["backup_dataset"])
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.run(syncoid_cmd, check=True,
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
||||||
except subprocess.CalledProcessError as err:
|
|
||||||
print(err.stdout.decode("ascii"), flush=True)
|
|
||||||
raise
|
|
||||||
|
@ -7,7 +7,7 @@ OnFailure=status-mail@%n.service
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=/usr/local/sbin/syncoid-batch --config-dir {{ system_etc_root_directory }}/syncoid-batch.d
|
ExecStart=/usr/local/sbin/syncoid-batch --config-dir {{ system_etc_root_directory }}/syncoid-batch.d backup
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=sanoid.service
|
WantedBy=sanoid.service
|
||||||
|
Loading…
x
Reference in New Issue
Block a user