Skip to content

Commit

Permalink
chore: simplify backup repository creation
Browse files Browse the repository at this point in the history
- move it to the model
- simplify condition to check first for existing repository without
  hitting the database
- prepare for storing more info on backups
  • Loading branch information
nijel committed Nov 27, 2024
1 parent cb78529 commit 7dc4ea2
Showing 1 changed file with 62 additions and 60 deletions.
122 changes: 62 additions & 60 deletions weblate_web/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,58 +181,6 @@ def as_sql(self, compiler, connection):
models.CharField.register_lookup(MySQLSearchLookup)


def create_backup_repository(service):
"""
Configure backup repository.
- create filesystem folders
- store SSH key
- create subaccount
"""
# Create folder and SSH key
client = SSHClient()
client.load_system_host_keys()
client.connect(
hostname=settings.STORAGE_SSH_HOSTNAME,
port=settings.STORAGE_SSH_PORT,
username=settings.STORAGE_SSH_USER,
)
ftp = client.open_sftp()
dirname = str(uuid4())
ftp.mkdir(dirname)
ftp.chdir(dirname)
with ftp.open("README.txt", "w") as handle:
handle.write(f"""Weblate Cloud Backup
====================
Service: {service.pk}
Customer: {service.customer.name}
""")

ftp.mkdir(".ssh")
ftp.chdir(".ssh")
with ftp.open("authorized_keys", "w") as handle:
handle.write(service.last_report.ssh_key)

# Create account on the service
url = SUBACCOUNTS_API.format(settings.STORAGE_BOX)
response = requests.post(
url,
data={
"homedirectory": f"weblate/{dirname}",
"ssh": "1",
"external_reachability": "1",
"comment": f"Weblate backup service {service.pk} ({service.customer.name})",
},
auth=(settings.STORAGE_USER, settings.STORAGE_PASSWORD),
timeout=720,
)
data = response.json()
return "ssh://{}@{}:23/./backups".format(
data["subaccount"]["username"], data["subaccount"]["server"]
)


class Donation(models.Model):
user = models.ForeignKey(User, on_delete=models.deletion.PROTECT)
customer = models.ForeignKey(Customer, on_delete=models.deletion.PROTECT, null=True)
Expand Down Expand Up @@ -846,14 +794,68 @@ def update_status(self):
self.save()

def create_backup(self):
backup = False
if self.hosted_subscriptions.filter(expires__gt=timezone.now()).exists():
backup = True
if self.backup_subscriptions.filter(expires__gt=timezone.now()).exists():
backup = True
if backup and not self.backup_repository and self.report_set.exists():
self.backup_repository = create_backup_repository(self)
self.save(update_fields=["backup_repository"])
subscriptions = self.hosted_subscriptions | self.backup_subscriptions
if (
not self.backup_repository
and subscriptions.filter(expires__gt=timezone.now()).exists()
and self.report_set.exists()
):
self.create_backup_repository()

Check warning on line 803 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L803

Added line #L803 was not covered by tests

def create_backup_repository(self):
"""
Configure backup repository.
- create filesystem folders
- store SSH key
- create subaccount
"""
if self.customer is None:
raise ValueError("Missing customer info!")

Check warning on line 814 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L814

Added line #L814 was not covered by tests
# Create folder and SSH key
client = SSHClient()
client.load_system_host_keys()
client.connect(

Check warning on line 818 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L816-L818

Added lines #L816 - L818 were not covered by tests
hostname=settings.STORAGE_SSH_HOSTNAME,
port=settings.STORAGE_SSH_PORT,
username=settings.STORAGE_SSH_USER,
)
ftp = client.open_sftp()
dirname = str(uuid4())
ftp.mkdir(dirname)
ftp.chdir(dirname)
with ftp.open("README.txt", "w") as handle:
handle.write(f"""Weblate Cloud Backup

Check warning on line 828 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L823-L828

Added lines #L823 - L828 were not covered by tests
====================
Service: {self.pk}
Customer: {self.customer.name}
""")

ftp.mkdir(".ssh")
ftp.chdir(".ssh")
with ftp.open("authorized_keys", "w") as handle:
handle.write(self.last_report.ssh_key)

Check warning on line 838 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L835-L838

Added lines #L835 - L838 were not covered by tests

# Create account on the service
url = SUBACCOUNTS_API.format(settings.STORAGE_BOX)
response = requests.post(

Check warning on line 842 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L841-L842

Added lines #L841 - L842 were not covered by tests
url,
data={
"homedirectory": f"weblate/{dirname}",
"ssh": "1",
"external_reachability": "1",
"comment": f"Weblate backup service {self.pk} ({self.customer.name})",
},
auth=(settings.STORAGE_USER, settings.STORAGE_PASSWORD),
timeout=720,
)
data = response.json()

Check warning on line 853 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L853

Added line #L853 was not covered by tests

self.backup_repository = "ssh://{}@{}:23/./backups".format(

Check warning on line 855 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L855

Added line #L855 was not covered by tests
data["subaccount"]["username"], data["subaccount"]["server"]
)
self.save(update_fields=["backup_repository"])

Check warning on line 858 in weblate_web/models.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/models.py#L858

Added line #L858 was not covered by tests

def get_limits(self):
return {
Expand Down

0 comments on commit 7dc4ea2

Please sign in to comment.