name: Backup (full) |
|
args: |
- |
name: backup.store |
label: Backup location |
placeholder: Path to blob directory |
- |
name: backup.pattern |
label: Backup names |
placeholder: The bit between the directory and _<ver>_full |
|
role: |
policies: |
- urn/api/policy/svnplace/Allow Everything |
parents: |
- urn/api/role/{user.username}/ |
- urn/api/role/svnplace/Backup Creater |
|
jobs: |
|
do_backup: |
runs_on: |
host_instance: "{repo.primary.rootdirectory.instance.api_id}" |
mapped_repo: "{repo.primary.api_id}" |
steps: |
- |
name: Backup |
python: | |
import os |
import subprocess |
import sys |
import xml.etree.ElementTree as ET |
from api_api import API |
|
repo = '{repo.urn}' |
repo_user = repo.rsplit('/',2)[1] |
repo_name = repo.rsplit('/',2)[2] |
repo_file = '/var/svnplace/process/repo' |
backup_file = os.path.abspath('./backup') |
|
def get_repo_version(repo): |
r = subprocess.run(['svn','info','--xml', 'FILE://'+repo], capture_output=True) |
if r.returncode != 0: |
print(r.stdout) |
print(r.stderr) |
return None |
|
tree = ET.fromstring(r.stdout) |
return int(tree.find('entry').attrib['revision']) |
|
def backup_blob(ver): |
return '{backup.store}/{backup.pattern}_%(ver)d_full' % {{ |
'backups': '{backup.store}', |
'username': repo_user, |
'reponame': repo_name, |
'ver': ver, |
} |
|
api = API('https://svnplace.com/api', ['~/.svnplace/config']) |
|
repo_desc = api.repos.describe_repo(repo) |
repo_ver = get_repo_version(repo_file) |
|
try: |
r = api.blobs.describe_blob('urn/blob/'+backup_blob(repo_ver)) |
except FileNotFoundError: |
pass |
else: |
print(f'{{repo_user}/{{repo_name}@{{repo_ver} is already backed up - nothing to do') |
sys.exit(0) |
|
print('Creating backup copy') |
|
r = subprocess.run(['svnadmin','hotcopy', repo_file, backup_file]) |
if r.returncode != 0: |
print('Failed to complete backup') |
sys.exit(1) |
|
backup_ver = get_repo_version(backup_file) |
if backup_ver is None: |
print('Failed to read backup version') |
sys.exit(1) |
|
print(f'Archiving backup {{repo_user}/{{repo_name}@{{backup_ver}') |
|
r0 = subprocess.Popen(('tar', '--strip-components', '1', '-C', backup_file, '-cz', '.'), stdout=subprocess.PIPE) |
r1 = subprocess.run(['blobcp', '-s', repo_desc.seal.api_id, '-s', 'urn/seal/user/svnplace/Backup - Full', '-', 'blob:'+backup_blob(backup_ver)], stdin=r0.stdout) |
|
if r1.returncode: |
print('Backup failed') |
sys.exit(1) |
|
print('Backup complete') |
|