[Kimchi-devel] [V2 1/2] Add users/groups to VM
huoyuxin at linux.vnet.ibm.com
huoyuxin at linux.vnet.ibm.com
Tue Jul 22 09:33:10 UTC 2014
From: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
Signed-off-by: Yu Xin Huo <huoyuxin at linux.vnet.ibm.com>
---
ui/css/theme-default/guest-edit.css | 116 +++++++++++++++++++++++++++++++++++
ui/images/theme-default/group.png | Bin 0 -> 1703 bytes
ui/images/theme-default/user.png | Bin 0 -> 1322 bytes
ui/js/src/kimchi.api.js | 28 ++++++++
ui/js/src/kimchi.guest_edit_main.js | 112 ++++++++++++++++++++++++++++++++-
ui/pages/guest-edit.html.tmpl | 37 +++++++++++
6 files changed, 290 insertions(+), 3 deletions(-)
create mode 100644 ui/images/theme-default/group.png
create mode 100644 ui/images/theme-default/user.png
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 3ce48be..8c2b26f 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -162,3 +162,119 @@
.guest-edit-interface .hide {
display: none;
}
+
+.guest-edit-permission {
+ height: 240px;
+ padding: 5px 10px!important;
+}
+
+.guest-edit-permission .column {
+ display: inline-block;
+ vertical-align: top;
+ height: 100%;
+}
+
+.guest-edit-permission .title {
+ margin-bottom: 3px;
+}
+
+.guest-edit-permission input[type="text"] {
+ margin-bottom: 3px;
+ font-size: 12px;
+ width: 97%;
+}
+
+.guest-edit-permission .body {
+ border: 1px solid #999999;
+ font-size: 12px;
+ padding: 1px;
+ overflow: auto;
+}
+
+.guest-edit-permission .body .head {
+ margin-bottom: 3px;
+ font-weight: bold;
+ background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0 transparent;
+}
+
+.guest-edit-permission .body .item {
+ padding: 2px 3px;
+ margin-bottom: 1px;
+ cursor: pointer;
+}
+
+.guest-edit-permission .body .item:hover {
+ background-color: #AAAAAA;
+}
+
+.guest-edit-permission .body .item-picked {
+ background-color: #BBBBBB;
+}
+
+.guest-edit-permission .body .item .icon {
+ display: inline-block;
+ height: 15px;
+ width: 15px;
+ vertical-align: bottom;
+}
+
+.guest-edit-permission .body .item .user-icon {
+ background: url('/images/theme-default/user.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .body .item .group-icon {
+ background: url('/images/theme-default/group.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .avail {
+ width: 58%;
+}
+
+.guest-edit-permission .avail .body {
+ height: 192px;
+}
+
+.guest-edit-permission .avail .body .column-user {
+ width: 48%;
+}
+.guest-edit-permission .avail .body .column-group {
+ width: 50%;
+}
+
+.guest-edit-permission .control {
+ width: 9%;
+}
+
+.guest-edit-permission .control button {
+ width: 26px;
+ margin-left: 18px;
+}
+
+.guest-edit-permission .control button:first-child {
+ margin-top: 110px;
+ margin-bottom: 2px;
+}
+
+.guest-edit-permission .control .ui-button-text-only .ui-button-text {
+ padding: 2px 8px;
+}
+
+.guest-edit-permission .selected {
+ width: 30%;
+ float: right;
+}
+
+.guest-edit-permission .selected .title {
+ height: 43px;
+}
+
+.guest-edit-permission .selected .body {
+ height: 192px;
+}
+
+#form-guest-edit-permission-save {
+ float: right;
+ margin-right: 10px;
+}
diff --git a/ui/images/theme-default/group.png b/ui/images/theme-default/group.png
new file mode 100644
index 0000000000000000000000000000000000000000..1160bd97178375f202c3c20fef689ddf4a6dcfae
GIT binary patch
literal 1703
zcmV;Y23YxtP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU&Nl8RORCwCNS9?s8R}{bBqot*VmO`u2
z73hYPhb at ot@PRUQFz|tzm>K_=)0sIn{<XyibGT({Vw{pJTQnrgqMI>U7Ux{1;*3V8
zWNO4Ij{2AksU%LE7{a^H{mv%^EG?Kp;%!du*ZbY?o^yWpch0$&^ZWhmWi~M(Az^%0
z;+Vj5yq)KHJN_wse%}?p&tC at zdxEE4tFIe0z|Z_+)C<jmkS~+VzLm at 67Eu(Xaj(bA
z+#dIXzP`RSc&-VjM;xniQ6}2eYV~iCk&zK-3<xle<Cxd$WiFS?)ZNv6ytA{j)a`bk
z4rPQm765pGXR*52!}17ugi@&_BnIBeWHL!G#si&0PyT&k at _0P1VQY-ReTIdt9M7dF
z6bi|6BJ at z9F+xQYM1w}FDWh+O89=c7pC7?*x7!zD-zCU{l at B!nhBBMYwg4n$!P~$~
z|HBDQ;Q1mzxeuOP2GZwbqHHe~vXIi^H;V=GkXkqcNN8 at HKGr~e at Ro-~0FwoHSFKj5
z&uKK8burqQd~J-jC|VQ!fl95q4z_Ptw7C4l+V$_dh;SnrKr+Q at bq3ZR6#;@*p;T0Y
z-D{wbMMXuiNL3_LsZ`Q4M4^mSemO0Fx^DKI*{dd}OqN*h^ZAAejnn($k~e<vd3`U2
z0KBt+)gO~Wf|%G%dr3lZu2d)`V<3m87tHv6>a>De;ZUIO*R5ZB73<ZKL8Br-L`kuv
ztiXo?g;A*eB{mcJU{D<TyzHFpswvitVe`zdn%T}>J37!W&$i`cNy>u|5QA$05oJ>R
zr2O{w_CbYV8X=RHpZB`SWZJ)d=k~W+TU(1A4GxBQXXzQ~EIvN|3Z|{f&Ccrqc^z1L
zi^uJ$8Z{Fd40_ at At=nw0LPcCjO|{6gtvT&LqonS})dYjVP>5G@$VGcr?mfURXtml?
z at LcBcdiHjAckA)4Vvqwtu%U>s!kLBFLJ=xhKvY&Xzw8pe$w#VPVoT5b$Ci<K7;*s5
z_uy?lw(%_V%%x1Jic~SA>@D`p+}&YGNDI#>obgTByfW!ITv!q5R=>Bp2QXhSy<*x5
z1wTe8BKiPzJ&1Z0+-QNa%TPK?%9Kdks2gMeLj-LEYNa7bNJ_J;*^YNsuJ}4FEj6Ta
znlldu&R;NZeNLubS@~(D&oIHjqNAgUc&W%6c8D=5I!Z!mXpNAf2x#bHb=A@~>J9qm
z!-C^=*v~EXjvJrh?=L?cJyukEv6eO7Ym}HzF<riBA(8JZFuMXCZLhs_ at nFNB4Hqi6
zZd1csPg`4?NMx2WUx-EyfD5dnqhltg*XxH?w`45vD?T-YFq<&+`5*PyHlSY$p at Rk;
zE{NHrybf?5118gO at c6Fg^vUXn4<FX-*}XU7(W6JQaLNM>=L81S4smgDaZ+3hypV;x
zIfwYy5M(r=x3~8=tlf{r&cZ0^WCMjpbZ>)P6_^`Mkb-~=ggbNO*pVGi+u9Cn{BTp^
zXvLI5Rj1QAB?I8O5n1gf7L1|HMb^^<SD%Zy+%D-k5Ry`LLxQ4t)YE?=B#fnbKVPZ4
zyt8Ug)uodsYPgY5pluLD!OhboU5xGvxlA4tD6N4cLj(%se<B!(R2RVH{!BP9S4!Eu
zP>v8wUbcMMK|*Gv;zX^hvrERqdmV-rQ_UV)*8^FR79wQ<=|ANROVNS4uhnUH8I8tG
zvx;VUM+#$Ft6*vY6DJrZyxZH?D+FK}OCuxTl?eo$xb2h5GpA0TDxvtNW;UByVp0N2
zNK9lI85t}qJF^GQoEO2wr7bNj10Id(kjhCXWS0C|^2#}L=j=;MPb--?X(B@^rq?$i
zj(+(aavtImVX-9u{kU8Yu$C-BHWz2W3P>)7oYpkk<3O6H{?=W`U}6IN>hbV?r~zGF
zU5V+I3>WSLb)ib|bJY;>D~$K`45+FkPWeaY6u))bM?IxwrA$glV{9nJY+?BVwz*<+
z*NfgaxW`Xhm!L0)6gM|JjrW_HSYzYg?19tCoX!UWX|wr$v&8b`$;ktRrMf_O%OrCW
zSe`@&5GP*MkXVvak4k625bdv~yMqQG9X`8G at f>s9X|P}{9b$!8`h}XZf7}bXK4dL=
xz7t?K_Pq&p;n{h??+d&4&l&Ktujl^>FaVgriY_I-t at r={002ovPDHLkV1m5fG0*@2
literal 0
HcmV?d00001
diff --git a/ui/images/theme-default/user.png b/ui/images/theme-default/user.png
new file mode 100644
index 0000000000000000000000000000000000000000..c57a81a92757ef31c424a4e6c741f71db62a1092
GIT binary patch
literal 1322
zcmV+_1=aeAP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%t=H+RCwCFS6xgTRTRGSvwt(QEW2!%
zZEC<RY*%PmU|~TT(9l}brY~)zO*HkzHZ`VcV>GER{yyo84?Y{zXpHs6S4l9Y#$eJ`
zmI9TeNz<hS;wC6n(*0#;*YAuwlVv;L6r^`@m^(Xj at A=NT=X~eDmCI%J$6w2=dc>kV
zY@@+(9ODK4xF85;1zu=k91CHOq^hbvsYP|PR4&aWrYD(|;jiDtI5Pm<(b&U^nWnhO
zZnuB!bUFte4hIuOQ3F&emDt+a8q4K!YCf0$1oO+2)4!@#0EkwQl5$ualok1!EXhHq
z%gJmu8{>K206<bG6ogDB^F}6}*^Ol{S=pO6{k6PaIG$r3kLNqL+Z|Ng3M1<QNK>wD
z0wClKm&?WQ4U=X0#ew+2^IHe7-h8rlfP at r~VhtmXu2yJ}XCzr-e!u_2cz2($B>?5B
zi|2UO+S2;E!|Bj0HB)Q`0>S806y at n{9{~c7$%@p!ndP-YM`IIhEY=e{_Fn+RjXY4D
zb{x;w(OtLDQsClyUxV+7?FS)7Fxa?e#qxE6tFbYV-gXdDdWFN`J9K{(0F)I&&kRj$
zI|#vW?8M0vpCb(|D<`nShlY!hry^t9K7x{3LJ-PdzWUnvKdl1r at A9)#r$@fP4l7&p
zK#etB9o>b2g9B$ST)a at CRMeTzOi1}V at 4bC5&=`2jO0Zg at ViXxFP-BUi$(LJN_Ksfp
z=3D3WYuB~o(FYyT;UkCH$jA$KK}644v0lp-vto3ht%C^2h1~xbJa874jpHaz!TRjf
zY@!{XyqnEtPcAMl+BGYX^P$j_DNIKpA3+{;9_VVv`tOm%b^yJ6^VZZ?maAd3z0;0@
z^8+}4h*+&yEHYHNtJz%k6}(OoDNW5J6wD))C57Iu_-s)vYB2+#M<hwQVt3em#0U9&
zo&oSVtQoZgARg=c6uf^<=YBd{Y`}8a9F^U1Jl{ry%u<!a_#1N%?h2Ge at cpwW*%8Sl
zF#ymAiApspWGS6aAB88zHwA!z8&qWFXDTRUy%7gEZ}J3fMsuAPv~1!2Wj+Ec3L+D2
zqQ(OhuzFCF7qC8cf8~C7W^Vd{X+O}>78M%&4WH3QB-PYQo53<|<J#h5P&Rc-l^#J?
ztdGi32J7nTKEUIfrfCS5pT-%6Ny$cqM^~a*D~g8DbG5~0>&O6nb1AyN(`O36>+`;^
zE8i^Fw<;AciT(!v#fQ?cbAMMCx}7NsJl&F=7!*g?e<hVl1yaAKR6|o}Z|D*QkY09o
zN@#y%ln=dSY#kHg^-=2m9;N1QW$4+`+|+aik2gd;`n?U_M)dhR4nPNiKf{Ix&_Fij
z3wd5}JSG6RifhF^Mi%tOdm`1jyVF9%1!9s64=8STpq4mxa*!S{s%Us%UnHDGZax<4
zb!iSYtJOTviuu)rdkcFeCVpX4i3FROnWX~qzgZm!1kk2;v%da**4x{|>b>>js0Gj0
z79%RJ$03IxgUidyp5)ymo1dR&^T~O(w6w(16;L1%wz|4%C<yKjGVr{ij5;GUFVxVY
zR|qke<XXV1A0cCv`|^h6xNTp%_8-x2w{KCTwpR&x%A<1^#8<T}S=9xRvL(nY<R)Z}
gniR8!<R1YB09_*wa#VgYhyVZp07*qoM6N<$f^kM~^#A|>
literal 0
HcmV?d00001
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 021be63..936e964 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -1056,5 +1056,33 @@ var kimchi = {
kimchi.message.error(data.responseJSON.reason);
}
});
+ },
+
+ getHostUsers : function(suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'host/users',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getHostGroups : function(suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url + 'host/groups',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
}
};
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 99dbe96..2e21e70 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -19,12 +19,13 @@ kimchi.guest_edit_main = function() {
var buttonContainer = $('#action-button-container');
$('#guest-edit-tabs').tabs({
beforeActivate: function(event, ui) {
+ $(buttonContainer).addClass('hidden');
+ $("#form-guest-edit-permission-save").addClass('hidden');
var deactivated = ui['newPanel'];
if($(deactivated).attr('id') === 'form-guest-edit-general') {
$(buttonContainer).removeClass('hidden');
- }
- else {
- $(buttonContainer).addClass('hidden');
+ }else if($(deactivated).attr('id') === 'form-guest-edit-permission'){
+ $("#form-guest-edit-permission-save").removeClass('hidden');
}
}
});
@@ -236,6 +237,110 @@ kimchi.guest_edit_main = function() {
});
};
+ var setupPermission = function() {
+ var userNodes = {}, groupNodes = {};
+ kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
+ kimchi.getHostUsers(function(users){
+ kimchi.getHostGroups(function(groups){
+ var subArray = function(a1, a2){ //a1-a2
+ for(var i=0; i<a2.length; i++){
+ for(var j=0; j<a1.length; j++){
+ if(a2[i] == a1[j]){
+ a1.splice(j, 1);
+ break;
+ }
+ }
+ }
+ };
+ subArray(users, vm.users); subArray(groups, vm.groups);
+ init(users, groups, vm.users, vm.groups);
+ });
+ });
+ });
+ var sortNodes = function(container, isUser){
+ nodes = container.children();
+ var keys = [];
+ nodes.each(function(){
+ keys.push($("label", this).text());
+ });
+ keys.sort();
+ container.empty();
+ for(var i=0; i<keys.length; i++){
+ var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]];
+ $(itemNode).click(function(){
+ $(this).toggleClass("item-picked");
+ });
+ container.append(itemNode);
+ }
+ };
+ var init = function(availUsers, availGroups, selUsers, selGroups){
+ var initNode = function(key, isUserNode){
+ var nodeGroups = isUserNode ? userNodes : groupNodes;
+ nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item').html(), {
+ val: key,
+ class: isUserNode? "user-icon" : "group-icon"
+ }));
+ };
+ for(var i=0; i<availUsers.length; i++){
+ initNode(availUsers[i], true);
+ $("#permission-avail-users").append(userNodes[availUsers[i]]);
+ sortNodes($("#permission-avail-users"), true);
+ }
+ for(var i=0; i<selUsers.length; i++){
+ initNode(selUsers[i], true);
+ $("#permission-sel-users").append(userNodes[selUsers[i]]);
+ sortNodes($("#permission-sel-users"), true);
+ }
+ for(var i=0; i<availGroups.length; i++){
+ initNode(availGroups[i], false);
+ $("#permission-avail-groups").append(groupNodes[availGroups[i]]);
+ sortNodes($("#permission-avail-groups"), false);
+ }
+ for(var i=0; i<selGroups.length; i++){
+ initNode(selGroups[i], false);
+ $("#permission-sel-groups").append(groupNodes[selGroups[i]]);
+ sortNodes($("#permission-sel-groups"), false);
+ }
+ };
+ var filterNodes = function(key, container){
+ container.children().each(function(){
+ $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : "");
+ });
+ }
+ $("#permission-searchBox").on("keyup", function() {
+ var key = $(this).val();
+ filterNodes(key, $("#permission-avail-users"));
+ filterNodes(key, $("#permission-avail-groups"));
+ });
+ $('#permissionGo').button().click(function() {
+ $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked");
+ sortNodes($("#permission-sel-users"), true);
+ $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked");
+ sortNodes($("#permission-sel-groups"), false);
+ });
+ $('#permissionBack').button().click(function() {
+ $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked");
+ sortNodes($("#permission-avail-users"), true);
+ $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked");
+ sortNodes($("#permission-avail-groups"), false);
+ $("#permission-searchBox").val("");
+ filterNodes("", $("#permission-avail-users"));
+ filterNodes("", $("#permission-avail-groups"));
+ });
+ $("#form-guest-edit-permission-save").on("click", function(){
+ var content = { users: [], groups: [] };
+ $("#permission-sel-users").children().each(function(){
+ content.users.push($("label", this).text());
+ });
+ $("#permission-sel-groups").children().each(function(){
+ content.groups.push($("label", this).text());
+ });
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ kimchi.window.close();
+ });
+ });
+ };
+
var initContent = function(guest) {
guest['icon'] = guest['icon'] || 'images/icon-vm.png';
$('#form-guest-edit-general').fillWithObject(guest);
@@ -265,6 +370,7 @@ kimchi.guest_edit_main = function() {
initStorageListeners();
setupInterface();
+ setupPermission();
kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index ded892c..bb5f28d 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -38,6 +38,9 @@
<li>
<a href="#form-guest-edit-interface">$_("Interface")</a>
</li>
+ <li>
+ <a href="#form-guest-edit-permission">$_("Permission")</a>
+ </li>
</ul>
<form id="form-guest-edit-general">
<fieldset class="guest-edit-fieldset">
@@ -109,6 +112,31 @@
</div>
<div class="body"></div>
</form>
+ <form id="form-guest-edit-permission" class="guest-edit-permission">
+ <div class="column avail">
+ <div class="title">$_("Available system users and groups")</div>
+ <input type="text" id="permission-searchBox">
+ <div class="body">
+ <div class="head">
+ <div class="column column-user"><div class="item">Users</div></div>
+ <div class="column column-group"><div class="item">Groups</div></div>
+ </div>
+ <div id="permission-avail-users" class="column column-user"></div>
+ <div id="permission-avail-groups" class="column column-group"></div>
+ </div>
+ </div>
+ <div class="column control">
+ <button id="permissionGo"> > </button>
+ <button id="permissionBack"> < </button>
+ </div>
+ <div class="column selected">
+ <div class="title">$_("Selected system users and groups")</div>
+ <div class="body">
+ <div id="permission-sel-users"></div>
+ <div id="permission-sel-groups"></div>
+ </div>
+ </div>
+ </form>
</div>
</div>
<footer>
@@ -117,6 +145,9 @@
<span class="text">$_("Save")</span>
</button>
</div>
+ <button id="form-guest-edit-permission-save" class="btn-normal hidden">
+ <span class="text">$_("Save")</span>
+ </button>
</footer>
</div>
<script id="cdrom-row-tmpl" type="text/html">
@@ -186,6 +217,12 @@
</span>
</div>
</script>
+<script id="permission-item" type="text/html">
+<div class="item">
+ <span class="icon {class}"></span>
+ <label>{val}</label>
+</div>
+</script>
<script type="text/javascript">
kimchi.guest_edit_main();
</script>
--
1.7.1
More information about the Kimchi-devel
mailing list