Repository: kudu
Updated Branches:
  refs/heads/master 9ad90eebe -> 36187ef62


[webui] Convert /tablet and its offshoots to mustache

This patch converts the following pages to mustache templates:

* /tablet
* /tablet-consensus-status
* /tablet-rowsetlayout-svg
* /log-anchors

It does the conversion as simply as possible and makes no changes to
the content exposed, except it linkifies the tablet id in a couple of
cases.

Follow-ups will make improvements and add more information.

Change-Id: Iea14f5504b9665b9c349efc9b3b13fc3fe19d8b2
Reviewed-on: http://gerrit.cloudera.org:8080/11288
Reviewed-by: Alexey Serbin <aser...@cloudera.com>
Tested-by: Will Berkeley <wdberke...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/a6baa721
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/a6baa721
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/a6baa721

Branch: refs/heads/master
Commit: a6baa721076f9e7a91d0f108ef5b4a443c731f7c
Parents: 9ad90ee
Author: Will Berkeley <wdberke...@gmail.org>
Authored: Tue Aug 21 10:39:40 2018 -0700
Committer: Will Berkeley <wdberke...@gmail.com>
Committed: Wed Aug 22 22:12:25 2018 +0000

----------------------------------------------------------------------
 src/kudu/server/webui_util.cc             |  41 -------
 src/kudu/tserver/tserver_path_handlers.cc | 141 ++++++++++---------------
 src/kudu/tserver/tserver_path_handlers.h  |   8 +-
 www/log-anchors.mustache                  |  25 +++++
 www/tablet-consensus-status.mustache      |  24 +++++
 www/tablet-rowsetlayout-svg.mustache      |  25 +++++
 www/tablet.mustache                       |  66 ++++++++++++
 7 files changed, 201 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/src/kudu/server/webui_util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/webui_util.cc b/src/kudu/server/webui_util.cc
index cd73042..590080f 100644
--- a/src/kudu/server/webui_util.cc
+++ b/src/kudu/server/webui_util.cc
@@ -17,7 +17,6 @@
 
 #include "kudu/server/webui_util.h"
 
-#include <sstream>
 #include <string>
 
 #include "kudu/common/common.pb.h"
@@ -29,7 +28,6 @@
 #include "kudu/util/compression/compression.pb.h"
 #include "kudu/util/easy_json.h"
 #include "kudu/util/monotime.h"
-#include "kudu/util/url-coding.h"
 
 using std::string;
 using strings::Substitute;
@@ -55,45 +53,6 @@ void SchemaToJson(const Schema& schema, EasyJson* output) {
   }
 }
 
-void HtmlOutputSchemaTable(const Schema& schema,
-                           std::ostringstream* output) {
-  *output << "<table class='table table-striped'>\n";
-  *output << "  <thead><tr>"
-          << "<th>Column</th><th>ID</th><th>Type</th>"
-          << "<th>Encoding</th><th>Compression</th>"
-          << "<th>Read default</th><th>Write default</th>"
-          << "</tr></thead>\n";
-  *output << "<tbody>";
-  for (int i = 0; i < schema.num_columns(); i++) {
-    const ColumnSchema& col = schema.column(i);
-    const string& html_escaped_col_name = EscapeForHtmlToString(col.name());
-    const string& col_name = schema.is_key_column(i) ?
-                                 Substitute("<u>$0</u>", 
html_escaped_col_name) :
-                                 html_escaped_col_name;
-    string read_default = "-";
-    if (col.has_read_default()) {
-      read_default = col.Stringify(col.read_default_value());
-    }
-    string write_default = "-";
-    if (col.has_write_default()) {
-      write_default = col.Stringify(col.write_default_value());
-    }
-    const ColumnStorageAttributes& attrs = col.attributes();
-    const string& encoding = EncodingType_Name(attrs.encoding);
-    const string& compression = CompressionType_Name(attrs.compression);
-    *output << Substitute("<tr><th>$0</th><td>$1</td><td>$2</td><td>$3</td>"
-                          "<td>$4</td><td>$5</td><td>$6</td></tr>\n",
-                          col_name,
-                          schema.column_id(i),
-                          col.TypeToString(),
-                          EscapeForHtmlToString(encoding),
-                          EscapeForHtmlToString(compression),
-                          EscapeForHtmlToString(read_default),
-                          EscapeForHtmlToString(write_default));
-  }
-  *output << "</tbody></table>\n";
-}
-
 void TaskListToJson(const std::vector<scoped_refptr<MonitoredTask> >& tasks, 
EasyJson* output) {
   EasyJson tasks_json = output->Set("tasks", EasyJson::kArray);
   for (const scoped_refptr<MonitoredTask>& task : tasks) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/src/kudu/tserver/tserver_path_handlers.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tserver_path_handlers.cc 
b/src/kudu/tserver/tserver_path_handlers.cc
index b8071ed..ddaa3c1 100644
--- a/src/kudu/tserver/tserver_path_handlers.cc
+++ b/src/kudu/tserver/tserver_path_handlers.cc
@@ -101,6 +101,16 @@ bool CompareByMemberType(const RaftPeerPB& a, const 
RaftPeerPB& b) {
   return a.member_type() < b.member_type();
 }
 
+string TabletLink(const string& id) {
+  return Substitute("<a href=\"/tablet?id=$0\">$1</a>",
+                    UrlEncodeToString(id),
+                    EscapeForHtmlToString(id));
+}
+
+bool IsTombstoned(const scoped_refptr<TabletReplica>& replica) {
+  return replica->data_state() == tablet::TABLET_DATA_TOMBSTONED;
+}
+
 string ConsensusStatePBToHtml(const ConsensusStatePB& cstate,
                               const string& local_uuid) {
   ostringstream html;
@@ -132,31 +142,36 @@ string ConsensusStatePBToHtml(const ConsensusStatePB& 
cstate,
 
 bool GetTabletID(const Webserver::WebRequest& req,
                  string* id,
-                 Webserver::PrerenderedWebResponse* resp) {
+                 Webserver::WebResponse* resp) {
   if (!FindCopy(req.parsed_args, "id", id)) {
     resp->status_code = HttpStatusCode::BadRequest;
-    *resp->output << "Tablet missing 'id' argument";
+    resp->output->Set("error", "Request missing 'id' argument");
     return false;
   }
   return true;
 }
 
-bool GetTabletReplica(TabletServer* tserver, const Webserver::WebRequest& 
/*req*/,
-                      scoped_refptr<TabletReplica>* replica, const string& 
tablet_id,
-                      Webserver::PrerenderedWebResponse* resp) {
+bool GetTabletReplica(TabletServer* tserver,
+                      const Webserver::WebRequest& /*req*/,
+                      scoped_refptr<TabletReplica>* replica,
+                      const string& tablet_id,
+                      Webserver::WebResponse* resp) {
   if (!tserver->tablet_manager()->LookupTablet(tablet_id, replica)) {
     resp->status_code = HttpStatusCode::NotFound;
-    *resp->output << "Tablet " << EscapeForHtmlToString(tablet_id) << " not 
found";
+    resp->output->Set("error",
+                      Substitute("Tablet $0 not found", tablet_id));
     return false;
   }
   return true;
 }
 
-bool TabletBootstrapping(const scoped_refptr<TabletReplica>& replica, const 
string& tablet_id,
-                         Webserver::PrerenderedWebResponse* resp) {
+bool TabletBootstrapping(const scoped_refptr<TabletReplica>& replica,
+                         const string& tablet_id,
+                         Webserver::WebResponse* resp) {
   if (replica->state() == tablet::BOOTSTRAPPING) {
     resp->status_code = HttpStatusCode::ServiceUnavailable;
-    *resp->output << "Tablet " << EscapeForHtmlToString(tablet_id) << " is 
still bootstrapping";
+    resp->output->Set("error",
+                      Substitute("Tablet $0 is still bootstrapping", 
tablet_id));
     return true;
   }
   return false;
@@ -167,7 +182,7 @@ bool TabletBootstrapping(const 
scoped_refptr<TabletReplica>& replica, const stri
 bool LoadTablet(TabletServer* tserver,
                 const Webserver::WebRequest& req,
                 string* tablet_id, scoped_refptr<TabletReplica>* replica,
-                Webserver::PrerenderedWebResponse* resp) {
+                Webserver::WebResponse* resp) {
   return GetTabletID(req, tablet_id, resp) &&
       GetTabletReplica(tserver, req, replica, *tablet_id, resp) &&
       !TabletBootstrapping(*replica, *tablet_id, resp);
@@ -187,7 +202,7 @@ Status TabletServerPathHandlers::Register(Webserver* 
server) {
     "/tablets", "Tablets",
     boost::bind(&TabletServerPathHandlers::HandleTabletsPage, this, _1, _2),
     true /* styled */, true /* is_on_nav_bar */);
-  server->RegisterPrerenderedPathHandler(
+  server->RegisterPathHandler(
     "/tablet", "",
     boost::bind(&TabletServerPathHandlers::HandleTabletPage, this, _1, _2),
     true /* styled */, false /* is_on_nav_bar */);
@@ -195,15 +210,15 @@ Status TabletServerPathHandlers::Register(Webserver* 
server) {
     "/transactions", "",
     boost::bind(&TabletServerPathHandlers::HandleTransactionsPage, this, _1, 
_2),
     true /* styled */, false /* is_on_nav_bar */);
-  server->RegisterPrerenderedPathHandler(
+  server->RegisterPathHandler(
     "/tablet-rowsetlayout-svg", "",
     boost::bind(&TabletServerPathHandlers::HandleTabletSVGPage, this, _1, _2),
     true /* styled */, false /* is_on_nav_bar */);
-  server->RegisterPrerenderedPathHandler(
+  server->RegisterPathHandler(
     "/tablet-consensus-status", "",
     boost::bind(&TabletServerPathHandlers::HandleConsensusStatusPage, this, 
_1, _2),
     true /* styled */, false /* is_on_nav_bar */);
-  server->RegisterPrerenderedPathHandler(
+  server->RegisterPathHandler(
     "/log-anchors", "",
     boost::bind(&TabletServerPathHandlers::HandleLogAnchorsPage, this, _1, _2),
     true /* styled */, false /* is_on_nav_bar */);
@@ -282,19 +297,6 @@ void 
TabletServerPathHandlers::HandleTransactionsPage(const Webserver::WebReques
   }
 }
 
-namespace {
-string TabletLink(const string& id) {
-  return Substitute("<a href=\"/tablet?id=$0\">$1</a>",
-                    UrlEncodeToString(id),
-                    EscapeForHtmlToString(id));
-}
-
-bool IsTombstoned(const scoped_refptr<TabletReplica>& replica) {
-  return replica->data_state() == tablet::TABLET_DATA_TOMBSTONED;
-}
-
-} // anonymous namespace
-
 void TabletServerPathHandlers::HandleTabletsPage(const Webserver::WebRequest& 
/*req*/,
                                                  Webserver::WebResponse* resp) 
{
   EasyJson* output = resp->output;
@@ -392,8 +394,7 @@ void TabletServerPathHandlers::HandleTabletsPage(const 
Webserver::WebRequest& /*
 }
 
 void TabletServerPathHandlers::HandleTabletPage(const Webserver::WebRequest& 
req,
-                                                
Webserver::PrerenderedWebResponse* resp) {
-  ostringstream* output = resp->output;
+                                                Webserver::WebResponse* resp) {
   string tablet_id;
   scoped_refptr<TabletReplica> replica;
   if (!LoadTablet(tserver_, req, &tablet_id, &replica, resp)) return;
@@ -405,87 +406,59 @@ void TabletServerPathHandlers::HandleTabletPage(const 
Webserver::WebRequest& req
     role = consensus->role();
   }
 
-  *output << "<h1>Tablet " << EscapeForHtmlToString(tablet_id)
-          << " (" << replica->HumanReadableState()
-          << "/" << RaftPeerPB::Role_Name(role) << ")</h1>\n";
-  *output << "<h3>Table " << EscapeForHtmlToString(table_name) << "</h3>";
+  EasyJson* output = resp->output;
+  output->Set("tablet_id", tablet_id);
+  output->Set("state", replica->HumanReadableState());
+  output->Set("role", RaftPeerPB::Role_Name(role));
+  output->Set("table_name", table_name);
 
-  // Output schema in tabular format.
-  *output << "<h2>Schema</h2>\n";
   const Schema& schema = replica->tablet_metadata()->schema();
-  HtmlOutputSchemaTable(schema, output);
-
-  *output << "<h2>Other Tablet Info Pages</h2>" << endl;
-
-  // List of links to various tablet-specific info pages
-  *output << "<ul>";
-
-  // Link to output svg of current DiskRowSet layout over keyspace.
-  *output << "<li>" << Substitute("<a 
href=\"/tablet-rowsetlayout-svg?id=$0\">$1</a>",
-                                  UrlEncodeToString(tablet_id),
-                                  "Rowset Layout Diagram")
-          << "</li>" << endl;
-
-  // Link to consensus status page.
-  *output << "<li>" << Substitute("<a 
href=\"/tablet-consensus-status?id=$0\">$1</a>",
-                                  UrlEncodeToString(tablet_id),
-                                  "Consensus Status")
-          << "</li>" << endl;
-
-  // Log anchors info page.
-  *output << "<li>" << Substitute("<a href=\"/log-anchors?id=$0\">$1</a>",
-                                  UrlEncodeToString(tablet_id),
-                                  "Tablet Log Anchors")
-          << "</li>" << endl;
-
-  // End list
-  *output << "</ul>\n";
+  SchemaToJson(schema, output);
 }
 
 void TabletServerPathHandlers::HandleTabletSVGPage(const 
Webserver::WebRequest& req,
-                                                   
Webserver::PrerenderedWebResponse* resp) {
-  ostringstream* output = resp->output;
-  string id;
+                                                   Webserver::WebResponse* 
resp) {
+  string tablet_id;
   scoped_refptr<TabletReplica> replica;
-  if (!LoadTablet(tserver_, req, &id, &replica, resp)) return;
+  if (!LoadTablet(tserver_, req, &tablet_id, &replica, resp)) return;
   shared_ptr<Tablet> tablet = replica->shared_tablet();
+  auto* output = resp->output;
   if (!tablet) {
-    *output << "Tablet " << EscapeForHtmlToString(id) << " not running";
+    output->Set("error", Substitute("Tablet $0 is not running", tablet_id));
     return;
   }
 
-  *output << "<h1>Rowset Layout Diagram for Tablet "
-          << TabletLink(id) << "</h1>\n";
-  tablet->PrintRSLayout(output);
-
+  output->Set("tablet_id", tablet_id);
+  ostringstream oss;
+  tablet->PrintRSLayout(&oss);
+  output->Set("rowset_layout", oss.str());
 }
 
 void TabletServerPathHandlers::HandleLogAnchorsPage(const 
Webserver::WebRequest& req,
-                                                    
Webserver::PrerenderedWebResponse* resp) {
-  ostringstream* output = resp->output;
+                                                    Webserver::WebResponse* 
resp) {
   string tablet_id;
   scoped_refptr<TabletReplica> replica;
   if (!LoadTablet(tserver_, req, &tablet_id, &replica, resp)) return;
 
-  *output << "<h1>Log Anchors for Tablet " << EscapeForHtmlToString(tablet_id) 
<< "</h1>"
-          << std::endl;
-
-  string dump = replica->log_anchor_registry()->DumpAnchorInfo();
-  *output << "<pre>" << EscapeForHtmlToString(dump) << "</pre>" << std::endl;
+  auto* output = resp->output;
+  output->Set("tablet_id", tablet_id);
+  output->Set("log_anchors", replica->log_anchor_registry()->DumpAnchorInfo());
 }
 
 void TabletServerPathHandlers::HandleConsensusStatusPage(const 
Webserver::WebRequest& req,
-                                                         
Webserver::PrerenderedWebResponse* resp) {
-  ostringstream* output = resp->output;
-  string id;
+                                                         
Webserver::WebResponse* resp) {
+  string tablet_id;
   scoped_refptr<TabletReplica> replica;
-  if (!LoadTablet(tserver_, req, &id, &replica, resp)) return;
+  if (!LoadTablet(tserver_, req, &tablet_id, &replica, resp)) return;
   shared_ptr<consensus::RaftConsensus> consensus = replica->shared_consensus();
+  auto* output = resp->output;
   if (!consensus) {
-    *output << "Tablet " << EscapeForHtmlToString(id) << " not initialized";
+    output->Set("error", Substitute("Tablet $0 not initialized", tablet_id));
     return;
   }
-  consensus->DumpStatusHtml(*output);
+  ostringstream oss;
+  consensus->DumpStatusHtml(oss);
+  output->Set("consensus_status", oss.str());
 }
 
 namespace {

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/src/kudu/tserver/tserver_path_handlers.h
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tserver_path_handlers.h 
b/src/kudu/tserver/tserver_path_handlers.h
index bd9124e..7b7beed 100644
--- a/src/kudu/tserver/tserver_path_handlers.h
+++ b/src/kudu/tserver/tserver_path_handlers.h
@@ -44,15 +44,15 @@ class TabletServerPathHandlers {
   void HandleTabletsPage(const Webserver::WebRequest& req,
                          Webserver::WebResponse* resp);
   void HandleTabletPage(const Webserver::WebRequest& req,
-                        Webserver::PrerenderedWebResponse* resp);
+                        Webserver::WebResponse* resp);
   void HandleTransactionsPage(const Webserver::WebRequest& req,
                               Webserver::PrerenderedWebResponse* resp);
   void HandleTabletSVGPage(const Webserver::WebRequest& req,
-                           Webserver::PrerenderedWebResponse* resp);
+                           Webserver::WebResponse* resp);
   void HandleLogAnchorsPage(const Webserver::WebRequest& req,
-                            Webserver::PrerenderedWebResponse* resp);
+                            Webserver::WebResponse* resp);
   void HandleConsensusStatusPage(const Webserver::WebRequest& req,
-                                 Webserver::PrerenderedWebResponse* resp);
+                                 Webserver::WebResponse* resp);
   void HandleDashboardsPage(const Webserver::WebRequest& req,
                             Webserver::PrerenderedWebResponse* resp);
   void HandleMaintenanceManagerPage(const Webserver::WebRequest& req,

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/www/log-anchors.mustache
----------------------------------------------------------------------
diff --git a/www/log-anchors.mustache b/www/log-anchors.mustache
new file mode 100644
index 0000000..a70ce0e
--- /dev/null
+++ b/www/log-anchors.mustache
@@ -0,0 +1,25 @@
+{{!
+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.
+}}
+{{#error}}
+  <div class="text-error">{{.}}</div>
+{{/error}}
+{{^error}}
+  <h1>Log Anchors for Tablet <a 
href="/tablet?id={{tablet_id}}">{{tablet_id}}</a></h1>
+  <pre>{{log_anchors}}</pre>
+{{/error}}

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/www/tablet-consensus-status.mustache
----------------------------------------------------------------------
diff --git a/www/tablet-consensus-status.mustache 
b/www/tablet-consensus-status.mustache
new file mode 100644
index 0000000..4d598e9
--- /dev/null
+++ b/www/tablet-consensus-status.mustache
@@ -0,0 +1,24 @@
+{{!
+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.
+}}
+{{#error}}
+  <div class="text-error">{{.}}</div>
+{{/error}}
+{{^error}}
+  {{{consensus_status}}}
+{{/error}}

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/www/tablet-rowsetlayout-svg.mustache
----------------------------------------------------------------------
diff --git a/www/tablet-rowsetlayout-svg.mustache 
b/www/tablet-rowsetlayout-svg.mustache
new file mode 100644
index 0000000..dc81f11
--- /dev/null
+++ b/www/tablet-rowsetlayout-svg.mustache
@@ -0,0 +1,25 @@
+{{!
+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.
+}}
+{{#error}}
+  <div class="text-error">{{.}}</div>
+{{/error}}
+{{^error}}
+  <h1>Rowset Layout Diagram for Tablet <a 
href="/tablet?id={{tablet_id}}">{{tablet_id}}</a></h1>
+  {{{rowset_layout}}}
+{{/error}}

http://git-wip-us.apache.org/repos/asf/kudu/blob/a6baa721/www/tablet.mustache
----------------------------------------------------------------------
diff --git a/www/tablet.mustache b/www/tablet.mustache
new file mode 100644
index 0000000..8f80581
--- /dev/null
+++ b/www/tablet.mustache
@@ -0,0 +1,66 @@
+{{!
+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.
+}}
+{{#error}}
+  <div class="text-error">{{.}}</div>
+{{/error}}
+{{^error}}
+  <h1>Tablet {{tablet_id}} ({{state}}/{{role}})</h1>
+  <h3>Table {{table_name}}</h3>
+
+  <h2>Schema</h2>
+  <table class='table table-striped'>
+    <thead><tr>
+      <th>Column</th>
+      <th>ID</th>
+      <th>Type</th>
+      <th>Encoding</th>
+      <th>Compression</th>
+      <th>Read default</th>
+      <th>Write default</th>
+    </tr></thead>
+    <tbody>
+    {{#columns}}
+      <tr>
+        <th>{{#is_key}}<u>{{/is_key}}
+          {{name}}
+          {{#is_key}}</u>{{/is_key}}</th>
+        <td>{{id}}</a></td>
+        <td>{{type}}</td>
+        <td>{{encoding}}</td>
+        <td>{{compression}}</td>
+        <td>{{read_default}}</td>
+        <td>{{write_default}}</td>
+      </tr>
+    {{/columns}}
+    </tbody>
+  </table>
+
+  <h2>Other Tablet Info Pages</h2>
+  <ul>
+    <li>
+      <a href="tablet-rowsetlayout-svg?id={{tablet_id}}">Rowset Layout 
Diagram</a>
+    </li>
+    <li>
+      <a href="tablet-consensus-status?id={{tablet_id}}">Consensus Status</a>
+    </li>
+    <li>
+      <a href="log-anchors?id={{tablet_id}}">Tablet Log Anchors</a>
+    </li>
+  </ul>
+{{/error}}

Reply via email to