62 lines
2.3 KiB
Python
62 lines
2.3 KiB
Python
import datetime
|
|
import traceback
|
|
|
|
from CTFd.utils import get_config
|
|
from .db import DBContainer, db
|
|
from .docker import DockerUtils
|
|
from .routers import Router
|
|
|
|
|
|
class ControlUtil:
|
|
@staticmethod
|
|
def try_add_container(user_id, challenge_id):
|
|
container = DBContainer.create_container_record(user_id, challenge_id)
|
|
try:
|
|
DockerUtils.add_container(container)
|
|
except Exception as e:
|
|
DBContainer.remove_container_record(user_id)
|
|
print(traceback.format_exc())
|
|
return False, 'Docker Creation Error'
|
|
ok, msg = Router.register(container)
|
|
if not ok:
|
|
DockerUtils.remove_container(container)
|
|
DBContainer.remove_container_record(user_id)
|
|
return False, msg
|
|
return True, 'Container created'
|
|
|
|
@staticmethod
|
|
def try_remove_container(user_id):
|
|
container = DBContainer.get_current_containers(user_id=user_id)
|
|
if not container:
|
|
return False, 'No such container'
|
|
for _ in range(3): # configurable? as "onerror_retry_cnt"
|
|
try:
|
|
ok, msg = Router.unregister(container)
|
|
if not ok:
|
|
return False, msg
|
|
DockerUtils.remove_container(container)
|
|
DBContainer.remove_container_record(user_id)
|
|
return True, 'Container destroyed'
|
|
except Exception as e:
|
|
print(traceback.format_exc())
|
|
return False, 'Failed when destroying instance, please contact admin!'
|
|
|
|
@staticmethod
|
|
def try_renew_container(user_id):
|
|
container = DBContainer.get_current_containers(user_id)
|
|
if not container:
|
|
return False, 'No such container'
|
|
timeout = int(get_config("whale:docker_timeout", "3600"))
|
|
container.start_time = container.start_time + \
|
|
datetime.timedelta(seconds=timeout)
|
|
if container.start_time > datetime.datetime.now():
|
|
container.start_time = datetime.datetime.now()
|
|
# race condition? useless maybe?
|
|
# useful when docker_timeout < poll timeout (10 seconds)
|
|
# doesn't make any sense
|
|
else:
|
|
return False, 'Invalid container'
|
|
container.renew_count += 1
|
|
db.session.commit()
|
|
return True, 'Container Renewed'
|