HDFS-7995. Implement chmod in the HDFS Web UI. Contributed by Ravi Prakash and Haohui Mai.
This commit is contained in:
parent
ab09573fcb
commit
a343aa928a
|
@ -578,6 +578,9 @@ Release 2.8.0 - UNRELEASED
|
||||||
HDFS-7986. Allow files / directories to be deleted from the NameNode UI.
|
HDFS-7986. Allow files / directories to be deleted from the NameNode UI.
|
||||||
(Ravi Prakash via wheat9)
|
(Ravi Prakash via wheat9)
|
||||||
|
|
||||||
|
HDFS-7995. Implement chmod in the HDFS Web UI.
|
||||||
|
(Ravi Prakash and Haohui Mai via wheat9)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than
|
HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than
|
||||||
|
|
|
@ -87,7 +87,6 @@
|
||||||
<button type="button" class="close" onclick="$('#alert-panel').hide();">×</button>
|
<button type="button" class="close" onclick="$('#alert-panel').hide();">×</button>
|
||||||
<div class="alert-body" id="alert-panel-body"></div>
|
<div class="alert-body" id="alert-panel-body"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal" id="btn-create-directory" tabindex="-1" role="dialog"
|
<div class="modal" id="btn-create-directory" tabindex="-1" role="dialog"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
|
@ -169,6 +168,46 @@
|
||||||
|
|
||||||
</div>
|
</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">
|
<script type="text/x-dust-template" id="tmpl-explorer">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -181,13 +220,17 @@
|
||||||
<th>Replication</th>
|
<th>Replication</th>
|
||||||
<th>Block Size</th>
|
<th>Block Size</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Delete</th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#FileStatus}
|
{#FileStatus}
|
||||||
<tr inode-path="{pathSuffix}" class="explorer-entry">
|
<tr inode-path="{pathSuffix}" data-permission="{permission}"
|
||||||
<td>{type|helper_to_directory}{permission|helper_to_permission}{aclBit|helper_to_acl_bit}</td>
|
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>{owner}</td>
|
||||||
<td>{group}</td>
|
<td>{group}</td>
|
||||||
<td>{length|fmt_bytes}</td>
|
<td>{length|fmt_bytes}</td>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
// in the preview.
|
// in the preview.
|
||||||
var TAIL_CHUNK_SIZE = 32768;
|
var TAIL_CHUNK_SIZE = 32768;
|
||||||
|
|
||||||
|
//This stores the current directory which is being browsed
|
||||||
var current_directory = "";
|
var current_directory = "";
|
||||||
|
|
||||||
function show_err_msg(msg) {
|
function show_err_msg(msg) {
|
||||||
|
@ -101,6 +102,50 @@
|
||||||
$('#delete-modal').modal();
|
$('#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) {
|
function encode_path(abs_path) {
|
||||||
abs_path = encodeURIComponent(abs_path);
|
abs_path = encodeURIComponent(abs_path);
|
||||||
var re = /%2F/g;
|
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() {
|
$('.explorer-entry .glyphicon-trash').click(function() {
|
||||||
var inode_name = $(this).closest('tr').attr('inode-path');
|
var inode_name = $(this).closest('tr').attr('inode-path');
|
||||||
var absolute_file_path = append_path(current_directory, inode_name);
|
var absolute_file_path = append_path(current_directory, inode_name);
|
||||||
|
@ -223,8 +276,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#btn-create-directory').on('show.bs.modal', function(event) {
|
$('#btn-create-directory').on('show.bs.modal', function(event) {
|
||||||
var modal = $(this)
|
$('#new_directory_pwd').text(current_directory);
|
||||||
$('#new_directory_pwd').html(current_directory);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#btn-create-directory-send').click(function () {
|
$('#btn-create-directory-send').click(function () {
|
||||||
|
|
|
@ -267,3 +267,22 @@ header.bs-docs-nav, header.bs-docs-nav .navbar-brand {
|
||||||
|
|
||||||
.explorer-entry .explorer-browse-links { cursor: pointer; }
|
.explorer-entry .explorer-browse-links { cursor: pointer; }
|
||||||
.explorer-entry .glyphicon-trash { 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;
|
||||||
|
}
|
Loading…
Reference in New Issue