Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge "Adding Jobs and Job Executions panels for Sahara"
- Loading branch information
Showing
33 changed files
with
2,142 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
27 changes: 27 additions & 0 deletions
27
openstack_dashboard/dashboards/project/data_processing/job_executions/panel.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# 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 openstack_dashboard.dashboards.project import dashboard | ||
|
||
|
||
class JobExecutionsPanel(horizon.Panel): | ||
name = _("Job Executions") | ||
slug = 'data_processing.job_executions' | ||
permissions = ('openstack.services.data_processing',) | ||
|
||
|
||
dashboard.Project.register(JobExecutionsPanel) |
112 changes: 112 additions & 0 deletions
112
openstack_dashboard/dashboards/project/data_processing/job_executions/tables.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# 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 logging | ||
|
||
from django.core import urlresolvers | ||
from django.utils import http | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from horizon import tables | ||
|
||
from openstack_dashboard.api import sahara as saharaclient | ||
from openstack_dashboard.dashboards.project.data_processing. \ | ||
jobs import tables as j_t | ||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
|
||
class DeleteJobExecution(tables.BatchAction): | ||
name = "delete" | ||
action_present = _("Delete") | ||
action_past = _("Deleted") | ||
data_type_singular = _("Job execution") | ||
data_type_plural = _("Job executions") | ||
classes = ('btn-danger', 'btn-terminate') | ||
|
||
def action(self, request, obj_id): | ||
saharaclient.job_execution_delete(request, obj_id) | ||
|
||
|
||
class ReLaunchJobExistingCluster(j_t.ChoosePlugin): | ||
name = "relaunch-job-existing" | ||
verbose_name = _("Relaunch On Existing Cluster") | ||
action_present = _("Launch") | ||
action_past = _("Launched") | ||
data_type_singular = _("Job") | ||
data_type_plural = _("Jobs") | ||
url = "horizon:project:data_processing.jobs:launch-job" | ||
classes = ('ajax-modal', 'btn-launch') | ||
|
||
def get_link_url(self, datum): | ||
base_url = urlresolvers.reverse(self.url) | ||
|
||
params = http.urlencode({'job_id': datum.job_id, | ||
'job_execution_id': datum.id}) | ||
return "?".join([base_url, params]) | ||
|
||
|
||
class ReLaunchJobNewCluster(ReLaunchJobExistingCluster): | ||
name = "relaunch-job-new" | ||
verbose_name = _("Relaunch On New Cluster") | ||
action_present = _("Launch") | ||
action_past = _("Launched") | ||
data_type_singular = _("Job") | ||
data_type_plural = _("Jobs") | ||
url = "horizon:project:data_processing.jobs:choose-plugin" | ||
classes = ('ajax-modal', 'btn-launch') | ||
|
||
|
||
class UpdateRow(tables.Row): | ||
ajax = True | ||
|
||
def get_data(self, request, job_execution_id): | ||
job_execution = saharaclient.job_execution_get(request, | ||
job_execution_id) | ||
return job_execution | ||
|
||
|
||
class JobExecutionsTable(tables.DataTable): | ||
class StatusColumn(tables.Column): | ||
def get_data(self, datum): | ||
return datum.info['status'] | ||
|
||
STATUS_CHOICES = ( | ||
("DONEWITHERROR", False), | ||
("FAILED", False), | ||
("KILLED", False), | ||
("SUCCEEDED", True), | ||
) | ||
|
||
name = tables.Column("id", | ||
verbose_name=_("ID"), | ||
display_choices=(("id", "ID"), ("name", "Name")), | ||
link=("horizon:project:data_processing.job_executions:details")) | ||
|
||
status = StatusColumn("info", | ||
status=True, | ||
status_choices=STATUS_CHOICES, | ||
verbose_name=_("Status")) | ||
|
||
def get_object_display(self, datum): | ||
return datum.id | ||
|
||
class Meta: | ||
name = "job_executions" | ||
row_class = UpdateRow | ||
status_columns = ["status"] | ||
verbose_name = _("Job Executions") | ||
table_actions = [DeleteJobExecution] | ||
row_actions = [DeleteJobExecution, | ||
ReLaunchJobExistingCluster, | ||
ReLaunchJobNewCluster] |
73 changes: 73 additions & 0 deletions
73
openstack_dashboard/dashboards/project/data_processing/job_executions/tabs.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# 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 logging | ||
|
||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from horizon import tabs | ||
|
||
from openstack_dashboard.api import sahara as saharaclient | ||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
|
||
class GeneralTab(tabs.Tab): | ||
name = _("General Info") | ||
slug = "job_execution_tab" | ||
template_name = ("project/data_processing.job_executions/_details.html") | ||
|
||
def get_context_data(self, request): | ||
job_execution_id = self.tab_group.kwargs['job_execution_id'] | ||
job_execution = saharaclient.job_execution_get(request, | ||
job_execution_id) | ||
object_names = self.get_object_names(job_execution, | ||
request) | ||
|
||
return {"job_execution": job_execution, | ||
"object_names": object_names} | ||
|
||
def get_object_names(self, job_ex, request): | ||
object_names = {} | ||
obj_names_map = {'input_name': {'obj': 'data_source_get', | ||
'obj_id': job_ex.input_id}, | ||
'output_name': {'obj': 'data_source_get', | ||
'obj_id': job_ex.output_id}, | ||
'cluster_name': {'obj': 'cluster_get', | ||
'obj_id': job_ex.cluster_id}, | ||
'job_name': {'obj': 'job_get', | ||
'obj_id': job_ex.job_id}} | ||
for item in obj_names_map: | ||
object_names[item] = ( | ||
self.get_object_name(obj_names_map[item]['obj_id'], | ||
obj_names_map[item]['obj'], | ||
request)) | ||
|
||
return object_names | ||
|
||
def get_object_name(self, obj_id, sahara_obj, request): | ||
object_name = None | ||
try: | ||
s_func = getattr(saharaclient, sahara_obj) | ||
obj = s_func(request, obj_id) | ||
object_name = obj.name | ||
except Exception as e: | ||
LOG.warn("Unable to get name for %s with object_id %s (%s)" % | ||
(sahara_obj, obj_id, str(e))) | ||
return object_name | ||
|
||
|
||
class JobExecutionDetailsTabs(tabs.TabGroup): | ||
slug = "job_execution_details" | ||
tabs = (GeneralTab,) | ||
sticky = True |
39 changes: 39 additions & 0 deletions
39
...ect/data_processing/job_executions/templates/data_processing.job_executions/_details.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{% load i18n sizeformat %} | ||
<h3>{% trans "Job Execution Overview" %}</h3> | ||
<div class="status row-fluid detail"> | ||
<dl> | ||
<dt>{% trans "Status" %}</dt> | ||
<dd>{{ job_execution.info.status }}</dd> | ||
<dt>{% trans "Id" %}</dt> | ||
<dd>{{ job_execution.id }}</dd> | ||
<dt>{% trans "Job Id" %}</dt> | ||
<dd>{{ job_execution.job_id }} ({{ object_names.job_name }})</dd> | ||
<dt>{% trans "Input Id" %}</dt> | ||
<dd>{{ job_execution.input_id }} ({{ object_names.input_name }})</dd> | ||
<dt>{% trans "Output Id" %}</dt> | ||
<dd>{{ job_execution.output_id }} ({{ object_names.output_name }})</dd> | ||
<dt>{% trans "Cluster Id" %}</dt> | ||
<dd>{{ job_execution.cluster_id }} ({{ object_names.cluster_name }})</dd> | ||
<dt>{% trans "Last Updated" %}</dt> | ||
<dd>{{ job_execution.updated_at }}</dd> | ||
<dt>{% trans "Return Code" %}</dt> | ||
<dd>{{ job_execution.return_code }}</dd> | ||
<dt>{% trans "Oozie Job Id" %}</dt> | ||
<dd>{{ job_execution.oozie_job_id }}</dd> | ||
<dt>{% trans "Created" %}</dt> | ||
<dd>{{ job_execution.created_at }}</dd> | ||
<dt>{% trans "Tenant Id" %}</dt> | ||
<dd>{{ job_execution.tenant_id }}</dd> | ||
<dt>{% trans "Job Configuration" %}</dt> | ||
<dd>{% for group, vals in job_execution.job_configs.iteritems %} | ||
<ul><li><span style="font-weight:bold">{{ group }}:</span> | ||
{%if group == "args" %} | ||
<ul>{% for val in vals %} <li>{{ val }}</li> {% endfor %}</ul> | ||
{% else %} | ||
<ul>{% for key, val in vals.iteritems %} <li>{{ key }} = {{ val }}</li> {% endfor %}</ul> | ||
{% endif %} | ||
</li></ul> | ||
{% endfor %} | ||
</dd> | ||
</dl> | ||
</div> |
15 changes: 15 additions & 0 deletions
15
...ject/data_processing/job_executions/templates/data_processing.job_executions/details.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{% extends 'base.html' %} | ||
{% load i18n %} | ||
{% block title %}{% trans "Job Execution Details" %}{% endblock %} | ||
|
||
{% block page_header %} | ||
{% include "horizon/common/_page_header.html" with title=_("Job Execution Details") %} | ||
{% endblock page_header %} | ||
|
||
{% block main %} | ||
<div class="row-fluid"> | ||
<div class="span12"> | ||
{{ tab_group.render }} | ||
</div> | ||
</div> | ||
{% endblock %} |
66 changes: 66 additions & 0 deletions
66
...ta_processing/job_executions/templates/data_processing.job_executions/job_executions.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
{% extends 'base.html' %} | ||
{% load i18n %} | ||
{% block title %}{% trans "Data Processing" %}{% endblock %} | ||
|
||
{% block page_header %} | ||
{% include "horizon/common/_page_header.html" with title=_("Job Executions") %} | ||
{% endblock page_header %} | ||
|
||
{% block main %} | ||
|
||
<div class="job_executions"> | ||
{{ job_executions_table.render }} | ||
</div> | ||
|
||
<script type="text/javascript"> | ||
addHorizonLoadEvent(function () { | ||
|
||
horizon.modals.addModalInitFunction(function (modal) { | ||
if ($(modal).find(".nav-tabs").find("li").size() == 1) { | ||
// hide tab bar for plugin/version modal wizard | ||
$('div#modal_wrapper ul.nav-tabs').hide(); | ||
} | ||
|
||
$(".hidden_nodegroups_field").val(""); | ||
$(".hidden_configure_field").val(""); | ||
|
||
lower_limit = 0; | ||
$(".count-field").change(); | ||
|
||
if ($(modal).find(".hidden_create_field").length > 0) { | ||
var form = $(".hidden_create_field").closest("form"); | ||
var successful = false; | ||
form.submit(function (e) { | ||
var newElement = $("<a id='hiddenbutton' class='btn btn-small ajax-modal' style='display:none'/>"); | ||
var oldHref = $("#job_executions__action_delete")[0].href; | ||
var plugin = $("#id_plugin_name option:selected").val(); | ||
var version = $("#id_" + plugin + "_version option:selected").val(); | ||
var job_id = $("#id_job_id").val(); | ||
var job_execution_id = $("#id_job_execution_id").val(); | ||
form.find(".close").click(); | ||
newElement.attr("href", "launch-job-new-cluster?" + | ||
"plugin_name=" + encodeURIComponent(plugin) + | ||
"&hadoop_version=" + encodeURIComponent(version) + | ||
"&job_id=" + encodeURIComponent(job_id) + | ||
"&job_execution_id=" + encodeURIComponent(job_execution_id)); | ||
newElement.appendTo("#main_content"); | ||
$("#hiddenbutton").click(); | ||
return false; | ||
}); | ||
$(".plugin_version_choice").closest(".control-group").hide(); | ||
} | ||
|
||
//display version for selected plugin | ||
$(document).on('change', '.plugin_name_choice', switch_versions); | ||
function switch_versions() { | ||
$(".plugin_version_choice").closest(".control-group").hide(); | ||
var plugin = $(this); | ||
$("." + plugin.val() + "_version_choice").closest(".control-group").show(); | ||
} | ||
$(".plugin_name_choice").change(); | ||
}); | ||
|
||
}); | ||
</script> | ||
|
||
{% endblock %} |
46 changes: 46 additions & 0 deletions
46
openstack_dashboard/dashboards/project/data_processing/job_executions/tests.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# 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 import http | ||
|
||
from mox import IsA # noqa | ||
|
||
from openstack_dashboard import api | ||
from openstack_dashboard.test import helpers as test | ||
|
||
|
||
INDEX_URL = reverse('horizon:project:data_processing.job_executions:index') | ||
DETAILS_URL = reverse( | ||
'horizon:project:data_processing.job_executions:details', args=['id']) | ||
|
||
|
||
class DataProcessingJobExecutionTests(test.TestCase): | ||
@test.create_stubs({api.sahara: ('job_execution_list',)}) | ||
def test_index(self): | ||
api.sahara.job_execution_list(IsA(http.HttpRequest)) \ | ||
.AndReturn(self.job_executions.list()) | ||
self.mox.ReplayAll() | ||
res = self.client.get(INDEX_URL) | ||
self.assertTemplateUsed(res, | ||
'project/data_processing.job_executions/job_executions.html') | ||
self.assertContains(res, 'Executions') | ||
|
||
@test.create_stubs({api.sahara: ('job_execution_get',)}) | ||
def test_details(self): | ||
api.sahara.job_execution_get(IsA(http.HttpRequest), IsA(unicode)) \ | ||
.AndReturn(self.job_executions.list()[0]) | ||
self.mox.ReplayAll() | ||
res = self.client.get(DETAILS_URL) | ||
self.assertTemplateUsed(res, | ||
'project/data_processing.job_executions/details.html') | ||
self.assertContains(res, 'RUNNING') |
Oops, something went wrong.