docker cleaner
This commit is contained in:
parent
1030d50acb
commit
ed23fe543b
18
Main/migrations/0033_solution_docker_instances.py
Normal file
18
Main/migrations/0033_solution_docker_instances.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.4 on 2022-05-08 12:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('Main', '0032_auto_20220408_0018'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='solution',
|
||||||
|
name='docker_instances',
|
||||||
|
field=models.JSONField(blank=True, default=list, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -21,6 +21,7 @@ class Solution(models.Model):
|
|||||||
test = models.IntegerField(default=None, null=True, blank=True)
|
test = models.IntegerField(default=None, null=True, blank=True)
|
||||||
set = models.ForeignKey(Set, null=True, blank=True, on_delete=models.SET_NULL)
|
set = models.ForeignKey(Set, null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
extras = models.JSONField(default=dict)
|
extras = models.JSONField(default=dict)
|
||||||
|
docker_instances = models.JSONField(null=True, blank=True, default=list)
|
||||||
|
|
||||||
_solutionfiles = None
|
_solutionfiles = None
|
||||||
|
|
||||||
|
@ -92,11 +92,19 @@ class BaseTester:
|
|||||||
|
|
||||||
def _setup_networking(self):
|
def _setup_networking(self):
|
||||||
self.call(f"docker network create solution_network_{self.solution.id}")
|
self.call(f"docker network create solution_network_{self.solution.id}")
|
||||||
|
self.solution.docker_instances.append({
|
||||||
|
"type": "network",
|
||||||
|
"name": f"solution_network_{self.solution.id}"
|
||||||
|
})
|
||||||
for file in self.solution.task.dockerfiles:
|
for file in self.solution.task.dockerfiles:
|
||||||
add_name = file.filename[11:]
|
add_name = file.filename[11:]
|
||||||
with open(join(self.path, "Dockerfile"), "w") as fs:
|
with open(join(self.path, "Dockerfile"), "w") as fs:
|
||||||
fs.write(file.text)
|
fs.write(file.text)
|
||||||
self.call(f"docker build -t solution_image_{self.solution.id}_{add_name} .")
|
self.call(f"docker build -t solution_image_{self.solution.id}_{add_name} .")
|
||||||
|
self.solution.docker_instances.append({
|
||||||
|
"type": "image",
|
||||||
|
"name": f"solution_image_{self.solution.id}_{add_name}"
|
||||||
|
})
|
||||||
run_command = (
|
run_command = (
|
||||||
f"docker run "
|
f"docker run "
|
||||||
f"--hostname {add_name} "
|
f"--hostname {add_name} "
|
||||||
@ -104,6 +112,10 @@ class BaseTester:
|
|||||||
f"--name solution_container_{self.solution.id}_{add_name} "
|
f"--name solution_container_{self.solution.id}_{add_name} "
|
||||||
f"-t -d solution_image_{self.solution.id}_{add_name}"
|
f"-t -d solution_image_{self.solution.id}_{add_name}"
|
||||||
)
|
)
|
||||||
|
self.solution.docker_instances.append({
|
||||||
|
"type": "container",
|
||||||
|
"name": f"solution_container_{self.solution.id}_{add_name}"
|
||||||
|
})
|
||||||
print("run command", run_command)
|
print("run command", run_command)
|
||||||
self.call(run_command)
|
self.call(run_command)
|
||||||
|
|
||||||
@ -150,6 +162,10 @@ class BaseTester:
|
|||||||
print("Files copied")
|
print("Files copied")
|
||||||
self._setup_networking()
|
self._setup_networking()
|
||||||
docker_command = f"docker run --network solution_network_{self.solution.id} --name solution_{self.solution.id} --volume={self.path}:/{self.working_directory} -t -d {self.solution.language.image}"
|
docker_command = f"docker run --network solution_network_{self.solution.id} --name solution_{self.solution.id} --volume={self.path}:/{self.working_directory} -t -d {self.solution.language.image}"
|
||||||
|
self.solution.docker_instances.append({
|
||||||
|
"type": "container",
|
||||||
|
"name": f"solution_{self.solution.id}"
|
||||||
|
})
|
||||||
print(docker_command)
|
print(docker_command)
|
||||||
call(docker_command, shell=True)
|
call(docker_command, shell=True)
|
||||||
checker = self.solution.task.checkerfile
|
checker = self.solution.task.checkerfile
|
||||||
@ -159,6 +175,11 @@ class BaseTester:
|
|||||||
f"docker run --network solution_network_{self.solution.id} --name solution_{self.solution.id}_checker --volume={self.path}:/app -t -d python:3.6",
|
f"docker run --network solution_network_{self.solution.id} --name solution_{self.solution.id}_checker --volume={self.path}:/app -t -d python:3.6",
|
||||||
shell=True,
|
shell=True,
|
||||||
)
|
)
|
||||||
|
self.solution.docker_instances.append({
|
||||||
|
"type": "container",
|
||||||
|
"name": f"solution_{self.solution.id}_checker"
|
||||||
|
})
|
||||||
|
self.solution.save()
|
||||||
print("Container created")
|
print("Container created")
|
||||||
try:
|
try:
|
||||||
self.before_test()
|
self.before_test()
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
from subprocess import call, PIPE, run
|
from subprocess import call
|
||||||
|
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
from Main.models import Solution
|
from Main.models import Solution
|
||||||
from SprintLib.utils import LoopWorker
|
from SprintLib.utils import LoopWorker
|
||||||
@ -8,51 +10,16 @@ class Command(LoopWorker):
|
|||||||
help = "starts docker cleaner"
|
help = "starts docker cleaner"
|
||||||
|
|
||||||
def go(self):
|
def go(self):
|
||||||
result = run("docker ps -a", universal_newlines=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
|
for solution in Solution.objects.filter(Q(result="Testing") | Q(result="In queue"), docker_instances__isnull=False):
|
||||||
lines = result.stdout.split('\n')[1:]
|
for instance in sorted(solution.docker_instances, key=lambda x: x['type']):
|
||||||
solution_id = None
|
if instance['type'] == 'network':
|
||||||
for line in lines:
|
call(f"docker network rm --force {instance['name']}")
|
||||||
line = [i for i in line.split() if i]
|
elif instance['type'] == 'image':
|
||||||
if line and line[-1].startswith('solution_'):
|
call(f"docker image rm --force {instance['name']}")
|
||||||
for el in line[-1].split('_'):
|
elif instance['type'] == 'container':
|
||||||
if el.isnumeric():
|
call(f"docker rm --force {instance['name']}")
|
||||||
solution_id = int(el)
|
else:
|
||||||
break
|
raise ValueError(f"Unknown docker type {instance['type']}")
|
||||||
if solution_id:
|
|
||||||
solution = Solution.objects.filter(id=solution_id).first()
|
|
||||||
if solution is not None and (solution.result == 'In queue' or solution.result.startswith('Testing')):
|
|
||||||
continue
|
|
||||||
call(f"docker rm --force {line[-1]}", shell=True)
|
|
||||||
solution_id = None
|
|
||||||
result = run("docker image ls", universal_newlines=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
|
|
||||||
lines = result.stdout.split('\n')[1:]
|
|
||||||
for line in lines:
|
|
||||||
line = [i for i in line.split() if i]
|
|
||||||
if line and line[0].startswith('solution_'):
|
|
||||||
for el in line[-1].split('_'):
|
|
||||||
if el.isnumeric():
|
|
||||||
solution_id = int(el)
|
|
||||||
break
|
|
||||||
if solution_id:
|
|
||||||
solution = Solution.objects.filter(id=solution_id).first()
|
|
||||||
if solution is not None and (solution.result == 'In queue' or solution.result.startswith('Testing')):
|
|
||||||
continue
|
|
||||||
call("docker image rm " + line[0], shell=True)
|
|
||||||
solution_id = None
|
|
||||||
result = run("docker network ls", universal_newlines=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
|
|
||||||
lines = result.stdout.split('\n')[1:]
|
|
||||||
for line in lines:
|
|
||||||
line = [i for i in line.split() if i]
|
|
||||||
if line and line[1].startswith('solution_'):
|
|
||||||
for el in line[-1].split('_'):
|
|
||||||
if el.isnumeric():
|
|
||||||
solution_id = int(el)
|
|
||||||
break
|
|
||||||
if solution_id:
|
|
||||||
solution = Solution.objects.filter(id=solution_id).first()
|
|
||||||
if solution is not None and (solution.result == 'In queue' or solution.result.startswith('Testing')):
|
|
||||||
continue
|
|
||||||
call("docker network rm " + line[0], shell=True)
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
call('docker image rm $(docker images -q mathwave/sprint-repo)', shell=True)
|
call('docker image rm $(docker images -q mathwave/sprint-repo)', shell=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user