Skip to content
This repository has been archived by the owner on Nov 9, 2021. It is now read-only.

Enhance ApplicationStatus based on presence of volumes #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions puffin/core/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ def __hash__(self):
return hash(self.application_id)


class ApplicationStatus(enum.Enum):
DELETED = 0
CREATED = 10
class ApplicationStatus(enum.IntEnum):
ERROR = -1
NEVER_STARTED = 0
DELETED = 10
UPDATING = 20
ERROR = 90
CREATED = 30


class ApplicationSettings:
Expand Down Expand Up @@ -229,3 +230,9 @@ def update_application_settings(application_settings):
elif application_settings.application_settings_id:
db.session.delete(application_settings)
db.session.commit()

def get_application_volume_names(user, application):
application_name = get_application_name(user, application)
compose_volumes = application.volumes
application_volumes = ['{}_{}'.format(application_name, volume) for volume in compose_volumes]
return application_volumes
44 changes: 33 additions & 11 deletions puffin/core/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_client():
return client

def create_application(client, user, application, async=True):
if get_application_status(client, user, application) != applications.ApplicationStatus.DELETED:
if get_application_status(client, user, application) > applications.ApplicationStatus.DELETED:
raise RuntimeError("Application already installed or updating, user: {}, application: {}".format(user.login, application.application_id))
name = applications.get_application_name(user, application)

Expand Down Expand Up @@ -79,35 +79,43 @@ def run_service(user, application, service, *arguments, **environment):

def get_application_status(client, user, application):
container = get_main_container(client, user, application)
return _get_application_status(user, application, container)
volumes = get_application_volumes(client, user, application)
return _get_application_status(user, application, container, volumes)

def get_application_statuses(client, user):
apps = applications.get_applications()
application_statuses = []
container_name = applications.get_application_name(user, None) + ".*_main_1"
containers = get_containers(client, container_name)
for container in containers:

def _app_id(container):
user_application_id = _get_user_application_id(container)
if not user_application_id:
continue
login, application_id = user_application_id
return None
_, application_id = user_application_id
return application_id

application = apps.get(application_id)
if not application:
app_id_to_container = {_app_id(container): container for container in containers}
for app_id, application in apps.items():
if not app_id or app_id[0] == '_':
continue

status = _get_application_status(user, application, container)
container = app_id_to_container.get(app_id)
volumes = get_application_volumes(client, user, application)
status = _get_application_status(user, application, container, volumes)
application_statuses.append((application, status))

return application_statuses

def _get_application_status(user, application, container):
def _get_application_status(user, application, container, volumes=None):
name = applications.get_application_name(user, application)
if queue.task_exists(name):
return applications.ApplicationStatus.UPDATING
if container:
return applications.ApplicationStatus.CREATED
else:
if volumes and any(vol is not None for vol in volumes.values()):
return applications.ApplicationStatus.DELETED
else:
return applications.ApplicationStatus.NEVER_STARTED

def get_all_running_applications():
apps = applications.get_applications()
Expand Down Expand Up @@ -167,6 +175,20 @@ def get_main_container(client, user, application):
else:
return None

def get_volumes(client, name=""):
return {volume.name: volume for volume in client.volumes.list(filters={"name": name})}

def get_application_volumes(client, user, application):
application_volume_names = applications.get_application_volume_names(user, application)

application_name = applications.get_application_name(user, application)
docker_volumes = get_volumes(client, application_name)
application_volumes = {
application_volume: docker_volumes.get(application_volume)
for application_volume in application_volume_names
}
return application_volumes

def wait_until_up(url, timeout=APPLICATION_CREATE_TIMEOUT):
start_time = time.time()
while True:
Expand Down
2 changes: 1 addition & 1 deletion puffin/gui/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def application_status(application_id):
def apps():
client = docker.get_client()
app_statuses = docker.get_application_statuses(client, current_user)
apps = [a[0] for a in app_statuses if a[1] == applications.ApplicationStatus.CREATED]
apps = [a[0] for a in app_statuses if a[1] != applications.ApplicationStatus.NEVER_STARTED]
return flask.render_template('applications.html', applications=apps)

@app.route('/media/<path:path>')
Expand Down
3 changes: 3 additions & 0 deletions puffin/templates/application.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ <h1>{{ application.name }}</h1>
<button type="submit" name="start" value="Start" class="btn btn-success"><span class="glyphicon glyphicon-play"></span> Run</button>
<a class="btn btn-info" role="button" href="{{ url_for("application_settings", application_id=application.application_id) }}"><span class="glyphicon glyphicon-cog"></span> Settings</a>
<a class="btn btn-warning" role="button" href="{{ url_for("application_backup", application_id=application.application_id) }}"><span class="glyphicon glyphicon-hdd"></span> Backup</a>
{% elif application_status == ApplicationStatus.NEVER_STARTED %}
<button type="submit" name="start" value="Start" class="btn btn-success"><span class="glyphicon glyphicon-play"></span> Run</button>
<a class="btn btn-info" role="button" href="{{ url_for("application_settings", application_id=application.application_id) }}"><span class="glyphicon glyphicon-cog"></span> Settings</a>
{% elif application_status == ApplicationStatus.UPDATING %}
<button type="button" class="btn btn-warning blinking"><span class="glyphicon glyphicon-refresh"></span> Updating</button>
<script>
Expand Down