3
Restore WIP
svnplace 25 Apr 2024 10:33
1 contributor
102 lines3.2 KB
Newer
Older
-
+
commited
{line.log.rev}
on
Last year
3
1
name: Initialise RepoRepository from Full Backup
2
3
triggers:
4
manual_trigger:
5
inputs:
6
-
7
name: reporepository
8
label: Repo repository
9
placeholder: Urn or api id
10
python_type: str
11
-
12
name: host
13
label: Host instance
14
placeholder: Urn or api id
15
python_type: str
16
-
17
name: blob
18
label: Backup blob
19
placeholder: Urn or api id
20
python_type: str
21
22
role:
23
policies:
24
- urn/api/policy/svnplace/Allow Everything
25
parents:
26
- urn/api/role/{user.username}/
27
- urn/api/role/svnplace/Backup Restorer
28
29
jobs:
30
restore:
31
runs_on:
32
host_instance: "{input.host}"
33
mapped_repo: "{input.reporepository}"
34
steps:
35
-
36
name: Restore
37
python: |
38
import os
39
import subprocess
40
import sys
41
import xml.etree.ElementTree as ET
42
from api_api import API
43
44
repo = '{repo.urn}'
45
repo_user = repo.rsplit('/',2)[1]
46
repo_name = repo.rsplit('/',2)[2]
47
repo_file = '/var/svnplace/process/repo'
48
49
api = API('https://svnplace.com/api', ['~/.svnplace/config'])
50
51
reporepo_desc = api.repos.describe_reporepository('{input.reporepository}')
52
if reporepo_desc.state.name != 'Initialising':
53
print(f'Reporepository in wrong state:{{reporepo_desc.state}')
54
sys.exit(1)
55
56
# confirm backup is an actual backup
57
backup_desc = api.blobs.describe_blob('urn/blob/{input.blob}')
58
backup_seal = api.blobs.describe_seal('urn/seal/user/svnplace/Backup - Full')
59
if backup_seal.id not in backup_desc.seals:
60
print('Blob not a full backup')
61
sys.exit(1)
62
63
# restore the backup files to the root directory
64
65
r0 = subprocess.Popen(['blobcp', 'blob:{input.blob}', '-'], stdout=subprocess.PIPE)
66
r1 = subprocess.run(['tar', '-xzf', '-', '-C', repo_file], stdin=r0.stdout)
67
68
if r1.returncode:
69
print('Backup failed: could not unpack backup')
70
sys.exit(1)
71
72
r0.wait()
73
if r0.returncode:
74
print('Backup failed: reading blob failed')
75
sys.exit(1)
76
77
backup_desc2 = api.blobs.describe_blob('urn/blob/{input.blob}')
78
if backup_desc2.seal_tag != backup_desc.seal_tag:
79
print('Backup failed: backup changed during restore')
80
sys.exit(1)
81
82
repo_desc = api.repos.describe_repo(repo)
83
if repo_desc.seal.api_id in backup_desc2.seals:
84
# backup is of this repo...
85
# leave the UUID alone
86
# leave the hooks in place
87
pass
88
else:
89
# backup is of a different repo...
90
91
# replace the uuid with a new one
92
r = subprocess.run(['svnadmin', 'setuuid', repo_file])
93
94
# clear all hooks
95
for item in os.scandir(f'{{repo_file}/hooks/descriptions'):
96
if item.is_file():
97
os.remove(item.path)
98
99
api.repos.modify_reporepository('{input.reporepository}', state='Ready')
100
101
print('Restore complete')
102