فهرست منبع

HUE-2214 [fb] Display and set replication

Added displaying of a replication factor in file/folder summary
Implemented setting of a replication factor for files
Fixed review remarks
Adrian Yavorskyy 8 سال پیش
والد
کامیت
a539ad0

+ 5 - 0
apps/filebrowser/src/filebrowser/forms.py

@@ -106,6 +106,11 @@ class BaseCopyFormSet(FormSet):
 
 CopyFormSet = formset_factory(CopyForm, formset=BaseCopyFormSet, extra=0)
 
+class SetReplicationFactorForm(forms.Form):
+  op = "setreplication"
+  src_path = CharField(label=_("File to set replication factor"), help_text=_("The file to set replication factor."))
+  replication_factor = CharField(label=_("Value of replication factor"), help_text=_("The value of replication factor."))
+
 class UploadFileForm(forms.Form):
   op = "upload"
   # The "hdfs" prefix in "hdfs_file" triggers the HDFSfileUploadHandler

+ 2 - 0
apps/filebrowser/src/filebrowser/templates/listdir.mako

@@ -68,6 +68,8 @@ ${ fb_components.menubar() }
               isCurrentDirSelected().length == 0"><i class="fa fa-fw fa-random"></i> ${_('Move')}</a></li>
               <li><a href="javascript: void(0)" title="${_('Copy')}" data-bind="click: copy, enable: selectedFiles().length > 0 &&
               isCurrentDirSelected().length == 0"><i class="fa fa-fw fa-files-o"></i> ${_('Copy')}</a></li>
+              <li><a href="javascript: void(0)" title="${_('Set Replication Factor')}" data-bind="visible: !inTrash() && !isS3() && selectedFiles().length == 1 && selectedFile().type == 'file', click: setReplicationFactor"
+              ><i class="fa fa-fw fa-hdd-o"></i>${_('Set replication factor')}</a></li>
               % if show_download_button:
               <li>
                 <a href="javascript: void(0)" title="${_('Download')}" data-bind="visible: !inTrash() && selectedFiles().length == 1 && selectedFile().type == 'file', click: downloadFile">

+ 77 - 1
apps/filebrowser/src/filebrowser/templates/listdir_components.mako

@@ -237,6 +237,28 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
     </div>
   </form>
 
+  <!-- set replication factor modal -->
+  <form id="setReplicationFactorForm" action="/filebrowser/set_replication_factor?next=${current_request_path | n,unicode }"  method="POST" enctype="multipart/form-data" class="form-inline form-padding-fix">
+    ${ csrf_token(request) | n,unicode }
+    <div id="setReplicationModal" class="modal hide fade">
+      <div class="modal-header">
+        <a href="#" class="close" data-dismiss="modal">&times;</a>
+        <h3>${_('Setting replication factor for :')} <span id="setReplFileName">file name</span></h3>
+      </div>
+      <div class="modal-body">
+        <label>${_('Replication factor')} <input id="newRepFactorInput" name="replication_factor" value="" type="number" class="input-xlarge"/></label>
+      </div>
+      <div class="modal-footer">
+        <div id="replicationFactorRequiredAlert" class="hide" style="position: absolute; left: 10px;">
+          <span class="label label-important">${_('Replication factor is required.')}</span>
+        </div>
+        <input id="SrcPath" type="hidden" name="src_path" type="text">
+        <a class="btn" data-dismiss="modal">${_('Cancel')}</a>
+        <input type="submit" value="${_('Submit')}" class="btn btn-primary" />
+      </div>
+    </div>
+  </form>
+
   <!-- chown modal -->
   % if is_fs_superuser:
   <form id="chownForm" action="/filebrowser/chown" method="POST" enctype="multipart/form-data" class="form-stacked form-padding-fix">
@@ -502,6 +524,10 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
           <th>${ _('Disk space quota') }</th>
           <td data-bind="text: formatBytes(contentSummary().spaceQuota(), 4)"></td>
         </tr>
+        <tr>
+          <th>${ _('Replication factor') }</th>
+          <td data-bind="text: contentSummary().replication()"></td>
+        </tr>
         <tr>
           <th>${ _('Number of directories') }</th>
           <td data-bind="text: contentSummary().directoryCount()"></td>
@@ -1108,7 +1134,8 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
         spaceQuota: -1,
         length: 0,
         directoryCount: 0,
-        fileCount: 0
+        fileCount: 0,
+        replication: 0
       }));
       self.showSummary = function () {
         self.isLoadingSummary(true);
@@ -1349,6 +1376,27 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
         });
       };
 
+      self.setReplicationFactor = function () {
+        $("#SrcPath").attr("value", self.selectedFile().path);
+
+        $("#setReplFileName").text(self.selectedFile().path);
+
+        $("#setReplicationFactorForm").attr("action", "/filebrowser/set_replication_factor?next=${url('filebrowser.views.view', path='')}" + self.currentPath());
+
+        $('#setReplicationFactorForm').ajaxForm({
+          dataType: 'json',
+          success: function() {
+            $("#setReplicationModal").modal('hide');
+            self.retrieveData(true);
+          }
+        });
+
+        $("#setReplicationModal").modal({
+          keyboard:true,
+          show:true
+        });
+      };
+
       self.move = function (mode, unselectedDrag) {
         var paths = [];
 
@@ -1996,6 +2044,20 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
         hideContextMenu();
       });
 
+      // Allow only numeric symbols for setting replication factor
+      $("#newRepFactorInput").keydown(function (e) {
+        if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
+          (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) ||
+          (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) ||
+          (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) ||
+          (e.keyCode >= 35 && e.keyCode <= 39)) {
+            return;
+        }
+        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
+          e.preventDefault();
+        }
+      });
+
       // Drag and drop uploads from anywhere on filebrowser screen
       if (window.FileReader) {
         var showHoverMsg = function (msg) {
@@ -2250,6 +2312,20 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
         }
        });
 
+      $("#setReplicationFactorForm").submit(function () {
+        if ($("#newRepFactorInput").val() == "") {
+          $("#replicationFactorRequiredAlert").show();
+          $("#newRepFactorInput").addClass("fieldError");
+          resetPrimaryButtonsStatus(); //globally available
+          return false;
+        }
+      });
+
+      $("#newRepFactorInput").focus(function () {
+        $("#replicationFactorRequiredAlert").hide();
+        $("#newRepFactorInput").removeClass("fieldError");
+      });
+
       huePubSub.subscribe('update.autocompleters', function(){
         $("#moveDestination").jHueHdfsAutocomplete({
           showOnFocus: true,

+ 1 - 0
apps/filebrowser/src/filebrowser/urls.py

@@ -47,6 +47,7 @@ urlpatterns = patterns('filebrowser.views',
   url(r'^touch$', 'touch', name='touch'),
   url(r'^move$', 'move', name='move'),
   url(r'^copy$', 'copy', name='copy'),
+  url(r'^set_replication_factor$', 'set_replication_factor', name='set_replication_factor'),
   url(r'^rmtree$', 'rmtree', name='rmtree'),
   url(r'^chmod$', 'chmod', name='chmod'),
   url(r'^chown$', 'chown', name='chown'),

+ 11 - 2
apps/filebrowser/src/filebrowser/views.py

@@ -69,7 +69,7 @@ from filebrowser.lib.rwx import filetype, rwx
 from filebrowser.lib import xxd
 from filebrowser.forms import RenameForm, UploadFileForm, UploadArchiveForm, MkDirForm, EditorForm, TouchForm,\
                               RenameFormSet, RmTreeFormSet, ChmodFormSet, ChownFormSet, CopyFormSet, RestoreFormSet,\
-                              TrashPurgeForm
+                              TrashPurgeForm, SetReplicationFactorForm
 
 
 DEFAULT_CHUNK_SIZE_BYTES = 1024 * 4 # 4KB
@@ -528,10 +528,11 @@ def stat(request, path):
 def content_summary(request, path):
     if not request.fs.exists(path):
         raise Http404(_("File not found: %(path)s") % {'path': escape(path)})
-
     response = {'status': -1, 'message': '', 'summary': None}
     try:
         stats = request.fs.get_content_summary(path)
+        replication_factor = request.fs.stats(path)['replication']
+        stats.summary.update({'replication': replication_factor})
         response['status'] = 0
         response['summary'] = stats.summary
     except WebHdfsException, e:
@@ -1054,6 +1055,14 @@ def rename(request):
 
     return generic_op(RenameForm, request, smart_rename, ["src_path", "dest_path"], None)
 
+def set_replication_factor(request):
+    def smart_set_replication_factor(src_path, replication_factor):
+        result = request.fs.set_replication_factor(src_path, replication_factor)
+        if not result:
+            raise PopupException(_("Setting of replication factor failed"))
+
+    return generic_op(SetReplicationFactorForm, request, smart_set_replication_factor, ["src_path", "replication_factor"], None)
+
 
 def mkdir(request):
     def smart_mkdir(path, name):

+ 9 - 0
desktop/libs/hadoop/src/hadoop/fs/webhdfs.py

@@ -36,6 +36,7 @@ from hadoop.fs.webhdfs_types import WebHdfsStat, WebHdfsContentSummary
 from hadoop.conf import UPLOAD_CHUNK_SIZE
 from hadoop.hdfs_site import get_nn_sentry_prefixes, get_umask_mode, get_supergroup
 
+
 import hadoop.conf
 import desktop.conf
 
@@ -416,6 +417,14 @@ class WebHdfs(Hdfs):
     for dirent in ls:
       self.rename(Hdfs.join(old_dir, dirent), Hdfs.join(new_dir, dirent))
 
+  def set_replication_factor(self, filename, repl_factor):
+    """set replication factor(filename, repl_factor)"""
+    params = self._getparams()
+    params['op'] = 'SETREPLICATION'
+    params['replication'] = repl_factor
+    result = self._root.put(filename, params)
+    return result['boolean']
+
   def chown(self, path, user=None, group=None, recursive=False):
     """chown(path, user=None, group=None, recursive=False)"""
     path = Hdfs.normpath(path)