feat: notify user on instance creation
parent
53ec0a3982
commit
f00746a36d
|
@ -0,0 +1,36 @@
|
|||
# Generated by Django 4.0.3 on 2022-06-29 18:30
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("dash", "0006_auto_20220619_0800"),
|
||||
("infrastructure", "0005_remove_instancecreated_gitea_password"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Job",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("job_type", models.CharField(max_length=10, verbose_name="Job Type")),
|
||||
(
|
||||
"instance",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="dash.instance"
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -12,11 +12,30 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
from django.db import models
|
||||
from enum import Enum, unique
|
||||
|
||||
from django.db import models
|
||||
from dash.models import Instance
|
||||
|
||||
|
||||
@unique
|
||||
class JobType(Enum):
|
||||
PING = "ping"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class InstanceCreated(models.Model):
|
||||
instance = models.ForeignKey(Instance, on_delete=models.PROTECT)
|
||||
created = models.BooleanField(default=False)
|
||||
|
||||
|
||||
class Job(models.Model):
|
||||
instance = models.ForeignKey(Instance, on_delete=models.CASCADE)
|
||||
|
||||
job_type = models.CharField(
|
||||
"Job Type",
|
||||
max_length=10,
|
||||
null=False,
|
||||
)
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
import shutil
|
||||
import time
|
||||
import os
|
||||
import requests
|
||||
from io import StringIO
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
from urllib.parse import urlunparse
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from django.test import TestCase, Client, override_settings
|
||||
from django.conf import settings
|
||||
from django.core.management import call_command
|
||||
|
@ -31,8 +31,8 @@ from accounts.tests import register_util, login_util
|
|||
from dash.tests import create_configurations, create_instance_util
|
||||
from infrastructure.management.commands.vm import translate_sizes
|
||||
|
||||
from .utils import Infra
|
||||
from .models import InstanceCreated
|
||||
from .utils import Infra, Worker
|
||||
from .models import InstanceCreated, Job, JobType
|
||||
|
||||
|
||||
def custom_config(test_name: str):
|
||||
|
@ -187,3 +187,26 @@ class InfraUtilTest(TestCase):
|
|||
|
||||
# run delete VM command to crudely check idempotency
|
||||
call_command("vm", "delete", subdomain)
|
||||
|
||||
def test_worker(self):
|
||||
subdomain = "gitea" # yes, gitea.hostea.org exists. will use it till I
|
||||
# figure out how to use requests_mock within django
|
||||
c = Client()
|
||||
login_util(self, c, "accounts.home")
|
||||
create_instance_util(
|
||||
t=self, c=c, instance_name=subdomain, config=self.instance_config[0]
|
||||
)
|
||||
|
||||
instance = Instance.objects.get(name=subdomain)
|
||||
job = Job.objects.create(instance=instance, job_type=JobType.PING)
|
||||
gitea_uri = Infra.get_gitea_uri(instance=instance)
|
||||
print(f"mocking {gitea_uri}")
|
||||
|
||||
w = Worker(job=job)
|
||||
w.start()
|
||||
time.sleep(5)
|
||||
self.assertEqual(w.is_alive(), False)
|
||||
w.join()
|
||||
self.assertEqual(
|
||||
Job.objects.filter(instance=instance, job_type=JobType.PING).exists(), True
|
||||
)
|
||||
|
|
|
@ -15,17 +15,65 @@
|
|||
import os
|
||||
import shutil
|
||||
import yaml
|
||||
import requests
|
||||
from pathlib import Path
|
||||
from threading import Thread, Event
|
||||
from time import sleep
|
||||
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.template.loader import render_to_string
|
||||
from django.core.mail import send_mail
|
||||
from django.conf import settings
|
||||
from git import Repo, Commit
|
||||
from git.exc import InvalidGitRepositoryError
|
||||
|
||||
from dash.models import Instance
|
||||
|
||||
from .models import InstanceCreated
|
||||
from infrastructure.models import InstanceCreated, JobType, Job
|
||||
|
||||
|
||||
class Worker(Thread):
|
||||
def __init__(self, job: Job):
|
||||
self.job = job
|
||||
super().__init__()
|
||||
|
||||
######### self.daemon = True
|
||||
|
||||
def run(self):
|
||||
gitea_uri = Infra.get_gitea_uri(instance=self.job.instance)
|
||||
woodpecker = Infra.get_woodpecker_hostname(instance=self.job.instance)
|
||||
while True:
|
||||
try:
|
||||
print(f"[ping] Trying to reach {gitea_uri}")
|
||||
resp = requests.get(gitea_uri)
|
||||
print(resp.status_code)
|
||||
if resp.status_code == 200:
|
||||
break
|
||||
except Exception:
|
||||
return False
|
||||
sleep(10)
|
||||
|
||||
print("sending email")
|
||||
job = self.job
|
||||
self.job = None
|
||||
email = job.instance.owned_by.email
|
||||
send_mail(
|
||||
subject="[Hostea] Your Hostea instance is now online!",
|
||||
message=f"""
|
||||
Hello,
|
||||
|
||||
The deployment job has run to completion and your Hostea instance is now online!
|
||||
Credentials to admin account was sent in an earlier email, please contact
|
||||
support if didn't receive it.
|
||||
|
||||
Gitea: {gitea_uri}
|
||||
Woodpecker CI: {woodpecker}
|
||||
""",
|
||||
from_email="No reply Hostea<no-reply@exampl.org>", # TODO read from settings.py
|
||||
recipient_list=[email],
|
||||
)
|
||||
job.delete()
|
||||
print("job deleted")
|
||||
|
||||
|
||||
def create_vm_if_not_exists(instance: Instance) -> (str, Commit):
|
||||
|
@ -35,13 +83,15 @@ def create_vm_if_not_exists(instance: Instance) -> (str, Commit):
|
|||
infra = Infra()
|
||||
if not InstanceCreated.objects.filter(instance=instance).exists():
|
||||
(gitea_password, commit) = infra.add_vm(instance=instance)
|
||||
instance = InstanceCreated.objects.create(instance=instance, created=True)
|
||||
instance.save()
|
||||
InstanceCreated.objects.create(instance=instance, created=True)
|
||||
job = Job.objects.create(instance=instance, job_type=str(JobType.PING))
|
||||
Worker(job=job).start()
|
||||
return (gitea_password, commit)
|
||||
else:
|
||||
if str.strip(infra.get_flavor(instance=instance)) != str.strip(
|
||||
infra.translate_size(instance=instance)
|
||||
):
|
||||
# Worker.init_global()
|
||||
return infra.add_vm(instance=instance)
|
||||
return None
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ pynvim==0.4.3
|
|||
pytz==2022.1
|
||||
PyYAML==6.0
|
||||
requests==2.27.1
|
||||
six==1.16.0
|
||||
smmap==5.0.0
|
||||
sqlparse==0.4.2
|
||||
stripe==3.4.0
|
||||
|
|
Loading…
Reference in New Issue