diff --git a/freezer_ui/api/__init__.py b/freezer_ui/api/__init__.py
index d95ce28..e69de29 100644
--- a/freezer_ui/api/__init__.py
+++ b/freezer_ui/api/__init__.py
@@ -1 +0,0 @@
-__author__ = 'jonas'
diff --git a/freezer_ui/api/api.py b/freezer_ui/api/api.py
index 4047e5a..1638fbb 100644
--- a/freezer_ui/api/api.py
+++ b/freezer_ui/api/api.py
@@ -90,6 +90,18 @@ class ActionJob(object):
self.backup_name = backup_name
+class Session(object):
+ def __init__(self, session_id, description, status, jobs,
+ start_datetime, interval, end_datetime):
+ self.session_id = session_id
+ self.description = description
+ self.status = status
+ self.jobs = jobs
+ self.start_datetime = start_datetime
+ self.interval = interval
+ self.end_datetime = end_datetime
+
+
@memoized
def get_service_url(request):
""" Get Freezer API url from keystone catalog.
@@ -263,3 +275,74 @@ def client_list(request):
clients = _freezerclient(request).registration.list()
clients = [Client(client) for client in clients]
return clients
+
+
+def add_job_to_session(request, session_id, job_id):
+ """This function will add a job to a session and the API will handle the
+ copy of job information to the session """
+ return _freezerclient(request).sessions.add_job(session_id, job_id)
+
+
+def remove_job_from_session(request, session_id, job_id):
+ """Remove a job from a session will delete the job information but not the
+ job itself """
+ return _freezerclient(request).sessions.remove_job(session_id, job_id)
+
+
+def session_create(request, context):
+ """A session is a group of jobs who share the same scheduling time. """
+ session = create_dict_action(**context)
+ session['description'] = session.pop('description', None)
+ schedule = {
+ 'end_datetime': session.pop('end_datetime', None),
+ 'interval': session.pop('interval', None),
+ 'start_datetime': session.pop('start_datetime', None),
+ }
+ session['schedule'] = schedule
+ return _freezerclient(request).sessions.create(session)
+
+
+def session_update(request, context):
+ """Update session information """
+ session = create_dict_action(**context)
+ session_id = session.pop('session_id', None)
+ session['description'] = session.pop('description', None)
+ schedule = {
+ 'end_datetime': session.pop('end_datetime', None),
+ 'interval': session.pop('interval', None),
+ 'start_datetime': session.pop('start_datetime', None),
+ }
+ session['schedule'] = schedule
+ return _freezerclient(request).sessions.update(session_id, session)
+
+
+def session_delete(request, session_id):
+ """Delete session from API """
+ return _freezerclient(request).sessions.delete(session_id)
+
+
+def session_list(request):
+ """List all sessions """
+ sessions = _freezerclient(request).sessions.list_all()
+ sessions = [Session(s['session_id'],
+ s['description'],
+ s['status'],
+ s['jobs'],
+ s['schedule']['start_datetime'],
+ s['schedule']['interval'],
+ s['schedule']['end_datetime'])
+ for s in sessions]
+ return sessions
+
+
+def session_get(request, session_id):
+ """Get a single session """
+ session = _freezerclient(request).sessions.get(session_id)
+ session = Session(session['session_id'],
+ session['description'],
+ session['status'],
+ session['jobs'],
+ session['schedule']['start_datetime'],
+ session['schedule']['interval'],
+ session['schedule']['end_datetime'])
+ return session
diff --git a/freezer_ui/dashboard.py b/freezer_ui/dashboard.py
index d0604e2..b6206ff 100644
--- a/freezer_ui/dashboard.py
+++ b/freezer_ui/dashboard.py
@@ -18,7 +18,7 @@ import horizon
class FreezerDR(horizon.PanelGroup):
slug = "freezerdr"
name = _("Backup and Restore")
- panels = ('jobs',)
+ panels = ('jobs', 'sessions')
class Freezer(horizon.Dashboard):
diff --git a/freezer_ui/jobs/tables.py b/freezer_ui/jobs/tables.py
index dd3a27d..9a73b96 100644
--- a/freezer_ui/jobs/tables.py
+++ b/freezer_ui/jobs/tables.py
@@ -47,6 +47,20 @@ def format_last_backup(last_backup):
'en="true"> {}'.format(colour, icon, text))
+class AttachJobToSession(tables.LinkAction):
+ name = "attach_job_to_session"
+ verbose_name = _("Attach To Session")
+ classes = ("ajax-modal")
+ url = "horizon:freezer_ui:sessions:attach"
+
+ def allowed(self, request, instance):
+ return True
+
+ def get_link_url(self, datum):
+ return reverse("horizon:freezer_ui:sessions:attach",
+ kwargs={'job_id': datum.job_id})
+
+
class Restore(tables.Action):
name = "restore"
verbose_name = _("Restore")
@@ -149,6 +163,7 @@ class JobsTable(tables.DataTable):
multi_select = False
row_actions = (CreateAction,
EditJob,
+ AttachJobToSession,
CloneJob,
DeleteJob,)
diff --git a/freezer_ui/jobs/templates/jobs/snapshot.html b/freezer_ui/jobs/templates/jobs/snapshot.html
deleted file mode 100644
index 36c0a71..0000000
--- a/freezer_ui/jobs/templates/jobs/snapshot.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% load i18n horizon humanize %}
-
-{% block help_message %}
-{% endblock %}
-
-
-
\ No newline at end of file
diff --git a/freezer_ui/sessions/__init__.py b/freezer_ui/sessions/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/freezer_ui/sessions/browsers.py b/freezer_ui/sessions/browsers.py
new file mode 100644
index 0000000..a775455
--- /dev/null
+++ b/freezer_ui/sessions/browsers.py
@@ -0,0 +1,27 @@
+# Copyright 2012 Nebula, Inc.
+# Copyright 2015 Hewlett-Packard
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+from horizon import browsers
+from horizon_web_ui.freezer_ui.sessions import tables
+
+
+class SessionBrowser(browsers.ResourceBrowser):
+ name = "session_configuration"
+ verbose_name = _("Session Configuration")
+ navigation_table_class = tables.SessionsTable
+ content_table_class = tables.JobsTable
+ navigable_item_name = _("Sessions")
+ navigation_kwarg_name = "session_id"
diff --git a/freezer_ui/sessions/panel.py b/freezer_ui/sessions/panel.py
new file mode 100644
index 0000000..cc28800
--- /dev/null
+++ b/freezer_ui/sessions/panel.py
@@ -0,0 +1,24 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+from horizon_web_ui.freezer_ui import dashboard
+
+
+class SessionsPanel(horizon.Panel):
+ name = _("Sessions")
+ slug = "sessions"
+
+
+dashboard.Freezer.register(SessionsPanel)
diff --git a/freezer_ui/sessions/tables.py b/freezer_ui/sessions/tables.py
new file mode 100644
index 0000000..c454169
--- /dev/null
+++ b/freezer_ui/sessions/tables.py
@@ -0,0 +1,154 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import datetime
+from django import shortcuts
+from django.utils import safestring
+from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ungettext_lazy
+
+from horizon import messages
+from horizon import tables
+from horizon.utils.urlresolvers import reverse
+
+import horizon_web_ui.freezer_ui.api.api as freezer_api
+from horizon_web_ui.freezer_ui.django_utils import timestamp_to_string
+
+
+def get_link(session):
+ return reverse('horizon:freezer_ui:sessions:index',
+ kwargs={'session_id': session.session_id})
+
+
+class CreateJob(tables.LinkAction):
+ name = "create_session"
+ verbose_name = _("Create Session")
+ url = "horizon:freezer_ui:sessions:create"
+ classes = ("ajax-modal",)
+ icon = "plus"
+
+
+class DeleteSession(tables.DeleteAction):
+ name = "delete"
+ classes = ("btn-danger",)
+ icon = "remove"
+ help_text = _("Delete sessions is not recoverable.")
+
+ @staticmethod
+ def action_present(count):
+ return ungettext_lazy(
+ u"Delete Session",
+ u"Delete Sessions",
+ count
+ )
+
+ @staticmethod
+ def action_past(count):
+ return ungettext_lazy(
+ u"Deleted Session",
+ u"Deleted Sessions",
+ count
+ )
+
+ def delete(self, request, session_id):
+ return freezer_api.session_delete(request, session_id)
+
+
+class EditSession(tables.LinkAction):
+ name = "edit_session"
+ verbose_name = _("Edit Session")
+ classes = ("ajax-modal",)
+ icon = "pencil"
+
+ def get_link_url(self, datum=None):
+ return reverse("horizon:freezer_ui:sessions:edit",
+ kwargs={'session_id': datum.session_id})
+
+
+class DeleteMultipleActions(DeleteSession):
+ name = "delete_multiple_actions"
+
+
+class DeleteJobFromSession(tables.DeleteAction):
+ name = "delete_job_from_session"
+ classes = ("btn-danger",)
+ icon = "remove"
+ help_text = _("Delete jobs is not recoverable.")
+
+ @staticmethod
+ def action_present(count):
+ return ungettext_lazy(
+ u"Delete Job",
+ u"Delete Jobs",
+ count
+ )
+
+ @staticmethod
+ def action_past(count):
+ return ungettext_lazy(
+ u"Deleted Job",
+ u"Deleted Jobs",
+ count
+ )
+
+ def delete(self, request, session):
+ job_id, session_id = session.split('===')
+ return freezer_api.remove_job_from_session(
+ request,
+ session_id,
+ job_id)
+
+
+class JobsTable(tables.DataTable):
+ client_id = tables.Column(
+ 'client_id',
+ verbose_name=_("Client ID"))
+
+ status = tables.Column(
+ 'status',
+ verbose_name=_("Status"))
+
+ def get_object_id(self, job):
+ # this is used to pass to values as an url
+ # TODO: look for a way to improve this
+ ids = '{0}==={1}'.format(job.job_id, job.session_id)
+ return ids
+
+ class Meta(object):
+ name = "jobs"
+ verbose_name = _("Jobs")
+ table_actions = ()
+ row_actions = (DeleteJobFromSession,)
+ footer = False
+ multi_select = True
+
+
+class SessionsTable(tables.DataTable):
+ description = tables.Column('description',
+ link=get_link,
+ verbose_name=_("Session"))
+
+ status = tables.Column('status',
+ verbose_name=_("Status"))
+
+ def get_object_id(self, session):
+ return session.session_id
+
+ class Meta(object):
+ name = "sessions"
+ verbose_name = _("Sessions")
+ table_actions = (CreateJob,
+ DeleteMultipleActions)
+ row_actions = (EditSession,
+ DeleteSession,)
+ footer = False
+ multi_select = True
diff --git a/freezer_ui/sessions/templates/sessions/browser.html b/freezer_ui/sessions/templates/sessions/browser.html
new file mode 100644
index 0000000..d1e7818
--- /dev/null
+++ b/freezer_ui/sessions/templates/sessions/browser.html
@@ -0,0 +1,11 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Session Configurations" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Session Configurations") %}
+{% endblock page_header %}
+
+{% block main %}
+ {{ session_configuration_browser.render }}
+{% endblock %}
diff --git a/freezer_ui/sessions/urls.py b/freezer_ui/sessions/urls.py
new file mode 100644
index 0000000..11adc48
--- /dev/null
+++ b/freezer_ui/sessions/urls.py
@@ -0,0 +1,38 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.conf.urls import patterns
+from django.conf.urls import url
+
+from horizon_web_ui.freezer_ui.sessions import views
+
+
+urlpatterns = patterns(
+ '',
+
+ url(r'^(?P[^/]+)?$',
+ views.SessionsView.as_view(),
+ name='index'),
+
+ url(r'^attach_to_session/(?P[^/]+)?$',
+ views.AttachToSessionWorkflow.as_view(),
+ name='attach'),
+
+ url(r'^create/$',
+ views.CreateSessionWorkflow.as_view(),
+ name='create'),
+
+ url(r'^edit/(?P[^/]+)?$',
+ views.CreateSessionWorkflow.as_view(),
+ name='edit'),
+
+)
diff --git a/freezer_ui/sessions/views.py b/freezer_ui/sessions/views.py
new file mode 100644
index 0000000..145cd81
--- /dev/null
+++ b/freezer_ui/sessions/views.py
@@ -0,0 +1,114 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed `under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _
+
+from horizon import browsers
+from horizon import exceptions
+from horizon import workflows
+
+import horizon_web_ui.freezer_ui.sessions.browsers as project_browsers
+from horizon_web_ui.freezer_ui.sessions.workflows import attach
+from horizon_web_ui.freezer_ui.sessions.workflows import create_session
+import horizon_web_ui.freezer_ui.api.api as freezer_api
+from horizon_web_ui.freezer_ui.utils import SessionJob
+
+
+class AttachToSessionWorkflow(workflows.WorkflowView):
+ workflow_class = attach.AttachJobToSession
+
+ def get_object(self, *args, **kwargs):
+ job_id = self.kwargs['job_id']
+ try:
+ return freezer_api.job_get(self.request, job_id)
+ except Exception:
+ redirect = reverse("horizon:freezer_ui:jobs:index")
+ msg = _('Unable to retrieve details.')
+ exceptions.handle(self.request, msg, redirect=redirect)
+
+ def is_update(self):
+ return 'job_id' in self.kwargs and \
+ bool(self.kwargs['job_id'])
+
+ def get_initial(self):
+ initial = super(AttachToSessionWorkflow, self).get_initial()
+ job = self.get_object()[0]
+ initial.update({'job_id': job.id})
+ return initial
+
+
+class SessionsView(browsers.ResourceBrowserView):
+ browser_class = project_browsers.SessionBrowser
+ template_name = "freezer_ui/sessions/browser.html"
+
+ def get_sessions_data(self):
+ sessions = []
+ try:
+ sessions = freezer_api.session_list(self.request)
+ except Exception:
+ msg = _('Unable to retrieve sessions list.')
+ exceptions.handle(self.request, msg)
+ return sessions
+
+ def get_jobs_data(self):
+ jobs = []
+ session = None
+ try:
+ if self.kwargs['session_id']:
+ session = freezer_api.session_get(
+ self.request,
+ self.kwargs['session_id'])
+
+ try:
+ jobs = [SessionJob(k,
+ self.kwargs['session_id'],
+ v['client_id'],
+ v['status'])
+ for k, v in session.jobs.iteritems()]
+ except AttributeError:
+ pass
+ except Exception:
+ msg = _('Unable to retrieve session information.')
+ exceptions.handle(self.request, msg)
+ return jobs
+
+
+class CreateSessionWorkflow(workflows.WorkflowView):
+ workflow_class = create_session.CreateSession
+
+ def get_object(self, *args, **kwargs):
+ session_id = self.kwargs['session_id']
+ try:
+ return freezer_api.session_get(self.request, session_id)
+ except Exception:
+ redirect = reverse("horizon:freezer_ui:sessions:index")
+ msg = _('Unable to retrieve session.')
+ exceptions.handle(self.request, msg, redirect=redirect)
+
+ def get_initial(self):
+ initial = super(CreateSessionWorkflow, self).get_initial()
+ if self.is_update():
+ session = self.get_object()
+ initial.update({
+ 'description': session.description,
+ 'session_id': session.session_id,
+ 'start_datetime': session.start_datetime,
+ 'interval': session.interval,
+ 'end_datetime': session.end_datetime
+ })
+ return initial
+
+ def is_update(self):
+ return 'session_id' in self.kwargs and \
+ bool(self.kwargs['session_id'])
diff --git a/freezer_ui/sessions/workflows/__init__.py b/freezer_ui/sessions/workflows/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/freezer_ui/sessions/workflows/attach.py b/freezer_ui/sessions/workflows/attach.py
new file mode 100644
index 0000000..9fdc581
--- /dev/null
+++ b/freezer_ui/sessions/workflows/attach.py
@@ -0,0 +1,72 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from django.utils.translation import ugettext_lazy as _
+
+from horizon import exceptions
+from horizon import forms
+from horizon import workflows
+
+import horizon_web_ui.freezer_ui.api.api as freezer_api
+
+
+class SessionConfigurationAction(workflows.Action):
+ session_id = forms.ChoiceField(
+ help_text=_("Set a session to attach this job"),
+ label=_("Session Name"),
+ required=True)
+
+ job_id = forms.CharField(
+ widget=forms.HiddenInput(),
+ required=True)
+
+ def populate_session_id_choices(self, request, context):
+ sessions = []
+ try:
+ sessions = freezer_api.session_list(request)
+ except Exception:
+ exceptions.handle(request, _('Error getting session list'))
+
+ sessions = [(s.session_id, s.description) for s in sessions]
+ sessions.insert(0, ('', _('Select A Session')))
+ return sessions
+
+ class Meta:
+ name = _("Sessions")
+ slug = "sessions"
+
+
+class SessionConfiguration(workflows.Step):
+ action_class = SessionConfigurationAction
+ contributes = ('session_id',
+ 'job_id')
+
+
+class AttachJobToSession(workflows.Workflow):
+ slug = "attach_job"
+ name = _("Attach To Session")
+ finalize_button_name = _("Attach")
+ success_message = _('Job saved successfully.')
+ failure_message = _('Unable to attach to session.')
+ success_url = "horizon:freezer_ui:jobs:index"
+ default_steps = (SessionConfiguration,)
+
+ def handle(self, request, context):
+ try:
+ freezer_api.add_job_to_session(
+ request,
+ context['session_id'],
+ context['job_id'])
+ return True
+ except Exception:
+ exceptions.handle(request)
+ return False
diff --git a/freezer_ui/sessions/workflows/create_session.py b/freezer_ui/sessions/workflows/create_session.py
new file mode 100644
index 0000000..3ac20f6
--- /dev/null
+++ b/freezer_ui/sessions/workflows/create_session.py
@@ -0,0 +1,123 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import datetime
+from django.utils.translation import ugettext_lazy as _
+
+from horizon import exceptions
+from horizon import forms
+from horizon import workflows
+
+import horizon_web_ui.freezer_ui.api.api as freezer_api
+
+
+class SessionConfigurationAction(workflows.Action):
+ description = forms.CharField(
+ label=_("Session Name"),
+ help_text=_("Define a name for this session"),
+ required=True)
+
+ session_id = forms.CharField(
+ widget=forms.HiddenInput(),
+ required=False)
+
+ class Meta:
+ name = _("Session Information")
+ slug = "sessions"
+
+
+class SessionConfiguration(workflows.Step):
+ action_class = SessionConfigurationAction
+ contributes = ('description',
+ 'session_id')
+
+
+class SchedulingConfigurationAction(workflows.Action):
+ start_datetime = forms.CharField(
+ label=_("Start Date and Time"),
+ required=False,
+ help_text=_(""))
+
+ interval = forms.CharField(
+ label=_("Interval"),
+ required=False,
+ help_text=_(""))
+
+ end_datetime = forms.CharField(
+ label=_("End Date and Time"),
+ required=False,
+ help_text=_(""))
+
+ def __init__(self, request, context, *args, **kwargs):
+ self.request = request
+ self.context = context
+ super(SchedulingConfigurationAction, self).__init__(
+ request, context, *args, **kwargs)
+
+ def clean(self):
+ cleaned_data = super(SchedulingConfigurationAction, self).clean()
+ self._check_start_datetime(cleaned_data)
+ self._check_end_datetime(cleaned_data)
+ return cleaned_data
+
+ def _validate_iso_format(self, start_date):
+ try:
+ return datetime.datetime.strptime(
+ start_date, "%Y-%m-%dT%H:%M:%S")
+ except ValueError:
+ return False
+
+ def _check_start_datetime(self, cleaned_data):
+ if cleaned_data.get('start_datetime') and not \
+ self._validate_iso_format(cleaned_data.get('start_datetime')):
+ msg = _("Start date time is not in ISO format.")
+ self._errors['start_datetime'] = self.error_class([msg])
+
+ def _check_end_datetime(self, cleaned_data):
+ if cleaned_data.get('end_datetime') and not \
+ self._validate_iso_format(cleaned_data.get('end_datetime')):
+ msg = _("End date time is not in ISO format.")
+ self._errors['end_datetime'] = self.error_class([msg])
+
+ class Meta(object):
+ name = _("Scheduling")
+ slug = "scheduling"
+ help_text_template = "freezer_ui/jobs" \
+ "/_scheduling.html"
+
+
+class SchedulingConfiguration(workflows.Step):
+ action_class = SchedulingConfigurationAction
+ contributes = ('start_datetime',
+ 'interval',
+ 'end_datetime')
+
+
+class CreateSession(workflows.Workflow):
+ slug = "create_session"
+ name = _("Create Session")
+ finalize_button_name = _("Create")
+ success_message = _('Session created successfully.')
+ failure_message = _('Unable to create session.')
+ success_url = "horizon:freezer_ui:sessions:index"
+ default_steps = (SessionConfiguration,
+ SchedulingConfiguration)
+
+ def handle(self, request, context):
+ try:
+ if context['session_id'] == '':
+ return freezer_api.session_create(request, context)
+ else:
+ return freezer_api.session_update(request, context)
+ except Exception:
+ exceptions.handle(request)
+ return False
diff --git a/freezer_ui/utils.py b/freezer_ui/utils.py
index 745ad88..396515e 100644
--- a/freezer_ui/utils.py
+++ b/freezer_ui/utils.py
@@ -17,3 +17,11 @@ def create_dict_action(**kwargs):
None values
"""
return {k: v for k, v in kwargs.items() if v}
+
+
+class SessionJob(object):
+ def __init__(self, job_id, session_id, client_id, status):
+ self.job_id = job_id
+ self.session_id = session_id
+ self.client_id = client_id
+ self.status = status