HDFS-7995. Implement chmod in the HDFS Web UI. Contributed by Ravi Prakash and Haohui Mai.

This commit is contained in:
Haohui Mai 2015-09-16 11:50:17 -07:00
parent ab09573fcb
commit a343aa928a
4 changed files with 123 additions and 6 deletions

View File

@ -578,6 +578,9 @@ Release 2.8.0 - UNRELEASED
HDFS-7986. Allow files / directories to be deleted from the NameNode UI.
(Ravi Prakash via wheat9)
HDFS-7995. Implement chmod in the HDFS Web UI.
(Ravi Prakash and Haohui Mai via wheat9)
OPTIMIZATIONS
HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than

View File

@ -87,7 +87,6 @@
<button type="button" class="close" onclick="$('#alert-panel').hide();">&times;</button>
<div class="alert-body" id="alert-panel-body"></div>
</div>
<div class="modal" id="btn-create-directory" tabindex="-1" role="dialog"
aria-hidden="true">
<div class="modal-dialog">
@ -169,6 +168,46 @@
</div>
<script type="text/x-template" id="explorer-popover-perm-info">
<div class="explorer-popover-perm-body">
<table class="table table-striped">
<thead>
<tr>
<th class="text-center">User</th>
<th class="text-center">Group</th>
<th class="text-center">Other</th>
</tr>
</thead>
<tbody>
<tr>
<td><label><input type="checkbox" data-bit="8" /> Read</label></td>
<td><label><input type="checkbox" data-bit="5" /> Read</label></td>
<td><label><input type="checkbox" data-bit="2" /> Read</label></td>
</tr>
<tr>
<td><label><input type="checkbox" data-bit="7" /> Write</label></td>
<td><label><input type="checkbox" data-bit="4" /> Write</label></td>
<td><label><input type="checkbox" data-bit="1" /> Write</label></td>
</tr>
<tr>
<td><label><input type="checkbox" data-bit="6" /> Execute</label></td>
<td><label><input type="checkbox" data-bit="3" /> Execute</label></td>
<td><label><input type="checkbox" data-bit="0" /> Execute</label></td>
</tr>
</tbody>
</table>
<div style="text-align: right; margin-right: 10px">
<label><input type="checkbox" id="explorer-perm-sticky" data-bit="9" /> Sticky bit</label>
</div>
<hr/>
<div style="text-align: right">
<button type="button" class="btn" id="explorer-perm-cancel">Cancel</button>
<button type="button" class="btn btn-success" id="explorer-set-perm-button"
data-complete-text="Updating...">Set</button>
</div>
</div>
</script>
<script type="text/x-dust-template" id="tmpl-explorer">
<table class="table">
<thead>
@ -181,13 +220,17 @@
<th>Replication</th>
<th>Block Size</th>
<th>Name</th>
<th>Delete</th>
<th></th>
</tr>
</thead>
<tbody>
{#FileStatus}
<tr inode-path="{pathSuffix}" class="explorer-entry">
<td>{type|helper_to_directory}{permission|helper_to_permission}{aclBit|helper_to_acl_bit}</td>
<tr inode-path="{pathSuffix}" data-permission="{permission}"
class="explorer-entry">
<td><span class="explorer-perm-links editable-click">
{type|helper_to_directory}{permission|helper_to_permission}
{aclBit|helper_to_acl_bit}
</span></td>
<td>{owner}</td>
<td>{group}</td>
<td>{length|fmt_bytes}</td>

View File

@ -22,6 +22,7 @@
// in the preview.
var TAIL_CHUNK_SIZE = 32768;
//This stores the current directory which is being browsed
var current_directory = "";
function show_err_msg(msg) {
@ -101,6 +102,50 @@
$('#delete-modal').modal();
}
/* This method loads the checkboxes on the permission info modal. It accepts
* the octal permissions, eg. '644' or '755' and infers the checkboxes that
* should be true and false
*/
function view_perm_details(e, filename, abs_path, perms) {
$('.explorer-perm-links').popover('destroy');
e.popover({html: true, content: $('#explorer-popover-perm-info').html(), trigger: 'focus'})
.on('shown.bs.popover', function(e) {
var popover = $(this), parent = popover.parent();
//Convert octal to binary permissions
var bin_perms = parseInt(perms, 8).toString(2);
bin_perms = bin_perms.length == 9 ? "0" + bin_perms : bin_perms;
parent.find('#explorer-perm-cancel').on('click', function() { popover.popover('destroy'); });
parent.find('#explorer-set-perm-button').off().click(function() { set_permissions(abs_path); });
parent.find('input[type=checkbox]').each(function(idx, element) {
var e = $(element);
e.prop('checked', bin_perms.charAt(9 - e.attr('data-bit')) == '1');
});
})
.popover('show');
}
// Use WebHDFS to set permissions on an absolute path
function set_permissions(abs_path) {
var p = 0;
$.each($('.popover .explorer-popover-perm-body input:checked'), function(idx, e) {
p |= 1 << (+$(e).attr('data-bit'));
});
var permission_mask = p.toString(8);
// PUT /webhdfs/v1/<path>?op=SETPERMISSION&permission=<permission>
var url = '/webhdfs/v1' + encode_path(abs_path) +
'?op=SETPERMISSION' + '&permission=' + permission_mask;
$.ajax(url, { type: 'PUT'
}).done(function(data) {
browse_directory(current_directory);
}).error(network_error_handler(url))
.complete(function() {
$('.explorer-perm-links').popover('destroy');
});
}
function encode_path(abs_path) {
abs_path = encodeURIComponent(abs_path);
var re = /%2F/g;
@ -198,6 +243,14 @@
}
});
//Set the handler for changing permissions
$('.explorer-perm-links').click(function() {
var filename = $(this).closest('tr').attr('inode-path');
var abs_path = append_path(current_directory, filename);
var perms = $(this).closest('tr').attr('data-permission');
view_perm_details($(this), filename, abs_path, perms);
});
$('.explorer-entry .glyphicon-trash').click(function() {
var inode_name = $(this).closest('tr').attr('inode-path');
var absolute_file_path = append_path(current_directory, inode_name);
@ -223,8 +276,7 @@
}
$('#btn-create-directory').on('show.bs.modal', function(event) {
var modal = $(this)
$('#new_directory_pwd').html(current_directory);
$('#new_directory_pwd').text(current_directory);
});
$('#btn-create-directory-send').click(function () {

View File

@ -267,3 +267,22 @@ header.bs-docs-nav, header.bs-docs-nav .navbar-brand {
.explorer-entry .explorer-browse-links { cursor: pointer; }
.explorer-entry .glyphicon-trash { cursor: pointer; }
.popover {
max-width: 400px;
}
.explorer-popover-perm-body table {
width: 30rem;
}
.explorer-popover-perm-body table > tbody > tr > td {
text-align: center;
}
.explorer-popover-perm-body label {
display:inline;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}