浏览代码

[zookeeper] Porting to current master

Support only one cluster for now.
Need restlying.
Need to change url zookeeper ids by just cluster name.
Need to i18m.
Romain Rigaux 12 年之前
父节点
当前提交
23eff10
共有 38 个文件被更改,包括 651 次插入652 次删除
  1. 4 2
      apps/Makefile
  2. 1 0
      apps/zookeeper/Makefile
  3. 1 0
      apps/zookeeper/hueversion.py
  4. 8 24
      apps/zookeeper/setup.py
  5. 0 32
      apps/zookeeper/src/zkui/static/bootstrap.js
  6. 0 62
      apps/zookeeper/src/zkui/static/css/zkui.css
  7. 0 50
      apps/zookeeper/src/zkui/static/js/Source/Zkui/Zkui.js
  8. 0 5
      apps/zookeeper/src/zkui/static/js/package.yml
  9. 0 33
      apps/zookeeper/src/zkui/templates/clients.mako
  10. 0 17
      apps/zookeeper/src/zkui/templates/create.mako
  11. 0 17
      apps/zookeeper/src/zkui/templates/edit.mako
  12. 0 37
      apps/zookeeper/src/zkui/templates/index.mako
  13. 0 53
      apps/zookeeper/src/zkui/templates/shared_components.mako
  14. 0 58
      apps/zookeeper/src/zkui/templates/tree.mako
  15. 5 5
      apps/zookeeper/src/zookeeper/__init__.py
  16. 39 0
      apps/zookeeper/src/zookeeper/conf.py
  17. 8 6
      apps/zookeeper/src/zookeeper/forms.py
  18. 5 6
      apps/zookeeper/src/zookeeper/models.py
  19. 10 12
      apps/zookeeper/src/zookeeper/rest.py
  20. 9 17
      apps/zookeeper/src/zookeeper/settings.py
  21. 0 0
      apps/zookeeper/src/zookeeper/static/art/icon_24.png
  22. 0 0
      apps/zookeeper/src/zookeeper/static/art/line_icons.png
  23. 59 0
      apps/zookeeper/src/zookeeper/static/css/zookeeper.css
  24. 0 0
      apps/zookeeper/src/zookeeper/static/help/index.html
  25. 11 9
      apps/zookeeper/src/zookeeper/stats.py
  26. 56 0
      apps/zookeeper/src/zookeeper/templates/clients.mako
  27. 42 0
      apps/zookeeper/src/zookeeper/templates/create.mako
  28. 42 0
      apps/zookeeper/src/zookeeper/templates/edit.mako
  29. 62 0
      apps/zookeeper/src/zookeeper/templates/index.mako
  30. 43 0
      apps/zookeeper/src/zookeeper/templates/shared_components.mako
  31. 83 0
      apps/zookeeper/src/zookeeper/templates/tree.mako
  32. 34 9
      apps/zookeeper/src/zookeeper/templates/view.mako
  33. 15 13
      apps/zookeeper/src/zookeeper/urls.py
  34. 19 10
      apps/zookeeper/src/zookeeper/utils.py
  35. 61 56
      apps/zookeeper/src/zookeeper/views.py
  36. 10 8
      apps/zookeeper/src/zookeeper/windmilltests.py
  37. 12 52
      desktop/conf.dist/hue.ini
  38. 12 59
      desktop/conf/pseudo-distributed.ini.tmpl

+ 4 - 2
apps/Makefile

@@ -44,7 +44,8 @@ APPS := about \
   pig \
   pig \
   search \
   search \
   hbase \
   hbase \
-  sqoop
+  sqoop \
+  zookeeper
 
 
 ################################################
 ################################################
 # Install all applications into the Desktop environment
 # Install all applications into the Desktop environment
@@ -117,7 +118,8 @@ I18N_APPS := about \
   pig \
   pig \
   search \
   search \
   hbase \
   hbase \
-  sqoop
+  sqoop \
+  zookeeper
 
 
 COMPILE_LOCALE_TARGETS := $(I18N_APPS:%=.recursive-compile-locales/%)
 COMPILE_LOCALE_TARGETS := $(I18N_APPS:%=.recursive-compile-locales/%)
 compile-locales: $(COMPILE_LOCALE_TARGETS)
 compile-locales: $(COMPILE_LOCALE_TARGETS)

+ 1 - 0
apps/zookeeper/Makefile

@@ -13,6 +13,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
+
 ifeq ($(ROOT),)
 ifeq ($(ROOT),)
   $(error "Error: Expect the environment variable $$ROOT to point to the Desktop installation")
   $(error "Error: Expect the environment variable $$ROOT to point to the Desktop installation")
 endif
 endif

+ 1 - 0
apps/zookeeper/hueversion.py

@@ -0,0 +1 @@
+../../VERSION

+ 8 - 24
apps/zookeeper/setup.py

@@ -13,34 +13,18 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
-from setuptools import setup, find_packages
-import os
 
 
-def expand_package_data(src_dirs, strip=""):
-  ret = []
-  for src_dir in src_dirs:
-    for path, dnames, fnames in os.walk(src_dir):
-      for fname in fnames:
-        ret.append(os.path.join(path, fname).replace(strip, ""))
-  return ret
+from setuptools import setup, find_packages
+from hueversion import VERSION
 
 
-os.chdir(os.path.dirname(os.path.abspath(__file__)))
 setup(
 setup(
-  name = "zkui",
-  version = "0.1",
-  url = 'http://github.com/andreisavu/hue',
-  description = 'ZooKeeper Browser',
+  name = "zookeeper",
+  version = VERSION,
+  author = "Hue",
+  url = 'http://github.com/cloudera/hue',
+  description = "ZooKeeper Browser",
   packages = find_packages('src'),
   packages = find_packages('src'),
   package_dir = {'': 'src'},
   package_dir = {'': 'src'},
   install_requires = ['setuptools', 'desktop'],
   install_requires = ['setuptools', 'desktop'],
-  entry_points = { 'desktop.sdk.application': 'zkui=zkui' },
-  zip_safe = False,
-  package_data = {
-    # Include static resources.  Package_data doesn't
-    # deal well with directory globs, so we enumerate
-    # the files manually.
-    'zkui': expand_package_data(
-      ["src/zkui/templates", "src/zkui/static"],
-      "src/zkui/")
-  }
+  entry_points = { 'desktop.sdk.application': 'zookeeper=zookeeper' },
 )
 )

+ 0 - 32
apps/zookeeper/src/zkui/static/bootstrap.js

@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-CCS.Desktop.register({
-	Zkui : {
-		name : 'ZooKeeper Browser',
-		css : '/zkui/static/css/zkui.css',
-		require: [ 'Zkui' ],
-		launch: function(path, options){
-			return new Zkui(path || '/zkui/', options);
-		},
-		menu: {
-			id: 'ccs-zkui-menu',
-			img: {
-				src: '/zkui/static/art/zkui.png'
-			}
-		},
-		help: '/help/zkui/'
-	}
-});

+ 0 - 62
apps/zookeeper/src/zkui/static/css/zkui.css

@@ -1,62 +0,0 @@
-/* 
-	zkui styles
-	important: these should be namespaced
-	example:
-		let's say you are creating an app called "calculator"; you should prefix all your styles with your application's name like so
-		
-		.calculator img {
-			border: 1px solid #000;
-		}
-		.calculator p {
-			margin: 10px 0px;
-		}
-		etc...
-
-	other notes:
-	* don't use ids - there may be more than one of your apps open; use classes!
-	* the toolbar element is absolutely positioned and 100% wide (and therefor 0px high);
-	  any elements inside it should also be absolutely positioned
-*/
-
-.zkui img.zkui_icon {
-	width: 55px;
-	height: 55px;
-	position: absolute;
-	top: 27px;
-	left: 3px;
-}
-
-div.zkui .left_col li {
-    margin: 5px 0px;
-    font-size: 16px;
-    background-color: white;
-    color: black;
-    padding: 2px 1px 1px 5px;
-    -moz-border-radius: 3px;
-    -webkit-border-radius: 3px;
-    border: solid black 1px;
-}
-
-div.zkui .left_col li:hover {
-    background-color: lightBlue;
-    color: white;
-}
-
-div.zkui .left_col li a {
-    color: black;
-    display: block;
-}
-
-div.zkui .left_col li a:hover {
-    text-decoration: none;
-}
-
-div.zkui td a.delete {
-//  background: url(/zkui/static/art/line_icons.png) no-repeat 0 -70px;
-}
-
-div.zkui .createZnodeForm td,
-div.zkui .editZnodeForm td {
-  padding: 5px;
-}
-

+ 0 - 50
apps/zookeeper/src/zkui/static/js/Source/Zkui/Zkui.js

@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-/*
----
-
-script: Zkui.js
-
-description: Defines Zkui; a Hue application that extends CCS.JBrowser.
-
-authors:
-- Unknown
-
-requires:
-- ccs-shared/CCS.JBrowser
-
-provides: [Zkui]
-
-...
-*/
-ART.Sheet.define('window.art.browser.zkui', {
-	'min-width': 620
-});
-
-var Zkui = new Class({
-
-	Extends: CCS.JBrowser,
-
-	options: {
-		className: 'art browser logo_header zkui'
-	},
-
-	initialize: function(path, options){
-		this.parent(path || '/zkui/', options);
-	}
-
-});

+ 0 - 5
apps/zookeeper/src/zkui/static/js/package.yml

@@ -1,5 +0,0 @@
-copyright: Apache License v2.0
-version: 0.1
-description: ZooKeeper Browser
-name: ZooKeeper Browser
-sources: [Source/Zkui/Zkui.js]

+ 0 - 33
apps/zookeeper/src/zkui/templates/clients.mako

@@ -1,33 +0,0 @@
-<%namespace name="shared" file="shared_components.mako" />
-
-${shared.header("ZooKeeper Browser > Clients > %s:%s" % (host, port))}
-
-<h1>${host}:${port} :: client connections</h1>
-<br />
-
-% if clients:
-  <table data-filters="HtmlTable"> 
-  <thead>
-    <tr>
-      <th>Host</th>
-      <th>Port</th>
-      <th>Interest Ops</th>
-      <th>Queued</th>
-      <th>Received</th>
-      <th>Sent</th>
-  </thead>
-  % for client in clients:
-    <tr>
-      <td>${client.host}</td>
-      <td>${client.port}</td>
-      <td>${client.interest_ops}</td>
-      <td>${client.queued}</td>
-      <td>${client.recved}</td>
-      <td>${client.sent}</td>
-    </tr>
-  % endfor
-  </table>
-% endif
-
-${shared.footer()}
-

+ 0 - 17
apps/zookeeper/src/zkui/templates/create.mako

@@ -1,17 +0,0 @@
-<%namespace name="shared" file="shared_components.mako" />
-
-${shared.header("ZooKeeper Browser > Create Znode")}
-
-<h2>Create New Znode :: ${path}</h2>
-<hr /><br />
-
-<form class="createZnodeForm" action="" method="POST">
-<table align="center">
-  ${form.as_table()|n}
-<tr><td colspan="2" align="right">
-  <button type="submit">Create</button>
-</td></tr>
-</table>
-</form>
-
-${shared.footer()}

+ 0 - 17
apps/zookeeper/src/zkui/templates/edit.mako

@@ -1,17 +0,0 @@
-<%namespace name="shared" file="shared_components.mako" />
-
-${shared.header("ZooKeeper Browser > Edit Znode > %s" % path)}
-
-<h2>Edit Znode Data :: ${path}</h2>
-<hr /><br />
-
-<form class="editZnodeForm" action="" method="POST">
-<table align="center">
-  ${form.as_table()|n}
-<tr><td colspan="2" align="right">
-  <button type="submit">Save</button>
-</td></tr>
-</table>
-</form>
-
-${shared.footer()}

+ 0 - 37
apps/zookeeper/src/zkui/templates/index.mako

@@ -1,37 +0,0 @@
-<%namespace name="shared" file="shared_components.mako" />
-
-${shared.header("ZooKeeper Browser")}
-
-<h2>Overview</h2>
-
-<br />
-
-% for i, c in enumerate(overview):
-  <h3> ${i+1}. <a href="${url('zkui.views.view', id=i)}">${c['nice_name']} Cluster Overview</a></h3><br />
-
-  <table data-filters="HtmlTable">
-  <thead>
-    <tr>
-      <th>Node</th>
-      <th>Role</th>
-      <th>Avg Latency</th>
-      <th>Watch Count</th>
-      <th>Version</th>
-    </tr>
-  </thead>
-  % for host, stats in c['stats'].items():
-    <tr>
-      <td>${host}</td>
-      <td>${stats.get('zk_server_state', '')}</td>
-      <td>${stats.get('zk_avg_latency', '')}</td>
-      <td>${stats.get('zk_watch_count', '')}</td>
-      <td>${stats.get('zk_version', '')}</td>
-    </tr>
-  % endfor
-  </table>
-
-  <br /><br />
-% endfor 
-
-${shared.footer()}
-

+ 0 - 53
apps/zookeeper/src/zkui/templates/shared_components.mako

@@ -1,53 +0,0 @@
-<%!
-#declare imports here, for example:
-#import datetime
-%>
-
-<%!
-import datetime
-from django.template.defaultfilters import urlencode, escape
-from zkui import settings
-%>
-
-<%def name="header(title='ZooKeeper Browser', toolbar=True)">
-  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
-  <html>
-    <head>
-      <title>${title}</title>
-    </head>
-    <body>
-      % if toolbar:
-      <div class="toolbar">
-        <a href="${url('zkui.views.index')}"><img src="/zkui/static/art/zkui.png" class="zkui_icon"/></a>
-      </div>
-      % endif
-
-    <div data-filters="SplitView">
-    <div class="left_col jframe_padded" style="width:150px;">
-        <ul>
-          <li><a href="${url("zkui.views.index")}">Overview</a></li>
-        </ul>
-        <br />
-
-        <h2>Clusters</h2>
-        <ul>
-            % for id, c in enumerate(settings.CLUSTERS):
-                <li><a href="${url("zkui.views.view", id=id)}">
-                    ${c['nice_name']}</a></li>
-            % endfor
-        </ul>
-    </div>
-
-    <div class="right_col jframe_padded">
-</%def>
-
-<%def name="info_button(url, text)">
-  <a data-filters="ArtButton" href="${url}" style="background: url(/static/art/info.png) left 50%; padding: 6px 6px 6px 20px; margin: 10px;" data-icon-styles="{'width': 14, 'height': 14}">${text}</a>
-</%def>
-
-<%def name="footer()">
-        </div>
-    </div>
-    </body>
-  </html>
-</%def>

+ 0 - 58
apps/zookeeper/src/zkui/templates/tree.mako

@@ -1,58 +0,0 @@
-<%namespace name="shared" file="shared_components.mako" />
-
-${shared.header("ZooKeeper Browser > Tree > %s > %s" % (cluster['nice_name'], path))}
-
-<h1>${cluster['nice_name'].lower()} :: ${path}</h1>
-<br />
-
-<table data-filters="HtmlTable">
-  <thead>
-  <th colspan="2">Children</th>
-  </thead>
-  % for child in children:
-    <tr><td width="100%">
-      <a href="${url('zkui.views.tree', id=cluster['id'], \
-          path=("%s/%s" % (path, child)).replace('//', '/'))}">
-      ${child}</a>
-    </td><td>
-      <a title="Delete ${child}" class="delete frame_tip confirm_and_post" alt="Are you sure you want to delete ${child}?" href="${url('zkui.views.delete', id=cluster['id'], \
-          path=("%s/%s" % (path, child)).replace('//', '/'))}">Delete</a>
-    </td></tr>
-  % endfor
-</table>
-<br />
-<span style="float: right">
-  ${shared.info_button(url('zkui.views.create', id=cluster['id'], path=path), 'Create New')}
-</span>
-
-<div style="clear: both"></div>
-
-<h2>data :: base64 :: length :: ${znode.get('dataLength', 0)}</h2>
-<br />
-
-<textarea name="data64" style="width: 100%;" rows="5" readonly="readonly">${znode.get('data64', '')}</textarea>
-<div style="clear: both"></div>
-<span style="float: right">
-  ${shared.info_button(url('zkui.views.edit_as_base64', id=cluster['id'], path=path), 'Edit as Base64')}
-  ${shared.info_button(url('zkui.views.edit_as_text', id=cluster['id'], path=path), 'Edit as Text')}
-</span>
-<div style="clear: both"></div>
-<br />
-
-<h2>stat information</h2>
-<br />
-
-<table data-filters="HtmlTable">
-  <thead><tr><th>Key</th>
-    <th width="80%">Value</th></tr></thead>
-  % for key in ('pzxid', 'ctime', 'aversion', 'mzxid', \
-      'ephemeralOwner', 'version', 'mtime', 'cversion', 'czxid'):
-    <tr><td>${key}</td><td>${znode[key]}</td></tr> 
-  % endfor
-</table>
-
-<br />
-<a target="_blank" href="http://hadoop.apache.org/zookeeper/docs/current/zookeeperProgrammers.html#sc_zkStatStructure">Details on stat information.</a>
-
-${shared.footer()}
-

+ 5 - 5
apps/zookeeper/src/zkui/__init__.py → apps/zookeeper/src/zookeeper/__init__.py

@@ -1,16 +1,16 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
-

+ 39 - 0
apps/zookeeper/src/zookeeper/conf.py

@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
+# to you 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 desktop.lib.conf import Config, UnspecifiedConfigSection, ConfigSection, validate_path, coerce_bool
+
+
+CLUSTERS = UnspecifiedConfigSection(
+  "clusters",
+  help="One entry for each Zookeeper cluster",
+  each=ConfigSection(
+    help="Information about a single Zookeeper cluster",
+    members=dict(
+      HOST_PORTS=Config(
+          "host_ports",
+          help="Zookeeper ensemble. Comma separated list of Host/Port, e.g. localhost:2181,localhost:2182,localhost:2183",
+          default="localhost:2181",
+      ),
+      REST_URL=Config(
+          "rest_url",
+          help="The URL of the REST contrib service.",
+          default="http://localhost:9998",
+      ),
+    )
+  )
+)

+ 8 - 6
apps/zookeeper/src/zkui/forms.py → apps/zookeeper/src/zookeeper/forms.py

@@ -1,29 +1,31 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
 
 
+
 from django import forms
 from django import forms
 from django.forms.widgets import Textarea, HiddenInput
 from django.forms.widgets import Textarea, HiddenInput
 
 
+
 class CreateZNodeForm(forms.Form):
 class CreateZNodeForm(forms.Form):
   name = forms.CharField(max_length=64)
   name = forms.CharField(max_length=64)
   data = forms.CharField(required=False, widget=Textarea)
   data = forms.CharField(required=False, widget=Textarea)
   sequence = forms.BooleanField(required=False)
   sequence = forms.BooleanField(required=False)
 
 
+
 class EditZNodeForm(forms.Form):
 class EditZNodeForm(forms.Form):
   data = forms.CharField(required=False, widget=Textarea)
   data = forms.CharField(required=False, widget=Textarea)
   version = forms.IntegerField(required=False, widget=HiddenInput)
   version = forms.IntegerField(required=False, widget=HiddenInput)
-  
-

+ 5 - 6
apps/zookeeper/src/zkui/models.py → apps/zookeeper/src/zookeeper/models.py

@@ -1,17 +1,16 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
-
-

+ 10 - 12
apps/zookeeper/src/zkui/rest.py → apps/zookeeper/src/zookeeper/rest.py

@@ -1,8 +1,8 @@
-
-# Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
@@ -21,6 +21,7 @@ import simplejson
 
 
 from contextlib import contextmanager
 from contextlib import contextmanager
 
 
+
 class RequestWithMethod(urllib2.Request):
 class RequestWithMethod(urllib2.Request):
     """ Request class that know how to set the method name """
     """ Request class that know how to set the method name """
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
@@ -34,6 +35,7 @@ class RequestWithMethod(urllib2.Request):
     def set_method(self, method):
     def set_method(self, method):
         self._method = method
         self._method = method
 
 
+
 class ZooKeeper(object):
 class ZooKeeper(object):
 
 
     class Error(Exception): pass
     class Error(Exception): pass
@@ -46,7 +48,7 @@ class ZooKeeper(object):
 
 
     class WrongVersion(Error): pass
     class WrongVersion(Error): pass
 
 
-    def __init__(self, uri = 'http://localhost:9998'):
+    def __init__(self, uri='http://localhost:9998'):
         self._base = uri
         self._base = uri
         self._session = None
         self._session = None
 
 
@@ -98,7 +100,7 @@ class ZooKeeper(object):
         for child in resp.get('children', []):
         for child in resp.get('children', []):
             yield child if not uris else resp['child_uri_template']\
             yield child if not uris else resp['child_uri_template']\
               .replace('{child}', urllib2.quote(child))
               .replace('{child}', urllib2.quote(child))
-       
+
     def create(self, path, data=None, sequence=False, ephemeral=False):
     def create(self, path, data=None, sequence=False, ephemeral=False):
         """ Create a new node. By default this call creates a persistent znode.
         """ Create a new node. By default this call creates a persistent znode.
 
 
@@ -117,19 +119,16 @@ class ZooKeeper(object):
             if self._session:
             if self._session:
                 flags['session'] = self._session
                 flags['session'] = self._session
             else:
             else:
-                raise ZooKeeper.Error, 'You need a session '\
-                    'to create an ephemeral node'
+                raise ZooKeeper.Error, 'You need a session to create an ephemeral node'
         flags = urllib.urlencode(flags)
         flags = urllib.urlencode(flags)
 
 
-        url = "%s/znodes/v1%s?op=create&name=%s&%s" % \
-            (self._base, head, name, flags)
+        url = "%s/znodes/v1%s?op=create&name=%s&%s" % (self._base, head, name, flags)
 
 
         return self._do_post(url, data)
         return self._do_post(url, data)
 
 
     def set(self, path, data=None, version=-1, null=False):
     def set(self, path, data=None, version=-1, null=False):
         """ Set the value of node """
         """ Set the value of node """
-        url = "%s/znodes/v1%s?%s" % (self._base, path, \
-            urllib.urlencode({
+        url = "%s/znodes/v1%s?%s" % (self._base, path, urllib.urlencode({
                 'version': version,
                 'version': version,
                 'null': 'true' if null else 'false'
                 'null': 'true' if null else 'false'
         }))
         }))
@@ -227,4 +226,3 @@ class ZooKeeper(object):
             if e.code == 412: # precondition failed
             if e.code == 412: # precondition failed
                 raise ZooKeeper.WrongVersion(uri)
                 raise ZooKeeper.WrongVersion(uri)
             raise
             raise
-

+ 9 - 17
apps/zookeeper/src/zkui/settings.py → apps/zookeeper/src/zookeeper/settings.py

@@ -1,30 +1,22 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
 
 
-DJANGO_APPS = [ "zkui" ]
+DJANGO_APPS = [ "zookeeper" ]
 NICE_NAME = "ZooKeeper Browser"
 NICE_NAME = "ZooKeeper Browser"
-REQUIRES_HADOOP = False
-
-CLUSTERS = [{
-        'nice_name': 'Default',
-        'hostport': 'localhost:2181,localhost:2182,localhost:2183',
-        'rest_gateway': 'http://localhost:9998'
-    }
-]
-
-DEPENDER_PACKAGE_YMLS = [
-    "src/zkui/static/js/package.yml",
-]
+MENU_INDEX = 58
+ICON = '/zookeeper/static/art/icon_24.png'
+IS_URL_NAMESPACED = True

+ 0 - 0
apps/zookeeper/src/zkui/static/art/zkui.png → apps/zookeeper/src/zookeeper/static/art/icon_24.png


+ 0 - 0
apps/zookeeper/src/zkui/static/art/line_icons.png → apps/zookeeper/src/zookeeper/static/art/line_icons.png


+ 59 - 0
apps/zookeeper/src/zookeeper/static/css/zookeeper.css

@@ -0,0 +1,59 @@
+/*
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+*/
+
+.zookeeper img.zookeeper_icon {
+	width: 55px;
+	height: 55px;
+	position: absolute;
+	top: 27px;
+	left: 3px;
+}
+
+div.zookeeper .left_col li {
+    margin: 5px 0px;
+    font-size: 16px;
+    background-color: white;
+    color: black;
+    padding: 2px 1px 1px 5px;
+    -moz-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    border: solid black 1px;
+}
+
+div.zookeeper .left_col li:hover {
+    background-color: lightBlue;
+    color: white;
+}
+
+div.zookeeper .left_col li a {
+    color: black;
+    display: block;
+}
+
+div.zookeeper .left_col li a:hover {
+    text-decoration: none;
+}
+
+div.zookeeper td a.delete {
+//  background: url(/zookeeper/static/art/line_icons.png) no-repeat 0 -70px;
+}
+
+div.zookeeper .createZnodeForm td,
+div.zookeeper .editZnodeForm td {
+  padding: 5px;
+}

+ 0 - 0
apps/zookeeper/src/zkui/static/help/index.html → apps/zookeeper/src/zookeeper/static/help/index.html


+ 11 - 9
apps/zookeeper/src/zkui/stats.py → apps/zookeeper/src/zookeeper/stats.py

@@ -1,13 +1,14 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,6 +20,7 @@ import re
 
 
 from StringIO import StringIO
 from StringIO import StringIO
 
 
+
 class Session(object):
 class Session(object):
 
 
   class BrokenLine(Exception): pass
   class BrokenLine(Exception): pass
@@ -33,7 +35,8 @@ class Session(object):
             k,v = d.split("=")
             k,v = d.split("=")
             self.__dict__[k] = v
             self.__dict__[k] = v
     else:
     else:
-        raise Session.BrokenLine() 
+        raise Session.BrokenLine()
+
 
 
 class ZooKeeperStats(object):
 class ZooKeeperStats(object):
 
 
@@ -93,7 +96,7 @@ class ZooKeeperStats(object):
     def _parse(self, data):
     def _parse(self, data):
         """ Parse the output from the 'mntr' 4letter word command """
         """ Parse the output from the 'mntr' 4letter word command """
         h = StringIO(data)
         h = StringIO(data)
-        
+
         result = {}
         result = {}
         for line in h.readlines():
         for line in h.readlines():
             try:
             try:
@@ -109,7 +112,7 @@ class ZooKeeperStats(object):
         h = StringIO(data)
         h = StringIO(data)
 
 
         result = {}
         result = {}
-        
+
         version = h.readline()
         version = h.readline()
         if version:
         if version:
             result['zk_version'] = version[version.index(':')+1:].strip()
             result['zk_version'] = version[version.index(':')+1:].strip()
@@ -150,7 +153,7 @@ class ZooKeeperStats(object):
                 result['zk_znode_count'] = int(m.group(1))
                 result['zk_znode_count'] = int(m.group(1))
                 continue
                 continue
 
 
-        return result 
+        return result
 
 
     def _parse_line(self, line):
     def _parse_line(self, line):
         try:
         try:
@@ -167,4 +170,3 @@ class ZooKeeperStats(object):
             pass
             pass
 
 
         return key, value
         return key, value
-

+ 56 - 0
apps/zookeeper/src/zookeeper/templates/clients.mako

@@ -0,0 +1,56 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="shared" file="shared_components.mako" />
+
+${ commonheader(_('Clients'), app_name, user, '100px') | n,unicode }
+${ shared.header("ZooKeeper Browser > Clients > %s:%s" % (host, port)) }
+
+<h1>${host}:${port} :: client connections</h1>
+<br />
+
+% if clients:
+  <table data-filters="HtmlTable">
+  <thead>
+    <tr>
+      <th>Host</th>
+      <th>Port</th>
+      <th>Interest Ops</th>
+      <th>Queued</th>
+      <th>Received</th>
+      <th>Sent</th>
+  </thead>
+  % for client in clients:
+    <tr>
+      <td>${client.host}</td>
+      <td>${client.port}</td>
+      <td>${client.interest_ops}</td>
+      <td>${client.queued}</td>
+      <td>${client.recved}</td>
+      <td>${client.sent}</td>
+    </tr>
+  % endfor
+  </table>
+% endif
+
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 42 - 0
apps/zookeeper/src/zookeeper/templates/create.mako

@@ -0,0 +1,42 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="shared" file="shared_components.mako" />
+
+${ commonheader("ZooKeeper Browser > Create Znode", app_name, user, '100px') | n,unicode }
+${ shared.header(clusters) }
+
+<h2>Create New Znode :: ${path}</h2>
+<hr /><br />
+
+<form class="createZnodeForm" action="" method="POST">
+  <table align="center">
+    ${form.as_table()|n}
+    <tr><td colspan="2" align="right">
+    <button type="submit">Create</button>
+    </td></tr>
+  </table>
+</form>
+
+
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 42 - 0
apps/zookeeper/src/zookeeper/templates/edit.mako

@@ -0,0 +1,42 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="shared" file="shared_components.mako" />
+
+${ commonheader("ZooKeeper Browser > Edit Znode > %s" % path, app_name, user, '100px') | n,unicode }
+${ shared.header(clusters) }
+
+<h2>Edit Znode Data :: ${path}</h2>
+<hr /><br />
+
+<form class="editZnodeForm" action="" method="POST">
+  <table align="center">
+    ${form.as_table()|n}
+    <tr><td colspan="2" align="right">
+    <button type="submit">Save</button>
+    </td></tr>
+  </table>
+</form>
+
+
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 62 - 0
apps/zookeeper/src/zookeeper/templates/index.mako

@@ -0,0 +1,62 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="shared" file="shared_components.mako" />
+
+${ commonheader(_('View'), app_name, user, '100px') | n,unicode }
+${ shared.header(clusters) }
+
+
+<h2>Overview</h2>
+
+<br />
+
+% for i, c in enumerate(clusters):
+  <h3> ${ i + 1 }. <a href="${ url('zookeeper:view', id=i) }">${ c } Cluster Overview</a></h3><br />
+
+  <table data-filters="HtmlTable">
+  <thead>
+    <tr>
+      <th>Node</th>
+      <th>Role</th>
+      <th>Avg Latency</th>
+      <th>Watch Count</th>
+      <th>Version</th>
+    </tr>
+  </thead>
+  % for host, stats in overview[c].items():
+    <tr>
+      <td><a href="${ url('zookeeper:view', id=i) }" data-row-selector="true">${ host }</a></td>
+      <td>${stats.get('zk_server_state', '')}</td>
+      <td>${stats.get('zk_avg_latency', '')}</td>
+      <td>${stats.get('zk_watch_count', '')}</td>
+      <td>${stats.get('zk_version', '')}</td>
+    </tr>
+  % endfor
+  </table>
+
+  <br /><br />
+% endfor
+
+
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 43 - 0
apps/zookeeper/src/zookeeper/templates/shared_components.mako

@@ -0,0 +1,43 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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.template.defaultfilters import urlencode, escape
+%>
+
+<%def name="header(clusters)">
+    <div data-filters="SplitView">
+    <div class="left_col jframe_padded" style="width:150px;">
+        <h2>Clusters</h2>
+        <ul>
+            % for id, c in enumerate(clusters):
+                <li>
+                  <a href="${ url('zookeeper:view', id=id) }">
+                    ${ c }
+                  </a>
+                </li>
+            % endfor
+        </ul>
+    </div>
+</%def>
+
+
+<%def name="info_button(url, text)">
+  <a data-filters="ArtButton" href="${url}" style="background: url(/static/art/info.png) left 50%; padding: 6px 6px 6px 20px; margin: 10px;"
+    data-icon-styles="{'width': 14, 'height': 14}">
+      ${text}
+  </a>
+</%def>

+ 83 - 0
apps/zookeeper/src/zookeeper/templates/tree.mako

@@ -0,0 +1,83 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
+<%namespace name="shared" file="shared_components.mako" />
+
+${ commonheader("ZooKeeper Browser > Tree > %s > %s" % (cluster['nice_name'], path), app_name, user, '100px') | n,unicode }
+${ shared.header(clusters) }
+
+
+<h1>${cluster['nice_name'].lower()} :: ${path}</h1>
+<br />
+
+<table data-filters="HtmlTable">
+  <thead>
+  <th colspan="2">Children</th>
+  </thead>
+  % for child in children:
+    <tr><td width="100%">
+      <a href="${url('zookeeper:tree', id=cluster['id'], \
+          path=("%s/%s" % (path, child)).replace('//', '/'))}">
+      ${child}</a>
+    </td><td>
+      <a title="Delete ${child}" class="delete frame_tip confirm_and_post" alt="Are you sure you want to delete ${child}?" href="${url('zookeeper:delete', id=cluster['id'], \
+          path=("%s/%s" % (path, child)).replace('//', '/'))}">Delete</a>
+    </td></tr>
+  % endfor
+</table>
+<br />
+<span style="float: right">
+  ${shared.info_button(url('zookeeper:create', id=cluster['id'], path=path), 'Create New')}
+</span>
+
+<div style="clear: both"></div>
+
+<h2>data :: base64 :: length :: ${znode.get('dataLength', 0)}</h2>
+<br />
+
+<textarea name="data64" style="width: 100%;" rows="5" readonly="readonly">${znode.get('data64', '')}</textarea>
+<div style="clear: both"></div>
+<span style="float: right">
+  ${shared.info_button(url('zookeeper:edit_as_base64', id=cluster['id'], path=path), 'Edit as Base64')}
+  ${shared.info_button(url('zookeeper:edit_as_text', id=cluster['id'], path=path), 'Edit as Text')}
+</span>
+<div style="clear: both"></div>
+<br />
+
+<h2>stat information</h2>
+<br />
+
+<table data-filters="HtmlTable">
+  <thead><tr><th>Key</th>
+    <th width="80%">Value</th></tr></thead>
+  % for key in ('pzxid', 'ctime', 'aversion', 'mzxid', \
+      'ephemeralOwner', 'version', 'mtime', 'cversion', 'czxid'):
+    <tr><td>${key}</td><td>${znode[key]}</td></tr>
+  % endfor
+</table>
+
+<br />
+<a target="_blank" href="http://hadoop.apache.org/zookeeper/docs/current/zookeeperProgrammers.html#sc_zkStatStructure">Details on stat information.</a>
+
+
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 34 - 9
apps/zookeeper/src/zkui/templates/view.mako → apps/zookeeper/src/zookeeper/templates/view.mako

@@ -1,6 +1,29 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you 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 desktop.views import commonheader, commonfooter
+  from django.utils.translation import ugettext as _
+%>
+
 <%namespace name="shared" file="shared_components.mako" />
 <%namespace name="shared" file="shared_components.mako" />
 
 
-${shared.header("ZooKeeper Browser > %s" % cluster['nice_name'])}
+${ commonheader(_('View'), app_name, user, '100px') | n,unicode }
+${ shared.header(clusters) }
+
 
 
 <%def name="show_stats(stats)">
 <%def name="show_stats(stats)">
     <thead>
     <thead>
@@ -40,11 +63,11 @@ ${shared.header("ZooKeeper Browser > %s" % cluster['nice_name'])}
       <td>${stats.get('zk_max_file_descriptor_count', '')}</td>
       <td>${stats.get('zk_max_file_descriptor_count', '')}</td>
     </tr>
     </tr>
 
 
-</%def> 
+</%def>
 
 
-<h2> ${cluster['nice_name']} Cluster Overview </h2>
+<h2> ${ cluster['nice_name'] } Cluster Overview </h2>
 
 
-${shared.info_button(url('zkui.views.tree', id=cluster['id'], path='/'), 'View Znode Hierarchy')}
+${ shared.info_button(url('zookeeper:tree', id=cluster['id'], path='/'), 'View Znode Hierarchy') }
 
 
 <br /><br />
 <br /><br />
 
 
@@ -72,12 +95,12 @@ ${shared.info_button(url('zkui.views.tree', id=cluster['id'], path='/'), 'View Z
 % if leader:
 % if leader:
   <h2>node :: ${leader['host']} :: leader</h2>
   <h2>node :: ${leader['host']} :: leader</h2>
 
 
-  ${shared.info_button(url('zkui.views.clients', host=leader['host']), 'View Client Connections')}
+  ${shared.info_button(url('zookeeper:clients', host=leader['host']), 'View Client Connections')}
 
 
   <br /><br />
   <br /><br />
   <table data-filters="HtmlTable">
   <table data-filters="HtmlTable">
     ${show_stats(leader)}
     ${show_stats(leader)}
-    
+
     <tr><td>Followers</td>
     <tr><td>Followers</td>
       <td>${leader.get('zk_followers', '')}</td>
       <td>${leader.get('zk_followers', '')}</td>
     </tr>
     </tr>
@@ -89,7 +112,7 @@ ${shared.info_button(url('zkui.views.tree', id=cluster['id'], path='/'), 'View Z
     <tr><td>Pending Syncs</td>
     <tr><td>Pending Syncs</td>
       <td>${leader.get('zk_pending_syncs', '')}</td>
       <td>${leader.get('zk_pending_syncs', '')}</td>
     </tr>
     </tr>
-  
+
   </table>
   </table>
 <br /><br />
 <br /><br />
 % endif
 % endif
@@ -98,7 +121,7 @@ ${shared.info_button(url('zkui.views.tree', id=cluster['id'], path='/'), 'View Z
   <h2>node :: ${stats['host']} :: follower</h2>
   <h2>node :: ${stats['host']} :: follower</h2>
   <br />
   <br />
 
 
-  ${shared.info_button(url('zkui.views.clients', host=stats['host']), 'View Client Connections')}
+  ${shared.info_button(url('zookeeper:clients', host=stats['host']), 'View Client Connections')}
 
 
   <br /><br />
   <br /><br />
   <table data-filters="HtmlTable">
   <table data-filters="HtmlTable">
@@ -107,5 +130,7 @@ ${shared.info_button(url('zkui.views.tree', id=cluster['id'], path='/'), 'View Z
   <br /><br />
   <br /><br />
 % endfor
 % endfor
 
 
-${shared.footer()}
 
 
+<link rel="stylesheet" href="/zookeeper/static/css/zookeeper.css">
+
+${ commonfooter(messages) | n,unicode }

+ 15 - 13
apps/zookeeper/src/zkui/urls.py → apps/zookeeper/src/zookeeper/urls.py

@@ -1,13 +1,14 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,13 +17,14 @@
 
 
 from django.conf.urls.defaults import patterns, url
 from django.conf.urls.defaults import patterns, url
 
 
-urlpatterns = patterns('zkui',
-  url(r'^$', 'views.index'),
-  url(r'view/(?P<id>\d+)$', 'views.view'),
-  url(r'clients/(?P<host>.+)$', 'views.clients'),
-  url(r'tree/(?P<id>\d+)(?P<path>.+)$', 'views.tree'),
-  url(r'create/(?P<id>\d+)(?P<path>.*)$', 'views.create'),
-  url(r'delete/(?P<id>\d+)(?P<path>.*)$', 'views.delete'),
-  url(r'edit/base64/(?P<id>\d+)(?P<path>.*)$', 'views.edit_as_base64'),
-  url(r'edit/text/(?P<id>\d+)(?P<path>.*)$', 'views.edit_as_text')
+
+urlpatterns = patterns('zookeeper.views',
+  url(r'^$', 'index', name='index'),
+  url(r'view/(?P<id>\d+)$', 'view', name='view'),
+  url(r'clients/(?P<host>.+)$', 'clients', name='clients'),
+  url(r'tree/(?P<id>\d+)(?P<path>.+)$', 'tree', name='tree'),
+  url(r'create/(?P<id>\d+)(?P<path>.*)$', 'create', name='create'),
+  url(r'delete/(?P<id>\d+)(?P<path>.*)$', 'delete', name='delete'),
+  url(r'edit/base64/(?P<id>\d+)(?P<path>.*)$', 'edit_as_base64', name='edit_as_base64'),
+  url(r'edit/text/(?P<id>\d+)(?P<path>.*)$', 'edit_as_text', name='edit_as_text')
 )
 )

+ 19 - 10
apps/zookeeper/src/zkui/utils.py → apps/zookeeper/src/zookeeper/utils.py

@@ -1,33 +1,42 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # limitations under the License.
 
 
-from zkui import settings
-
 from django.http import Http404
 from django.http import Http404
 
 
+from zookeeper.conf import CLUSTERS
+
+
 def get_cluster_or_404(id):
 def get_cluster_or_404(id):
   try:
   try:
     id = int(id)
     id = int(id)
-    if not (0 <= id < len(settings.CLUSTERS)):
+    if not (0 <= id < len(CLUSTERS.get())):
       raise ValueError, 'Undefined cluster id.'
       raise ValueError, 'Undefined cluster id.'
   except (TypeError, ValueError):
   except (TypeError, ValueError):
     raise Http404()
     raise Http404()
 
 
-  cluster = settings.CLUSTERS[id]
-  cluster['id'] = id
+  # Support only one cluster
+  name = [k for (k, v) in CLUSTERS.get().iteritems() if v == 0]
+  cluster = CLUSTERS.get()[k]
 
 
-  return cluster
+  cluster = {
+    'id': id,
+    'nice_name': k,
+    'host_ports': cluster.HOST_PORTS.get(),
+    'rest_url': cluster.REST_URL.get(),
+  }
 
 
+  return cluster

+ 61 - 56
apps/zookeeper/src/zkui/views.py → apps/zookeeper/src/zookeeper/views.py

@@ -1,13 +1,14 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,58 +18,69 @@
 from desktop.lib.django_util import render
 from desktop.lib.django_util import render
 from django.http import Http404
 from django.http import Http404
 
 
-from zkui import settings
-from zkui.stats import ZooKeeperStats
-from zkui.rest import ZooKeeper
-from zkui.utils import get_cluster_or_404
-from zkui.forms import CreateZNodeForm, EditZNodeForm
+from zookeeper import settings
+
+from zookeeper.conf import CLUSTERS
+from zookeeper.forms import CreateZNodeForm, EditZNodeForm
+from zookeeper.stats import ZooKeeperStats
+from zookeeper.rest import ZooKeeper
+from zookeeper.utils import get_cluster_or_404
+
 
 
 def _get_global_overview():
 def _get_global_overview():
-  overview = []
-  for c in settings.CLUSTERS:
-    overview.append(_get_overview(c))
-  return overview
+  clusters = CLUSTERS.get()
+  return dict([(c, _get_overview(clusters[c].HOST_PORTS.get())) for c in clusters])
+
 
 
-def _get_overview(cluster):
+def _get_overview(host_ports):
   stats = {}
   stats = {}
-  for s in cluster['hostport'].split(','):
+
+  for s in host_ports.split(','):
     host, port = map(str.strip, s.split(':'))
     host, port = map(str.strip, s.split(':'))
 
 
     zks = ZooKeeperStats(host, port)
     zks = ZooKeeperStats(host, port)
     stats[s] = zks.get_stats() or {}
     stats[s] = zks.get_stats() or {}
 
 
-  cluster['stats'] = stats
-  return cluster
+  return stats
 
 
-def _group_stats_by_role(cluster):
+
+def _group_stats_by_role(stats):
   leader, followers = None, []
   leader, followers = None, []
-  for host, stats in cluster['stats'].items():
+  for host, stats in stats.items():
     stats['host'] = host
     stats['host'] = host
 
 
     if stats.get('zk_server_state') == 'leader':
     if stats.get('zk_server_state') == 'leader':
       leader = stats
       leader = stats
 
 
     elif stats.get('zk_server_state') == 'follower':
     elif stats.get('zk_server_state') == 'follower':
-      followers.append(stats) 
+      followers.append(stats)
+
+  return leader, followers
+
 
 
-  return leader, followers           
- 
 def index(request):
 def index(request):
-  overview = _get_global_overview()  
-  return render('index.mako', request, 
-    dict(overview=overview))
+  overview = _get_global_overview()
+
+  return render('index.mako', request, {
+      'clusters': CLUSTERS.get(),
+      'overview': overview
+  })
+
 
 
 def view(request, id):
 def view(request, id):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
 
 
-  cluster = _get_overview(cluster)
-  leader, followers = _group_stats_by_role(cluster)
+  stats = _get_overview(cluster['host_ports'])
+  leader, followers = _group_stats_by_role(stats)
+
+  return render('view.mako', request, {
+      'cluster': cluster, 'leader': leader, 'followers': followers,
+      'clusters': CLUSTERS.get(),
+  })
 
 
-  return render('view.mako', request, 
-    dict(cluster=cluster, leader=leader, followers=followers))
 
 
 def clients(request, host):
 def clients(request, host):
-  parts = host.split(':')  
+  parts = host.split(':')
   if len(parts) != 2:
   if len(parts) != 2:
     raise Http404
     raise Http404
 
 
@@ -79,21 +91,21 @@ def clients(request, host):
   return render('clients.mako', request,
   return render('clients.mako', request,
     dict(host=host, port=port, clients=clients))
     dict(host=host, port=port, clients=clients))
 
 
+
 def tree(request, id, path):
 def tree(request, id, path):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
-  zk = ZooKeeper(cluster['rest_gateway'])
+  zk = ZooKeeper(cluster['rest_url'])
 
 
   znode = zk.get(path)
   znode = zk.get(path)
   children = sorted(zk.get_children_paths(path))
   children = sorted(zk.get_children_paths(path))
-  
-  return render('tree.mako', request,
-    dict(cluster=cluster, path=path, \
-      znode=znode, children=children))
+
+  return render('tree.mako', request, {'cluster': cluster, 'path': path, 'znode': znode, 'children': children, 'clusters': CLUSTERS.get(),})
+
 
 
 def delete(request, id, path):
 def delete(request, id, path):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
   if request.method == 'POST':
   if request.method == 'POST':
-    zk = ZooKeeper(cluster['rest_gateway'])
+    zk = ZooKeeper(cluster['rest_url'])
     try:
     try:
       zk.recursive_delete(path)
       zk.recursive_delete(path)
     except ZooKeeper.NotFound:
     except ZooKeeper.NotFound:
@@ -101,30 +113,28 @@ def delete(request, id, path):
 
 
   return tree(request, id, path[:path.rindex('/')] or '/')
   return tree(request, id, path[:path.rindex('/')] or '/')
 
 
+
 def create(request, id, path):
 def create(request, id, path):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
 
 
   if request.method == 'POST':
   if request.method == 'POST':
     form = CreateZNodeForm(request.POST)
     form = CreateZNodeForm(request.POST)
     if form.is_valid():
     if form.is_valid():
-      zk = ZooKeeper(cluster['rest_gateway'])
+      zk = ZooKeeper(cluster['rest_url'])
 
 
-      full_path = ("%s/%s" % (path, form.cleaned_data['name']))\
-        .replace('//', '/')
+      full_path = ("%s/%s" % (path, form.cleaned_data['name'])).replace('//', '/')
 
 
-      zk.create(full_path, \
-        form.cleaned_data['data'], \
-        sequence = form.cleaned_data['sequence'])
+      zk.create(full_path, form.cleaned_data['data'], sequence = form.cleaned_data['sequence'])
       return tree(request, id, path)
       return tree(request, id, path)
   else:
   else:
     form = CreateZNodeForm()
     form = CreateZNodeForm()
 
 
-  return render('create.mako', request, 
-    dict(path=path, form=form))
+  return render('create.mako', request, {'path': path, 'form': form, 'clusters': CLUSTERS.get(),})
+
 
 
 def edit_as_base64(request, id, path):
 def edit_as_base64(request, id, path):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
-  zk = ZooKeeper(cluster['rest_gateway'])
+  zk = ZooKeeper(cluster['rest_url'])
   node = zk.get(path)
   node = zk.get(path)
 
 
   if request.method == 'POST':
   if request.method == 'POST':
@@ -137,15 +147,15 @@ def edit_as_base64(request, id, path):
     return tree(request, id, path)
     return tree(request, id, path)
   else:
   else:
     form = EditZNodeForm(dict(\
     form = EditZNodeForm(dict(\
-      data=node.get('data64', ''), 
+      data=node.get('data64', ''),
       version=node.get('version', '-1')))
       version=node.get('version', '-1')))
 
 
-  return render('edit.mako', request,
-    dict(path=path, form=form))
+  return render('edit.mako', request, {'path': path, 'form': form, 'clusters': CLUSTERS.get(),})
+
 
 
 def edit_as_text(request, id, path):
 def edit_as_text(request, id, path):
   cluster = get_cluster_or_404(id)
   cluster = get_cluster_or_404(id)
-  zk = ZooKeeper(cluster['rest_gateway'])
+  zk = ZooKeeper(cluster['rest_url'])
   node = zk.get(path)
   node = zk.get(path)
 
 
   if request.method == 'POST':
   if request.method == 'POST':
@@ -155,11 +165,6 @@ def edit_as_text(request, id, path):
 
 
     return tree(request, id, path)
     return tree(request, id, path)
   else:
   else:
-    form = EditZNodeForm(dict(data=node.get('data64', '')\
-      .decode('base64').strip(), 
-      version=node.get('version', '-1')))
-
-  return render('edit.mako', request,
-    dict(path=path, form=form))
-
+    form = EditZNodeForm(dict(data=node.get('data64', '').decode('base64').strip(), version=node.get('version', '-1')))
 
 
+  return render('edit.mako', request, {'path': path, 'form': form, 'clusters': CLUSTERS.get(),})

+ 10 - 8
apps/zookeeper/src/zkui/windmilltests.py → apps/zookeeper/src/zookeeper/windmilltests.py

@@ -1,13 +1,14 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
 # or more contributor license agreements.  See the NOTICE file
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
 # distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
+# regarding copyright ownership.  Cloudera, Inc. licenses this file
 # to you under the Apache License, Version 2.0 (the
 # to you under the Apache License, Version 2.0 (the
 # "License"); you may not use this file except in compliance
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 # with the License.  You may obtain a copy of the License at
-
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
 #     http://www.apache.org/licenses/LICENSE-2.0
-
+#
 # Unless required by applicable law or agreed to in writing, software
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,8 +17,9 @@
 
 
 from desktop.lib.windmill_util import logged_in_client
 from desktop.lib.windmill_util import logged_in_client
 
 
-def test_zkui():
-  """ launches the default view for zkui """
+
+def test_zookeeper():
+  """ launches the default view for zookeeper """
   client = logged_in_client()
   client = logged_in_client()
-  client.click(id='ccs-zkui-menu')
-  client.waits.forElement(classname='CCS-ZKUI', timeout='2000')  
+  client.click(id='ccs-zookeeper-menu')
+  client.waits.forElement(classname='CCS-zookeeper', timeout='2000')

+ 12 - 52
desktop/conf.dist/hue.ini

@@ -512,60 +512,20 @@
 
 
 
 
 ###########################################################################
 ###########################################################################
-# Settings to configure the Shell application
+# Settings to configure the Zookeeper application.
 ###########################################################################
 ###########################################################################
 
 
-[shell]
-  # The shell_buffer_amount specifies the number of bytes of output per shell
-  # that the Shell app will keep in memory. If not specified, it defaults to
-  # 524288 (512 MiB).
-  ## shell_buffer_amount=100
-
-  # If you run Hue against a Hadoop cluster with Kerberos security enabled, the
-  # Shell app needs to acquire delegation tokens for the subprocesses to work
-  # correctly. These delegation tokens are stored as temporary files in some
-  # directory. You can configure this directory here. If not specified, it
-  # defaults to /tmp/hue_delegation_tokens.
-  ## shell_delegation_token_dir=/tmp/hue_delegation_tokens
-
-  [[ shelltypes ]]
-
-    # Define and configure a new shell type "pig"
-    # ------------------------------------------------------------------------
-    [[[ pig ]]]
-      nice_name = "Pig Shell (Grunt)"
-      command = "/usr/bin/pig -l /dev/null"
-      help = "The command-line interpreter for Pig"
-
-      [[[[ environment ]]]]
-        # You can specify environment variables for the Pig shell
-        # in this section. Note that JAVA_HOME must be configured
-        # for the Pig shell to run.
-
-        [[[[[ JAVA_HOME ]]]]]
-          value = "/usr/lib/jvm/java-6-sun"
-
-    # Define and configure a new shell type "Sqoop 2"
-    # ------------------------------------------------------------------------
-    [[[ sqoop2 ]]]
-      nice_name = "Sqoop 2 Shell"
-      command = "/usr/bin/sqoop2"
-      help = "The command-line Sqoop 2 client."
-
-      [[[[ environment ]]]]
-        # You can configure environment variables for the Sqoop 2 shell
-        # in this section.
-
-    # Define and configure a new shell type "hbase"
-    # ------------------------------------------------------------------------
-    [[[ hbase ]]]
-      nice_name = "HBase Shell"
-      command = "/usr/bin/hbase shell"
-      help = "The command-line HBase client interface."
-
-      [[[[ environment ]]]]
-        # You can configure environment variables for the HBase shell
-        # in this section.
+[zookeeper]
+
+  [[clusters]]
+
+    [[[default]]]
+      # Zookeeper ensemble. Comma separated list of Host/Port.
+      # e.g. localhost:2181,localhost:2182,localhost:2183
+      ## host_ports=localhost:2181
+
+      # The URL of the REST contrib service
+      ## rest_url=http://localhost:9998
 
 
 
 
 ###########################################################################
 ###########################################################################

+ 12 - 59
desktop/conf/pseudo-distributed.ini.tmpl

@@ -516,67 +516,20 @@
 
 
 
 
 ###########################################################################
 ###########################################################################
-# Settings to configure the Shell application
+# Settings to configure the Zookeeper application.
 ###########################################################################
 ###########################################################################
 
 
-[shell]
-  # The shell_buffer_amount specifies the number of bytes of output per shell
-  # that the Shell app will keep in memory. If not specified, it defaults to
-  # 524288 (512 MiB).
-  ## shell_buffer_amount=100
-
-  # If you run Hue against a Hadoop cluster with Kerberos security enabled, the
-  # Shell app needs to acquire delegation tokens for the subprocesses to work
-  # correctly. These delegation tokens are stored as temporary files in some
-  # directory. You can configure this directory here. If not specified, it
-  # defaults to /tmp/hue_delegation_tokens.
-  ## shell_delegation_token_dir=/tmp/hue_delegation_tokens
-
-  [[ shelltypes ]]
-
-    # Define and configure a new shell type "pig"
-    # ------------------------------------------------------------------------
-    [[[ pig ]]]
-      nice_name = "Pig Shell (Grunt)"
-      command = "/usr/bin/pig -l /dev/null"
-      help = "The command-line interpreter for Pig"
-
-      [[[[ environment ]]]]
-        # You can specify environment variables for the Pig shell
-        # in this section. Note that JAVA_HOME must be configured
-        # for the Pig shell to run.
-
-        [[[[[ JAVA_HOME ]]]]]
-          value = "/usr/lib/jvm/java-6-sun"
-
-    # Define and configure a new shell type "hbase"
-    # ------------------------------------------------------------------------
-    [[[ hbase ]]]
-      nice_name = "HBase Shell"
-      command = "/usr/bin/hbase shell"
-      help = "The command-line HBase client interface."
-
-      [[[[ environment ]]]]
-        # You can configure environment variables for the HBase shell
-        # in this section.
-
-    # Define and configure a new shell type "Sqoop 2"
-    # ------------------------------------------------------------------------
-    [[[ sqoop2 ]]]
-      nice_name = "Sqoop 2 Shell"
-      command = "/usr/bin/sqoop2"
-      help = "The command-line Sqoop 2 client."
-
-      [[[[ environment ]]]]
-        # You can configure environment variables for the Sqoop 2 shell
-        # in this section.
-
-    # Define and configure a new shell type "bash" for testing only
-    # ------------------------------------------------------------------------
-    [[[ bash ]]]
-      nice_name = "Bash (Test only!!!)"
-      command = "/bin/bash"
-      help = "A shell that does not depend on Hadoop components"
+[zookeeper]
+
+  [[clusters]]
+
+    [[[default]]]
+      # Zookeeper ensemble. Comma separated list of Host/Port.
+      # e.g. localhost:2181,localhost:2182,localhost:2183
+      ## host_ports=localhost:2181
+
+      # The URL of the REST contrib service
+      ## rest_url=http://localhost:9998
 
 
 
 
 ###########################################################################
 ###########################################################################