ソースを参照

[notebook] Skeleton of sessions and snippet properties

(cherry picked from commit eb52cb9996484ca4ad06abc815ddc48535454581)
Romain Rigaux 10 年 前
コミット
904e94c667

+ 8 - 1
apps/spark/src/spark/api.py

@@ -39,9 +39,16 @@ LOG = logging.getLogger(__name__)
 def create_session(request):
   response = {'status': -1}
 
+  notebook = json.loads(request.POST.get('notebook', '{}'))
   snippet = json.loads(request.POST.get('snippet', '{}'))
 
-  response['session'] = get_api(request.user, snippet).create_session(lang=snippet['type'])
+  session = [session for session in notebook['sessions'] if snippet['type'] == session['type']]
+  if any(session):
+    properties = session[0]['properties']
+  else:
+    properties = None
+
+  response['session'] = get_api(request.user, snippet).create_session(lang=snippet['type'], properties=properties)
   response['status'] = 0
 
   return JsonResponse(response)

+ 16 - 5
apps/spark/src/spark/models.py

@@ -16,6 +16,7 @@
 # limitations under the License.
 
 import json
+import logging
 import re
 import time
 
@@ -34,6 +35,9 @@ from spark.job_server_api import get_api as get_spark_api
 from spark.data_export import download as spark_download
 
 
+LOG = logging.getLogger(__name__)
+
+
 # To move to Editor API
 class SessionExpired(Exception):
   pass
@@ -103,7 +107,7 @@ class TextApi():
   def __init__(self, user):
     self.user = user
 
-  def create_session(self, lang):
+  def create_session(self, lang, properties=None):
     return {
         'type': lang,
         'id': None
@@ -144,7 +148,7 @@ class HS2Api():
 
     return dbms.get(self.user, query_server=get_query_server_config(name=name))
 
-  def create_session(self, lang):
+  def create_session(self, lang, properties=None):
     return {
         'type': lang,
         'id': None # Real one at some point
@@ -279,8 +283,14 @@ class SparkApi():
   def __init__(self, user):
     self.user = user
 
-  def create_session(self, lang='scala'):
+  def create_session(self, lang='scala', properties=None):
+    if properties is None:
+      settings = { 
+          'executor-memory': '1G' # Some props only in YARN mode
+      }
+
     api = get_spark_api(self.user)
+    print 'TODO: we should use the settings %s for creating the new sessions' % settings
     response = api.create_session(kind=lang)
 
     status = api.get_session(response['id'])
@@ -296,7 +306,8 @@ class SparkApi():
 
     return {
         'type': lang,
-        'id': response['id']
+        'id': response['id'],
+        'properties': settings
     }
 
   def execute(self, notebook, snippet):
@@ -432,7 +443,7 @@ class SparkBatchApi():
   def __init__(self, user):
     self.user = user
 
-  def create_session(self, lang):
+  def create_session(self, lang, properties=None):
     return {
         'type': lang,
         'id': None

+ 9 - 1
apps/spark/src/spark/static/spark/js/spark.ko.js

@@ -313,6 +313,7 @@ var Snippet = function (vm, notebook, snippet) {
   self.create_session = function (callback) {
     self.status('loading');
     $.post("/spark/api/create_session", {
+      notebook: ko.mapping.toJSON(notebook.getContext()),
       snippet: ko.mapping.toJSON(self.getContext())
     }, function (data) {
       if (data.status == 0) {
@@ -597,8 +598,15 @@ var Notebook = function (vm, notebook) {
       properties['py_file'] = '';
       properties['class'] = '';
       properties['arguments'] = [];
+    } else if (self.selectedSnippet() == 'hive') {
+      properties['settings'] = [];
+      properties['files'] = [];
+    } else if (self.selectedSnippet() == 'pig') {
+      properties['parameters'] = [];
+      properties['hadoop_properties'] = [];
+      properties['files'] = [];
     }
-
+	
     var _snippet = new Snippet(vm, self, {type: self.selectedSnippet(), properties: properties, result: {}});
     self.snippets.push(_snippet);
 

+ 73 - 38
apps/spark/src/spark/templates/editor.mako

@@ -128,52 +128,57 @@ ${ commonheader(_('Query'), app_name, user, "68px") | n,unicode }
 <div class="search-bar">
   <div class="pull-right" style="padding-right:50px">
 
-     <div class="btn-group">
-       <a class="btn dropdown-toggle" data-toggle="dropdown">
-         <i class="fa fa-check-square-o"></i>
-         <i class="fa fa-caret-down"></i>
-       </a>
-       <ul class="dropdown-menu">
-         <li>
-           <a href="javascript:void(0)" data-bind="click: function() { $root.selectedNotebook().clearResults() }">
-             <i class="fa fa-play fa-fw"></i> ${ _('Execute all snippets') }
-           </a>
-         </li>
-         <li>
-           <a href="javascript:void(0)" data-bind="click: function() { $root.selectedNotebook().clearResults() }">
-             <i class="fa fa-eraser fa-fw"></i> ${ _('Clear all results') }
-           </a>
-         </li>
-         <li>
-           <a href="javascript:void(0)" data-bind="click: displayCombinedContent">
-             <i class="fa fa-file-text-o fa-fw"></i> ${ _('Display all Notebook content') }
-           </a>
-         </li>
-       </ul>
-     </div>
+    <div class="btn-group">
+      <a class="btn dropdown-toggle" data-toggle="dropdown">
+        <i class="fa fa-check-square-o"></i>
+        <i class="fa fa-caret-down"></i>
+      </a>
+      <ul class="dropdown-menu">
+        <li>
+          <a href="javascript:void(0)" data-bind="click: function() { $root.selectedNotebook().clearResults() }">
+            <i class="fa fa-play fa-fw"></i> ${ _('Execute all snippets') }
+          </a>
+        </li>
+        <li>
+          <a href="javascript:void(0)" data-bind="click: function() { $root.selectedNotebook().clearResults() }">
+            <i class="fa fa-eraser fa-fw"></i> ${ _('Clear all results') }
+          </a>
+        </li>
+        <li>
+          <a href="javascript:void(0)" data-bind="click: displayCombinedContent">
+            <i class="fa fa-file-text-o fa-fw"></i> ${ _('Display all Notebook content') }
+          </a>
+        </li>
+      </ul>
+   </div>
 
    &nbsp;&nbsp;&nbsp;
 
-    <a title="${ _('Edit') }" rel="tooltip" data-placement="bottom" data-bind="click: toggleEditing, css: {'btn': true, 'btn-inverse': isEditing}">
-      <i class="fa fa-pencil"></i>
-    </a>
+   <a title="${ _('Edit') }" rel="tooltip" data-placement="bottom" data-bind="click: toggleEditing, css: {'btn': true, 'btn-inverse': isEditing}">
+     <i class="fa fa-pencil"></i>
+   </a>
 
-    &nbsp;&nbsp;&nbsp;
+   <a class="btn pointer" title="${ _('Sessions') }" rel="tooltip" data-placement="bottom" data-toggle="modal" data-target="#sessionsDemiModal"
+       data-bind="css: {'btn': true}">
+     <i class="fa fa-cloud"></i>
+   </a>
 
-    <a class="btn" title="${ _('Save') }" rel="tooltip" data-placement="bottom" data-loading-text="${ _("Saving...") }"
-        data-bind="click: saveNotebook, css: {'btn': true}">
-      <i class="fa fa-save"></i>
-    </a>
+   &nbsp;&nbsp;&nbsp;
 
-    &nbsp;&nbsp;&nbsp;
+   <a class="btn" title="${ _('Save') }" rel="tooltip" data-placement="bottom" data-loading-text="${ _("Saving...") }"
+      data-bind="click: saveNotebook, css: {'btn': true}">
+     <i class="fa fa-save"></i>
+   </a>
 
-    <a class="btn" href="${ url('spark:new') }" title="${ _('New Notebook') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}">
-      <i class="fa fa-file-o"></i>
-    </a>
+   &nbsp;&nbsp;&nbsp;
 
-    <a class="btn" href="${ url('spark:notebooks') }" title="${ _('Notebooks') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}">
-      <i class="fa fa-tags"></i>
-    </a>
+   <a class="btn" href="${ url('spark:new') }" title="${ _('New Notebook') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}">
+     <i class="fa fa-file-o"></i>
+   </a>
+
+   <a class="btn" href="${ url('spark:notebooks') }" title="${ _('Notebooks') }" rel="tooltip" data-placement="bottom" data-bind="css: {'btn': true}">
+     <i class="fa fa-tags"></i>
+   </a>
   </div>
 
 
@@ -666,6 +671,9 @@ ${ commonheader(_('Query'), app_name, user, "68px") | n,unicode }
         ${ _('Loading...') }
       </div>
     </div>
+
+    <span data-bind="text: ko.mapping.toJSON(properties)"></span>
+
   </div>
 </script>
 
@@ -695,6 +703,33 @@ ${ commonheader(_('Query'), app_name, user, "68px") | n,unicode }
 </div>
 
 
+<div id="sessionsDemiModal" class="demi-modal fade" data-backdrop="false">
+  <a href="javascript: void(0)" data-dismiss="modal" class="pull-right" style="margin: 10px"><i class="fa fa-times"></i></a>
+  <div class="modal-body">
+    <div class="row-fluid">
+      <div class="span12">
+        <!-- ko if: $root.selectedNotebook() -->
+        <form class="form-horizontal">
+          <fieldset>
+            <legend><i class="fa fa-cloud"></i> ${ _('Sessions') }</legend>
+            
+            <div class="control-group" data-bind="foreach: $root.selectedNotebook().sessions">
+              <label class="control-label">${ _('Content') }</label>
+              <div class="controls">
+                <span data-bind="text: ko.mapping.toJSON($data)"></span>
+              </div>
+            </div>
+            </br>
+          </fieldset>
+        </form>
+        <!-- /ko -->
+      </div>
+    </div>
+
+  </div>
+  <div><a class="pointer demi-modal-chevron" data-dismiss="modal"><i class="fa fa-chevron-up"></i></a></div>
+</div>
+
 
 ${ koComponents.assistPanel() }