diff --git a/xCAT-UI/css/style.css b/xCAT-UI/css/style.css index ad52d320c..8286748ff 100644 --- a/xCAT-UI/css/style.css +++ b/xCAT-UI/css/style.css @@ -1,815 +1,868 @@ -/*--- Dialogs ---*/ -.ui-dialog input { - border: solid 1px #BDBDBD; - font: 12px sans-serif; -} - -.ui-dialog label,.ui-dialog input,.ui-dialog p,.ui-dialog button,.ui-dialog td { - font: 12px sans-serif; -} - -.ui-widget { - font: 12px sans-serif; -} - -.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button { - font: 12px sans-serif; -} - -/*--- Tooltip ---*/ -.tooltip { - background-color: #000; - border: 1px solid #fff; - padding: 10px 15px; - display: none; - color: #fff; - text-align: left; - max-width: 300px; - font-size: 10px; - /* Outline radius for firefox only */ - -moz-box-shadow: 0 0 10px #000; - -webkit-box-shadow: 0 0 10px #000; -} - -.tooltip h3 { - margin: 0px; -} - -/*--- Header ---*/ -#header { - height: 39px; - width: 1000px; - margin: 0px auto; - -moz-border-radius: .3em; - -webkit-border-radius: .3em; - border-radius: .3em; -} - -#header ul { - float: left; - list-style: none; - padding: 0 0 0 30px; - margin: 0; - height: 39px; - position: relative; -} - -#header ul li { - display: block; - float: left; - position: relative; -} - -#header ul li a { - text-decoration: none; - cursor: pointer; - float: left; - font: 14px sans-serif; - font-weight: bold; - padding: 11px 30px; - cursor: pointer; -} - -/* User name and log out */ -#header div { - float: right; - margin: 12px; -} - -#header div a { - padding: 0px 6px; - color: #0000FF; - text-decoration: none; - cursor: pointer; - font-weight: normal; -} - -#header div a:hover { - color: #FF0000; -} - -/*--- Body and content ---*/ -body { - background: #1C1C1C; - font: 12px sans-serif; -} - -.content { - -moz-border-radius: .3em; - -webkit-border-radius: .3em; - border-radius: .3em; - width: 1000px; - min-height: 600px; - margin: 10px auto; - background-color: white; - overflow: auto; -} - -.ui-widget-content { - background: white; - color: inherit; -} - -pre { - font-size: 10px; -} - -/*--- Groups ---*/ -#groups { - width: 150px; - vertical-align: top; - float: left; - position: relative; - margin-top: 10px; -} - -#groups ul h3 { - text-transform: uppercase; - color: #424242; - display: inline-table; -} - -#groups a { - color: #0000FF; - display: inline-table; - padding: 5px 0px 5px 20px; /* Top right bottom left */ - text-decoration: none; - cursor: pointer; -} - -#groups .grouplabel { - padding: 5px 0px 5px 10px; - font-weight: bold; - font-size: 15px; -} - -#groups .groupdiv { - padding-left: 10px; -} - -#groups .groupdiv div { - color: blue; - padding: 5px 0px 5px 20px; -} - -#groups .groupdiv div:hover { - background: #E7EBFF; - cursor: pointer; -} - -#groups .selectgroup { - background: #E5E5E5; - font-weight: bold; -} - -#groups .actionDiv { - text-align: right; - padding-right: 5px; - border-top: thin solid #E7EBFF; -} - -/*--- Nodes section ---*/ -#nodes { - width: 790px; - min-height: 570px; - margin: 10px 0px 0px 0px; - padding: 0px 0px 0px 5px; - display: inline-block; - border-left: medium solid #E5E5E5; -} - -.summarypie { - width: 260px; - height: 220px; -} - -.summarypie td { - min-width: 0px; -} - -#summaryTab td { - border: 0px; - padding: 0px; - text-align: left; - line-height: 1; -} - -/*--- Info and warning bar ---*/ -span.ui-icon-info { - float: left; - margin-right: 0.3em; -} - -.ui-icon { - float: left; -} - -.ui-button { - display: inline-block; - position: relative; - padding: 0; - margin: 5px; - text-decoration: none !important; - cursor: pointer; - text-align: center; - zoom: 1; - overflow: visible; - text-align: center -} - -/*--- jQuery tabs ---*/ -.tab { - font: 12px sans-serif; - border-style: none; - overflow: visible; -} - -.tab p { - word-wrap: break-word; -} - -.tab a { - cursor: pointer; -} - -.tab .ui-icon-close { - float: left; - margin: 0.4em 0.2em 0 0; - cursor: pointer; -} - -/*--- Inventory and user entry ---*/ -.tab table { - border-width: 1px; - border-spacing: 0px; - border-style: solid; - border-color: #BDBDBD; - border-collapse: collapse; -} - -.tab th { - font: bold 12px sans-serif; - padding: 10px; - border-width: 1px; - border-style: solid; - vertical-align: middle; - text-align: center; -} - -.tab td { - font: 12px sans-serif; - padding: 5px 15px; - border-width: 1px; - border-style: solid; - border-color: #BDBDBD; - vertical-align: middle; -} - -.tab table a { - color: blue; -} - -.tab span a,.tab li a { - text-decoration: none; - cursor: pointer; -} - -fieldset { - margin-bottom: 5px; - border-width: 1px 0 0 0; - border-style: solid none none none; - border-color: gray; -} - -.tab label { - color: #424242; - display: inline-block; - line-height: 1.5; - vertical-align: top; - width: 140px; -} - -legend { - font: 12px sans-serif; - color: #424242; - font-weight: bold; - padding: 10px 5px; -} - -.tab ol { - margin: 0; - padding: 0; -} - -.tab li { - list-style: none; - padding: 5px; - margin: 1; -} - -.tab textarea { - font: 12px sans-serif; - border: solid 0px #BDBDBD; - padding: 5px; - display: inline-table; - width: 400px; - height: 300px; -} - -/*--- menu Div Actions bar ---*/ -.menuDiv { - padding: 0.5em; - height: 30px; -} - -.sf-menu { - border-radius: 0.3em 0.3em 0.3em 0.3em; - margin-bottom: 0; - background: none; - border: 0px solid; -} - -.sf-menu ul li { - width: 99%; -} - -.sf-menu .sf-menu { - border: 0px solid; -} - -.sf-menu li:hover,.sf-menu li.sfHover { - background: none; -} - -.sf-sub-indicator { - right: 0; -} - -.actionBar { - display: inline-table; -} - -.actionBar div { - padding: 10px 0px; -} - -.actionBar a { - font-weight: bold; -} - -.actionBar li { - list-style: none; - margin: 0; -} - -/*--- jQuery datatable ---*/ -.dataTables_wrapper { - width: auto; - margin: 10px auto; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - background-color: #f5f5f5; -} - -/*** Show X entries ***/ -.dataTables_length { - width: 40%; - float: left; - padding: 10px 20px; - text-align: left; -} - -/*** Search ***/ -.dataTables_filter { - width: 40%; - display: block; - float: right; - text-align: right; -} - -.tab input,select { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - padding: 4px; -} - -/*** Showing X to X of X entries ***/ -.dataTables_info { - padding: 10px 20px; - width: 40%; - float: left; -} - -/*** < > buttons ***/ -.paginate_disabled_previous,.paginate_enabled_previous,.paginate_disabled_next,.paginate_enabled_next { - height: 19px; - width: 19px; - margin-left: 2px; - float: left; -} - -/*** Table ***/ -.datatable { - width: 100%; - border-spacing: 0px; - border-collapse: collapse; - display: inline-table; -} - -.datatable th,td { - font: 12px sans-serif; - padding: 5px 0px; - white-space: nowrap; /* Do not use word wrap */ - vertical-align: middle; - text-align: center; - min-width: 30px; -} - -.datatable th { - font: bold 12px sans-serif; - border-width: 0px; -} - -/*** Row color (odd) ***/ -.datatable tr.odd { - background-color: #E0ECF8; -} - -.datatable tr.odd td.sorting_1 { - background-color: #A9D0F5; -} - -/*** Row color (even) ***/ -.datatable tr.even { - background-color: #EFF5FB; -} - -.datatable tr.even td.sorting_1 { - background-color: #CEE3F6; -} - -.datatable a { - text-decoration: none; - color: blue; - cursor: pointer; -} - -.datatable a:hover { - color: #FF0000; -} - -/*--- Editable column ---*/ -.tab .datatable textarea { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - overflow: hidden; -} - -.tab .datatable button { - border: solid 1px #BDBDBD; - -moz-border-radius: .3em; - -webkit-border-radius: .3em; - padding: 5px 10px; - margin: 0 10px; - background-color: #D8D8D8; - color: #424242; - font-size: 12px; -} - -.tab .datatable button:hover { - background-color: #E6E6E6; -} - -.sorting_asc,.sorting_desc,.sorting { - background: none; -} - -/*--- jQuery context menu ---*/ -.context-menu-theme-vista { - background: #FAFAFA url(../images/contextmenu/context-menu-bg.gif) - repeat-y left top; - border: 1px solid #868686; -} - -.context-menu-theme-vista .context-menu-item { - text-align: left; - cursor: pointer; - color: black; - font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; - font-size: 12px; -} - -.context-menu-theme-vista .context-menu-separator { - margin: 0px 0px 0px 32px; - font-size: 0px; - border-top: 1px solid #C5C5C5; - border-bottom: 1px solid #F5F5F5; -} - -.context-menu-theme-vista .context-menu-item-hover { - background: transparent - url(../images/contextmenu/context-menu-item-hover.gif) repeat-x left - center; - border: 1px solid #D7D0B3; -} - -.context-menu-theme-vista .context-menu-item .context-menu-item-inner { - padding: 4px 16px 4px 35px; - margin-left: 1px; - background-color: none; - background-repeat: no-repeat; - background-position: 3px center; - background-image: none; -} - -.context-menu-theme-vista .context-menu-item-hover .context-menu-item-inner { - padding: 3px 15px 3px 35px; - margin-left: 0px; -} - -.context-menu-theme-vista .context-menu-item-disabled { - color: #A7A7A7; -} - -/*--- Forms ---*/ -.form label { - color: #424242; - line-height: 1.5; - vertical-align: middle; - width: 120px; - padding: 0px 0px 0px 20px; - display: inline-block; -} - -.form div { - margin: 5px 0; - display: block; -} - -.form ol { - margin: 0; - padding: 0; -} - -.form li { - list-style: none; - padding: 5px 5px 5px 20px; - margin: 0; -} - -.form .indent { - display: inline-table; -} - -.form input,.form textarea,.form select { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - padding: 5px; - display: inline-block; -} - -.form textarea { - width: 350px; - height: 150px; -} - -table a { - font: 12px sans-serif; - text-decoration: none; - color: #0000FF; - cursor: pointer; -} - -table a:hover { - color: #FF0000; -} - -.button { - padding: 3px 10px; - margin: 0 10px; - background-color: #314e90; - border: solid 1px #f4f4f4; - color: #ffffff; - font-weight: bold; - font-size: 12px; -} - -.button:hover { - border: solid 1px #d4d4d4; -} - -/*--- Provision disk table ---*/ -.provision table { - border-width: 1px; - border-spacing: 0px; - border-style: solid; - border-color: #BDBDBD; - border-collapse: collapse; - display: inline-table; -} - -.provision input { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - padding: 3px; - width: 60px; -} - -/*--- Provision and clone table ---*/ -.special table { - border-width: 1px; - border-spacing: 0px; - border-style: solid; - border-color: #BDBDBD; - border-collapse: collapse; - display: inline-table; -} - -.special input { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - padding: 3px; -} - -/*--- Provision and monitor forms ---*/ -.monitor-normal { - background: #66CD00; - cursor: pointer; -} - -.mornitor-warning { - background: #FFD700; - cursor: pointer; -} - -.monitor-error { - background: #FF3030; -} - -.monitor-unknown { - background: #8B8B7A; -} - -.monitor-node-li { - width: 10px; - height: 10px; - float: left; - border: 1px solid white; -} - -.monitor-sum-div { - width: 300px; - height: 180px; - float: left; - margin: 0px 0px 10px 10px; -} - -.monitor-sum-div td { - padding: 0; - border-style: none; - font-size: 10px; -} - -.monitor-node-div { - width: 240px; - height: 120px; - margin: 0px 0px 15px 0px; -} - -.monitor-zoom-link { - cursor: pointer; - color: blue; -} - -.provision div,.monitor div { - margin: 10px 0; - display: block; -} - -.provision textarea,.monitor textarea { - font: 12px sans-serif; - border: solid 1px #BDBDBD; - padding: 5px; - display: inline-table; - width: 350px; - height: 150px; -} - -/*--- Physical layout section ---*/ -.frameDiv { - width: 179px; - height: 500px; - font-size: 10px; - background: url(../images/nodes/bpa.jpg); - border-width: 2px; - text-align: left; - white-space: normal; -} - -.fspDiv2 { - font-size: 12px; - height: 21px; - line-height: 21px; - width: 140px; - text-align: center; - background: url(../images/nodes/2ufsp.jpg); - border-style: solid; - border-width: 1px; - cursor: pointer; - display: inline-block; -} - -.fspDiv4 { - font-size: 12px; - height: 44px; - line-height: 44px; - width: 140px; - text-align: center; - background: url(../images/nodes/4ufsp.jpg); - border-style: solid; - border-width: 1px; - cursor: pointer; - display: inline-block; -} - -.fspDiv42 { - width: 179px; - height: 500px; - font-size: 15px; - background: url(../images/nodes/42ufsp.jpg); - border-width: 2px; - cursor: pointer; -} - -.lparDiv { - margin: 1px 0px 0px 1px; - width: 80px; - height: 10px; - opacity: 1; -} - -.lparStatus { - min-width: 10px; - height: 11px; -} - -.fspCheckbox { - padding: 0px; - margin: 3px 3px 1px 3px; -} - -.chasisDiv { - width: 172px; - height: 108px; - font-size: 10px; - background: url(../images/nodes/chasis.jpg); - border-width: 2px; - text-align: left; - white-space: normal; - padding: 11px 0px 0px 11px; -} - -.bladeDiv { - float: left; - width: 11px; - height: 89px; - text-align: left; - white-space: normal; -} - -.bladeInsertDiv { - background: url(../images/nodes/blade.jpg); -} - -.xNodeDiv { - font-size: 12px; - height: 21px; - line-height: 21px; - width: 140px; - text-align: center; - background: url(../images/nodes/2ufsp.jpg); - border-style: solid; - border-width: 1px; - cursor: pointer; - display: inline-block; -} - -/*--- jqPlot Pie legend ---*/ -td.jqplot-table-legend { - border-width: 0px; -} - -td.jqplot-table-legend>div { - border-width: 0px; -} - -/*--- setup wizard section ---*/ -#discoverTab table{ - border-style: none; -} - -#discoverTab td{ - border-style: none; - text-align: left; +/*--- Dialogs ---*/ +.ui-dialog input { + border: solid 1px #BDBDBD; + font: 12px sans-serif; +} + +.ui-dialog label,.ui-dialog input,.ui-dialog p,.ui-dialog button,.ui-dialog td { + font: 12px sans-serif; +} + +.ui-widget { + font: 12px sans-serif; +} + +.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button { + font: 12px sans-serif; +} + +/*--- Tooltip ---*/ +.tooltip { + background-color: #000; + border: 1px solid #fff; + padding: 10px 15px; + display: none; + color: #fff; + text-align: left; + max-width: 300px; + font-size: 10px; + /* Outline radius for firefox only */ + -moz-box-shadow: 0 0 10px #000; + -webkit-box-shadow: 0 0 10px #000; +} + +.tooltip h3 { + margin: 0px; +} + +/*--- Header ---*/ +#header { + height: 39px; + width: 1000px; + margin: 0px auto; + -moz-border-radius: .3em; + -webkit-border-radius: .3em; + border-radius: .3em; +} + +#header ul { + float: left; + list-style: none; + padding: 0 0 0 30px; + margin: 0; + height: 39px; + position: relative; +} + +#header ul li { + display: block; + float: left; + position: relative; +} + +#header ul li a { + text-decoration: none; + cursor: pointer; + float: left; + font: 14px sans-serif; + font-weight: bold; + padding: 11px 30px; + cursor: pointer; +} + +/* User name and log out */ +#header div { + float: right; + margin: 12px; +} + +#header div a { + padding: 0px 6px; + color: #0000FF; + text-decoration: none; + cursor: pointer; + font-weight: normal; +} + +#header div a:hover { + color: #FF0000; +} + +/*--- Body and content ---*/ +body { + background: #1C1C1C; + font: 12px sans-serif; +} + +.content { + -moz-border-radius: .3em; + -webkit-border-radius: .3em; + border-radius: .3em; + width: 1000px; + min-height: 600px; + margin: 10px auto; + background-color: white; + overflow: auto; +} + +.ui-widget-content { + background: white; + color: inherit; +} + +pre { + font-size: 10px; +} + +/*--- Groups ---*/ +#groups { + width: 150px; + vertical-align: top; + float: left; + position: relative; + margin-top: 10px; +} + +#groups ul h3 { + text-transform: uppercase; + color: #424242; + display: inline-table; +} + +#groups a { + color: #0000FF; + display: inline-table; + padding: 5px 0px 5px 20px; /* Top right bottom left */ + text-decoration: none; + cursor: pointer; +} + +#groups .grouplabel { + padding: 5px 0px 5px 10px; + font-weight: bold; + font-size: 15px; +} + +#groups .groupdiv { + padding-left: 10px; +} + +#groups .groupdiv div { + color: blue; + padding: 5px 0px 5px 20px; +} + +#groups .groupdiv div:hover { + background: #E7EBFF; + cursor: pointer; +} + +#groups .selectgroup { + background: #E5E5E5; + font-weight: bold; +} + +#groups .actionDiv { + text-align: right; + padding-right: 5px; + border-top: thin solid #E7EBFF; +} + +/*--- Nodes section ---*/ +#nodes { + width: 790px; + min-height: 570px; + margin: 10px 0px 0px 0px; + padding: 0px 0px 0px 5px; + display: inline-block; + border-left: medium solid #E5E5E5; +} + +.summarypie { + width: 260px; + height: 220px; +} + +.summarypie td { + min-width: 0px; +} + +#summaryTab td { + border: 0px; + padding: 0px; + text-align: left; + line-height: 1; +} + +/*--- Info and warning bar ---*/ +span.ui-icon-info { + float: left; + margin-right: 0.3em; +} + +.ui-icon { + float: left; +} + +.ui-button { + display: inline-block; + position: relative; + padding: 0; + margin: 5px; + text-decoration: none !important; + cursor: pointer; + text-align: center; + zoom: 1; + overflow: visible; + text-align: center +} + +/*--- jQuery tabs ---*/ +.tab { + font: 12px sans-serif; + border-style: none; + overflow: visible; +} + +.tab p { + word-wrap: break-word; +} + +.tab a { + cursor: pointer; +} + +.tab .ui-icon-close { + float: left; + cursor: pointer; +} + +/*--- Inventory and user entry ---*/ +.tab table { + border-width: 1px; + border-spacing: 0px; + border-style: solid; + border-color: #BDBDBD; + border-collapse: collapse; +} + +.tab th { + font: bold 12px sans-serif; + padding: 10px; + border-width: 1px; + border-style: solid; + vertical-align: middle; + text-align: center; +} + +.tab td { + font: 12px sans-serif; + padding: 5px 15px; + border-width: 1px; + border-style: solid; + border-color: #BDBDBD; + vertical-align: middle; +} + +.tab table a { + color: blue; +} + +.tab span a,.tab li a { + text-decoration: none; + cursor: pointer; +} + +fieldset { + margin-bottom: 5px; + border-width: 1px 0 0 0; + border-style: solid none none none; + border-color: gray; +} + +.tab label { + color: #424242; + display: inline-block; + line-height: 1.5; + vertical-align: top; + width: 140px; +} + +legend { + font: 12px sans-serif; + color: #424242; + font-weight: bold; + padding: 10px 5px; +} + +.tab ol { + margin: 0; + padding: 0; +} + +.tab li { + list-style: none; + padding: 5px; + margin: 1; +} + +.tab textarea { + font: 12px sans-serif; + border: solid 0px #BDBDBD; + padding: 5px; + display: inline-table; + width: 400px; + height: 300px; +} + +/*--- menu Div Actions bar ---*/ +.menuDiv { + padding: 0.5em; + height: 30px; +} + +.sf-menu { + border-radius: 0.3em 0.3em 0.3em 0.3em; + margin-bottom: 0; + background: none; + border: 0px solid; +} + +.sf-menu ul li { + width: 99%; +} + +.sf-menu .sf-menu { + border: 0px solid; +} + +.sf-menu li:hover,.sf-menu li.sfHover { + background: none; +} + +.sf-sub-indicator { + right: 0; +} + +.actionBar { + display: inline-table; +} + +.actionBar div { + padding: 10px 0px; +} + +.actionBar a { + font-weight: bold; +} + +.actionBar li { + list-style: none; + margin: 0; +} + +/*--- jQuery datatable ---*/ +.dataTables_wrapper { + width: auto; + margin: 10px auto; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: #f5f5f5; +} + +/*** Show X entries ***/ +.dataTables_length { + width: 40%; + float: left; + padding: 10px 20px; + text-align: left; +} + +/*** Search ***/ +.dataTables_filter { + width: 40%; + display: block; + float: right; + text-align: right; + margin: 5px 0px; +} + +.tab input,select { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + padding: 4px; +} + +/*** Showing X to X of X entries ***/ +.dataTables_info { + padding: 10px 20px; + width: 40%; + float: left; +} + +/*** < > buttons ***/ +.paginate_disabled_previous,.paginate_enabled_previous,.paginate_disabled_next,.paginate_enabled_next { + height: 19px; + width: 19px; + margin-left: 2px; + float: left; +} + +/*** Table ***/ +.datatable { + width: 100%; + border-spacing: 0px; + border-collapse: collapse; + display: inline-table; +} + +.dataTables_filter label { + display: inline; + vertical-align: middle; +} + +.datatable th,td { + font: 12px sans-serif; + padding: 5px 0px; + white-space: nowrap; /* Do not use word wrap */ + vertical-align: middle; + text-align: center; + min-width: 30px; +} + +.datatable th { + font: bold 12px sans-serif; + border-width: 0px; +} + +.form .datatable th,td { + font: 12px sans-serif; + padding: 5px 0px; + white-space: nowrap; /* Do not use word wrap */ + vertical-align: middle; + text-align: center; + min-width: 30px; +} + +.form .datatable th { + font: bold 12px sans-serif; + border-width: 0px; +} + +/*** Row color (odd) ***/ +.datatable tr.odd { + background-color: #E0ECF8; +} + +.datatable tr.odd td.sorting_1 { + background-color: #A9D0F5; +} + +/*** Row color (even) ***/ +.datatable tr.even { + background-color: #EFF5FB; +} + +.datatable tr.even td.sorting_1 { + background-color: #CEE3F6; +} + +.datatable a { + text-decoration: none; + color: blue; + cursor: pointer; +} + +.datatable a:hover { + color: #FF0000; +} + +/*--- Editable column ---*/ +.tab .datatable textarea { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + overflow: hidden; +} + +.tab .datatable button { + border: solid 1px #BDBDBD; + -moz-border-radius: .3em; + -webkit-border-radius: .3em; + padding: 5px 10px; + margin: 0 10px; + background-color: #D8D8D8; + color: #424242; + font-size: 12px; +} + +.tab .datatable button:hover { + background-color: #E6E6E6; +} + +.sorting_asc,.sorting_desc,.sorting { + background: none; +} + +/*--- jQuery context menu ---*/ +.context-menu-theme-vista { + background: #FAFAFA url(../images/contextmenu/context-menu-bg.gif) + repeat-y left top; + border: 1px solid #868686; +} + +.context-menu-theme-vista .context-menu-item { + text-align: left; + cursor: pointer; + color: black; + font-size: 12px; +} + +.context-menu-theme-vista .context-menu-separator { + margin: 0px 0px 0px 32px; + font-size: 0px; + border-top: 1px solid #C5C5C5; + border-bottom: 1px solid #F5F5F5; +} + +.context-menu-theme-vista .context-menu-item-hover { + background: transparent + url(../images/contextmenu/context-menu-item-hover.gif) repeat-x left + center; + border: 1px solid #D7D0B3; +} + +.context-menu-theme-vista .context-menu-item .context-menu-item-inner { + padding: 4px 16px 4px 35px; + margin-left: 1px; + background-color: none; + background-repeat: no-repeat; + background-position: 3px center; + background-image: none; +} + +.context-menu-theme-vista .context-menu-item-hover .context-menu-item-inner { + padding: 3px 15px 3px 35px; + margin-left: 0px; +} + +.context-menu-theme-vista .context-menu-item-disabled { + color: #A7A7A7; +} + +/*--- Forms ---*/ +.form label { + color: #424242; + line-height: 1.5; + vertical-align: middle; + width: 140px; + padding: 0px 0px 0px 20px; + display: inline-block; +} + +.form div { + margin: 5px 0; + display: block; +} + +.form ol { + margin: 0; + padding: 0; +} + +.form li { + list-style: none; + padding: 5px 5px 5px 20px; + margin: 0; +} + +.form .indent { + display: inline-table; +} + +.form input,.form textarea,.form select { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + padding: 5px; + display: inline-block; +} + +.form textarea { + width: 350px; + height: 150px; +} + +.form table { + border-width: 1px; + border-spacing: 0px; + border-style: solid; + border-color: #BDBDBD; + border-collapse: collapse; +} + +.form th { + font: bold 12px sans-serif; + padding: 10px; + border-width: 1px; + border-style: solid; + vertical-align: middle; + text-align: center; +} + +.form td { + font: 12px sans-serif; + padding: 5px 15px; + border-width: 1px; + border-style: solid; + border-color: #BDBDBD; + vertical-align: middle; +} + +.form table a { + color: blue; +} + +/*--- Datatable header and body ---*/ +.form .dataTables_wrapper div { + margin: 0px; +} + +table a { + font: 12px sans-serif; + text-decoration: none; + color: #0000FF; + cursor: pointer; +} + +table a:hover { + color: #FF0000; +} + +.button { + padding: 3px 10px; + margin: 0 10px; + background-color: #314e90; + border: solid 1px #f4f4f4; + color: #ffffff; + font-weight: bold; + font-size: 12px; +} + +.button:hover { + border: solid 1px #d4d4d4; +} + +/*--- Provision disk table ---*/ +.provision table { + border-width: 1px; + border-spacing: 0px; + border-style: solid; + border-color: #BDBDBD; + border-collapse: collapse; + display: inline-table; +} + +.provision input { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + padding: 3px; + width: 60px; +} + +/*--- Provision and clone table ---*/ +.special table { + border-width: 1px; + border-spacing: 0px; + border-style: solid; + border-color: #BDBDBD; + border-collapse: collapse; + display: inline-table; +} + +.special input { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + padding: 3px; +} + +/*--- Provision and monitor forms ---*/ +.monitor-normal { + background: #66CD00; + cursor: pointer; +} + +.mornitor-warning { + background: #FFD700; + cursor: pointer; +} + +.monitor-error { + background: #FF3030; +} + +.monitor-unknown { + background: #8B8B7A; +} + +.monitor-node-li { + width: 10px; + height: 10px; + float: left; + border: 1px solid white; +} + +.monitor-sum-div { + width: 300px; + height: 180px; + float: left; + margin: 0px 0px 10px 10px; +} + +.monitor-sum-div td { + padding: 0; + border-style: none; + font-size: 10px; +} + +.monitor-node-div { + width: 240px; + height: 120px; + margin: 0px 0px 15px 0px; +} + +.monitor-zoom-link { + cursor: pointer; + color: blue; +} + +.provision div,.monitor div { + margin: 10px 0; + display: block; +} + +.provision textarea,.monitor textarea { + font: 12px sans-serif; + border: solid 1px #BDBDBD; + padding: 5px; + display: inline-table; + width: 350px; + height: 150px; +} + +/*--- Physical layout section ---*/ +.frameDiv { + width: 179px; + height: 500px; + font-size: 10px; + background: url(../images/nodes/bpa.jpg); + border-width: 2px; + text-align: left; + white-space: normal; +} + +.fspDiv2 { + font-size: 12px; + height: 21px; + line-height: 21px; + width: 140px; + text-align: center; + background: url(../images/nodes/2ufsp.jpg); + border-style: solid; + border-width: 1px; + cursor: pointer; + display: inline-block; +} + +.fspDiv4 { + font-size: 12px; + height: 44px; + line-height: 44px; + width: 140px; + text-align: center; + background: url(../images/nodes/4ufsp.jpg); + border-style: solid; + border-width: 1px; + cursor: pointer; + display: inline-block; +} + +.fspDiv42 { + width: 179px; + height: 500px; + font-size: 15px; + background: url(../images/nodes/42ufsp.jpg); + border-width: 2px; + cursor: pointer; +} + +.lparDiv { + margin: 1px 0px 0px 1px; + width: 80px; + height: 10px; + opacity: 1; +} + +.lparStatus { + min-width: 10px; + height: 11px; +} + +.fspCheckbox { + padding: 0px; + margin: 3px 3px 1px 3px; +} + +.chasisDiv { + width: 172px; + height: 108px; + font-size: 10px; + background: url(../images/nodes/chasis.jpg); + border-width: 2px; + text-align: left; + white-space: normal; + padding: 11px 0px 0px 11px; +} + +.bladeDiv { + float: left; + width: 11px; + height: 89px; + text-align: left; + white-space: normal; +} + +.bladeInsertDiv { + background: url(../images/nodes/blade.jpg); +} + +.xNodeDiv { + font-size: 12px; + height: 21px; + line-height: 21px; + width: 140px; + text-align: center; + background: url(../images/nodes/2ufsp.jpg); + border-style: solid; + border-width: 1px; + cursor: pointer; + display: inline-block; +} + +/*--- jqPlot Pie legend ---*/ +td.jqplot-table-legend { + border-width: 0px; +} + +td.jqplot-table-legend>div { + border-width: 0px; +} + +/*--- setup wizard section ---*/ +#discoverTab table{ + border-style: none; +} + +#discoverTab td{ + border-style: none; + text-align: left; } \ No newline at end of file diff --git a/xCAT-UI/ganglianode.php b/xCAT-UI/ganglianode.php index 3ee6b5d89..88f8d060f 100644 --- a/xCAT-UI/ganglianode.php +++ b/xCAT-UI/ganglianode.php @@ -14,19 +14,20 @@ EEE; ?> diff --git a/xCAT-UI/js/configure/configure.js b/xCAT-UI/js/configure/configure.js index 2adcd2cec..22f20bc3a 100644 --- a/xCAT-UI/js/configure/configure.js +++ b/xCAT-UI/js/configure/configure.js @@ -1,488 +1,556 @@ -/** - * Global variables - */ -var configTabs; // Config tabs -var configDatatables = new Object(); // Datatables on the config page - -/** - * Set the datatable - * - * @param id The ID of the datatable - * @param obj Datatable object - */ -function setConfigDatatable(id, obj) { - configDatatables[id] = obj; -} - -/** - * Get the datatable with the given ID - * - * @param id The ID of the datatable - * @return Datatable object - */ -function getConfigDatatable(id) { - return configDatatables[id]; -} - -/** - * Set the configure tab - * - * @param obj Tab object - */ -function setConfigTab(obj) { - configTabs = obj; -} - -/** - * Get the configure tab - * - * @param Nothing - * @return Tab object - */ -function getConfigTab() { - return configTabs; -} - -/** - * Load configure page - */ -function loadConfigPage() { - // If the configure page has already been loaded - if ($('#content').children().length) { - // Do not reload configure page - return; - } - - // Create configure tab - var tab = new Tab(); - setConfigTab(tab); - tab.init(); - $('#content').append(tab.object()); - - // Create loader - var loader = $('
').append(createLoader()); - - // Add tab to configure xCAT tables - tab.add('configTablesTab', 'Tables', loader, false); - - // Add the update tab - tab.add('updateTab', 'Update', '', false); - - // Add the discover tab - tab.add('discoverTab', 'Discover', '', false); - - // Add the self-service tab - tab.add('serviceTab', 'Service', '', false); - - // Get list of tables and their descriptions - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'tabdump', - tgt : '', - args : '-d', - msg : '' - }, - - success : loadTableNames - }); - - loadUpdatePage(); - loadDiscoverPage(); - loadServicePage(); -} - -/** - * Load xCAT database table names and their descriptions - * - * @param data Data returned from HTTP request - */ -function loadTableNames(data) { - // Get output - var tables = data.rsp; - - // Remove loader - var tabId = 'configTablesTab'; - $('#' + tabId).find('img').hide(); - - // Create a groups division - var tablesDIV = $('
'); - $('#' + tabId).append(tablesDIV); - - // Create info bar - var infoBar = createInfoBar('Select a table to view or edit.'); - tablesDIV.append(infoBar); - - // Create a list for the tables - var list = $(''); - // Loop through each table - for ( var i = 0; i < tables.length; i++) { - // Create a link for each table - var args = tables[i].split(':'); - var link = $('' + args[0] + ''); - - // Open table on click - link.bind('click', function(e) { - // Get table ID that was clicked - var id = (e.target) ? e.target.id : e.srcElement.id; - - // Create loader - var loader = $('
').append(createLoader()); - - // Add a new tab for this table - var configTab = getConfigTab(); - if (!$('#' + id + 'Tab').length) { - configTab.add(id + 'Tab', id, loader, true); - - // Get contents of selected table - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'tabdump', - tgt : '', - args : id, - msg : id - }, - - success : loadTable - }); - } - - // Select new tab - configTab.select(id + 'Tab'); - }); - - var item = $('
  • '); - item.append(link); - - // Append the table description - item.append(': ' + args[1]); - - // Append item to list - list.append(item); - } - - tablesDIV.append(list); -} - -/** - * Load a given database table - * - * @param data Data returned from HTTP request - */ -function loadTable(data) { - // Get response - var rsp = data.rsp; - // Get table ID - var id = data.msg; - - // Remove loader - var tabId = id + 'Tab'; - $('#' + tabId).find('img').remove(); - - // Create info bar - var infoBar = createInfoBar('Click on a cell to edit. Click outside the table to write to the cell. Once you are satisfied with how the table looks, click on Save.'); - $('#' + tabId).append(infoBar); - - // Create action bar - var actionBar = $('
    '); - $('#' + tabId).append(actionBar); - - // Get table headers - var args = rsp[0].replace('#', ''); - var headers = args.split(','); - - // Create container for original table contents - var origCont = new Array(); // Original table content - origCont[0] = rsp[0].split(','); // Headers - - // Create container for new table contents - var newCont = new Object(); - var tmp = new Object(); - tmp[0] = '#' + headers[0]; // Put a # in front of the header - for ( var i = 1; i < headers.length; i++) { - tmp[i] = headers[i]; - } - newCont[0] = tmp; - - // Create a new datatable - var tableId = id + 'Datatable'; - var table = new DataTable(tableId); - - // Add column for the remove row button - headers.unshift(''); - table.init(headers); - headers.shift(); - - // Append datatable to tab - $('#' + tabId).append(table.object()); - - // Add table rows - // Start with the 2nd row (1st row is the headers) - for ( var i = 1; i < rsp.length; i++) { - // Split into columns - var cols = rsp[i].split(','); - - // Go through each column - for ( var j = 0; j < cols.length; j++) { - - // If the column is not complete - if (cols[j].count('"') == 1) { - while (cols[j].count('"') != 2) { - // Merge this column with the adjacent one - cols[j] = cols[j] + "," + cols[j + 1]; - - // Remove merged row - cols.splice(j + 1, 1); - } - } - - // Replace quote - cols[j] = cols[j].replace(new RegExp('"', 'g'), ''); - } - - // Add remove button - cols.unshift(''); - - // Add row - table.add(cols); - - // Save original table content - origCont[i] = cols; - } - - // Turn table into datatable - var dTable = $('#' + id + 'Datatable').dataTable({ - 'iDisplayLength': 50, - 'bLengthChange': false, - "sScrollX": "100%", - "bAutoWidth": true - }); - - /** - * Enable editable columns - */ - // Do not make 1st column editable - $('#' + tableId + ' td:not(td:nth-child(1))').editable( - function(value, settings) { - // Get column index - var colPos = this.cellIndex; - // Get row index - var rowPos = dTable.fnGetPosition(this.parentNode); - - // Update datatable - dTable.fnUpdate(value, rowPos, colPos); - - return (value); - }, { - onblur : 'submit', // Clicking outside editable area submits changes - type : 'textarea', - placeholder: ' ', - height : '30px' // The height of the text area - }); - - // Create action bar - var actionBar = $('
    '); - - var saveLnk = $('Save'); - saveLnk.click(function() { - // Get table ID and name - var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); - var tableName = tableId.replace('Datatable', ''); - - // Get datatable - var dTable = $('#' + tableId).dataTable(); - // Get the nodes from the table - var dRows = dTable.fnGetNodes(); - - // Go through each row - for ( var i = 0; i < dRows.length; i++) { - // If there is row with values - if (dRows[i]) { - // Go through each column - // Ignore the 1st column because it is a button - var cols = dRows[i].childNodes; - var vals = new Object(); - for ( var j = 1; j < cols.length; j++) { - var val = cols.item(j).firstChild.nodeValue; - - // Insert quotes - if (val == ' ') { - vals[j - 1] = ''; - } else { - vals[j - 1] = val; - } - } - - // Save row - newCont[i + 1] = vals; - } - } - - // Update xCAT table - $.ajax({ - type : 'POST', - url : 'lib/tabRestore.php', - dataType : 'json', - data : { - table : tableName, - cont : newCont - }, - success : function(data) { - // Create info message - var dialog = $('
    ').append(createInfoBar('Changes saved!')); - - // Open dialog - dialog.dialog({ - modal: true, - title: 'Info', - width: 400, - buttons: { - "Ok": function(){ - $(this).dialog("close"); - } - } - }); - } - }); - }); - - var undoLnk = $('Undo'); - undoLnk.click(function() { - // Get table ID - var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); - - // Get datatable - var dTable = $('#' + tableId).dataTable(); - - // Clear entire datatable - dTable.fnClearTable(); - - // Add original content back into datatable - for ( var i = 1; i < origCont.length; i++) { - dTable.fnAddData(origCont[i], true); - } - - // Enable editable columns (again) - // Do not make 1st column editable - $('#' + tableId + ' td:not(td:nth-child(1))').editable( - function(value, settings) { - // Get column index - var colPos = this.cellIndex; - // Get row index - var rowPos = dTable.fnGetPosition(this.parentNode); - - // Update datatable - dTable.fnUpdate(value, rowPos, colPos); - - return (value); - }, { - onblur : 'submit', // Clicking outside editable area submits changes - type : 'textarea', - placeholder: ' ', - height : '30px' // The height of the text area - }); - }); - - var addLnk = $('Add row'); - addLnk.click(function() { - // Create an empty row - var row = new Array(); - - /** - * Remove button - */ - row.push(''); - for ( var i = 0; i < headers.length; i++) { - row.push(''); - } - - // Get table ID and name - var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); - - // Get datatable - var dTable = $('#' + tableId).dataTable(); - - // Add the row to the data table - dTable.fnAddData(row); - - // Enable editable columns (again) - // Do not make 1st column editable - $('#' + tableId + ' td:not(td:nth-child(1))').editable( - function(value, settings) { - // Get column index - var colPos = this.cellIndex; - // Get row index - var rowPos = dTable.fnGetPosition(this.parentNode); - - // Update datatable - dTable.fnUpdate(value, rowPos, colPos); - - return (value); - }, { - onblur : 'submit', // Clicking outside editable area submits changes - type : 'textarea', - placeholder: ' ', - height : '30px' // The height of the text area - }); - }); - - // Create an action menu - var actionsMenu = createMenu([saveLnk, undoLnk, addLnk]); - actionsMenu.superfish(); - actionsMenu.css('display', 'inline-block'); - actionBar.append(actionsMenu); - - // Set correct theme for action menu - actionsMenu.find('li').hover(function() { - setMenu2Theme($(this)); - }, function() { - setMenu2Normal($(this)); - }); - - // Create a division to hold actions menu - var menuDiv = $(''); - $('#' + id + 'Datatable_wrapper').prepend(menuDiv); - menuDiv.append(actionBar); - $('#' + id + 'Datatable_filter').appendTo(menuDiv); -} - -/** - * Delete a row in the data table - * - * @param obj The object that was clicked - */ -function deleteRow(obj) { - // Get table ID - var tableId = $(obj).parents('table').attr('id'); - - // Get datatable - var dTable = $('#' + tableId).dataTable(); - - // Get all nodes within the datatable - var rows = dTable.fnGetNodes(); - // Get target row - var tgtRow = $(obj).parent().parent().get(0); - - // Find the target row in the datatable - for ( var i in rows) { - // If the row matches the target row - if (rows[i] == tgtRow) { - // Remove row - dTable.fnDeleteRow(i, null, true); - break; - } - } -} - -/** - * Count the number of occurrences of a specific character in a string - * - * @param c Character to count - * @return The number of occurrences - */ -String.prototype.count = function(c) { - return (this.length - this.replace(new RegExp(c, 'g'), '').length)/c.length; -}; \ No newline at end of file +/** + * Global variables + */ +var configTabs; // Config tabs +var configDatatables = new Object(); // Datatables on the config page + +/** + * Set the datatable + * + * @param id The ID of the datatable + * @param obj Datatable object + */ +function setConfigDatatable(id, obj) { + configDatatables[id] = obj; +} + +/** + * Get the datatable with the given ID + * + * @param id The ID of the datatable + * @return Datatable object + */ +function getConfigDatatable(id) { + return configDatatables[id]; +} + +/** + * Set the configure tab + * + * @param obj Tab object + */ +function setConfigTab(obj) { + configTabs = obj; +} + +/** + * Get the configure tab + * + * @param Nothing + * @return Tab object + */ +function getConfigTab() { + return configTabs; +} + +/** + * Load configure page + */ +function loadConfigPage() { + // If the configure page has already been loaded + if ($('#content').children().length) { + // Do not reload configure page + return; + } + + // Create configure tab + var tab = new Tab(); + setConfigTab(tab); + tab.init(); + $('#content').append(tab.object()); + + // Create loader + var loader = $('
    ').append(createLoader()); + + // Add tab to configure xCAT tables + tab.add('configTablesTab', 'Tables', loader, false); + + // Add the update tab + tab.add('updateTab', 'Update', '', false); + + // Add the self-service tab + tab.add('usersTab', 'Users', '', false); + + // Add the discover tab + tab.add('discoverTab', 'Discover', '', false); + + // Add the self-service tab + tab.add('serviceTab', 'Service', '', false); + + // Get list of tables and their descriptions + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : '-d', + msg : '' + }, + + success : loadTableNames + }); + + // Do not load everything at once + // Load when tab is shown + tab.object().bind('tabsshow', function(event, ui) { + if ($(ui.panel).children().length) { + return; + } + + if (ui.index == 1) { + loadUpdatePage(); + } else if (ui.index == 2) { + loadUserPage(); + } else if (ui.index == 3) { + loadDiscoverPage(); + } else if (ui.index == 4) { + loadServicePage(); + } + }); +} + +/** + * Load xCAT database table names and their descriptions + * + * @param data Data returned from HTTP request + */ +function loadTableNames(data) { + // Get output + var tables = data.rsp; + + // Remove loader + var tabId = 'configTablesTab'; + $('#' + tabId).find('img').hide(); + + // Create a groups division + var tablesDIV = $('
    '); + $('#' + tabId).append(tablesDIV); + + // Create info bar + var infoBar = createInfoBar('Select a table to view or edit.'); + tablesDIV.append(infoBar); + + // Create a list for the tables + var list = $(''); + // Loop through each table + for ( var i = 0; i < tables.length; i++) { + // Create a link for each table + var args = tables[i].split(':'); + var link = $('' + args[0] + ''); + + // Open table on click + link.bind('click', function(e) { + // Get table ID that was clicked + var id = (e.target) ? e.target.id : e.srcElement.id; + + // Create loader + var loader = $('
    ').append(createLoader()); + + // Add a new tab for this table + var configTab = getConfigTab(); + if (!$('#' + id + 'Tab').length) { + configTab.add(id + 'Tab', id, loader, true); + + // Get contents of selected table + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : id, + msg : id + }, + + success : loadTable + }); + } + + // Select new tab + configTab.select(id + 'Tab'); + }); + + var item = $('
  • '); + item.append(link); + + // Append the table description + item.append(': ' + args[1]); + + // Append item to list + list.append(item); + } + + tablesDIV.append(list); +} + +/** + * Load a given database table + * + * @param data Data returned from HTTP request + */ +function loadTable(data) { + // Get response + var rsp = data.rsp; + // Get table ID + var id = data.msg; + + // Remove loader + var tabId = id + 'Tab'; + $('#' + tabId).find('img').remove(); + + // Create info bar + var infoBar = createInfoBar('Click on a cell to edit. Click outside the table to write to the cell. Once you are satisfied with how the table looks, click on Save.'); + $('#' + tabId).append(infoBar); + + // Create action bar + var actionBar = $('
    '); + $('#' + tabId).append(actionBar); + + // Get table headers + var args = rsp[0].replace('#', ''); + var headers = args.split(','); + + // Create container for original table contents + var origCont = new Array(); // Original table content + origCont[0] = rsp[0].split(','); // Headers + + // Create container for new table contents + var newCont = new Object(); + var tmp = new Object(); + tmp[0] = '#' + headers[0]; // Put a # in front of the header + for ( var i = 1; i < headers.length; i++) { + tmp[i] = headers[i]; + } + newCont[0] = tmp; + + // Create a new datatable + var tableId = id + 'Datatable'; + var table = new DataTable(tableId); + + // Add column for the remove row button + headers.unshift(''); + table.init(headers); + headers.shift(); + + // Append datatable to tab + $('#' + tabId).append(table.object()); + + // Add table rows + // Start with the 2nd row (1st row is the headers) + for ( var i = 1; i < rsp.length; i++) { + // Split into columns + var cols = rsp[i].split(','); + + // Go through each column + for ( var j = 0; j < cols.length; j++) { + + // If the column is not complete + if (cols[j].count('"') == 1) { + while (cols[j].count('"') != 2) { + // Merge this column with the adjacent one + cols[j] = cols[j] + "," + cols[j + 1]; + + // Remove merged row + cols.splice(j + 1, 1); + } + } + + // Replace quote + cols[j] = cols[j].replace(new RegExp('"', 'g'), ''); + } + + // Add remove button + cols.unshift(''); + + // Add row + table.add(cols); + + // Save original table content + origCont[i] = cols; + } + + // Turn table into datatable + var dTable = $('#' + id + 'Datatable').dataTable({ + 'iDisplayLength': 50, + 'bLengthChange': false, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + + /** + * Enable editable columns + */ + // Do not make 1st column editable + $('#' + tableId + ' td:not(td:nth-child(1))').editable( + function(value, settings) { + // Get column index + var colPos = this.cellIndex; + // Get row index + var rowPos = dTable.fnGetPosition(this.parentNode); + + // Update datatable + dTable.fnUpdate(value, rowPos, colPos); + + return (value); + }, { + onblur : 'submit', // Clicking outside editable area submits changes + type : 'textarea', + placeholder: ' ', + height : '30px' // The height of the text area + }); + + // Create action bar + var actionBar = $('
    '); + + var saveLnk = $('Save'); + saveLnk.click(function() { + // Get table ID and name + var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); + var tableName = tableId.replace('Datatable', ''); + + // Get datatable + var dTable = $('#' + tableId).dataTable(); + // Get the nodes from the table + var dRows = dTable.fnGetNodes(); + + // Go through each row + for ( var i = 0; i < dRows.length; i++) { + // If there is row with values + if (dRows[i]) { + // Go through each column + // Ignore the 1st column because it is a button + var cols = dRows[i].childNodes; + var vals = new Object(); + for ( var j = 1; j < cols.length; j++) { + var val = cols.item(j).firstChild.nodeValue; + + // Insert quotes + if (val == ' ') { + vals[j - 1] = ''; + } else { + vals[j - 1] = val; + } + } + + // Save row + newCont[i + 1] = vals; + } + } + + // Update xCAT table + $.ajax({ + type : 'POST', + url : 'lib/tabRestore.php', + dataType : 'json', + data : { + table : tableName, + cont : newCont + }, + success : function(data) { + // Create info message + var dialog = $('
    ').append(createInfoBar('Changes saved!')); + + // Open dialog + dialog.dialog({ + modal: true, + title: 'Info', + width: 400, + buttons: { + "Ok": function(){ + $(this).dialog("close"); + } + } + }); + } + }); + }); + + var undoLnk = $('Undo'); + undoLnk.click(function() { + // Get table ID + var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); + + // Get datatable + var dTable = $('#' + tableId).dataTable(); + + // Clear entire datatable + dTable.fnClearTable(); + + // Add original content back into datatable + for ( var i = 1; i < origCont.length; i++) { + dTable.fnAddData(origCont[i], true); + } + + // Enable editable columns (again) + // Do not make 1st column editable + $('#' + tableId + ' td:not(td:nth-child(1))').editable( + function(value, settings) { + // Get column index + var colPos = this.cellIndex; + // Get row index + var rowPos = dTable.fnGetPosition(this.parentNode); + + // Update datatable + dTable.fnUpdate(value, rowPos, colPos); + + return (value); + }, { + onblur : 'submit', // Clicking outside editable area submits changes + type : 'textarea', + placeholder: ' ', + height : '30px' // The height of the text area + }); + }); + + var addLnk = $('Add row'); + addLnk.click(function() { + // Create an empty row + var row = new Array(); + + /** + * Remove button + */ + row.push(''); + for ( var i = 0; i < headers.length; i++) { + row.push(''); + } + + // Get table ID and name + var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); + + // Get datatable + var dTable = $('#' + tableId).dataTable(); + + // Add the row to the data table + dTable.fnAddData(row); + + // Enable editable columns (again) + // Do not make 1st column editable + $('#' + tableId + ' td:not(td:nth-child(1))').editable( + function(value, settings) { + // Get column index + var colPos = this.cellIndex; + // Get row index + var rowPos = dTable.fnGetPosition(this.parentNode); + + // Update datatable + dTable.fnUpdate(value, rowPos, colPos); + + return (value); + }, { + onblur : 'submit', // Clicking outside editable area submits changes + type : 'textarea', + placeholder: ' ', + height : '30px' // The height of the text area + }); + }); + + // Create an action menu + var actionsMenu = createMenu([saveLnk, undoLnk, addLnk]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + id + 'Datatable_wrapper').prepend(menuDiv); + menuDiv.append(actionBar); + $('#' + id + 'Datatable_filter').appendTo(menuDiv); +} + +/** + * Delete a row in the data table + * + * @param obj The object that was clicked + */ +function deleteRow(obj) { + // Get table ID + var tableId = $(obj).parents('table').attr('id'); + + // Get datatable + var dTable = $('#' + tableId).dataTable(); + + // Get all nodes within the datatable + var rows = dTable.fnGetNodes(); + // Get target row + var tgtRow = $(obj).parent().parent().get(0); + + // Find the target row in the datatable + for ( var i in rows) { + // If the row matches the target row + if (rows[i] == tgtRow) { + // Remove row + dTable.fnDeleteRow(i, null, true); + break; + } + } +} + +/** + * Count the number of occurrences of a specific character in a string + * + * @param c Character to count + * @return The number of occurrences + */ +String.prototype.count = function(c) { + return (this.length - this.replace(new RegExp(c, 'g'), '').length)/c.length; +}; + +/** + * Update dialog + * + * @param data HTTP request data + */ +function updatePanel(data) { + var dialogId = data.msg; + var infoMsg; + + // Create info message + if (jQuery.isArray(data.rsp)) { + infoMsg = ''; + for (var i in data.rsp) { + infoMsg += data.rsp[i] + '
    '; + } + } else { + infoMsg = data.rsp; + } + + // Create info bar with close button + var infoBar = $('
    ').css('margin', '5px 0px'); + var icon = $('').css({ + 'display': 'inline-block', + 'margin': '10px 5px' + }); + + // Create close button to close info bar + var close = $('').css({ + 'display': 'inline-block', + 'float': 'right' + }).click(function() { + $(this).parent().remove(); + }); + + var msg = $('
    ' + infoMsg + '
    ').css({ + 'display': 'inline-block', + 'width': '85%' + }); + + infoBar.append(icon, msg, close); + infoBar.prependTo($('#' + dialogId)); +} \ No newline at end of file diff --git a/xCAT-UI/js/configure/discover.js b/xCAT-UI/js/configure/discover.js index a99b9ad09..719c8be2e 100644 --- a/xCAT-UI/js/configure/discover.js +++ b/xCAT-UI/js/configure/discover.js @@ -324,10 +324,10 @@ function initSelectPlatform() { selectPlatform.append(info); var hwList = $('
      Platforms available:
    '); - hwList.append('
  • '); - hwList.append('
  • BladeCenter
  • '); - hwList.append('
  • System p hardware (P7 IH)
  • '); - hwList.append('
  • System p hardware (Non P7 IH)
  • '); + hwList.append('
  • iDataPlex
  • '); + hwList.append('
  • BladeCenter
  • '); + hwList.append('
  • System p hardware (P7 IH)
  • '); + hwList.append('
  • System p hardware (Non P7 IH)
  • '); hwList.find('li').css('padding', '2px 10px'); selectPlatform.append(hwList); diff --git a/xCAT-UI/js/configure/service.js b/xCAT-UI/js/configure/service.js index 116932cca..c1e8b2ab9 100644 --- a/xCAT-UI/js/configure/service.js +++ b/xCAT-UI/js/configure/service.js @@ -19,9 +19,9 @@ function loadServicePage(tabId) { // Create radio buttons for platforms var hwList = $('
      Platforms available:
    '); - var esx = $('
  • ESX
  • '); - var kvm = $('
  • KVM
  • '); - var zvm = $('
  • z\/VM
  • '); + var esx = $('
  • ESX
  • '); + var kvm = $('
  • KVM
  • '); + var zvm = $('
  • z\/VM
  • '); hwList.append(esx); hwList.append(kvm); @@ -90,433 +90,6 @@ function loadServicePage(tabId) { servicePg.append(okBtn); } -/** - * Load the user panel where users can be created, modified, or deleted - * - * @param panelId Panel ID - */ -function loadUserPanel(panelId) { - // Get users list - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'tabdump', - tgt : '', - args : 'passwd', - msg : panelId - }, - - success : loadUserTable - }); -} - -/** - * Load user datatable - * - * @param data HTTP request data - */ -function loadUserTable(data) { - // Get response - var rsp = data.rsp; - // Get panel ID - var panelId = data.msg; - - // Wipe panel clean - $('#' + panelId).empty(); - - // Add info bar - $('#' + panelId).append(createInfoBar('Create, edit, and delete users for the self-service portal. Double-click on a cell to edit a users properties. Click outside the table to save changes. Hit the Escape key to ignore changes.')); - - // Get table headers - // The table headers in the passwd table are: key, username, password, cryptmethod, comments, and disable - var headers = new Array('priority', 'username', 'password', 'max-vm'); - - // Create a new datatable - var tableId = panelId + 'Datatable'; - var table = new DataTable(tableId); - - // Add column for the checkbox - headers.unshift(''); - table.init(headers); - headers.shift(); - - // Append datatable to panel - $('#' + panelId).append(table.object()); - - // Add table rows - // Start with the 2nd row (1st row is the headers) - for ( var i = 1; i < rsp.length; i++) { - // Split into columns - var tmp = rsp[i].split(','); - - // Go through each column - for (var j = 0; j < tmp.length; j++) { - // Replace quote - tmp[j] = tmp[j].replace(new RegExp('"', 'g'), ''); - } - - // Only add users having the key = xcat - if (tmp[0] == 'xcat') { - // Columns are: priority, username, password, and max-vm - var cols = new Array('', tmp[1], tmp[2], ''); - - // Add remove button where id = user name - cols.unshift(''); - - // Add row - table.add(cols); - } - } - - // Turn table into datatable - $('#' + tableId).dataTable({ - 'iDisplayLength': 50, - 'bLengthChange': false, - "sScrollX": "100%", - "bAutoWidth": true - }); - - // Create action bar - var actionBar = $('
    ').css("width", "400px"); - - var createLnk = $('Create'); - createLnk.click(function() { - openCreateUserDialog(); - }); - - var deleteLnk = $('Delete'); - deleteLnk.click(function() { - var users = getNodesChecked(tableId); - if (users) { - openDeleteUserDialog(users); - } - }); - - var refreshLnk = $('Refresh'); - refreshLnk.click(function() { - loadUserPanel(panelId); - }); - - // Create an action menu - var actionsMenu = createMenu([createLnk, deleteLnk, refreshLnk]); - actionsMenu.superfish(); - actionsMenu.css('display', 'inline-block'); - actionBar.append(actionsMenu); - - // Set correct theme for action menu - actionsMenu.find('li').hover(function() { - setMenu2Theme($(this)); - }, function() { - setMenu2Normal($(this)); - }); - - // Create a division to hold actions menu - var menuDiv = $(''); - $('#' + tableId + '_wrapper').prepend(menuDiv); - menuDiv.append(actionBar); - $('#' + tableId + '_filter').appendTo(menuDiv); - - // Get policy data - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'tabdump', - tgt : '', - args : 'policy', - msg : tableId - }, - - success : loadUserTable4Policy - }); - - /** - * Enable editable cells - */ - // Do not make 1st or 2nd column editable - $('#' + tableId + ' td:not(td:nth-child(1),td:nth-child(2))').editable( - function(value, settings) { - // If users did not make changes, return the value directly - // jeditable saves the old value in this.revert - if ($(this).attr('revert') == value){ - return value; - } - - var panelId = $(this).parents('.ui-accordion-content').attr('id'); - - // Get column index - var colPos = this.cellIndex; - - // Get row index - var dTable = $('#' + tableId).dataTable(); - var rowPos = dTable.fnGetPosition(this.parentNode); - - // Update datatable - dTable.fnUpdate(value, rowPos, colPos, false); - - // Get table headers - var headers = $('#' + nodesTableId).parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th'); - - // Get user attributes - var priority = $(this).parent().find('td:eq(1)').text(); - var user = $(this).parent().find('td:eq(2)').text(); - var password = $(this).parent().find('td:eq(3)').text(); - var maxVM = $(this).parent().find('td:eq(4)').text(); - - // Send command to change user attributes - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'updateuser;' + priority + ';' + user + ';' + password + ';' + maxVM, - msg : panelId - }, - success : updatePanel - }); - - return value; - }, { - onblur : 'submit', // Clicking outside editable area submits changes - type : 'textarea', - placeholder: ' ', - event : "dblclick", // Double click and edit - height : '30px' // The height of the text area - }); - - // Resize accordion - $('#' + tableId).parents('.ui-accordion').accordion('resize'); -} - -/** - * Update user datatable for policy - * - * @param data HTTP request data - */ -function loadUserTable4Policy(data) { - // Get response - var rsp = data.rsp; - // Get datatable ID - var tableId = data.msg; - - // Get datatable - var datatable = $('#' + tableId).dataTable(); - - // Update max-vm column - // The data coming back contains: priority, name, host, commands, noderange, parameters, time, rule, comments, disable - - // Start with the 2nd row (1st row is the headers) - topPriority = 0; - for (var i = 1; i < rsp.length; i++) { - // Split into columns - var tmp = rsp[i].split(','); - - // Go through each column - for (var j = 0; j < tmp.length; j++) { - // Replace quote - tmp[j] = tmp[j].replace(new RegExp('"', 'g'), ''); - } - - // Get the row containing the user name - var rowPos = -1; - if (tmp[1]) - rowPos = findRow(tmp[1], '#' + tableId, 2); - - // Update the priority and max-vm columns - if (rowPos > -1) { - var maxVM = 0; - var comments = tmp[8].split(';'); - for (var k in comments) { - if (comments[k].indexOf('max-vm:') > -1) - maxVM = comments[k].replace('max-vm:', ''); - } - - datatable.fnUpdate(maxVM, rowPos, 4, false); - - var priority = tmp[0]; - datatable.fnUpdate(priority, rowPos, 1, false); - - // Set the highest priority - if (priority > topPriority) - topPriority = priority; - } - } - - // Adjust column sizes - adjustColumnSize(tableId); - - // Resize accordion - $('#' + tableId).parents('.ui-accordion').accordion('resize'); -} - -/** - * Open a dialog to create a user - */ -function openCreateUserDialog() { - var dialogId = 'createUser'; - var dialog = $('
    '); - var info = createInfoBar('Create an xCAT user. A priority will be generated for the new user.'); - dialog.append(info); - - // Generate the user priority - var userPriority = parseFloat(topPriority) + 0.01; - userPriority = userPriority.toPrecision(3); - - // Create node inputs - dialog.append($('
    ')); - dialog.append($('
    ')); - dialog.append($('
    ')); - dialog.append($('
    ')); - - dialog.dialog({ - title: 'Create user', - modal: true, - width: 400, - close: function(){ - $(this).remove(); - }, - buttons: { - "OK" : function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Change dialog buttons - $('#' + dialogId).dialog('option', 'buttons', { - 'Close':function(){ - $(this).dialog('close'); - } - }); - - var priority = $(this).find('input[name="priority"]').val(); - var user = $(this).find('input[name="username"]').val(); - var password = $(this).find('input[name="password"]').val(); - var maxVM = $(this).find('input[name="maxvm"]').val(); - - // Verify inputs are provided - if (!user || !password || !maxVM) { - var warn = createWarnBar('Please provide a value for each missing field!'); - warn.prependTo($(this)); - } else { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'updateuser;' + priority + ';' + user + ';' + password + ';' + maxVM, - msg : dialogId - }, - success : updatePanel - }); - - // Update highest priority - topPriority = priority; - } - }, - "Cancel": function(){ - $(this).dialog('close'); - } - } - }); -} - -/** - * Update dialog - * - * @param data HTTP request data - */ -function updatePanel(data) { - var dialogId = data.msg; - var infoMsg; - - // Create info message - if (jQuery.isArray(data.rsp)) { - infoMsg = ''; - for (var i in data.rsp) { - infoMsg += data.rsp[i] + '
    '; - } - } else { - infoMsg = data.rsp; - } - - // Create info bar with close button - var infoBar = $('
    ').css('margin', '5px 0px'); - var icon = $('').css({ - 'display': 'inline-block', - 'margin': '10px 5px' - }); - - // Create close button to close info bar - var close = $('').css({ - 'display': 'inline-block', - 'float': 'right' - }).click(function() { - $(this).parent().remove(); - }); - - var msg = $('
    ' + infoMsg + '
    ').css({ - 'display': 'inline-block', - 'width': '85%' - }); - - infoBar.append(icon, msg, close); - infoBar.prependTo($('#' + dialogId)); -} - -/** - * Open dialog to confirm user delete - * - * @param users Users to delete - */ -function openDeleteUserDialog(users) { - // Create form to delete disk to pool - var dialogId = 'deleteUser'; - var deleteForm = $('
    '); - - // Create info bar - var info = createInfoBar('Are you sure you want to delete ' + users.replace(new RegExp(',', 'g'), ', ') + '?'); - deleteForm.append(info); - - // Open dialog to delete user - deleteForm.dialog({ - title:'Delete user', - modal: true, - width: 400, - close: function(){ - $(this).remove(); - }, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Change dialog buttons - $(this).dialog('option', 'buttons', { - 'Close': function() {$(this).dialog("close");} - }); - - // Delete user - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'deleteuser;' + users, - msg : dialogId - }, - success : updatePanel - }); - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - /** * Round a floating point to a given precision * @@ -680,10 +253,18 @@ function configImagePanel(data) { // Turn into datatable $('#' + tableId).dataTable({ - 'iDisplayLength': 50, + 'iDisplayLength': 50, 'bLengthChange': false, - "sScrollX": "100%", - "bAutoWidth": true + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } }); // Create action bar @@ -1186,10 +767,18 @@ function configGroupPanel(data) { // Turn into datatable $('#' + tableId).dataTable({ - 'iDisplayLength': 50, + 'iDisplayLength': 50, 'bLengthChange': false, - "sScrollX": "100%", - "bAutoWidth": true + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } }); // Create action bar diff --git a/xCAT-UI/js/configure/update.js b/xCAT-UI/js/configure/update.js index c8e41db07..1422f1023 100644 --- a/xCAT-UI/js/configure/update.js +++ b/xCAT-UI/js/configure/update.js @@ -8,7 +8,6 @@ function loadUpdatePage() { statusDiv.hide(); $('#updateTab').append(statusDiv); - $('#updateTab').append('
    '); $('#updateTab').append(repositoryDiv); $('#updateTab').append(rpmDiv); diff --git a/xCAT-UI/js/configure/users.js b/xCAT-UI/js/configure/users.js new file mode 100644 index 000000000..3781df970 --- /dev/null +++ b/xCAT-UI/js/configure/users.js @@ -0,0 +1,469 @@ +/** + * Global variables + */ +var userDatatable; +var topPriority = 0; +var tableId = 'usersTable'; + +/** + * Get user access table + * + * @returns User access table + */ +function getUsersTable(){ + return userDatatable; +} + +/** + * Set user access table + * + * @param table User access table + */ +function setUsersTable(table){ + userDatatable = table; +} + +/** + * Load the user page + */ +function loadUserPage() { + // Retrieve users from policy table + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : 'policy', + msg : '' + }, + + success : loadUserTable + }); +} + +/** + * Load user table + * + * @param data Data returned from HTTP request + */ +function loadUserTable(data){ + var tabId = 'usersTab'; + + $('#' + tabId).empty(); + + // Set padding for page + $('#' + tabId).css('padding', '20px 60px'); + + // Create info bar + var info = $('#' + tabId).find('.ui-state-highlight'); + // If there is no info bar + if (!info.length) { + var infoBar = createInfoBar('Configure access given to users.'); + + // Create users page + var userPg = $('
    '); + $('#' + tabId).append(infoBar, userPg); + } + + if (data.rsp) { + // Create a datatable if one does not exist + var table = new DataTable(tableId); + var headers = new Array('Priority', 'Name', 'Host', 'Commands', 'Noderange', 'Parameters', 'Time', 'Rule', 'Comments', 'Disable'); + + // Add column for the checkbox + headers.unshift(''); + table.init(headers); + headers.shift(); + + // Append datatable to panel + $('#' + tabId).append(table.object()); + + topPriority = 0; + + // Add table rows + // Start with the 2nd row (1st row is the headers) + for (var i = 1; i < data.rsp.length; i++) { + // Trim returned data + data.rsp[i] = jQuery.trim(data.rsp[i]); + // Split data into columns + var cols = data.rsp[i].split(','); + + // Go through each column + // Column names are: priority, name, host, commands, noderange, parameters, time, rule, comments, disable + for (var j = 0; j < cols.length; j++) { + // Replace quote + cols[j] = cols[j].replace(/"/g, ''); + } + + // Set the highest priority + priority = cols[0]; + if (priority > topPriority) + topPriority = priority; + + // Add check box where name = user name + cols.unshift(''); + + // Add row + table.add(cols); + } + + // Turn table into datatable + var dTable = $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + 'bLengthChange': false, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "100%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + setUsersTable(dTable); // Cache user access table + } + + // Create action bar + var actionBar = $('
    ').css("width", "450px"); + + var createLnk = $('Create'); + createLnk.click(function() { + openCreateUserDialog(""); + }); + + var editLnk = $('Edit'); + editLnk.click(function() { + // Should only allow 1 user to be edited at a time + var users = getNodesChecked(tableId).split(',') + for (var i in users) { + openCreateUserDialog(users[i]); + } + }); + + var deleteLnk = $('Delete'); + deleteLnk.click(function() { + // Find the user name from datatable + var usersList = ""; + var users = $('#' + tableId + ' input[type=checkbox]:checked'); + for (var i in users) { + var user = users.eq(i).parents('tr').find('td:eq(2)').text(); + if (user && user != "undefined") { + usersList += user; + if (i < users.length - 1) { + usersList += ','; + } + } + } + + if (usersList) { + openDeleteUserDialog(usersList); + } + }); + + var refreshLnk = $('Refresh'); + refreshLnk.click(function() { + loadUserPage(); + }); + + // Create an action menu + var actionsMenu = createMenu([createLnk, editLnk, deleteLnk, refreshLnk]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_wrapper').prepend(menuDiv); + menuDiv.append(actionBar); + $('#' + tableId + '_filter').appendTo(menuDiv); +} + +/** + * Open create user dialog + * + * @param data User data (only during edit) + */ +function openCreateUserDialog(data) { + var dialogId = 'createUser'; + + // Generate the user priority + var priority = parseFloat(topPriority) + 0.01; + priority = priority.toPrecision(3); + + // Create form to create user + var createUserForm = $('
    '); + + // Create info bar + var info = createInfoBar('Create a user and configure access to xCAT.'); + + var userFS = $('
    '); + var userLegend = $('User'); + userFS.append(userLegend); + + var userAttr = $('
    '); + userFS.append($('
    ')); + userFS.append(userAttr); + + var optionFS = $('
    '); + var optionLegend = $('Options'); + optionFS.append(optionLegend); + + var optionAttr = $('
    '); + optionFS.append($('
    ')); + optionFS.append(optionAttr); + + createUserForm.append(info, userFS, optionFS); + + userAttr.append($('
    ')); + userAttr.append($('
    ')); + userAttr.append($('
    ')); + userAttr.append($('
    ')); + optionAttr.append($('
    ')); + optionAttr.append($('
    ')); + optionAttr.append($('
    ')); + optionAttr.append($('
    ')); + optionAttr.append($('
    ')); + var rootPrivilege = $('
    '); + var accessCheckbox = $(''); + optionAttr.append(rootPrivilege); + rootPrivilege.append(accessCheckbox); + + optionAttr.append($('
    ')); + optionAttr.append($('
    ')); + + // Open dialog to add disk + createUserForm.dialog({ + title:'Configure user', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 600, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var priority = $(this).find('input[name=priority]').val(); + var usrName = $(this).find('input[name=name]').val(); + var password = $(this).find('input[name=password]').val(); + var confirmPassword = $(this).find('input[name=confirm_password]').val(); + var host = $(this).find('input[name=host]').val(); + var commands = $(this).find('input[name=commands]').val(); + var parameters = $(this).find('input[name=parameters]').val(); + var nodeRange = $(this).find('input[name=nodeRange]').val(); + var rule = $(this).find('select[name=rule]').val(); + var comments = $(this).find('input[name=comments]').val(); + var disable = $(this).find('select[name=disable]').val(); + + // Verify user name and passwords are supplied + if (!usrName) { + var warn = createWarnBar('Please provide a user name'); + warn.prependTo($(this)); + return; + } + + // Verify passwords match + if (password != confirmPassword) { + var warn = createWarnBar('Passwords do not match'); + warn.prependTo($(this)); + return; + } + + var args = ""; + if (usrName) { + args += ' policy.name=' + usrName; + } if (host) { + args += " policy.host='" + host + "'"; + } if (commands) { + args += " policy.commands='" + commands + "'"; + } if (parameters) { + args += " policy.parameters='" + parameters + "'"; + } if (nodeRange) { + args += " policy.noderange='" + nodeRange + "'"; + } if (rule) { + args += ' policy.rule=' + rule; + } if (disable) { + args += ' policy.disable=' + disable; + } if (comments) { + args += " policy.comments='" + comments + "'"; + } + + // Trim any extra spaces + args = jQuery.trim(args); + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Submit request to update policy and passwd tables + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'policy|' + priority + '|' + args, + msg : dialogId + }, + + success : updatePanel + }); + + if (password) { + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'passwd|' + usrName + '|' + password, + msg : dialogId + }, + + success : updatePanel + }); + } + + // Update highest priority + topPriority = priority; + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); + + // Change comments if access checkbox is checked + accessCheckbox.click( function(){ + var comments = createUserForm.find('input[name=comments]').val(); + var tag = "privilege:root"; + comments = jQuery.trim(comments); + + // Append tag to comments + if (accessCheckbox.is(':checked')) { + if (comments && comments.charAt(comments.length - 1) != ";") { + comments += ";"; + } + + comments += tag; + createUserForm.find('input[name=comments]').val(comments); + } else { + comments = comments.replace(tag, ""); + comments = comments.replace(";;", ";"); + createUserForm.find('input[name=comments]').val(comments); + } + + // Strip off leading semi-colon + if (comments.charAt(0) == ";") { + comments = comments.substr(1, comments.length); + createUserForm.find('input[name=comments]').val(comments); + } + }); + + // Set the user data (on edit) + if (data) { + var checkBox = $('#' + tableId + ' input[name="' + data + '"]'); + + var priority = data; + var name = checkBox.parents('tr').find('td:eq(2)').text(); + var host = checkBox.parents('tr').find('td:eq(3)').text(); + var commands = checkBox.parents('tr').find('td:eq(4)').text(); + var noderange = checkBox.parents('tr').find('td:eq(5)').text(); + var parameters = checkBox.parents('tr').find('td:eq(6)').text(); + var time = checkBox.parents('tr').find('td:eq(7)').text(); + var rule = checkBox.parents('tr').find('td:eq(8)').text(); + var comments = checkBox.parents('tr').find('td:eq(9)').text(); + var disable = checkBox.parents('tr').find('td:eq(10)').text(); + + createUserForm.find('input[name=priority]').val(priority); + createUserForm.find('input[name=name]').val(name); + + // Do not show password (security) + createUserForm.find('input[name=password]').val(); + createUserForm.find('input[name=confirm_password]').val(); + + createUserForm.find('input[name=host]').val(host); + createUserForm.find('input[name=commands]').val(commands); + createUserForm.find('input[name=parameters]').val(parameters); + createUserForm.find('input[name=nodeRange]').val(noderange); + createUserForm.find('select[name=rule]').val(rule); + createUserForm.find('input[name=comments]').val(comments); + createUserForm.find('select[name=disable]').val(disable); + + if (comments.indexOf("privilege:root") > -1) { + accessCheckbox.attr("checked", true); + } + } +} +/** + * Open dialog to confirm user delete + * + * @param users Users to delete + */ +function openDeleteUserDialog(users) { + // Create form to delete disk to pool + var dialogId = 'deleteUser'; + var deleteForm = $('
    '); + + // Create info bar + var info = createInfoBar('Are you sure you want to delete ' + users.replace(new RegExp(',', 'g'), ', ') + '?'); + deleteForm.append(info); + + // Open dialog to delete user + deleteForm.dialog({ + title:'Delete user', + modal: true, + width: 400, + close: function(){ + $(this).remove(); + }, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Delete user + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'deleteuser|' + users, + msg : dialogId + }, + success : updatePanel + }); + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} \ No newline at end of file diff --git a/xCAT-UI/js/custom/blade.js b/xCAT-UI/js/custom/blade.js index 8c119fcc7..bf3d761f1 100644 --- a/xCAT-UI/js/custom/blade.js +++ b/xCAT-UI/js/custom/blade.js @@ -584,7 +584,7 @@ function createBladeProvisionExisting(inst) { // Create group input var group = $('
    '); - var groupLabel = $(''); + var groupLabel = $(''); group.append(groupLabel); // Turn on auto complete for group @@ -622,7 +622,7 @@ function createBladeProvisionExisting(inst) { // Create node input var node = $('
    '); - var nodeLabel = $(''); + var nodeLabel = $(''); var nodeDatatable = $('

    Select a group to view its nodes

    '); node.append(nodeLabel); node.append(nodeDatatable); @@ -630,7 +630,7 @@ function createBladeProvisionExisting(inst) { // Create boot method drop down var method = $('
    '); - var methodLabel = $(''); + var methodLabel = $(''); var methodSelect = $(''); methodSelect.append('' + '' @@ -645,7 +645,7 @@ function createBladeProvisionExisting(inst) { // Create operating system input var os = $('
    '); - var osLabel = $(''); + var osLabel = $(''); var osInput = $(''); osInput.one('focus', function() { var tmp = $.cookie('osvers'); @@ -662,7 +662,7 @@ function createBladeProvisionExisting(inst) { // Create architecture input var arch = $('
    '); - var archLabel = $(''); + var archLabel = $(''); var archInput = $(''); archInput.one('focus', function() { var tmp = $.cookie('osarchs'); @@ -679,7 +679,7 @@ function createBladeProvisionExisting(inst) { // Create profile input var profile = $('
    '); - var profileLabel = $(''); + var profileLabel = $(''); var profileInput = $(''); profileInput.one('focus', function() { var tmp = $.cookie('profiles'); diff --git a/xCAT-UI/js/custom/customUtils.js b/xCAT-UI/js/custom/customUtils.js index add88765e..51ab0498b 100644 --- a/xCAT-UI/js/custom/customUtils.js +++ b/xCAT-UI/js/custom/customUtils.js @@ -67,7 +67,10 @@ function createNodesDatatable(group, outId) { // Sort headers var sorted = new Array(); for ( var key in headers) { - sorted.push(key); + // Do not put in status or comments + if (key.indexOf("status") < 0 && key.indexOf("usercomment") < 0) { + sorted.push(key); + } } sorted.sort(); @@ -103,7 +106,23 @@ function createNodesDatatable(group, outId) { } $('#' + outId).append(dTable.object()); - $('#' + dTableId).dataTable(); + $('#' + dTableId).dataTable({ + 'iDisplayLength': 50, + 'bLengthChange': false, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + + // Fix table styling + $('#' + dTableId + '_wrapper .dataTables_filter label').css('width', '250px'); } // End of function(data) }); } @@ -121,7 +140,7 @@ function createProvisionExisting(plugin, inst) { // Create group input var group = $('
    '); - var groupLabel = $(''); + var groupLabel = $(''); group.append(groupLabel); // Turn on auto complete for group @@ -159,7 +178,7 @@ function createProvisionExisting(plugin, inst) { // Create node input var node = $('
    '); - var nodeLabel = $(''); + var nodeLabel = $(''); var nodeDatatable = $('

    Select a group to view its nodes

    '); node.append(nodeLabel); node.append(nodeDatatable); @@ -167,7 +186,7 @@ function createProvisionExisting(plugin, inst) { // Create boot method drop down var method = $('
    '); - var methodLabel = $(''); + var methodLabel = $(''); var methodSelect = $(''); methodSelect.append('' + '' @@ -181,7 +200,7 @@ function createProvisionExisting(plugin, inst) { // Create boot type drop down var type = $('
    '); - var typeLabel = $(''); + var typeLabel = $(''); var typeSelect = $(''); typeSelect.append('' + '' @@ -193,7 +212,7 @@ function createProvisionExisting(plugin, inst) { // Create operating system input var os = $('
    '); - var osLabel = $(''); + var osLabel = $(''); var osInput = $(''); osInput.one('focus', function() { var tmp = $.cookie('osvers'); @@ -210,7 +229,7 @@ function createProvisionExisting(plugin, inst) { // Create architecture input var arch = $('
    '); - var archLabel = $(''); + var archLabel = $(''); var archInput = $(''); archInput.one('focus', function() { var tmp = $.cookie('osarchs'); @@ -227,7 +246,7 @@ function createProvisionExisting(plugin, inst) { // Create profile input var profile = $('
    '); - var profileLabel = $(''); + var profileLabel = $(''); var profileInput = $(''); profileInput.one('focus', function() { var tmp = $.cookie('profiles'); @@ -266,12 +285,12 @@ function createProvisionNew(plugin, inst) { var provNew = $('
    '); // Create node input - var nodeName = $('
    '); + var nodeName = $('
    '); provNew.append(nodeName); // Create group input var group = $('
    '); - var groupLabel = $(''); + var groupLabel = $(''); var groupInput = $(''); groupInput.one('focus', function() { var groupNames = $.cookie('groups'); @@ -288,7 +307,7 @@ function createProvisionNew(plugin, inst) { // Create boot method drop down var method = $('
    '); - var methodLabel = $(''); + var methodLabel = $(''); var methodSelect = $(''); methodSelect.append('' + '' @@ -302,7 +321,7 @@ function createProvisionNew(plugin, inst) { // Create boot type drop down var type = $('
    '); - var typeLabel = $(''); + var typeLabel = $(''); var typeSelect = $(''); typeSelect.append('' + '' @@ -314,7 +333,7 @@ function createProvisionNew(plugin, inst) { // Create operating system input var os = $('
    '); - var osLabel = $(''); + var osLabel = $(''); var osInput = $(''); osInput.one('focus', function() { var tmp = $.cookie('osvers'); @@ -331,7 +350,7 @@ function createProvisionNew(plugin, inst) { // Create architecture input var arch = $('
    '); - var archLabel = $(''); + var archLabel = $(''); var archInput = $(''); archInput.one('focus', function() { var tmp = $.cookie('osarchs'); @@ -348,7 +367,7 @@ function createProvisionNew(plugin, inst) { // Create profile input var profile = $('
    '); - var profileLabel = $(''); + var profileLabel = $(''); var profileInput = $(''); profileInput.one('focus', function() { var tmp = $.cookie('profiles'); diff --git a/xCAT-UI/js/custom/esx.js b/xCAT-UI/js/custom/esx.js index d5e229ea2..92b084c90 100644 --- a/xCAT-UI/js/custom/esx.js +++ b/xCAT-UI/js/custom/esx.js @@ -19,18 +19,6 @@ var esxPlugin = function() { */ esxPlugin.prototype.loadConfigPage = function(tabId) { var configAccordion = $('
    '); - - // Create accordion panel for user - var userSection = $('
    '); - var userLnk = $('

    Users

    ').click(function () { - // Do not load panel again if it is already loaded - if ($('#esxConfigUser').find('.dataTables_wrapper').length) - return; - else - $('#esxConfigUser').append(createLoader('')); - - loadUserPanel('esxConfigUser'); - }); // Create accordion panel for profiles var profileSection = $('
    '); @@ -41,6 +29,14 @@ esxPlugin.prototype.loadConfigPage = function(tabId) { else $('#esxConfigProfile').append(createLoader('')); + // Wipe panel clean + $('#esxConfigProfile').empty(); + + // Add info bar + $('#esxConfigProfile').append(createInfoBar('Not yet supported')); + + // Resize accordion + configAccordion.accordion('resize'); }); // Create accordion panel for images @@ -67,11 +63,11 @@ esxPlugin.prototype.loadConfigPage = function(tabId) { queryGroups('esxConfigGroups'); }); - configAccordion.append(userLnk, userSection, profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); + configAccordion.append(profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); $('#' + tabId).append(configAccordion); configAccordion.accordion(); - userLnk.trigger('click'); + profileLnk.trigger('click'); }; /** diff --git a/xCAT-UI/js/custom/ipmi.js b/xCAT-UI/js/custom/ipmi.js index 00a2698d0..f57be63e9 100644 --- a/xCAT-UI/js/custom/ipmi.js +++ b/xCAT-UI/js/custom/ipmi.js @@ -329,7 +329,7 @@ function createIpmiProvisionExisting(inst) { // Create group input var group = $('
    '); - var groupLabel = $(''); + var groupLabel = $(''); group.append(groupLabel); // Turn on auto complete for group @@ -370,7 +370,7 @@ function createIpmiProvisionExisting(inst) { // Create node input var node = $('
    '); - var nodeLabel = $(''); + var nodeLabel = $(''); var nodeDatatable = $('

    Select a group to view its nodes

    '); @@ -380,7 +380,7 @@ function createIpmiProvisionExisting(inst) { // Create boot method drop down var method = $('
    '); - var methodLabel = $(''); + var methodLabel = $(''); var methodSelect = $(''); methodSelect.append('' + '' @@ -394,7 +394,7 @@ function createIpmiProvisionExisting(inst) { // Create operating system input var os = $('
    '); - var osLabel = $(''); + var osLabel = $(''); var osInput = $(''); osInput.one('focus', function() { var tmp = $.cookie('osvers'); @@ -411,7 +411,7 @@ function createIpmiProvisionExisting(inst) { // Create architecture input var arch = $('
    '); - var archLabel = $(''); + var archLabel = $(''); var archInput = $(''); archInput.one('focus', function() { var tmp = $.cookie('osarchs'); @@ -428,7 +428,7 @@ function createIpmiProvisionExisting(inst) { // Create profile input var profile = $('
    '); - var profileLabel = $(''); + var profileLabel = $(''); var profileInput = $(''); profileInput.one('focus', function() { var tmp = $.cookie('profiles'); diff --git a/xCAT-UI/js/custom/kvm.js b/xCAT-UI/js/custom/kvm.js index d8cdc0bd0..1f2ca89b1 100644 --- a/xCAT-UI/js/custom/kvm.js +++ b/xCAT-UI/js/custom/kvm.js @@ -18,18 +18,6 @@ var kvmPlugin = function() { kvmPlugin.prototype.loadConfigPage = function(tabId) { var configAccordion = $('
    '); - // Create accordion panel for user - var userSection = $('
    '); - var userLnk = $('

    Users

    ').click(function () { - // Do not load panel again if it is already loaded - if ($('#kvmConfigUser').find('.dataTables_wrapper').length) - return; - else - $('#kvmConfigUser').append(createLoader('')); - - loadUserPanel('kvmConfigUser'); - }); - // Create accordion panel for profiles var profileSection = $('
    '); var profileLnk = $('

    Profiles

    ').click(function () { @@ -39,6 +27,14 @@ kvmPlugin.prototype.loadConfigPage = function(tabId) { else $('#kvmConfigProfile').append(createLoader('')); + // Wipe panel clean + $('#kvmConfigProfile').empty(); + + // Add info bar + $('#kvmConfigProfile').append(createInfoBar('Not yet supported')); + + // Resize accordion + configAccordion.accordion('resize'); }); // Create accordion panel for images @@ -65,11 +61,11 @@ kvmPlugin.prototype.loadConfigPage = function(tabId) { queryGroups('kvmConfigGroups'); }); - configAccordion.append(userLnk, userSection, profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); + configAccordion.append(profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); $('#' + tabId).append(configAccordion); configAccordion.accordion(); - userLnk.trigger('click'); + profileLnk.trigger('click'); }; /** diff --git a/xCAT-UI/js/custom/zvm.js b/xCAT-UI/js/custom/zvm.js index 6c62c0c2e..015b050b2 100644 --- a/xCAT-UI/js/custom/zvm.js +++ b/xCAT-UI/js/custom/zvm.js @@ -18,18 +18,6 @@ var zvmPlugin = function() { */ zvmPlugin.prototype.loadConfigPage = function(tabId) { var configAccordion = $('
    '); - - // Create accordion panel for user - var userSection = $('
    '); - var userLnk = $('

    Users

    ').click(function () { - // Do not load panel again if it is already loaded - if ($('#zvmConfigUser').find('.dataTables_wrapper').length) - return; - else - $('#zvmConfigUser').append(createLoader('')); - - loadUserPanel('zvmConfigUser'); - }); // Create accordion panel for profiles var profileSection = $('
    '); @@ -67,11 +55,11 @@ zvmPlugin.prototype.loadConfigPage = function(tabId) { queryGroups('zvmConfigGroups'); }); - configAccordion.append(userLnk, userSection, profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); + configAccordion.append(profileLnk, profileSection, imgLnk, imgSection, groupsLnk, groupsSection); $('#' + tabId).append(configAccordion); configAccordion.accordion(); - userLnk.trigger('click'); + profileLnk.trigger('click'); }; /** @@ -145,14 +133,14 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { var img = $('#select-table tbody tr:eq(0) td:eq(2) input[name="image"]:checked').val(); var owner = $.cookie('xcat_username'); - if(!hcp || !group || !img) { + if (!hcp || !group || !img) { // Show warning message var warn = createWarnBar('You need to select an option for each column'); warn.prependTo($(this).parent()); } else { // Begin by creating VM createzVM(tabId, group, hcp, img, owner); - } + } }); provForm.append(provisionBtn); @@ -161,7 +149,7 @@ zvmPlugin.prototype.loadServiceProvisionPage = function(tabId) { loadOSImages(imageCol); // Get zVM host names - if (!$.cookie('srv_zvm')){ + if (!$.cookie('zvm')){ $.ajax( { url : 'lib/srv_cmd.php', dataType : 'json', @@ -208,23 +196,26 @@ zvmPlugin.prototype.loadServiceInventory = function(data) { // Get node inventory var inv = data.rsp[0].split(node + ':'); - // Create array of property keys - var keys = new Array('userId', 'host', 'os', 'arch', 'hcp', 'priv', 'memory', 'proc', 'disk', 'zfcp', 'nic'); + // Create array of property keys (VM) + var keys = new Array('userId', 'host', 'os', 'arch', 'uptime', 'cpuusedtime', 'hcp', 'priv', 'memory', 'maxmemory', 'proc', 'disk', 'zfcp', 'nic'); - // Create hash table for property names + // Create hash table for property names (VM) var attrNames = new Object(); attrNames['userId'] = 'z/VM UserID:'; attrNames['host'] = 'z/VM Host:'; attrNames['os'] = 'Operating System:'; attrNames['arch'] = 'Architecture:'; + attrNames['uptime'] = 'Uptime:'; + attrNames['cpuusedtime'] = 'CPU Used Time:'; attrNames['hcp'] = 'HCP:'; attrNames['priv'] = 'Privileges:'; attrNames['memory'] = 'Total Memory:'; + attrNames['maxmemory'] = 'Max Memory:'; attrNames['proc'] = 'Processors:'; attrNames['disk'] = 'Disks:'; attrNames['zfcp'] = 'zFCP:'; attrNames['nic'] = 'NICs:'; - + // Create hash table for node attributes var attrs = getAttrs(keys, attrNames, inv); @@ -308,7 +299,7 @@ zvmPlugin.prototype.loadServiceInventory = function(data) { */ if (keys[k] == 'priv') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Loop through each line @@ -339,7 +330,7 @@ zvmPlugin.prototype.loadServiceInventory = function(data) { */ else if (keys[k] == 'memory') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Loop through each value line @@ -467,7 +458,7 @@ zvmPlugin.prototype.loadServiceInventory = function(data) { */ else if (keys[k] == 'zfcp') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Create a table to hold NIC data @@ -553,6 +544,11 @@ zvmPlugin.prototype.loadServiceInventory = function(data) { nicTable.append(nicBody); item.append(nicTable); } + + // Ignore any fields not in key + else { + continue; + } oList.append(item); } @@ -623,14 +619,14 @@ zvmPlugin.prototype.loadClonePage = function(node) { vmFS.append(vmAttr); // Create hardware fieldset - var hwFS = $('
    '); - var hwLegend = $('Hardware'); - hwFS.append(hwLegend); - cloneForm.append(hwFS); + var storageFS = $('
    '); + var storageLegend = $('Storage'); + storageFS.append(storageLegend); + cloneForm.append(storageFS); - var hwAttr = $('
    '); - hwFS.append($('
    ')); - hwFS.append(hwAttr); + var storageAttr = $('
    '); + storageFS.append($('
    ')); + storageFS.append(storageAttr); vmAttr.append('
    '); vmAttr.append('
    '); @@ -639,7 +635,7 @@ zvmPlugin.prototype.loadClonePage = function(node) { // Create group input var group = $('
    '); - var groupLabel = $(''); + var groupLabel = $(''); var groupInput = $(''); groupInput.one('focus', function(){ var groupNames = $.cookie('groups'); @@ -684,9 +680,9 @@ zvmPlugin.prototype.loadClonePage = function(node) { }); poolDiv.append(poolLabel); poolDiv.append(poolInput); - hwAttr.append(poolDiv); + storageAttr.append(poolDiv); - hwAttr.append('
    '); + storageAttr.append('
    '); // Generate tooltips cloneForm.find('div input[title]').tooltip({ @@ -708,8 +704,8 @@ zvmPlugin.prototype.loadClonePage = function(node) { */ var cloneBtn = createButton('Clone'); cloneBtn.bind('click', function(event) { - // Remove any warning messages - $(this).parent().parent().find('.ui-state-error').remove(); + // Remove any warning messages + $(this).parents('.ui-tabs-panel').find('.ui-state-error').remove(); var ready = true; var errMsg = ''; @@ -952,7 +948,7 @@ zvmPlugin.prototype.loadClonePage = function(node) { */ zvmPlugin.prototype.loadInventory = function(data) { var args = data.msg.split(','); - + // Get tab ID var tabId = args[0].replace('out=', ''); // Get node @@ -963,16 +959,19 @@ zvmPlugin.prototype.loadInventory = function(data) { // Check for error var error = false; - if (data.rsp[0].indexOf('Error') > -1) { + if (data.rsp.length && data.rsp[0].indexOf('Error') > -1) { error = true; var warn = createWarnBar(data.rsp[0]); $('#' + tabId).append(warn); } - // Get node inventory - var inv = data.rsp[0].split(node + ':'); - + // Determine the node type + if (data.rsp.length && data.rsp[0].indexOf('Hypervisor OS:') > -1) { + loadHypervisorInventory(data); + return; + } + // Create status bar var statBarId = node + 'StatusBar'; var statBar = createStatusBar(statBarId); @@ -981,31 +980,8 @@ zvmPlugin.prototype.loadInventory = function(data) { var loader = createLoader(node + 'StatusBarLoader').hide(); statBar.find('div').append(loader); statBar.hide(); - - // Create array of property keys - var keys = new Array('userId', 'host', 'os', 'arch', 'hcp', 'priv', 'memory', 'proc', 'disk', 'zfcp', 'nic'); - - // Create hash table for property names - var attrNames = new Object(); - attrNames['userId'] = 'z/VM UserID:'; - attrNames['host'] = 'z/VM Host:'; - attrNames['os'] = 'Operating System:'; - attrNames['arch'] = 'Architecture:'; - attrNames['hcp'] = 'HCP:'; - attrNames['priv'] = 'Privileges:'; - attrNames['memory'] = 'Total Memory:'; - attrNames['proc'] = 'Processors:'; - attrNames['disk'] = 'Disks:'; - attrNames['zfcp'] = 'zFCP:'; - attrNames['nic'] = 'NICs:'; - - // Create hash table for node attributes - var attrs; - if (!error) { - attrs = getAttrs(keys, attrNames, inv); - } - // Create division to hold user entry + // Create division to hold user entry var ueDivId = node + 'UserEntry'; var ueDiv = $('
    '); @@ -1060,6 +1036,40 @@ zvmPlugin.prototype.loadInventory = function(data) { $('#' + tabId).append(toggleLnkDiv); $('#' + tabId).append(ueDiv); $('#' + tabId).append(invDiv); + + // Do not load inventory if no inventory is returned + if (data.rsp.length && data.rsp[0].indexOf('z/VM UserID:') > -1) { + // Do nothing + } else { + return; + } + + // Create array of property keys (VM) + var keys = new Array('userId', 'host', 'os', 'arch', 'uptime', 'cpuusedtime', 'hcp', 'priv', 'memory', 'maxmemory', 'proc', 'disk', 'zfcp', 'nic'); + + // Create hash table for property names (VM) + var attrNames = new Object(); + attrNames['userId'] = 'z/VM UserID:'; + attrNames['host'] = 'z/VM Host:'; + attrNames['os'] = 'Operating System:'; + attrNames['arch'] = 'Architecture:'; + attrNames['uptime'] = 'Uptime:'; + attrNames['cpuusedtime'] = 'CPU Used Time:'; + attrNames['hcp'] = 'HCP:'; + attrNames['priv'] = 'Privileges:'; + attrNames['memory'] = 'Total Memory:'; + attrNames['maxmemory'] = 'Max Memory:'; + attrNames['proc'] = 'Processors:'; + attrNames['disk'] = 'Disks:'; + attrNames['zfcp'] = 'zFCP:'; + attrNames['nic'] = 'NICs:'; + + // Create hash table for node attributes + var inv = data.rsp[0].split(node + ':'); + var attrs; + if (!error) { + attrs = getAttrs(keys, attrNames, inv); + } // Do not continue if error if (error) { @@ -1076,7 +1086,7 @@ zvmPlugin.prototype.loadInventory = function(data) { var item, label, args; // Loop through each property - for (var k = 0; k < 5; k++) { + for (var k = 0; k < 6; k++) { // Create a list item for each property item = $('
  • '); @@ -1107,7 +1117,7 @@ zvmPlugin.prototype.loadInventory = function(data) { // Loop through each property var label; - for (k = 5; k < keys.length; k++) { + for (k = 6; k < keys.length; k++) { // Create a list item item = $('
  • '); @@ -1120,7 +1130,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ if (keys[k] == 'priv') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Loop through each line @@ -1151,7 +1161,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ else if (keys[k] == 'memory') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Loop through each value line @@ -1170,7 +1180,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ else if (keys[k] == 'proc') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Create a table to hold processor data @@ -1267,7 +1277,7 @@ zvmPlugin.prototype.loadInventory = function(data) { /** * Add processor */ - var addProcLink = $('Add temporary processor'); + var addProcLink = $('+ Add temporary processor'); addProcLink.bind('click', function(event) { openAddProcDialog(node); }); @@ -1282,7 +1292,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ else if (keys[k] == 'disk') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Create a table to hold disk (DASD) data @@ -1357,7 +1367,7 @@ zvmPlugin.prototype.loadInventory = function(data) { /** * Add disk */ - var addDasdLink = $('Add disk'); + var addDasdLink = $('+ Add disk'); addDasdLink.bind('click', function(event) { var hcp = attrs['hcp'][0].split('.'); openAddDiskDialog(node, hcp[0]); @@ -1373,7 +1383,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ else if (keys[k] == 'zfcp') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Create a table to hold NIC data @@ -1448,15 +1458,26 @@ zvmPlugin.prototype.loadInventory = function(data) { zfcpTable.append(zfcpBody); + /** + * Add dedicated device + */ + var dedicateDeviceLink = $('+ Add dedicated device').css('display', 'block'); + dedicateDeviceLink.bind('click', function(event) { + var hcp = attrs['hcp'][0].split('.'); + openDedicateDeviceDialog(node, hcp[0]); + }); + /** * Add zFCP device */ - var addZfcpLink = $('Add zFCP'); + var addZfcpLink = $('+ Add zFCP').css('display', 'block'); addZfcpLink.bind('click', function(event) { var hcp = attrs['hcp'][0].split('.'); - openAddZfcpDialog(node, hcp[0]); + var zvm = attrs['host'][0].toLowerCase(); + openAddZfcpDialog(node, hcp[0], zvm); }); - zfcpFooter.append(addZfcpLink); + + zfcpFooter.append(dedicateDeviceLink, addZfcpLink); zfcpTable.append(zfcpFooter); item.append(zfcpTable); @@ -1467,7 +1488,7 @@ zvmPlugin.prototype.loadInventory = function(data) { */ else if (keys[k] == 'nic') { // Create a label - Property name - label = $(''); + label = $(''); item.append(label); // Create a table to hold NIC data @@ -1545,7 +1566,7 @@ zvmPlugin.prototype.loadInventory = function(data) { /** * Add NIC */ - var addNicLink = $('Add NIC'); + var addNicLink = $('+ Add NIC'); addNicLink.bind('click', function(event) { var hcp = attrs['hcp'][0].split('.'); openAddNicDialog(node, hcp[0]); @@ -1554,6 +1575,11 @@ zvmPlugin.prototype.loadInventory = function(data) { nicTable.append(nicFooter); item.append(nicTable); + } + + // Ignore any fields not in key + else { + continue; } oList.append(item); @@ -1564,6 +1590,148 @@ zvmPlugin.prototype.loadInventory = function(data) { invDiv.append(fieldSet); }; +/** + * Load hypervisor inventory + * + * @param data Data from HTTP request + */ +function loadHypervisorInventory(data) { + var args = data.msg.split(','); + + // Get tab ID + var tabId = args[0].replace('out=', ''); + // Get node + var node = args[1].replace('node=', ''); + + // Remove loader + $('#' + tabId).find('img').remove(); + + // Check for error + var error = false; + if (data.rsp.length && data.rsp[0].indexOf('Error') > -1) { + error = true; + + var warn = createWarnBar(data.rsp[0]); + $('#' + tabId).append(warn); + } + + // Get node inventory + var inv = data.rsp[0].split(node + ':'); + + // Create status bar + var statBarId = node + 'StatusBar'; + var statBar = createStatusBar(statBarId); + + // Add loader to status bar and hide it + var loader = createLoader(node + 'StatusBarLoader').hide(); + statBar.find('div').append(loader); + statBar.hide(); + + // Create array of property keys (z/VM hypervisor) + var keys = new Array('host', 'hcp', 'arch', 'cecvendor', 'cecmodel', 'hypos', 'hypname', 'lparcputotal', 'lparcpuused', 'lparmemorytotal', 'lparmemoryused', 'lparmemoryoffline'); + + // Create hash table for property names (z/VM hypervisor) + var attrNames = new Object(); + attrNames['host'] = 'z/VM Host:'; + attrNames['hcp'] = 'zHCP:'; + attrNames['arch'] = 'Architecture:'; + attrNames['cecvendor'] = 'CEC Vendor:'; + attrNames['cecmodel'] = 'CEC Model:'; + attrNames['hypos'] = 'Hypervisor OS:'; + attrNames['hypname'] = 'Hypervisor Name:'; + attrNames['lparcputotal'] = 'LPAR CPU Total:'; + attrNames['lparcpuused'] = 'LPAR CPU Used:'; + attrNames['lparmemorytotal'] = 'LPAR Memory Total:'; + attrNames['lparmemoryused'] = 'LPAR Memory Used:'; + attrNames['lparmemoryoffline'] = 'LPAR Memory Offline:'; + + // Remove loader + $('#' + tabId).find('img').remove(); + + // Create hash table for node attributes + var attrs; + if (!error) { + attrs = getAttrs(keys, attrNames, inv); + } + + // Create division to hold inventory + var invDivId = node + 'Inventory'; + var invDiv = $('
    '); + + // Append to tab + $('#' + tabId).append(statBar); + $('#' + tabId).append(invDiv); + + // Do not continue if error + if (error) { + return; + } + + /** + * General info section + */ + var fieldSet = $('
    '); + var legend = $('General'); + fieldSet.append(legend); + var oList = $('
      '); + var item, label, args; + + // Loop through each property + for (var k = 0; k < 7; k++) { + // Create a list item for each property + item = $('
    1. '); + + // Create a label - Property name + label = $(''); + item.append(label); + + for (var l = 0; l < attrs[keys[k]].length; l++) { + // Create a input - Property value(s) + // Handle each property uniquely + item.append(attrs[keys[k]][l]); + } + + oList.append(item); + } + // Append to inventory form + fieldSet.append(oList); + invDiv.append(fieldSet); + + /** + * Hardware info section + */ + var hwList, hwItem; + fieldSet = $('
      '); + legend = $('Hardware'); + fieldSet.append(legend); + oList = $('
        '); + + // Loop through each property + var label; + for (k = 7; k < keys.length; k++) { + // Create a list item for each property + item = $('
      1. '); + + // Create a label - Property name + label = $(''); + item.append(label); + + for (var l = 0; l < attrs[keys[k]].length; l++) { + // Create a input - Property value(s) + // Handle each property uniquely + item.append(attrs[keys[k]][l]); + } + + oList.append(item); + } + // Append to inventory form + fieldSet.append(oList); + invDiv.append(fieldSet); + + // Append to inventory form + $('#' + tabId).append(invDiv); +}; + /** * Load provision page * @@ -1702,10 +1870,10 @@ zvmPlugin.prototype.addNode = function() { type.append(typeLabel); type.append(typeSelect); addNodeForm.append(type); - + addNodeForm.append('
        '); addNodeForm.append('
        '); - addNodeForm.append('
        '); + addNodeForm.append('
        '); addNodeForm.append('
        '); addNodeForm.append('
        '); addNodeForm.append('
        '); @@ -1719,11 +1887,11 @@ zvmPlugin.prototype.addNode = function() { typeSelect.change(function(){ var selected = $(this).val(); if (selected == 'host') { - addNodeForm.find('input[name=userId]').parent().toggle(); - addNodeForm.find('input[name=os]').parent().toggle(); + addNodeForm.find('input[name=userId]').parent().toggle(); + addNodeForm.find('input[name=os]').parent().toggle(); } else { - addNodeForm.find('input[name=userId]').parent().toggle(); - addNodeForm.find('input[name=os]').parent().toggle(); + addNodeForm.find('input[name=userId]').parent().toggle(); + addNodeForm.find('input[name=os]').parent().toggle(); } }); @@ -1749,17 +1917,17 @@ zvmPlugin.prototype.addNode = function() { // Check required fields if (type == 'host') { - if (!nodeRange || !os || !group || !hcp) { + if (!nodeRange || !os || !group || !hcp) { var warn = createWarnBar('Please provide a value for each missing field!'); warn.prependTo($(this)); return; - } + } } else { - if (!nodeRange || !userIdRange || !group || !hcp) { + if (!nodeRange || !userIdRange || !group || !hcp) { var warn = createWarnBar('Please provide a value for each missing field!'); warn.prependTo($(this)); return; - } + } } // Check node range and user ID range @@ -1876,13 +2044,13 @@ zvmPlugin.prototype.addNode = function() { var args = ""; if (type == 'host') { - args = node + ';zvm.hcp=' + hcp - + ';nodehm.mgt=zvm;hypervisor.type=zvm;groups=' + group - + ';nodetype.os=' + os; + args = node + ';zvm.hcp=' + hcp + + ';nodehm.mgt=zvm;hypervisor.type=zvm;groups=' + group + + ';nodetype.os=' + os; } else { - args = node + ';zvm.hcp=' + hcp - + ';zvm.userid=' + userId - + ';nodehm.mgt=zvm' + ';groups=' + group; + args = node + ';zvm.hcp=' + hcp + + ';zvm.userid=' + userId + + ';nodehm.mgt=zvm' + ';groups=' + group; } if (ipRange != "" && ipRange != null) { @@ -1952,16 +2120,16 @@ zvmPlugin.prototype.addNode = function() { } }); } - } else { + } else { var args = ""; if (type == 'host') { - args = nodeRange + ';zvm.hcp=' + hcp + args = nodeRange + ';zvm.hcp=' + hcp + ';nodehm.mgt=zvm;hypervisor.type=zvm;groups=' + group + ';nodetype.os=' + os; } else { - args = nodeRange + ';zvm.hcp=' + hcp - + ';zvm.userid=' + userIdRange - + ';nodehm.mgt=zvm' + ';groups=' + group; + args = nodeRange + ';zvm.hcp=' + hcp + + ';zvm.userid=' + userIdRange + + ';nodehm.mgt=zvm' + ';groups=' + group; } if (ipRange) @@ -2029,4 +2197,465 @@ zvmPlugin.prototype.addNode = function() { } } }); +}; + +/** + * Migrate page + * + * @param tgtNode Targets to migrate + */ +zvmPlugin.prototype.loadMigratePage = function(tgtNode) { + var hosts = $.cookie('zvms').split(','); + var radio, zvmBlock, args; + var zvms = new Array(); + var hcp = new Object(); + + // Create a drop-down for z/VM destinations + var destSelect = $('') + destSelect.append($('')); + for (var i in hosts) { + args = hosts[i].split(':'); + hcp[args[0]] = args[1]; + zvms.push(args[0]); + + destSelect.append($('')); + } + + // Get nodes tab + var tab = getNodesTab(); + + // Generate new tab ID + var inst = 0; + var newTabId = 'migrateTab' + inst; + while ($('#' + newTabId).length) { + // If one already exists, generate another one + inst = inst + 1; + newTabId = 'migrateTab' + inst; + } + + // Open new tab + // Create remote script form + var migrateForm = $('
        '); + + // Create status bar + var barId = 'migrateStatusBar' + inst; + var statBar = createStatusBar(barId); + statBar.hide(); + migrateForm.append(statBar); + + // Create loader + var loader = createLoader('migrateLoader' + inst); + statBar.find('div').append(loader); + + // Create info bar + var infoBar = createInfoBar('Migrate, test relocation eligibility, or cancel the relocation of the specified virtual machine, while it continues to run, to the specified system within the z/VM SSI cluster.'); + migrateForm.append(infoBar); + + // Virtual machine label + var vmFS = $('
        Virtual Machine
        '); + migrateForm.append(vmFS); + + var vmAttr = $('
        '); + vmFS.append($('
        ')); + vmFS.append(vmAttr); + + // Target node or group + var tgt = $('
        '); + vmAttr.append(tgt); + + // Destination + var dest = $('
        '); + var destInput = $(''); + destInput.autocomplete({ + source: zvms + }); + + // Create a drop-down if there are known z/VMs + if (zvms.length) { + dest.append(destSelect); + } else { + dest.append(destInput); + } + vmAttr.append(dest); + + // Action Parameter + var actionparam = $('
        '); + vmAttr.append(actionparam); + + // Parameters label + var optionalFS = $('
        Optional
        ').css('margin-top', '20px'); + migrateForm.append(optionalFS); + + var optAttr = $('
        '); + optionalFS.append($('
        ')); + optionalFS.append(optAttr); + + // Immediate Parameter + var immediateparam = $('
        '); + optAttr.append(immediateparam); + immediateparam.change(function() { + if ($('#' + newTabId + ' select[name=immediate]').val() == 'yes') { + $('#' + newTabId + ' input[name=maxQuiesce]').val('0'); + } else { + $('#' + newTabId + ' input[name=maxQuiesce]').val('10'); + } + }); + + // Max total + var maxTotalParam = $('
        '); + optAttr.append(maxTotalParam); + + // Max quiesce + var maxQuiesceParam = $('
        '); + optAttr.append(maxQuiesceParam); + + // Force parameter + var forceParam = $('
        ArchitectureDomainStorage
        '); + optAttr.append(forceParam); + + // Generate tooltips + migrateForm.find('div input[title]').tooltip({ + position: "center right", + offset: [-2, 10], + effect: "fade", + opacity: 0.7, + predelay: 800, + events : { + def : "mouseover,mouseout", + input : "mouseover,mouseout", + widget : "focus mouseover,blur mouseout", + tooltip : "mouseover,mouseout" + } + }); + + /** + * Run + */ + var runBtn = createButton('Run'); + runBtn.click(function() { + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + var tgt = $('#' + newTabId + ' input[name=target]'); + + // Drop-down box exists if z/VM systems are known + // Otherwise, only input box exists + var dest = $('#' + newTabId + ' select[name=dest]'); + if (!dest.length) { + dest = $('#' + newTabId + ' input[name=dest]'); + } + + var action = $('#' + newTabId + ' select[name=action]'); + var immediate = $('#' + newTabId + ' select[name=immediate]'); + var maxTotal = $('#' + newTabId + ' input[name=maxTotal]'); + var maxQuiesce = $('#' + newTabId + ' input[name=maxQuiesce]'); + var tgts = $('#' + newTabId + ' input[name=target]'); + + // Change borders color back to normal + var inputs = $('#' + newTabId + ' input').css('border', 'solid #BDBDBD 1px'); + var inputs = $('#' + newTabId + ' select').css('border', 'solid #BDBDBD 1px'); + + // Check if required arguments are given + var message = ""; + if (!isInteger(maxTotal.val())) { + message += "Max total time must be an integer. "; + maxTotal.css('border', 'solid #FF0000 1px'); + } if (!isInteger(maxQuiesce.val())) { + message += "Max quiesce time must be an integer. "; + maxQuiesce.css('border', 'solid #FF0000 1px'); + } if (!tgt.val()) { + message += "Target must be specified. "; + tgt.css('border', 'solid #FF0000 1px'); + } if (!dest.val()) { + message += "Destination must be specified. "; + dest.css('border', 'solid #FF0000 1px'); + } if (!action.val()) { + message += "Action must be specified. "; + action.css('border', 'solid #FF0000 1px'); + } + + // Show warning message + if (message) { + var warn = createWarnBar(message); + warn.prependTo($(this).parent().parent()); + return; + } + + var args = "destination=" + dest.val() + ";action=" + action.val() + ";immediate=" + immediate.val() + ";"; + + // Append max total argument. Specified <= 0 to accomodate negative values. + if (maxTotal.val() <= 0) { + args = args + "max_total=NOLIMIT;"; + } else { + args = args + "max_total=" + maxTotal.val() + ";"; + } + + // Append max quiesce argument. Specified <= 0 to accomodate negative values. + if (maxQuiesce.val() <= 0) { + args = args + "max_quiesce=NOLIMIT;"; + } else { + args = args + "'max_quiesce=" + maxQuiesce.val() + "';"; + } + + // Append force argument + if ($("input[name=force]:checked").length > 0) { + args = args + "'force=" + $("input[name=force]:checked").each(function() { + args = args + $(this).val() + ' '; + }); + args = args + "';"; + } else { + args = args + ";"; + } + + var statBarId = 'migrateStatusBar' + inst; + $('#' + statBarId).show(); + + // Disable all fields + $('#' + newTabId + ' input').attr('disabled', 'true'); + $('#' + newTabId + ' select').attr('disabled', 'true'); + + // Disable buttons + $('#' + newTabId + ' button').attr('disabled', 'true'); + + // Run migrate + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'rmigrate', + tgt : tgts.val(), + args : args, + msg : 'out=migrateStatusBar' + inst + ';cmd=rmigrate;tgt=' + tgts.val() + }, + + success : updateStatusBar + }); + }); + migrateForm.append(runBtn); + + // Append to discover tab + tab.add(newTabId, 'Migrate', migrateForm, true); + + // Select new tab + tab.select(newTabId); +}; + +/** + * Load event log configuration page + * + * @param node Source node to clone + */ +zvmPlugin.prototype.loadLogPage = function(node) { + // Get nodes tab + var tab = getNodesTab(); + var newTabId = node + 'LogsTab'; + + // If there is no existing clone tab + if (!$('#' + newTabId).length) { + // Get table headers + var tableId = $('#' + node).parents('table').attr('id'); + var headers = $('#' + tableId).parents('.dataTables_scroll').find('.dataTables_scrollHead thead tr:eq(0) th'); + var cols = new Array(); + for ( var i = 0; i < headers.length; i++) { + var col = headers.eq(i).text(); + cols.push(col); + } + + // Get hardware control point column + var hcpCol = $.inArray('hcp', cols); + + // Get hardware control point + var nodeRow = $('#' + node).parent().parent(); + var datatable = $('#' + getNodesTableId()).dataTable(); + var rowPos = datatable.fnGetPosition(nodeRow.get(0)); + var aData = datatable.fnGetData(rowPos); + var hcp = aData[hcpCol]; + + // Create status bar and hide it + var statBarId = node + 'CloneStatusBar'; + var statBar = createStatusBar(statBarId).hide(); + + // Create info bar + var infoBar = createInfoBar('Retrieve, clear, or set options for event logs.'); + + // Create clone form + var logForm = $('
        '); + logForm.append(statBar); + logForm.append(infoBar); + + // Create VM fieldset + var vmFS = $('
        '); + var vmLegend = $('Virtual Machine'); + vmFS.append(vmLegend); + logForm.append(vmFS); + + var vmAttr = $('
        '); + vmFS.append($('
        ')); + vmFS.append(vmAttr); + + // Create logs fieldset + var logFS = $('
        '); + var logLegend = $('Logs'); + logFS.append(logLegend); + logForm.append(logFS); + + var logAttr = $('
        '); + logFS.append($('
        ')); + logFS.append(logAttr); + + vmAttr.append('
        '); + logAttr.append('
        '); + + var optsLabel = $(''); + var optsList = $(''); + logAttr.append(optsLabel); + logAttr.append(optsList); + + // Create retrieve log checkbox + var retrieveChkBox = $('
      2. '); + optsList.append(retrieveChkBox); + retrieveChkBox.append('Retrieve log'); + + // Create log destination input + var tgtLog = $('
      3. '); + tgtLog.hide(); + optsList.append(tgtLog); + + // Create set log checkbox + var setChkBox = $('
      4. '); + optsList.append(setChkBox); + setChkBox.append('Set options'); + + // Create log options input + var logOpt = $('
      5. '); + logOpt.hide(); + optsList.append(logOpt); + + // Create clear log checkbox + var clearChkBox = $('
      6. '); + optsList.append(clearChkBox); + clearChkBox.append('Clear log'); + + retrieveChkBox.bind('click', function(event) { + tgtLog.toggle(); + }); + + setChkBox.bind('click', function(event) { + logOpt.toggle(); + }); + + // Generate tooltips + logForm.find('div input[title]').tooltip({ + position : "center right", + offset : [ -2, 10 ], + effect : "fade", + opacity : 0.7, + predelay: 800, + events : { + def : "mouseover,mouseout", + input : "mouseover,mouseout", + widget : "focus mouseover,blur mouseout", + tooltip : "mouseover,mouseout" + } + }); + + /** + * Run node + */ + var runBtn = createButton('Run'); + runBtn.bind('click', function(event) { + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + var ready = true; + var errMsg = ''; + + // Verify required inputs are provided + var inputs = $('#' + newTabId + ' input'); + for ( var i = 0; i < inputs.length; i++) { + if (!inputs.eq(i).val() + && inputs.eq(i).attr('name') != 'tgtLog' + && inputs.eq(i).attr('name') != 'logOpt') { + inputs.eq(i).css('border', 'solid #FF0000 1px'); + ready = false; + } else { + inputs.eq(i).css('border', 'solid #BDBDBD 1px'); + } + } + + // Write error message + if (!ready) { + errMsg = errMsg + 'Please provide a value for each missing field.
        '; + } + + var tgts = $('#' + newTabId + ' input[name=tgtNode]').val(); + var srcLog = $('#' + newTabId + ' input[name=srcLog]').val(); + + var chkBoxes = $("#" + newTabId + " input[type='checkbox']:checked"); + var optStr = '-s;' + srcLog + ';'; + var opt; + for ( var i = 0; i < chkBoxes.length; i++) { + opt = chkBoxes.eq(i).attr('name'); + optStr += '-' + opt; + + // If it is the retrieve log + if (opt == 's') { + // Append log destination + optStr += ';' + $('#' + newTabId + ' input[name=tgtLog]').val(); + } + + // If it is set options + if (opt == 'o') { + // Append options + optStr += ';' + $('#' + newTabId + ' input[name=logOpt]').val(); + } + + // Append ; to end of string + if (i < (chkBoxes.length - 1)) { + optStr += ';'; + } + } + + // If a value is given for every input + if (ready) { + // Disable all inputs + var inputs = $('#' + newTabId + ' input'); + inputs.attr('disabled', 'disabled'); + + /** + * (1) Retrieve, clear, or set options for event logs + */ + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'reventlog', + tgt : tgts, + args : optStr, + msg : 'out=' + statBarId + ';cmd=reventlog;tgt=' + tgts + }, + + success : updateStatusBar + }); + + // Create loader + $('#' + statBarId).find('div').append(createLoader()); + $('#' + statBarId).show(); + + // Disable run button + $(this).attr('disabled', 'true'); + } else { + // Show warning message + var warn = createWarnBar(errMsg); + warn.prependTo($(this).parent().parent()); + } + }); + logForm.append(runBtn); + + // Add clone tab + tab.add(newTabId, 'Logs', logForm, true); + } + + tab.select(newTabId); }; \ No newline at end of file diff --git a/xCAT-UI/js/custom/zvmUtils.js b/xCAT-UI/js/custom/zvmUtils.js index 4d27b2c3b..5df11d311 100644 --- a/xCAT-UI/js/custom/zvmUtils.js +++ b/xCAT-UI/js/custom/zvmUtils.js @@ -1,4506 +1,5613 @@ -/** - * Global variables - */ -var diskDatatable; // zVM datatable containing disks -var zfcpDatatable; // zVM datatable containing zFCP devices -var networkDatatable; // zVM datatable containing networks - -/** - * Get the disk datatable - * - * @return Data table object - */ -function getDiskDataTable() { - return diskDatatable; -} - -/** - * Set the disk datatable - * - * @param table Data table object - */ -function setDiskDataTable(table) { - diskDatatable = table; -} - -/** - * Get the zFCP datatable - * - * @return Data table object - */ -function getZfcpDataTable() { - return zfcpDatatable; -} - -/** - * Set the zFCP datatable - * - * @param table Data table object - */ -function setZfcpDataTable(table) { - zfcpDatatable = table; -} - -/** - * Get the network datatable - * - * @return Data table object - */ -function getNetworkDataTable() { - return networkDatatable; -} - -/** - * Set the network datatable - * - * @param table Data table object - */ -function setNetworkDataTable(table) { - networkDatatable = table; -} - -/** - * Load HCP specific info - * - * @param data Data from HTTP request - */ -function loadHcpInfo(data) { - var args = data.msg.split(';'); - - // Get group - var group = args[0].replace('group=', ''); - // Get hardware control point - var hcp = args[1].replace('hcp=', ''); - - // Get user directory entry - var userEntry = data.rsp; - if (userEntry[0].indexOf('Failed') < 0) { - if (hcp) { - // If there is no cookie for the disk pool names - if (!$.cookie(hcp + 'diskpools')) { - // Get disk pools - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--diskpoolnames', - msg : hcp - }, - - success : setDiskPoolCookies - }); - } - - // If there is no cookie for the zFCP pool names - if (!$.cookie(hcp + 'zfcppools')) { - // Get disk pools - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--zfcppoolnames', - msg : hcp - }, - - success : setZfcpPoolCookies - }); - } - - // If there is no cookie for the network names - if (!$.cookie(hcp + 'networks')) { - // Get network names - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--getnetworknames', - msg : hcp - }, - - success : setNetworkCookies - }); - } - } // End of if (hcp) - } else { - // Create warning dialog - var warning = createWarnBar('z/VM SMAPI is not responding to ' + hcp + '. It needs to be reset.'); - var warnDialog = $('
        ').append(warning); - - // Open dialog - warnDialog.dialog({ - title:'Warning', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Reset": function(){ - $(this).dialog("close"); - - // Reset SMAPI - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : hcp, - args : '--resetsmapi', - msg : 'group=' + group + ';hcp=' + hcp - }, - - /** - * Refresh group tab - * - * @param data - * Data from HTTP request - * @return Nothing - */ - success : function(data) { - var args = data.msg.split(';'); - - // Get group - var group = args[0].replace('group=', ''); - - // Clear nodes division - $('#nodes').children().remove(); - // Create loader - var loader = $('
        ').append(createLoader()); - - // Create a tab for this group - var tab = new Tab(); - setNodesTab(tab); - tab.init(); - $('#nodes').append(tab.object()); - tab.add('nodesTab', 'Nodes', loader, false); - - // Get nodes within selected group - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsdef', - tgt : '', - args : group, - msg : group - }, - - success : loadNodes - }); - } // End of function - }); - }, - - "Ignore": function() { - $(this).dialog("close"); - } - } - }); - } -} - -/** - * Load user entry of a given node - * - * @param data Data from HTTP request - */ -function loadUserEntry(data) { - var args = data.msg.split(';'); - - // Get tab ID - var ueDivId = args[0].replace('out=', ''); - // Get node - var node = args[1].replace('node=', ''); - // Get user directory entry - var userEntry = data.rsp[0].split(node + ':'); - - // Remove loader - $('#' + node + 'TabLoader').remove(); - - var toggleLinkId = node + 'ToggleLink'; - $('#' + toggleLinkId).click(function() { - // Get text within this link - var lnkText = $(this).text(); - - // Toggle user entry division - $('#' + node + 'UserEntry').toggle(); - // Toggle inventory division - $('#' + node + 'Inventory').toggle(); - - // Change text - if (lnkText == 'Show directory entry') { - $(this).text('Show inventory'); - } else { - $(this).text('Show directory entry'); - } - }); - - // Put user entry into a list - var fieldSet = $('
        '); - var legend = $('Directory Entry'); - fieldSet.append(legend); - - var txtArea = $(''); - for ( var i = 1; i < userEntry.length; i++) { - userEntry[i] = jQuery.trim(userEntry[i]); - txtArea.append(userEntry[i]); - - if (i < userEntry.length) { - txtArea.append('\n'); - } - } - txtArea.attr('readonly', 'readonly'); - fieldSet.append(txtArea); - - /** - * Edit user entry - */ - txtArea.bind('dblclick', function(event) { - txtArea.attr('readonly', ''); - txtArea.css( { - 'border-width' : '1px' - }); - - saveBtn.show(); - cancelBtn.show(); - saveBtn.css('display', 'inline-table'); - cancelBtn.css('display', 'inline-table'); - }); - - /** - * Save - */ - var saveBtn = createButton('Save').hide(); - saveBtn.bind('click', function(event) { - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); - - // Replace user entry - var newUserEntry = jQuery.trim(txtArea.val()) + '\n'; - - // Replace user entry - $.ajax( { - url : 'lib/zCmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--replacevs', - att : newUserEntry, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process and save it in a cookie - incrementNodeProcess(node); - - txtArea.attr('readonly', 'readonly'); - txtArea.css( { - 'border-width' : '0px' - }); - - // Disable save button - $(this).hide(); - cancelBtn.hide(); - }); - - /** - * Cancel - */ - var cancelBtn = createButton('Cancel').hide(); - cancelBtn.bind('click', function(event) { - txtArea.attr('readonly', 'readonly'); - txtArea.css( { - 'border-width' : '0px' - }); - - cancelBtn.hide(); - saveBtn.hide(); - }); - - // Create info bar - var infoBar = createInfoBar('Double click on the directory entry to edit it.'); - - // Append user entry into division - $('#' + ueDivId).append(infoBar); - $('#' + ueDivId).append(fieldSet); - $('#' + ueDivId).append(saveBtn); - $('#' + ueDivId).append(cancelBtn); -} - -/** - * Increment number of processes running against a node - * - * @param node Node to increment running processes - */ -function incrementNodeProcess(node) { - // Get current processes - var procs = $.cookie(node + 'processes'); - if (procs) { - // One more process - procs = parseInt(procs) + 1; - $.cookie(node + 'processes', procs); - } else { - $.cookie(node + 'processes', 1); - } -} - -/** - * Update provision new node status - * - * @param data Data returned from HTTP request - */ -function updateZProvisionNewStatus(data) { - // Parse ajax response - var rsp = data.rsp; - var args = data.msg.split(';'); - var lastCmd = args[0].replace('cmd=', ''); - var out2Id = args[1].replace('out=', ''); - - // IDs for status bar, tab, and loader - var statBarId = 'zProvisionStatBar' + out2Id; - var tabId = 'zvmProvisionTab' + out2Id; - var loaderId = 'zProvisionLoader' + out2Id; - - var node = $('#' + tabId + ' input[name=nodeName]').val(); - - /** - * (2) Create user entry - */ - if (lastCmd == 'nodeadd') { - if (rsp.length) { - $('#' + loaderId).hide(); - $('#' + statBarId).find('div').append('
        (Error) Failed to create node definition
        '); - } else { - $('#' + statBarId).find('div').append('
        Node definition created for ' + node + '
        '); - - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // Create user entry - var userEntry = $('#' + tabId + ' textarea').val(); - $.ajax( { - url : 'lib/zCmd.php', - dataType : 'json', - data : { - cmd : 'mkvm', - tgt : node, - args : '', - att : userEntry, - msg : 'cmd=mkvm;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - /** - * (3) Update /etc/hosts - */ - else if (lastCmd == 'mkvm') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // If there was an error, quit - if (containErrors(prg.html())) { - $('#' + loaderId).hide(); - } else { - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'makehosts', - tgt : '', - args : '', - msg : 'cmd=makehosts;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - /** - * (4) Update DNS - */ - else if (lastCmd == 'makehosts') { - // If there was an error, quit - if (rsp.length) { - $('#' + loaderId).hide(); - $('#' + statBarId).find('div').append('
        (Error) Failed to update /etc/hosts
        '); - } else { - $('#' + statBarId).find('div').append('
        /etc/hosts updated
        '); - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'makedns', - tgt : '', - args : '', - msg : 'cmd=makedns;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - /** - * (5) Add disk - */ - else if (lastCmd == 'makedns') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // If there was an error, quit - if (containErrors(prg.html())) { - $('#' + loaderId).hide(); - } else { - // Set cookie for number of disks - var diskRows = $('#' + tabId + ' table:eq(0):visible tbody tr'); - $.cookie('disks2add' + out2Id, diskRows.length); - if (diskRows.length > 0) { - for ( var i = 0; i < diskRows.length; i++) { - var diskArgs = diskRows.eq(i).find('td'); - var type = diskArgs.eq(1).find('select').val(); - var address = diskArgs.eq(2).find('input').val(); - var size = diskArgs.eq(3).find('input').val(); - var mode = diskArgs.eq(4).find('select').val(); - var pool = diskArgs.eq(5).find('select').val(); - var password = diskArgs.eq(6).find('input').val(); - - // Create ajax arguments - var args = ''; - if (type == '3390') { - args = '--add' + type + ';' + pool + ';' + address - + ';' + size + ';' + mode + ';' + password + ';' - + password + ';' + password; - } else if (type == '9336') { - var blkSize = '512'; - args = '--add' + type + ';' + pool + ';' + address + ';' - + blkSize + ';' + size + ';' + mode + ';' + password + ';' - + password + ';' + password; - } - - // Attach disk to node - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : args, - msg : 'cmd=chvm-disk;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - // Set cookie for number of zFCP devices - var zfcpRows = $('#' + tabId + ' table:eq(1):visible tbody tr'); - $.cookie('zfcp2add' + out2Id, zfcpRows.length); - if (zfcpRows.length > 0) { - for ( var i = 0; i < zfcpRows.length; i++) { - var diskArgs = zfcpRows.eq(i).find('td'); - var address = diskArgs.eq(1).find('input').val(); - var size = diskArgs.eq(2).find('input').val(); - var pool = diskArgs.eq(3).find('select').val(); - var tag = diskArgs.eq(4).find('input').val(); - var portName = diskArgs.eq(5).find('input').val(); - var unitNo = diskArgs.eq(6).find('input').val(); - - // This is either true or false - var loaddev = diskArgs.eq(7).find('input').attr('checked'); - if (loaddev) { - loaddev = "1"; - } else { - loaddev = "0"; - } - - // Create ajax arguments - var args = '--addzfcp;' + pool + ';' + address + ';' + loaddev + ';' + size; - if (tag && tag != "null") { - args += ';' + tag; - } if (portName && tag != "null") { - args += ';' + portName; - } if (unitNo && tag != "null") { - args += ';' + unitNo; - } - - // Attach zFCP device to node - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : args, - msg : 'cmd=chvm-zfcp;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - // Done if no disks to add - var zfcp2add = $.cookie('zfcp2add' + out2Id); - var zfcp2add = $.cookie('zfcp2add' + out2Id); - if (disks2add < 1 && zfcp2add < 1) { - $('#' + loaderId).hide(); - } - } - } - - /** - * (6) Set operating system for given node - */ - else if (lastCmd == 'chvm-disk' || lastCmd == 'chvm-zfcp') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // If there was an error, quit - if (containErrors(prg.html())) { - $('#' + loaderId).hide(); - } else { - // Set cookie for number of disks - // One less disk to add - var disks2add = $.cookie('disks2add' + out2Id); - if (lastCmd == 'chvm-disk') { - if (disks2add > 0) { - disks2add--; - $.cookie('disks2add' + out2Id, disks2add); - } - } - - var zfcp2add = $.cookie('zfcp2add' + out2Id); - if (lastCmd == 'chvm-zfcp') { - if (zfcp2add > 0) { - zfcp2add--; - $.cookie('zfcp2add' + out2Id, zfcp2add); - } - } - - // Only set operating system if there are no more disks to add - if (zfcp2add < 1 && disks2add < 1) { - // If an operating system image is given - var osImage = $('#' + tabId + ' select[name=os]:visible').val(); - if (osImage) { - // Get operating system, architecture, provision method, and profile - var tmp = osImage.split('-'); - var os = tmp[0]; - var arch = tmp[1]; - var profile = tmp[3]; - - // If the last disk is added - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeadd', - tgt : '', - args : node + ';noderes.netboot=zvm;nodetype.os=' - + os + ';nodetype.arch=' + arch - + ';nodetype.profile=' + profile, - msg : 'cmd=noderes;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } else { - $('#' + loaderId).hide(); - } - } - } - } - - /** - * (7) Update DHCP - */ - else if (lastCmd == 'noderes') { - // If there was an error, do not continue - if (rsp.length) { - $('#' + loaderId).hide(); - $('#' + statBarId).find('div').append('
        (Error) Failed to set operating system
        '); - } else { - $('#' + statBarId).find('div').append('
        Operating system for ' + node + ' set
        '); - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'makedhcp', - tgt : '', - args : '-a', - msg : 'cmd=makedhcp;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - /** - * (8) Prepare node for boot - */ - else if (lastCmd == 'makedhcp') { - // Prepare node for boot - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeset', - tgt : node, - args : 'install', - msg : 'cmd=nodeset;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - - /** - * (9) Boot node to network - */ - else if (lastCmd == 'nodeset') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // If there was an error - // Do not continue - if (containErrors(prg.html())) { - $('#' + loaderId).hide(); - } else { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'rnetboot', - tgt : node, - args : 'ipl=000C', - msg : 'cmd=rnetboot;out=' + out2Id - }, - - success : updateZProvisionNewStatus - }); - } - } - - /** - * (10) Done - */ - else if (lastCmd == 'rnetboot') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - if (prg.html().indexOf('Error') < 0) { - $('#' + statBarId).find('div').append('
        Open a VNC viewer to see the installation progress.  It might take a couple of minutes before you can connect.
        '); - } - - // Hide loader - $('#' + loaderId).hide(); - } -} - -/** - * Update the provision existing node status - * - * @param data Data returned from HTTP request - */ -function updateZProvisionExistingStatus(data) { - // Get ajax response - var rsp = data.rsp; - var args = data.msg.split(';'); - - // Get command invoked - var cmd = args[0].replace('cmd=', ''); - // Get provision tab instance - var inst = args[1].replace('out=', ''); - - // Get provision tab and status bar ID - var statBarId = 'zProvisionStatBar' + inst; - var tabId = 'zvmProvisionTab' + inst; - - /** - * (2) Prepare node for boot - */ - if (cmd == 'nodeadd') { - // Get operating system - var bootMethod = $('#' + tabId + ' select[name=bootMethod]').val(); - - // Get nodes that were checked - var dTableId = 'zNodesDatatable' + inst; - var tgts = getNodesChecked(dTableId); - - // Prepare node for boot - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeset', - tgt : tgts, - args : bootMethod, - msg : 'cmd=nodeset;out=' + inst - }, - - success : updateZProvisionExistingStatus - }); - } - - /** - * (3) Boot node from network - */ - else if (cmd == 'nodeset') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - // If there was an error, do not continue - if (containErrors(prg.html())) { - var loaderId = 'zProvisionLoader' + inst; - $('#' + loaderId).remove(); - return; - } - - // Get nodes that were checked - var dTableId = 'zNodesDatatable' + inst; - var tgts = getNodesChecked(dTableId); - - // Boot node from network - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'rnetboot', - tgt : tgts, - args : 'ipl=000C', - msg : 'cmd=rnetboot;out=' + inst - }, - - success : updateZProvisionExistingStatus - }); - } - - /** - * (4) Done - */ - else if (cmd == 'rnetboot') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + statBarId).find('div').append(prg); - - var loaderId = 'zProvisionLoader' + inst; - $('#' + loaderId).remove(); - } -} - -/** - * Update zVM node status - * - * @param data Data returned from HTTP request - */ -function updateZNodeStatus(data) { - var node = data.msg; - var rsp = data.rsp; - - // Get cookie for number processes performed against this node - var actions = $.cookie(node + 'processes'); - // One less process - actions = actions - 1; - $.cookie(node + 'processes', actions); - - if (actions < 1) { - // Hide loader when there are no more processes - var statusBarLoaderId = node + 'StatusBarLoader'; - $('#' + statusBarLoaderId).hide(); - } - - var statBarId = node + 'StatusBar'; - - // Write ajax response to status bar - var prg = writeRsp(rsp, '[A-Za-z0-9._-]+:'); - $('#' + statBarId).find('div').append(prg); -} - -/** - * Update clone status - * - * @param data Data returned from HTTP request - */ -function updateZCloneStatus(data) { - // Get ajax response - var rsp = data.rsp; - var args = data.msg.split(';'); - var cmd = args[0].replace('cmd=', ''); - - // Get provision instance - var inst = args[1].replace('inst=', ''); - // Get output division ID - var out2Id = args[2].replace('out=', ''); - - /** - * (2) Update /etc/hosts - */ - if (cmd == 'nodeadd') { - var node = args[3].replace('node=', ''); - - // If there was an error, do not continue - if (rsp.length) { - $('#' + out2Id).find('img').hide(); - $('#' + out2Id).find('div').append('
        (Error) Failed to create node definition
        '); - } else { - $('#' + out2Id).find('div').append('
        Node definition created for ' + node + '
        '); - - // If last node definition was created - var tmp = inst.split('/'); - if (tmp[0] == tmp[1]) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'makehosts', - tgt : '', - args : '', - msg : 'cmd=makehosts;inst=' + inst + ';out=' + out2Id - }, - - success : updateZCloneStatus - }); - } - } - } - - /** - * (3) Update DNS - */ - else if (cmd == 'makehosts') { - // If there was an error, do not continue - if (rsp.length) { - $('#' + out2Id).find('img').hide(); - $('#' + out2Id).find('div').append('
        (Error) Failed to update /etc/hosts
        '); - } else { - $('#' + out2Id).find('div').append('
        /etc/hosts updated
        '); - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'makedns', - tgt : '', - args : '', - msg : 'cmd=makedns;inst=' + inst + ';out=' + out2Id - }, - - success : updateZCloneStatus - }); - } - } - - /** - * (4) Clone - */ - else if (cmd == 'makedns') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + out2Id).find('div').append(prg); - - // Get clone tab - var tabId = out2Id.replace('CloneStatusBar', 'CloneTab'); - - // If a node range is given - var tgtNodeRange = $('#' + tabId + ' input[name=tgtNode]').val(); - var tgtNodes = ''; - if (tgtNodeRange.indexOf('-') > -1) { - var tmp = tgtNodeRange.split('-'); - - // Get node base name - var nodeBase = tmp[0].match(/[a-zA-Z]+/); - // Get the starting index - var nodeStart = parseInt(tmp[0].match(/\d+/)); - // Get the ending index - var nodeEnd = parseInt(tmp[1].match(/\d+/)); - for ( var i = nodeStart; i <= nodeEnd; i++) { - // Do not append comma for last node - if (i == nodeEnd) { - tgtNodes += nodeBase + i.toString(); - } else { - tgtNodes += nodeBase + i.toString() + ','; - } - } - } else { - tgtNodes = tgtNodeRange; - } - - // Get other inputs - var srcNode = $('#' + tabId + ' input[name=srcNode]').val(); - hcp = $('#' + tabId + ' input[name=newHcp]').val(); - var group = $('#' + tabId + ' input[name=newGroup]').val(); - var diskPool = $('#' + tabId + ' input[name=diskPool]').val(); - var diskPw = $('#' + tabId + ' input[name=diskPw]').val(); - if (!diskPw) { - diskPw = ''; - } - - // Clone - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'mkvm', - tgt : tgtNodes, - args : srcNode + ';pool=' + diskPool + ';pw=' + diskPw, - msg : 'cmd=mkvm;inst=' + inst + ';out=' + out2Id - }, - - success : updateZCloneStatus - }); - } - - /** - * (5) Done - */ - else if (cmd == 'mkvm') { - // Write ajax response to status bar - var prg = writeRsp(rsp, ''); - $('#' + out2Id).find('div').append(prg); - - // Hide loader - $('#' + out2Id).find('img').hide(); - } -} - -/** - * Get zVM resources - * - * @param data Data from HTTP request - */ -function getZResources(data) { - // Do not continue if there is no output - if (data.rsp) { - // Push hardware control points into an array - var node, hcp; - var hcpHash = new Object(); - for (var i in data.rsp) { - node = data.rsp[i][0]; - hcp = data.rsp[i][1]; - hcpHash[hcp] = 1; - } - - // Create an array for hardware control points - var hcps = new Array(); - for (var key in hcpHash) { - // Get the short host name - hcp = key.split('.')[0]; - hcps.push(hcp); - } - - // Set hardware control point cookie - $.cookie('hcp', hcps); - - // Delete loader - var tabId = 'zvmResourceTab'; - $('#' + tabId).find('img[src="images/loader.gif"]').remove(); - - // Create accordion panel for disk - var resourcesAccordion = $('
        '); - var diskSection = $('
        '); - var diskLnk = $('

        Disks

        ').click(function () { - // Do not load panel again if it is already loaded - if ($('#zvmDiskResource').children().length) - return; - else - $('#zvmDiskResource').append(createLoader('')); - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - // Query the disk pools for each - for (var i in hcps) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcps[i], - args : '--diskpoolnames', - msg : hcps[i] - }, - - success : getDiskPool - }); - } - }); - - // Create accordion panel for zFCP devices - var zfcpSection = $('
        '); - var zfcpLnk = $('

        zFCP

        ').click(function () { - // Do not load panel again if it is already loaded - if ($('#zfcpResource').children().length) - return; - else - $('#zfcpResource').append(createLoader('')); - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - for ( var i in hcps) { - // Gather networks from hardware control points - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcps[i], - args : '--zfcppoolnames', - msg : hcps[i] - }, - - success : getZfcpPool - }); - } - }); - - // Create accordion panel for network - var networkSection = $('
        '); - var networkLnk = $('

        Networks

        ').click(function () { - // Do not load panel again if it is already loaded - if ($('#zvmNetworkResource').children().length) - return; - else - $('#zvmNetworkResource').append(createLoader('')); - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - for ( var i in hcps) { - // Gather networks from hardware control points - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcps[i], - args : '--getnetworknames', - msg : hcps[i] - }, - - success : getNetwork - }); - } - }); - - resourcesAccordion.append(diskLnk, diskSection, zfcpLnk, zfcpSection, networkLnk, networkSection); - - // Append accordion to tab - $('#' + tabId).append(resourcesAccordion); - resourcesAccordion.accordion(); - diskLnk.trigger('click'); - } -} - -/** - * Get node attributes from HTTP request data - * - * @param propNames Hash table of property names - * @param keys Property keys - * @param data Data from HTTP request - * @return Hash table of property values - */ -function getAttrs(keys, propNames, data) { - // Create hash table for property values - var attrs = new Object(); - - // Go through inventory and separate each property out - var curKey = null; // Current property key - var addLine; // Add a line to the current property? - for ( var i = 1; i < data.length; i++) { - addLine = true; - - // Loop through property keys - // Does this line contains one of the properties? - for ( var j = 0; j < keys.length; j++) { - // Find property name - if (data[i].indexOf(propNames[keys[j]]) > -1) { - attrs[keys[j]] = new Array(); - - // Get rid of property name in the line - data[i] = data[i].replace(propNames[keys[j]], ''); - // Trim the line - data[i] = jQuery.trim(data[i]); - - // Do not insert empty line - if (data[i].length > 0) { - attrs[keys[j]].push(data[i]); - } - - curKey = keys[j]; - addLine = false; // This line belongs to a property - } - } - - // Line does not contain a property - // Must belong to previous property - if (addLine && data[i].length > 1) { - data[i] = jQuery.trim(data[i]); - attrs[curKey].push(data[i]); - } - } - - return attrs; -} - -/** - * Create add processor dialog - * - * @param node Node to add processor to - */ -function openAddProcDialog(node) { - // Create form to add processor - var addProcForm = $('
        '); - // Create info bar - var info = createInfoBar('Add a temporary processor to this virtual server.'); - addProcForm.append(info); - addProcForm.append('
        '); - addProcForm.append('
        '); - - // Create drop down for processor type - var procType = $('
        '); - procType.append(''); - var typeSelect = $(''); - typeSelect.append('' - + '' - + '' - + '' - ); - procType.append(typeSelect); - addProcForm.append(procType); - - // Open dialog to add processor - addProcForm.dialog({ - title:'Add processor', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Get inputs - var node = $(this).find('input[name=procNode]').val(); - var address = $(this).find('input[name=procAddress]').val(); - var type = $(this).find('select[name=procType]').val(); - - // If inputs are not complete, show warning message - if (!node || !address || !type) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Add processor - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--addprocessoractive;' + address + ';' + type, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - var statusId = node + 'StatusBar'; - var statusBarLoaderId = node + 'StatusBarLoader'; - $('#' + statusBarLoaderId).show(); - $('#' + statusId).show(); - - // Close dialog - $(this).dialog( "close" ); - } - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Create add disk dialog - * - * @param node Node to add disk to - * @param hcp Hardware control point of node - */ -function openAddDiskDialog(node, hcp) { - // Get list of disk pools - var cookie = $.cookie(hcp + 'diskpools'); - var pools = cookie.split(','); - - // Create form to add disk - var addDiskForm = $('
        '); - // Create info bar - var info = createInfoBar('Add a ECKD|3390 or FBA|9336 disk to this virtual server.'); - addDiskForm.append(info); - addDiskForm.append('
        '); - addDiskForm.append('
        '); - addDiskForm.append('
        '); - addDiskForm.append('
        '); - - // Create drop down for disk pool - var diskPool = $('
        '); - diskPool.append(''); - var poolSelect = $(''); - for ( var i = 0; i < pools.length; i++) { - poolSelect.append(''); - } - diskPool.append(poolSelect); - addDiskForm.append(diskPool); - - // Create drop down for disk mode - var diskMode = $('
        '); - diskMode.append(''); - var modeSelect = $(''); - modeSelect.append('' - + '' - + '' - + '' - + '' - + '' - + '' - ); - diskMode.append(modeSelect); - addDiskForm.append(diskMode); - - addDiskForm.append('
        '); - - // Open dialog to add disk - addDiskForm.dialog({ - title:'Add disk', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Get inputs - var node = $(this).find('input[name=diskNode]').val(); - var type = $(this).find('select[name=diskType]').val(); - var address = $(this).find('input[name=diskAddress]').val(); - var size = $(this).find('input[name=diskSize]').val(); - var pool = $(this).find('select[name=diskPool]').val(); - var mode = $(this).find('select[name=diskMode]').val(); - var password = $(this).find('input[name=diskPassword]').val(); - - // If inputs are not complete, show warning message - if (!node || !type || !address || !size || !pool || !mode) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Add disk - if (type == '3390') { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--add3390;' + pool + ';' + address + ';' + size - + ';' + mode + ';' + password + ';' + password + ';' + password, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - var statusId = node + 'StatusBar'; - var statusBarLoaderId = node + 'StatusBarLoader'; - $('#' + statusBarLoaderId).show(); - $('#' + statusId).show(); - } else if (type == '9336') { - // Default block size for FBA volumes = 512 - var blkSize = '512'; - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--add9336;' + pool + ';' + address + ';' + blkSize + ';' + size - + ';' + mode + ';' + password + ';' + password + ';' + password, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - var statusId = node + 'StatusBar'; - var statusBarLoaderId = node + 'StatusBarLoader'; - $('#' + statusBarLoaderId).show(); - $('#' + statusId).show(); - } - - // Close dialog - $(this).dialog( "close" ); - } // End of else - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Create add zFCP device dialog - * - * @param node Node to add disk to - * @param hcp Hardware control point of node - */ -function openAddZfcpDialog(node, hcp) { - // Get list of disk pools - var cookie = $.cookie(hcp + 'zfcppools'); - var pools = cookie.split(','); - - // Create form to add disk - var addZfcpForm = $('
        '); - // Create info bar - var info = createInfoBar('Add a SCSI|FCP disk to this virtual server.'); - addZfcpForm.append(info); - addZfcpForm.append('
        '); - addZfcpForm.append('
        '); - addZfcpForm.append('
        '); - addZfcpForm.append('
        '); - - // Create drop down for disk pool - var diskPool = $('
        '); - diskPool.append(''); - var poolSelect = $(''); - for ( var i = 0; i < pools.length; i++) { - poolSelect.append(''); - } - diskPool.append(poolSelect); - addZfcpForm.append(diskPool); - - // Tag to identify where device will be used - addZfcpForm.append('
        '); - - // Create advanced link to set advanced zFCP properties - var advancedLnk = $('
        '); - addZfcpForm.append(advancedLnk); - var advanced = $('
        ').hide(); - addZfcpForm.append(advanced); - - var portName = $('
        '); - var unitNo = $('
        '); - advanced.append(portName, unitNo); - - // Toggle port name and unit number when clicking on advanced link - advancedLnk.click(function() { - advanced.toggle(); - }); - - // Open dialog to add disk - addZfcpForm.dialog({ - title:'Add zFCP device', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Get inputs - var node = $(this).find('input[name=diskNode]').val(); - var address = $(this).find('input[name=diskAddress]').val(); - var loaddev = $(this).find('input[name=diskLoaddev]'); - var size = $(this).find('input[name=diskSize]').val(); - var pool = $(this).find('select[name=diskPool]').val(); - var tag = $(this).find('select[name=diskTag]').val(); - var portName = $(this).find('select[name=diskPortName]').val(); - var unitNo = $(this).find('select[name=diskUnitNo]').val(); - - // If inputs are not complete, show warning message - if (!node || !address || !size || !pool) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - if (loaddev.attr('checked')) { - loaddev = 1; - } else { - loaddev = 0; - } - - var args = '--addzfcp;' + pool + ';' + address + ';' + loaddev + ';' + size; - - if (tag && tag != "null") { - args += ';' + tag; - } if (portName && tag != "null") { - args += ';' + portName; - } if (unitNo && tag != "null") { - args += ';' + unitNo; - } - - // Add zFCP device - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : args, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - var statusId = node + 'StatusBar'; - var statusBarLoaderId = node + 'StatusBarLoader'; - $('#' + statusBarLoaderId).show(); - $('#' + statusId).show(); - - // Close dialog - $(this).dialog( "close" ); - } // End of else - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Create add NIC dialog - * - * @param node Node to add NIC to - * @param hcp Hardware control point of node - */ -function openAddNicDialog(node, hcp) { - // Get network names - var networks = $.cookie(hcp + 'networks').split(','); - - // Create form to add NIC - var addNicForm = $('
        '); - // Create info bar - var info = createInfoBar('Add a NIC to this virtual server.'); - addNicForm.append(info); - addNicForm.append('
        '); - addNicForm.append('
        '); - - // Create drop down for NIC types - var nicType = $('
        '); - nicType.append(''); - var nicTypeSelect = $(''); - nicTypeSelect.append('' - + '' - + '' - ); - nicType.append(nicTypeSelect); - addNicForm.append(nicType); - - // Create drop down for network types - var networkType = $('
        '); - networkType.append(''); - var networkTypeSelect = $(''); - networkTypeSelect.append('' - + '' - + '' - ); - networkType.append(networkTypeSelect); - addNicForm.append(networkType); - - // Create drop down for network names - var gLansQdioSelect = $(''); - var gLansHipersSelect = $(''); - var vswitchSelect = $(''); - for ( var i = 0; i < networks.length; i++) { - var network = networks[i].split(' '); - var networkOption = $(''); - if (network[0] == 'VSWITCH') { - vswitchSelect.append(networkOption); - } else if (network[0] == 'LAN:QDIO') { - gLansQdioSelect.append(networkOption); - } else if (network[0] == 'LAN:HIPERS') { - gLansHipersSelect.append(networkOption); - } - } - - // Hide network name drop downs until the NIC type and network type is selected - // QDIO Guest LAN drop down - var guestLanQdio = $('
        ').hide(); - guestLanQdio.append(''); - guestLanQdio.append(gLansQdioSelect); - addNicForm.append(guestLanQdio); - - // HIPERS Guest LAN drop down - var guestLanHipers = $('
        ').hide(); - guestLanHipers.append(''); - guestLanHipers.append(gLansHipersSelect); - addNicForm.append(guestLanHipers); - - // VSWITCH drop down - var vswitch = $('
        ').hide(); - vswitch.append(''); - vswitch.append(vswitchSelect); - addNicForm.append(vswitch); - - // Show network names on change - networkTypeSelect.change(function(){ - // Remove any warning messages - $(this).parent().parent().find('.ui-state-error').remove(); - - // Get NIC type and network type - var nicType = $(this).parent().parent().find('select[name=nicType]').val(); - var networkType = $(this).val(); - - // Hide network name drop downs - var guestLanQdio = $(this).parent().parent().find('select[name=nicLanQdioName]').parent(); - var guestLanHipers = $(this).parent().parent().find('select[name=nicLanHipersName]').parent(); - var vswitch = $(this).parent().parent().find('select[name=nicVSwitchName]').parent(); - guestLanQdio.hide(); - guestLanHipers.hide(); - vswitch.hide(); - - // Show correct network name - if (networkType == 'Guest LAN' && nicType == 'QDIO') { - guestLanQdio.show(); - } else if (networkType == 'Guest LAN' && nicType == 'HiperSockets') { - guestLanHipers.show(); - } else if (networkType == 'Virtual Switch') { - if (nicType == 'QDIO') { - vswitch.show(); - } else { - // No such thing as HIPERS VSWITCH - var warn = createWarnBar('The selected choices are not valid.'); - warn.prependTo($(this).parent().parent()); - } - } - }); - - // Show network names on change - nicTypeSelect.change(function(){ - // Remove any warning messages - $(this).parent().parent().find('.ui-state-error').remove(); - - // Get NIC type and network type - var nicType = $(this).val(); - var networkType = $(this).parent().parent().find('select[name=nicNetworkType]').val(); - - // Hide network name drop downs - var guestLanQdio = $(this).parent().parent().find('select[name=nicLanQdioName]').parent(); - var guestLanHipers = $(this).parent().parent().find('select[name=nicLanHipersName]').parent(); - var vswitch = $(this).parent().parent().find('select[name=nicVSwitchName]').parent(); - guestLanQdio.hide(); - guestLanHipers.hide(); - vswitch.hide(); - - // Show correct network name - if (networkType == 'Guest LAN' && nicType == 'QDIO') { - guestLanQdio.show(); - } else if (networkType == 'Guest LAN' && nicType == 'HiperSockets') { - guestLanHipers.show(); - } else if (networkType == 'Virtual Switch') { - if (nicType == 'QDIO') { - vswitch.show(); - } else { - // No such thing as HIPERS VSWITCH - var warn = createWarnBar('The selected choices are not valid.'); - warn.prependTo($(this).parent().parent()); - } - } - }); - - // Open dialog to add NIC - addNicForm.dialog({ - title:'Add NIC', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - var ready = true; - var errMsg = ''; - - // Get inputs - var node = $(this).find('input[name=nicNode]').val(); - var nicType = $(this).find('select[name=nicType]').val(); - var networkType = $(this).find('select[name=nicNetworkType]').val(); - var address = $(this).find('input[name=nicAddress]').val(); - - // If inputs are not complete, show warning message - if (!node || !nicType || !networkType || !address) { - errMsg = 'Please provide a value for each missing field.
        '; - ready = false; - } - - // If a HIPERS VSWITCH is selected, show warning message - if (nicType == 'HiperSockets' && networkType == 'Virtual Switch') { - errMsg += 'The selected choices are not valid.'; - ready = false; - } - - // If there are errors - if (!ready) { - // Show warning message - var warn = createWarnBar(errMsg); - warn.prependTo($(this)); - } else { - // Add guest LAN - if (networkType == 'Guest LAN') { - var temp; - if (nicType == 'QDIO') { - temp = $(this).find('select[name=nicLanQdioName]').val().split(' '); - } else { - temp = $(this).find('select[name=nicLanHipersName]').val().split(' '); - } - - var lanOwner = temp[0]; - var lanName = temp[1]; - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--addnic;' + address + ';' + nicType + ';3', - msg : 'node=' + node + ';addr=' + address + ';lan=' - + lanName + ';owner=' + lanOwner - }, - success : connect2GuestLan - }); - } - - // Add virtual switch - else if (networkType == 'Virtual Switch' && nicType == 'QDIO') { - var temp = $(this).find('select[name=nicVSwitchName]').val().split(' '); - var vswitchName = temp[1]; - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--addnic;' + address + ';' + nicType + ';3', - msg : 'node=' + node + ';addr=' + address + ';vsw=' - + vswitchName - }, - - success : connect2VSwitch - }); - } - - // Increment node process - incrementNodeProcess(node); - - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); - - // Close dialog - $(this).dialog( "close" ); - } // End of else - }, - "Cancel": function(){ - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Remove processor - * - * @param node Node where processor is attached - * @param address Virtual address of processor - */ -function removeProcessor(node, address) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--removeprocessor;' + address, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); -} - -/** - * Remove disk - * - * @param node Node where disk is attached - * @param address Virtual address of disk - */ -function removeDisk(node, address) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--removedisk;' + address, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); -} - -/** - * Remove zFCP device - * - * @param node Node where disk is attached - * @param address Virtual address of zFCP device - * @param wwpn World wide port name of zFCP device - * @param lun Logical unit number of zFCP device - */ -function removeZfcp(node, address, wwpn, lun) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--removezfcp;' + address + ';' + wwpn + ';' + lun, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); -} - -/** - * Remove NIC - * - * @param node Node where NIC is attached - * @param address Virtual address of NIC - */ -function removeNic(node, nic) { - var args = nic.split('.'); - var address = args[0]; - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--removenic;' + address, - msg : node - }, - - success : updateZNodeStatus - }); - - // Increment node process - incrementNodeProcess(node); - - // Show loader - $('#' + node + 'StatusBarLoader').show(); - $('#' + node + 'StatusBar').show(); -} - -/** - * Set a cookie for the network names of a given node - * - * @param data Data from HTTP request - */ -function setNetworkCookies(data) { - if (data.rsp) { - var node = data.msg; - var networks = data.rsp[0].split(node + ': '); - - // Set cookie to expire in 60 minutes - var exDate = new Date(); - exDate.setTime(exDate.getTime() + (60 * 60 * 1000)); - $.cookie(node + 'networks', networks, { expires: exDate }); - } -} - -/** - * Get contents of each disk pool - * - * @param data HTTP request data - */ -function getDiskPool(data) { - if (data.rsp) { - var hcp = data.msg; - var pools = data.rsp[0].split(hcp + ': '); - - // Get contents of each disk pool - for ( var i in pools) { - if (pools[i]) { - pools[i] = jQuery.trim(pools[i]); - - // Get used space - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--diskpool;' + pools[i] + ';used', - msg : 'hcp=' + hcp + ';pool=' + pools[i] + ';stat=used' - }, - - success : loadDiskPoolTable - }); - - // Get free space - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--diskpool;' + pools[i] + ';free', - msg : 'hcp=' + hcp + ';pool=' + pools[i] + ';stat=free' - }, - - success : loadDiskPoolTable - }); - } // End of if - } // End of for - } -} - -/** - * Get contents of each zFCP pool - * - * @param data HTTP request data - */ -function getZfcpPool(data) { - if (data.rsp.length) { - var hcp = data.msg; - var pools = data.rsp[0].split(hcp + ': '); - - // Get contents of each disk pool - for ( var i in pools) { - if (pools[i]) { - pools[i] = jQuery.trim(pools[i]); - - // Query used and free space - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--zfcppool;' + pools[i] + ';all', - msg : 'hcp=' + hcp + ';pool=' + pools[i] - }, - - success : loadZfcpPoolTable - }); - } // End of if - } // End of for - } else { - // Load empty table - loadZfcpPoolTable(null); - } -} - -/** - * Get details of each network - * - * @param data HTTP request data - */ -function getNetwork(data) { - if (data.rsp) { - var hcp = data.msg; - var networks = data.rsp[0].split(hcp + ': '); - - // Loop through each network - for ( var i = 1; i < networks.length; i++) { - var args = networks[i].split(' '); - var type = args[0]; - var name = args[2]; - - // Get network details - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcp, - args : '--getnetwork;' + name, - msg : 'hcp=' + hcp + ';type=' + type + ';network=' + name - }, - - success : loadNetworkTable - }); - } // End of for - } // End of if -} - -/** - * Load disk pool contents into a table - * - * @param data HTTP request data - */ -function loadDiskPoolTable(data) { - // Remove loader - var panelId = 'zvmDiskResource'; - $('#' + panelId).find('img[src="images/loader.gif"]').remove(); - - var args = data.msg.split(';'); - var hcp = args[0].replace('hcp=', ''); - var pool = args[1].replace('pool=', ''); - var stat = args[2].replace('stat=', ''); - var tmp = data.rsp[0].split(hcp + ': '); - - // Resource tab ID - var info = $('#' + panelId).find('.ui-state-highlight'); - // If there is no info bar - if (!info.length) { - // Create info bar - info = createInfoBar('Below are disks that are defined in the EXTENT CONTROL file.'); - $('#' + panelId).append(info); - } - - // Get datatable - var tableId = 'zDiskDataTable'; - var dTable = getDiskDataTable(); - if (!dTable) { - // Create a datatable - var table = new DataTable(tableId); - // Resource headers: volume ID, device type, start address, and size - table.init( [ '', 'zHCP', 'Pool', 'Status', 'Region', 'Device type', 'Starting address', 'Size' ]); - - // Append datatable to panel - $('#' + panelId).append(table.object()); - - // Turn into datatable - dTable = $('#' + tableId).dataTable(); - setDiskDataTable(dTable); - } - - // Skip index 0 and 1 because it contains nothing - for ( var i = 2; i < tmp.length; i++) { - tmp[i] = jQuery.trim(tmp[i]); - var diskAttrs = tmp[i].split(' '); - dTable.fnAddData( [ '', hcp, pool, stat, diskAttrs[0], diskAttrs[1], diskAttrs[2], diskAttrs[3] ]); - } - - // Create actions menu - if (!$('#zvmResourceActions').length) { - // Empty filter area - $('#' + tableId + '_length').empty(); - - // Add disk to pool - var addLnk = $('Add'); - addLnk.bind('click', function(event){ - openAddDisk2PoolDialog(); - }); - - // Delete disk from pool - var removeLnk = $('Remove'); - removeLnk.bind('click', function(event){ - var disks = getNodesChecked(tableId); - openRemoveDiskFromPoolDialog(disks); - }); - - // Refresh table - var refreshLnk = $('Refresh'); - refreshLnk.bind('click', function(event){ - $('#zvmDiskResource').empty().append(createLoader('')); - setDiskDataTable(''); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - // Query the disk pools for each - for (var i in hcps) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcps[i], - args : '--diskpoolnames', - msg : hcps[i] - }, - - success : getDiskPool - }); - } - }); - - // Create action bar - var actionBar = $('
        ').css("width", "400px"); - - // Create an action menu - var actionsMenu = createMenu([addLnk, removeLnk, refreshLnk]); - actionsMenu.superfish(); - actionsMenu.css('display', 'inline-block'); - actionBar.append(actionsMenu); - - // Set correct theme for action menu - actionsMenu.find('li').hover(function() { - setMenu2Theme($(this)); - }, function() { - setMenu2Normal($(this)); - }); - - // Create a division to hold actions menu - var menuDiv = $(''); - $('#' + tableId + '_length').prepend(menuDiv); - $('#' + tableId + '_length').css({ - 'padding': '0px', - 'width': '500px' - }); - $('#' + tableId + '_filter').css('padding', '10px'); - menuDiv.append(actionBar); - } - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); -} - -/** - * Load zFCP pool contents into a table - * - * @param data HTTP request data - */ -function loadZfcpPoolTable(data) { - // Delete loader - var panelId = 'zfcpResource'; - $('#' + panelId).find('img[src="images/loader.gif"]').remove(); - - var args, hcp, pool, tmp; - if (data) { - args = data.msg.split(';'); - hcp = args[0].replace('hcp=', ''); - pool = args[1].replace('pool=', ''); - tmp = data.rsp[0].split(hcp + ': '); - } - - // Resource tab ID - var info = $('#' + panelId).find('.ui-state-highlight'); - // If there is no info bar, create info bar - if (!info.length) { - info = createInfoBar('Below are devices that are defined internally in the zFCP pools.'); - $('#' + panelId).append(info); - } - - // Get datatable - var tableId = 'zFcpDataTable'; - var dTable = getZfcpDataTable(); - if (!dTable) { - // Create a datatable - var table = new DataTable(tableId); - // Resource headers: status, WWPN, LUN, size, owner, channel, tag - table.init( [ '', 'zHCP', 'Pool', 'Status', 'Port name', 'Unit number', 'Size', 'Owner', 'Channel', 'Tag' ]); - - // Append datatable to panel - $('#' + panelId).append(table.object()); - - // Turn into datatable - dTable = $('#' + tableId).dataTable({ - "sScrollX": "100%", - "bAutoWidth": true - }); - setZfcpDataTable(dTable); - } - - if (data) { - // Skip index 0 and 1 because it contains nothing - for ( var i = 2; i < tmp.length; i++) { - tmp[i] = jQuery.trim(tmp[i]); - var diskAttrs = tmp[i].split(','); - dTable.fnAddData( [ '', hcp, pool, diskAttrs[0], diskAttrs[1], diskAttrs[2], diskAttrs[3], diskAttrs[4], diskAttrs[5], diskAttrs[6] ]); - } - } - - // Create actions menu - if (!$('#zFcpResourceActions').length) { - // Empty filter area - $('#' + tableId + '_length').empty(); - - // Add disk to pool - var addLnk = $('Add'); - addLnk.bind('click', function(event){ - openAddZfcp2PoolDialog(); - }); - - // Delete disk from pool - var removeLnk = $('Remove'); - removeLnk.bind('click', function(event){ - var disks = getNodesChecked(tableId); - openRemoveZfcpFromPoolDialog(disks); - }); - - // Refresh table - var refreshLnk = $('Refresh'); - refreshLnk.bind('click', function(event){ - $('#zfcpResource').empty().append(createLoader('')); - setZfcpDataTable(''); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - // Query the disk pools for each - for (var i in hcps) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : hcps[i], - args : '--zfcppoolnames', - msg : hcps[i] - }, - - success : getZfcpPool - }); - } - }); - - // Create action bar - var actionBar = $('
        ').css("width", "400px"); - - // Create an action menu - var actionsMenu = createMenu([addLnk, removeLnk, refreshLnk]); - actionsMenu.superfish(); - actionsMenu.css('display', 'inline-block'); - actionBar.append(actionsMenu); - - // Set correct theme for action menu - actionsMenu.find('li').hover(function() { - setMenu2Theme($(this)); - }, function() { - setMenu2Normal($(this)); - }); - - // Create a division to hold actions menu - var menuDiv = $(''); - $('#' + tableId + '_length').prepend(menuDiv); - $('#' + tableId + '_length').css({ - 'padding': '0px', - 'width': '500px' - }); - $('#' + tableId + '_filter').css('padding', '10px'); - menuDiv.append(actionBar); - } - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); -} - -/** - * Open dialog to remove disk from pool - * - * @param disks2remove Disks selected in table - */ -function openRemoveDiskFromPoolDialog(disks2remove) { - // Create form to delete disk from pool - var dialogId = 'zvmDeleteDiskFromPool'; - var deleteDiskForm = $('
        '); - - // Create info bar - var info = createInfoBar('Remove a disk from a disk pool defined in the EXTENT CONTROL.'); - deleteDiskForm.append(info); - var action = $('
        '); - var actionSelect = $(''); - action.append(actionSelect); - - var hcp = $('
        '); - var hcpSelect = $(''); - hcp.append(hcpSelect); - - // Set region input based on those selected on table (if any) - var region = $('
        '); - var group = $('
        '); - deleteDiskForm.append(action, hcp, region, group); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - // Append options for hardware control points - for (var i in hcps) { - hcpSelect.append($('')); - } - - actionSelect.change(function() { - if ($(this).val() == '1' || $(this).val() == '3') { - region.show(); - group.hide(); - } else if ($(this).val() == '2') { - region.show(); - group.show(); - } else if ($(this).val() == '7') { - region.val('FOOBAR'); - region.hide(); - group.show(); - } - }); - - // Open dialog to delete disk - deleteDiskForm.dialog({ - title:'Delete disk from pool', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 500, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Get inputs - var action = $(this).find('select[name=action]').val(); - var hcp = $(this).find('select[name=hcp]').val(); - var region = $(this).find('input[name=region]').val(); - var group = $(this).find('input[name=group]').val(); - - // If inputs are not complete, show warning message - if (!action || !hcp) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Change dialog buttons - $(this).dialog('option', 'buttons', { - 'Close': function() {$(this).dialog("close");} - }); - - var args; - if (action == '2' || action == '7') - args = region + ';' + group; - else - args = group; - - // Remove disk from pool - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : hcp, - args : '--removediskfrompool;' + action + ';' + args, - msg : dialogId - }, - - success : updateResourceDialog - }); - } - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Open dialog to add disk to pool - */ -function openAddDisk2PoolDialog() { - // Create form to add disk to pool - var dialogId = 'zvmAddDisk2Pool'; - var addDiskForm = $('
        '); - // Create info bar - var info = createInfoBar('Add a disk to a disk pool defined in the EXTENT CONTROL. The disk has to already be attached to SYSTEM.'); - addDiskForm.append(info); - var action = $('
        '); - var actionSelect = $(''); - action.append(actionSelect); - - var hcp = $('
        '); - var hcpSelect = $(''); - hcp.append(hcpSelect); - var region = $('
        '); - var volume = $('
        '); - var group = $('
        '); - addDiskForm.append(action, hcp, region, volume, group); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) - hcps = $.cookie('hcp').split(','); - else - hcps.push($.cookie('hcp')); - - // Append options for hardware control points - for (var i in hcps) { - hcpSelect.append($('')); - } - - actionSelect.change(function() { - if ($(this).val() == '4') { - volume.show(); - } else if ($(this).val() == '5') { - volume.hide(); - } - }); - - // Open dialog to add disk - addDiskForm.dialog({ - title:'Add disk to pool', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 500, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - // Get inputs - var action = $(this).find('select[name=action]').val(); - var hcp = $(this).find('select[name=hcp]').val(); - var region = $(this).find('input[name=region]').val(); - var volume = $(this).find('input[name=volume]').val(); - var group = $(this).find('input[name=group]').val(); - - // If inputs are not complete, show warning message - if (!action || !hcp || !region || !group) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Change dialog buttons - $(this).dialog('option', 'buttons', { - 'Close': function() {$(this).dialog("close");} - }); - - var args; - if (action == '4') - args = region + ';' + volume + ';' + group; - else - args = region + ';' + group; - - // Add disk to pool - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : hcp, - args : '--adddisk2pool;' + action + ';' + args, - msg : dialogId - }, - - success : updateResourceDialog - }); - } - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Open dialog to remove zFCP from pool - * - * @param devices2remove Comman separated devices selected in table - */ -function openRemoveZfcpFromPoolDialog(devices2remove) { - // Create form to delete device from pool - var dialogId = 'zvmDeleteZfcpFromPool'; - var deleteDiskForm = $('
        '); - - // Verify disks are in the same zFCP pool - var devices = devices2remove.split(','); - var tmp, tgtPool; - var tgtUnitNo = ""; - for (var i in devices) { - tmp = devices[i].split('-'); - - if (tgtPool && tmp[0] != tgtPool) { - openDialog("warn", "Please select devices in the same zFCP"); - return; - } else { - tgtPool = tmp[0]; - } - - tgtUnitNo += tmp[1] + ","; - } - - // Strip out last comma - tgtUnitNo = tgtUnitNo.slice(0, -1); - - // Create info bar - var info = createInfoBar('Remove a zFCP device that is defined in a zFCP pool.'); - deleteDiskForm.append(info); - - var hcp = $('
        '); - var hcpSelect = $(''); - hcp.append(hcpSelect); - - var pool = $('
        '); - var unitNo = $('
        '); - deleteDiskForm.append(hcp, pool, unitNo); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) { - hcps = $.cookie('hcp').split(','); - } else { - hcps.push($.cookie('hcp')); - } - - // Append options for hardware control points - for (var i in hcps) { - hcpSelect.append($('')); - } - - // Open dialog to delete device - deleteDiskForm.dialog({ - title:'Delete device from pool', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 500, - buttons: { - "Ok": function(){ - // Remove any warning messages - $(this).find('.ui-state-error').remove(); - - var hcp = $(this).find('select[name=hcp]').val(); - var pool = $(this).find('input[name=zfcpPool]').val(); - var unitNo = $(this).find('input[name=unitNo]').val(); - - // If inputs are not complete, show warning message - if (!hcp || !pool || !unitNo) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Change dialog buttons - $(this).dialog('option', 'buttons', { - 'Close': function() {$(this).dialog("close");} - }); - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : hcp, - args : '--removezfcpfrompool;' + pool + ';' + unitNo, - msg : dialogId - }, - - success : updateResourceDialog - }); - } - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Open dialog to add zFCP to pool - */ -function openAddZfcp2PoolDialog() { - // Create form to add disk to pool - var dialogId = 'zvmAddDisk2Pool'; - var addDiskForm = $('
        '); - var info = createInfoBar('Add a device to a zFCP pool defined in xCAT.'); - addDiskForm.append(info); - - var hcp = $('
        '); - var hcpSelect = $(''); - hcp.append(hcpSelect); - - var pool = $('
        '); - var status = $('
        '); - var portName = $('
        '); - var unitNo = $('
        '); - var size = $('
        '); - var owner = $('
        '); - addDiskForm.append(hcp, pool, status, portName, unitNo, size, owner); - - // Create a array for hardware control points - var hcps = new Array(); - if ($.cookie('hcp').indexOf(',') > -1) { - hcps = $.cookie('hcp').split(','); - } else { - hcps.push($.cookie('hcp')); - } - - for (var i in hcps) { - hcpSelect.append($('')); - } - - // Open dialog to add disk - addDiskForm.dialog({ - title:'Add device to pool', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 500, - buttons: { - "Ok": function(){ - // Delete any warning messages - $(this).find('.ui-state-error').remove(); - - var tgtHcp = $(this).find('select[name=hcp]').val(); - var tgtPool = $(this).find('input[name=zfcpPool]').val(); - var tgtStatus = $(this).find('select[name=zfcpStatus]').val(); - var tgtPortName = $(this).find('input[name=zfcpPortName]').val(); - var tgtUnitNo = $(this).find('input[name=zfcpUnitNo]').val(); - var tgtSize = $(this).find('input[name=zfcpSize]').val(); - - // Device owner is optional - var tgtOwner = ""; - if ($(this).find('input[name=zfcpOwner]').val()) { - tgtOwner = $(this).find('input[name=zfcpOwner]').val(); - } - - // If inputs are not complete, show warning message - if (!tgtHcp || !tgtPool || !tgtStatus || !tgtPortName || !tgtUnitNo || !tgtSize) { - var warn = createWarnBar('Please provide a value for each missing field.'); - warn.prependTo($(this)); - } else { - // Change dialog buttons - $(this).dialog('option', 'buttons', { - 'Close': function() {$(this).dialog("close");} - }); - - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : tgtHcp, - args : '--addzfcp2pool;' + tgtPool + ';' + tgtStatus + ';' + tgtPortName + ';' + tgtUnitNo + ';' + tgtSize + ';' + tgtOwner, - msg : dialogId - }, - - success : updateResourceDialog - }); - } - }, - "Cancel": function() { - $(this).dialog( "close" ); - } - } - }); -} - -/** - * Update resource dialog - * - * @param data HTTP request data - */ -function updateResourceDialog(data) { - var dialogId = data.msg; - var infoMsg; - - // Create info message - if (jQuery.isArray(data.rsp)) { - infoMsg = ''; - for (var i in data.rsp) { - infoMsg += data.rsp[i] + '
        '; - } - } else { - infoMsg = data.rsp; - } - - // Create info bar with close button - var infoBar = $('
        ').css('margin', '5px 0px'); - var icon = $('').css({ - 'display': 'inline-block', - 'margin': '10px 5px' - }); - - // Create close button to close info bar - var close = $('').css({ - 'display': 'inline-block', - 'float': 'right' - }).click(function() { - $(this).parent().remove(); - }); - - var msg = $('
        ' + infoMsg + '
        ').css({ - 'display': 'inline-block', - 'width': '90%' - }); - - infoBar.append(icon, msg, close); - infoBar.prependTo($('#' + dialogId)); -} - -/** - * Select all checkboxes in the datatable - * - * @param event Event on element - * @param obj Object triggering event - */ -function selectAllDisk(event, obj) { - // This will ascend from - var tableObj = obj.parents('.datatable'); - var status = obj.attr('checked'); - tableObj.find(' :checkbox').attr('checked', status); - - // Handle datatable scroll - tableObj = obj.parents('.dataTables_scroll'); - if (tableObj.length) { - tableObj.find(' :checkbox').attr('checked', status); - } - - event.stopPropagation(); -} - -/** - * Load network details into a table - * - * @param data HTTP request data - */ -function loadNetworkTable(data) { - // Remove loader - var panelId = 'zvmNetworkResource'; - $('#' + panelId).find('img[src="images/loader.gif"]').remove(); - - var args = data.msg.split(';'); - var hcp = args[0].replace('hcp=', ''); - var type = args[1].replace('type=', ''); - var name = args[2].replace('network=', ''); - var tmp = data.rsp[0].split(hcp + ': '); - - // Resource tab ID - var info = $('#' + panelId).find('.ui-state-highlight'); - // If there is no info bar - if (!info.length) { - // Create info bar - info = createInfoBar('Below are LANs/VSWITCHes available to use.'); - $('#' + panelId).append(info); - } - - // Get datatable - var dTable = getNetworkDataTable(); - if (!dTable) { - // Create table - var tableId = 'zNetworkDataTable'; - var table = new DataTable(tableId); - table.init( [ 'HCP', 'Type', 'Name', 'Details' ]); - - // Append datatable to tab - $('#' + panelId).append(table.object()); - - // Turn into datatable - dTable = $('#' + tableId).dataTable(); - setNetworkDataTable(dTable); - - // Set the column width - var cols = table.object().find('thead tr th'); - cols.eq(0).css('width', '20px'); // HCP column - cols.eq(1).css('width', '20px'); // Type column - cols.eq(2).css('width', '20px'); // Name column - cols.eq(3).css({'width': '600px'}); // Details column - } - - // Skip index 0 because it contains nothing - var details = '
        ';
        -    for ( var i = 1; i < tmp.length; i++) {
        -        details += tmp[i];
        -    }
        -    details += '
        '; - - dTable.fnAddData([ '
        ' + hcp + '
        ', '
        ' + type + '
        ', '
        ' + name + '
        ', details ]); - - // Resize accordion - $('#zvmResourceAccordion').accordion('resize'); -} - -/** - * Connect a NIC to a Guest LAN - * - * @param data Data from HTTP request - */ -function connect2GuestLan(data) { - var rsp = data.rsp; - var args = data.msg.split(';'); - var node = args[0].replace('node=', ''); - var address = args[1].replace('addr=', ''); - var lanName = args[2].replace('lan=', ''); - var lanOwner = args[3].replace('owner=', ''); - - // Write ajax response to status bar - var prg = writeRsp(rsp, node + ': '); - $('#' + node + 'StatusBar').find('div').append(prg); - - // Connect NIC to Guest LAN - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--connectnic2guestlan;' + address + ';' + lanName + ';' - + lanOwner, - msg : node - }, - - success : updateZNodeStatus - }); -} - -/** - * Connect a NIC to a VSwitch - * - * @param data Data from HTTP request - */ -function connect2VSwitch(data) { - var rsp = data.rsp; - var args = data.msg.split(';'); - var node = args[0].replace('node=', ''); - var address = args[1].replace('addr=', ''); - var vswitchName = args[2].replace('vsw=', ''); - - // Write ajax response to status bar - var prg = writeRsp(rsp, node + ': '); - $('#' + node + 'StatusBar').find('div').append(prg); - - // Connect NIC to VSwitch - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'chvm', - tgt : node, - args : '--connectnic2vswitch;' + address + ';' + vswitchName, - msg : node - }, - - success : updateZNodeStatus - }); -} - -/** - * Create provision existing node division - * - * @param inst Provision tab instance - * @return Provision existing node division - */ -function createZProvisionExisting(inst) { - // Create provision existing and hide it - var provExisting = $('
        ').hide(); - - var vmFS = $('
        '); - var vmLegend = $('Virtual Machine'); - vmFS.append(vmLegend); - provExisting.append(vmFS); - - var vmAttr = $('
        '); - vmFS.append($('
        ')); - vmFS.append(vmAttr); - - var osFS = $('
        '); - var osLegend = $('Operating System'); - osFS.append(osLegend); - provExisting.append(osFS); - - var osAttr = $('
        '); - osFS.append($('
        ')); - osFS.append(osAttr); - - // Create group input - var group = $('
        '); - var groupLabel = $(''); - group.append(groupLabel); - - // Turn on auto complete for group - var groupNames = $.cookie('groups'); - if (groupNames) { - // Split group names into an array - var tmp = groupNames.split(','); - - // Create drop down for groups - var groupSelect = $(''); - groupSelect.append(''); - for (var i in tmp) { - // Add group into drop down - var opt = $(''); - groupSelect.append(opt); - } - group.append(groupSelect); - - // Create node datatable - groupSelect.change(function(){ - // Get group selected - var thisGroup = $(this).val(); - // If a valid group is selected - if (thisGroup) { - createNodesDatatable(thisGroup, 'zNodesDatatableDIV' + inst); - } - }); - } else { - // If no groups are cookied - var groupInput = $(''); - group.append(groupInput); - } - vmAttr.append(group); - - // Create node input - var node = $('
        '); - var nodeLabel = $(''); - var nodeDatatable = $('

        Select a group to view its nodes

        '); - node.append(nodeLabel); - node.append(nodeDatatable); - vmAttr.append(node); - - // Create operating system image input - var os = $('
        '); - var osLabel = $(''); - var osInput = $(''); - // Get image names on focus - osInput.one('focus', function(){ - var imageNames = $.cookie('imagenames'); - if (imageNames) { - // Turn on auto complete - $(this).autocomplete({ - source: imageNames.split(',') - }); - } - }); - os.append(osLabel); - os.append(osInput); - osAttr.append(os); - - // Create boot method drop down - var bootMethod = $('
        '); - var methoddLabel = $(''); - var methodSelect = $(''); - methodSelect.append('' - + '' - + '' - + '' - + '' - ); - bootMethod.append(methoddLabel); - bootMethod.append(methodSelect); - osAttr.append(bootMethod); - - // Generate tooltips - provExisting.find('div input[title]').tooltip({ - position: "center right", - offset: [-2, 10], - effect: "fade", - opacity: 0.7, - predelay: 800, - events: { - def: "mouseover,mouseout", - input: "mouseover,mouseout", - widget: "focus mouseover,blur mouseout", - tooltip: "mouseover,mouseout" - } - }); - - /** - * Provision existing - */ - var provisionBtn = createButton('Provision'); - provisionBtn.bind('click', function(event) { - // Remove any warning messages - $(this).parent().parent().find('.ui-state-error').remove(); - - var ready = true; - var errMsg = ''; - - // Get provision tab ID - var thisTabId = $(this).parent().parent().parent().attr('id'); - // Get provision tab instance - var inst = thisTabId.replace('zvmProvisionTab', ''); - - // Get nodes that were checked - var dTableId = 'zNodesDatatable' + inst; - var tgts = getNodesChecked(dTableId); - if (!tgts) { - errMsg += 'You need to select a node.
        '; - ready = false; - } - - // Check operating system image - var os = $('#' + thisTabId + ' input[name=os]:visible'); - if (!os.val()) { - errMsg += 'You need to select a operating system image.'; - os.css('border', 'solid #FF0000 1px'); - ready = false; - } else { - os.css('border', 'solid #BDBDBD 1px'); - } - - // If all inputs are valid, ready to provision - if (ready) { - // Disable provision button - $(this).attr('disabled', 'true'); - - // Show loader - $('#zProvisionStatBar' + inst).show(); - $('#zProvisionLoader' + inst).show(); - - // Disable all inputs - var inputs = $('#' + thisTabId + ' input:visible'); - inputs.attr('disabled', 'disabled'); - - // Disable all selects - var selects = $('#' + thisTabId + ' select'); - selects.attr('disabled', 'disabled'); - - // Get operating system image - var osImage = $('#' + thisTabId + ' input[name=os]:visible').val(); - var tmp = osImage.split('-'); - var os = tmp[0]; - var arch = tmp[1]; - var profile = tmp[3]; - - /** - * (1) Set operating system - */ - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeadd', - tgt : '', - args : tgts + ';noderes.netboot=zvm;nodetype.os=' + os + ';nodetype.arch=' + arch + ';nodetype.profile=' + profile, - msg : 'cmd=nodeadd;out=' + inst - }, - - success : updateZProvisionExistingStatus - }); - } else { - // Show warning message - var warn = createWarnBar(errMsg); - warn.prependTo($(this).parent().parent()); - } - }); - provExisting.append(provisionBtn); - - return provExisting; -} - -/** - * Create provision new node division - * - * @param inst Provision tab instance - * @return Provision new node division - */ -function createZProvisionNew(inst) { - // Create provision new node division - var provNew = $('
        '); - - // Create VM fieldset - var vmFS = $('
        '); - var vmLegend = $('Virtual Machine'); - vmFS.append(vmLegend); - provNew.append(vmFS); - - var vmAttr = $('
        '); - vmFS.append($('
        ')); - vmFS.append(vmAttr); - - // Create OS fieldset - var osFS = $('
        '); - var osLegend = $('Operating System'); - osFS.append(osLegend); - provNew.append(osFS); - - // Create hardware fieldset - var hwFS = $('
        '); - var hwLegend = $('Hardware'); - hwFS.append(hwLegend); - provNew.append(hwFS); - - var hwAttr = $('
        '); - hwFS.append($('
        ')); - hwFS.append(hwAttr); - - var osAttr = $('
        '); - osFS.append($('
        ')); - osFS.append(osAttr); - - // Create group input - var group = $('
        '); - var groupLabel = $(''); - var groupInput = $(''); - // Get groups on-focus - groupInput.one('focus', function(){ - var groupNames = $.cookie('groups'); - if (groupNames) { - // Turn on auto complete - $(this).autocomplete({ - source: groupNames.split(',') - }); - } - }); - group.append(groupLabel); - group.append(groupInput); - vmAttr.append(group); - - // Create node input - var nodeName = $('
        '); - var nodeLabel = $(''); - var nodeInput = $(''); - nodeName.append(nodeLabel); - nodeName.append(nodeInput); - vmAttr.append(nodeName); - - // Create user ID input - var userId = $('
        '); - vmAttr.append(userId); - - // Create hardware control point input - var hcpDiv = $('
        '); - var hcpLabel = $(''); - var hcpInput = $(''); - hcpInput.blur(function() { - if ($(this).val()) { - var args = $(this).val().split('.'); - if (!$.cookie(args[0] + 'diskpools')) { - // Get disk pools - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : args[0], - args : '--diskpoolnames', - msg : args[0] - }, - - success : setDiskPoolCookies - }); - } - - if (!$.cookie(args[0] + 'zfcppools')) { - // Get zFCP pools - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'lsvm', - tgt : args[0], - args : '--zfcppoolnames', - msg : args[0] - }, - - success : setZfcpPoolCookies - }); - } - } - }); - hcpDiv.append(hcpLabel); - hcpDiv.append(hcpInput); - vmAttr.append(hcpDiv); - - // Create an advanced link to set IP address and hostname - var advancedLnk = $('
        '); - vmAttr.append(advancedLnk); - var advanced = $('
        ').hide(); - vmAttr.append(advanced); - - var ip = $('
        '); - advanced.append(ip); - var hostname = $('
        '); - advanced.append(hostname); - - // Show IP address and hostname inputs on-click - advancedLnk.click(function() { - advanced.toggle(); - }); - - // Create operating system image input - var os = $('
        '); - var osLabel = $(''); - var osSelect = $(''); - osSelect.append($('')); - - var imageNames = $.cookie('imagenames').split(','); - if (imageNames) { - imageNames.sort(); - for (var i in imageNames) { - osSelect.append($('')); - } - } - os.append(osLabel); - os.append(osSelect); - osAttr.append(os); - - // Create user entry input - var defaultChkbox = $('').click(function() { - // Remove any warning messages - $(this).parents('.form').find('.ui-state-error').remove(); - - // Get tab ID - var thisTabId = $(this).parents('.ui-tabs-panel').attr('id'); - - // Get objects for HCP, user ID, and OS - var userId = $('#' + thisTabId + ' input[name=userId]'); - var os = $('#' + thisTabId + ' select[name=os]'); - - // Get default user entry when clicked - if ($(this).attr('checked')) { - if (!os.val() || !userId.val()) { - // Show warning message - var warn = createWarnBar('Please specify the operating system and user ID before checking this box'); - warn.prependTo($(this).parents('.form')); - - // Highlight empty fields - jQuery.each([os, userId], function() { - if (!$(this).val()) { - $(this).css('border', 'solid #FF0000 1px'); - } - }); - } else { - // Un-highlight empty fields - jQuery.each([os, userId], function() { - $(this).css('border', 'solid #BDBDBD 1px'); - }); - - // Get profile name - var tmp = os.val().split('-'); - var profile = tmp[3]; - - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'getdefaultuserentry;' + profile, - msg : thisTabId - }, - - success:function(data) { - // Populate user entry - var tabId = data.msg; - var entry = new String(data.rsp); - var userId = $('#' + tabId + ' input[name=userId]').val(); - entry = entry.replace(new RegExp('LXUSR', 'g'), userId); - $('#' + tabId + ' textarea:visible').val(entry); - } - }); - } - } else { - $('#' + thisTabId + ' textarea:visible').val(''); - - // Un-highlight empty fields - jQuery.each([os, userId], function() { - $(this).css('border', 'solid #BDBDBD 1px'); - }); - } - }); - var userEntry = $('
        '); - userEntry.append($('').append(defaultChkbox, 'Use default')); - hwAttr.append(userEntry); - - // Create disk table - var diskDiv = $('
        '); - var diskLabel = $(''); - var diskTable = $('
        '); - var diskHeader = $(' Type Address Size Mode Pool Password '); - // Adjust header width - diskHeader.find('th').css( { - 'width' : '80px' - }); - diskHeader.find('th').eq(0).css( { - 'width' : '20px' - }); - var diskBody = $(''); - var diskFooter = $(''); - - /** - * Add disks - */ - var addDiskLink = $('Add disk'); - addDiskLink.bind('click', function(event) { - // Get list of disk pools - var thisTabId = $(this).parents('.tab').attr('id'); - var thisHcp = $('#' + thisTabId + ' input[name=hcp]').val(); - var definedPools = null; - if (thisHcp) { - // Get node without domain name - var temp = thisHcp.split('.'); - definedPools = $.cookie(temp[0] + 'diskpools').split(','); - } - - // Create a row - var diskRow = $(''); - - // Add remove button - var removeBtn = $(''); - var col = $('').append(removeBtn); - removeBtn.bind('click', function(event) { - diskRow.remove(); - }); - diskRow.append(col); - - // Create disk type drop down - var diskType = $(''); - var diskTypeSelect = $(''); - diskTypeSelect.append('' - + '' - ); - diskType.append(diskTypeSelect); - diskRow.append(diskType); - - // Create disk address input - var diskAddr = $(''); - diskRow.append(diskAddr); - - // Create disk size input - var diskSize = $(''); - diskRow.append(diskSize); - - // Create disk mode input - var diskMode = $(''); - var diskModeSelect = $(''); - diskModeSelect.append('' - + '' - + '' - + '' - + '' - + '' - + '' - ); - diskMode.append(diskModeSelect); - diskRow.append(diskMode); - - // Create disk pool drop down - var diskPool = $(''); - var diskPoolSelect = $(''); - for (var i in definedPools) { - diskPoolSelect.append(''); - } - diskPool.append(diskPoolSelect); - diskRow.append(diskPool); - - // Create disk password input - var diskPw = $(''); - diskRow.append(diskPw); - - diskBody.append(diskRow); - - // Generate tooltips - diskBody.find('td input[title]').tooltip({ - position: "top right", - offset: [-4, 4], - effect: "fade", - opacity: 0.7, - predelay: 800, - events: { - def: "mouseover,mouseout", - input: "mouseover,mouseout", - widget: "focus mouseover,blur mouseout", - tooltip: "mouseover,mouseout" - } - }); - }); - - // Create disk table - diskFooter.append(addDiskLink); - diskTable.append(diskHeader); - diskTable.append(diskBody); - diskTable.append(diskFooter); - - diskDiv.append(diskLabel); - diskDiv.append(diskTable); - hwAttr.append(diskDiv); - - // Create zFCP table - var zfcpDiv = $('
        '); - var zfcpLabel = $(''); - var zfcpTable = $('
        '); - var zfcpHeader = $(' Address Size Pool Tag Port Name Unit # LOADDEV'); - // Adjust header width - zfcpHeader.find('th').css( { - 'width' : '80px' - }); - zfcpHeader.find('th').eq(0).css( { - 'width' : '20px' - }); - var zfcpBody = $(''); - var zfcpFooter = $(''); - - /** - * Add zFCP devices - */ - var addZfcpLink = $('Add zFCP'); - addZfcpLink.bind('click', function(event) { - // Get list of disk pools - var thisTabId = $(this).parents('.tab').attr('id'); - var thisHcp = $('#' + thisTabId + ' input[name=hcp]').val(); - var definedPools = null; - if (thisHcp) { - // Get node without domain name - var temp = thisHcp.split('.'); - definedPools = $.cookie(temp[0] + 'zfcppools').split(','); - } - - // Create a row - var zfcpRow = $(''); - - // Add remove button - var removeBtn = $(''); - var col = $('').append(removeBtn); - removeBtn.bind('click', function(event) { - zfcpRow.remove(); - }); - zfcpRow.append(col); - - // Create disk address input - var zfcpAddr = $(''); - zfcpRow.append(zfcpAddr); - - // Create disk size input - var zfcpSize = $(''); - zfcpRow.append(zfcpSize); - - // Create zFCP pool drop down - var zfcpPool = $(''); - var zfcpPoolSelect = $(''); - for (var i in definedPools) { - zfcpPoolSelect.append(''); - } - zfcpPool.append(zfcpPoolSelect); - zfcpRow.append(zfcpPool); - - // Create disk tag - var zfcpTag = $(''); - zfcpRow.append(zfcpTag); - - // Create device port name - var zfcpPortName = $(''); - zfcpRow.append(zfcpPortName); - - // Create device unit number - var zfcpUnitNo = $(''); - zfcpRow.append(zfcpUnitNo); - - // Create LOADDEV checkbox - var zfcpLoaddev = $(''); - zfcpRow.append(zfcpLoaddev); - - zfcpBody.append(zfcpRow); - - // Generate tooltips - zfcpBody.find('td input[title]').tooltip({ - position: "top right", - offset: [-4, 4], - effect: "fade", - opacity: 0.7, - predelay: 800, - events: { - def: "mouseover,mouseout", - input: "mouseover,mouseout", - widget: "focus mouseover,blur mouseout", - tooltip: "mouseover,mouseout" - } - }); - }); - - zfcpFooter.append(addZfcpLink); - zfcpTable.append(zfcpHeader); - zfcpTable.append(zfcpBody); - zfcpTable.append(zfcpFooter); - - zfcpDiv.append(zfcpLabel); - zfcpDiv.append(zfcpTable); - hwAttr.append(zfcpDiv); - - // Generate tooltips - provNew.find('div input[title]').tooltip({ - position: "center right", - offset: [-2, 10], - effect: "fade", - opacity: 0.7, - predelay: 800, - events: { - def: "mouseover,mouseout", - input: "mouseover,mouseout", - widget: "focus mouseover,blur mouseout", - tooltip: "mouseover,mouseout" - } - }); - - /** - * Provision new - */ - var provisionBtn = createButton('Provision'); - provisionBtn.bind('click', function(event) { - // Remove any warning messages - $(this).parent().parent().find('.ui-state-error').remove(); - - var ready = true; - var errMsg = ''; - - // Get tab ID - var thisTabId = $(this).parents('.ui-tabs-panel').attr('id'); - // Get provision tab instance - var inst = thisTabId.replace('zvmProvisionTab', ''); - - // Check node name, userId, hardware control point, and group - // Check disks and zFCP devices - var inputs = $('#' + thisTabId + ' input:visible'); - for ( var i = 0; i < inputs.length; i++) { - // Do not check some inputs - if (!inputs.eq(i).val() - && inputs.eq(i).attr('type') != 'password' - && inputs.eq(i).attr('name') != 'zfcpTag' - && inputs.eq(i).attr('name') != 'zfcpPortName' - && inputs.eq(i).attr('name') != 'zfcpUnitNo') { - inputs.eq(i).css('border', 'solid #FF0000 1px'); - ready = false; - } else { - inputs.eq(i).css('border', 'solid #BDBDBD 1px'); - } - } - - var selects = $('#' + thisTabId + ' select:visible'); - for ( var i = 0; i < selects.length; i++) { - if (!selects.eq(i).val() && selects.eq(i).attr('name') != 'os') { - selects.eq(i).css('border', 'solid #FF0000 1px'); - ready = false; - } else { - selects.eq(i).css('border', 'solid #BDBDBD 1px'); - } - } - - // Check user entry - var thisUserEntry = $('#' + thisTabId + ' textarea:visible'); - thisUserEntry.val(thisUserEntry.val().toUpperCase()); - if (!thisUserEntry.val()) { - thisUserEntry.css('border', 'solid #FF0000 1px'); - ready = false; - } else { - thisUserEntry.css('border', 'solid #BDBDBD 1px'); - } - - // Show error message for missing inputs - if (!ready) { - errMsg = errMsg + 'Please provide a value for each missing field.
        '; - } - - // Check if user entry contains user ID - var thisUserId = $('#' + thisTabId + ' input[name=userId]:visible'); - var pos = thisUserEntry.val().indexOf('USER ' + thisUserId.val().toUpperCase()); - if (pos < 0) { - errMsg = errMsg + 'The directory entry does not contain the correct user ID.
        '; - ready = false; - } - - // If no operating system is specified, create only user entry - os = $('#' + thisTabId + ' select[name=os]:visible'); - - // Check number of disks - var diskRows = $('#' + thisTabId + ' table tr'); - // If an OS is given, disks are needed - if (os.val() && (diskRows.length < 1)) { - errMsg = errMsg + 'You need to add at some disks.
        '; - ready = false; - } - - // If inputs are valid, ready to provision - if (ready) { - if (!os.val()) { - // If no OS is given, create a virtual server - var msg = ''; - if (diskRows.length > 0) { - msg = 'Do you want to create a virtual server without an operating system?'; - } else { - // If no disks are given, create a virtual server (no disk) - msg = 'Do you want to create a virtual server without an operating system or disks?'; - } - - // Open dialog to confirm - var confirmDialog = $('

        ' + msg + '

        '); - confirmDialog.dialog({ - title:'Confirm', - modal: true, - close: function(){ - $(this).remove(); - }, - width: 400, - buttons: { - "Ok": function(){ - // Disable provision button - provisionBtn.attr('disabled', 'true'); - - // Show loader - $('#zProvisionStatBar' + inst).show(); - $('#zProvisionLoader' + inst).show(); - - // Disable add disk button - addDiskLink.attr('disabled', 'true'); - - // Disable close button on disk table - $('#' + thisTabId + ' table span').unbind('click'); - - // Disable all inputs - var inputs = $('#' + thisTabId + ' input'); - inputs.attr('disabled', 'disabled'); - - // Disable all selects - var selects = $('#' + thisTabId + ' select'); - selects.attr('disabled', 'disabled'); - - // Add a new line at the end of the user entry - var textarea = $('#' + thisTabId + ' textarea'); - var tmp = jQuery.trim(textarea.val()); - textarea.val(tmp + '\n'); - textarea.attr('readonly', 'readonly'); - textarea.css( { - 'background-color' : '#F2F2F2' - }); - - // Get node name - var node = $('#' + thisTabId + ' input[name=nodeName]').val(); - // Get userId - var userId = $('#' + thisTabId + ' input[name=userId]').val(); - // Get hardware control point - var hcp = $('#' + thisTabId + ' input[name=hcp]').val(); - // Get group - var group = $('#' + thisTabId + ' input[name=group]').val(); - // Get IP address and hostname - var ip = $('#' + thisTabId + ' input[name=ip]').val(); - var hostname = $('#' + thisTabId + ' input[name=hostname]').val(); - - // Generate arguments to sent - var args = node + ';zvm.hcp=' + hcp - + ';zvm.userid=' + userId - + ';nodehm.mgt=zvm' - + ';groups=' + group; - if (ip) - args += ';hosts.ip=' + ip; - - if (hostname) - args += ';hosts.hostnames=' + hostname; - - /** - * (1) Define node - */ - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeadd', - tgt : '', - args : args, - msg : 'cmd=nodeadd;out=' + inst - }, - - success : updateZProvisionNewStatus - }); - - $(this).dialog("close"); - }, - "Cancel": function() { - $(this).dialog("close"); - } - } - }); - } else { - /** - * Create a virtual server and install OS - */ - - // Disable provision button - $(this).attr('disabled', 'true'); - - // Show loader - $('#zProvisionStatBar' + inst).show(); - $('#zProvisionLoader' + inst).show(); - - // Disable add disk button - addDiskLink.attr('disabled', 'true'); - - // Disable close button on disk table - $('#' + thisTabId + ' table span').unbind('click'); - - // Disable all inputs - var inputs = $('#' + thisTabId + ' input'); - inputs.attr('disabled', 'disabled'); - inputs.css( { - 'background-color' : '#F2F2F2' - }); - - // Disable all selects - var selects = $('#' + thisTabId + ' select'); - selects.attr('disabled', 'disabled'); - selects.css( { - 'background-color' : '#F2F2F2' - }); - - // Add a new line at the end of the user entry - var textarea = $('#' + thisTabId + ' textarea'); - var tmp = jQuery.trim(textarea.val()); - textarea.val(tmp + '\n'); - textarea.attr('readonly', 'readonly'); - textarea.css( { - 'background-color' : '#F2F2F2' - }); - - // Get node name - var node = $('#' + thisTabId + ' input[name=nodeName]').val(); - // Get userId - var userId = $('#' + thisTabId + ' input[name=userId]').val(); - // Get hardware control point - var hcp = $('#' + thisTabId + ' input[name=hcp]').val(); - // Get group - var group = $('#' + thisTabId + ' input[name=group]').val(); - // Get IP address and hostname - var ip = $('#' + thisTabId + ' input[name=ip]').val(); - var hostname = $('#' + thisTabId + ' input[name=hostname]').val(); - - // Generate arguments to sent - var args = node + ';zvm.hcp=' + hcp - + ';zvm.userid=' + userId - + ';nodehm.mgt=zvm' - + ';groups=' + group; - if (ip) - args += ';hosts.ip=' + ip; - - if (hostname) - args += ';hosts.hostnames=' + hostname; - - /** - * (1) Define node - */ - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'nodeadd', - tgt : '', - args : args, - msg : 'cmd=nodeadd;out=' + inst - }, - - success : updateZProvisionNewStatus - }); - } - } else { - // Show warning message - var warn = createWarnBar(errMsg); - warn.prependTo($(this).parent().parent()); - } - }); - provNew.append(provisionBtn); - - return provNew; -} - -/** - * Load zVMs into column (service page) - * - * @param col Table column where OS images will be placed - */ -function loadzVMs(col) { - // Get group names and description and append to group column - var groupNames = $.cookie('srv_zvms').split(','); - var radio, zvmBlock, args, zvm, hcp; - for (var i in groupNames) { - args = groupNames[i].split(':'); - zvm = args[0]; - hcp = args[1]; - - // Create block for each group - zvmBlock = $('
        ').css({ - 'border': '1px solid', - 'max-width': '200px', - 'margin': '5px auto', - 'padding': '5px', - 'display': 'block', - 'vertical-align': 'middle', - 'cursor': 'pointer', - 'white-space': 'normal' - }).click(function(){ - $(this).children('input:radio').attr('checked', 'checked'); - $(this).parents('td').find('div').attr('class', 'ui-state-default'); - $(this).attr('class', 'ui-state-active'); - }); - radio = $('').css('display', 'none'); - zvmBlock.append(radio, $('' + zvm + ' managed by ' + hcp + '')); - zvmBlock.children('span').css({ - 'display': 'block', - 'margin': '5px', - 'text-align': 'left' - }); - col.append(zvmBlock); - } -} - -/** - * Load groups into column - * - * @param col Table column where OS images will be placed - */ -function loadSrvGroups(col) { - // Get group names and description and append to group column - var groupNames = $.cookie('srv_groups').split(','); - var groupBlock, radio, args, name, ip, hostname, desc; - for (var i in groupNames) { - args = groupNames[i].split(':'); - name = args[0]; - ip = args[1]; - hostname = args[2]; - desc = args[3]; - - // Create block for each group - groupBlock = $('
        ').css({ - 'border': '1px solid', - 'max-width': '200px', - 'margin': '5px auto', - 'padding': '5px', - 'display': 'block', - 'vertical-align': 'middle', - 'cursor': 'pointer', - 'white-space': 'normal' - }).click(function(){ - $(this).children('input:radio').attr('checked', 'checked'); - $(this).parents('td').find('div').attr('class', 'ui-state-default'); - $(this).attr('class', 'ui-state-active'); - }); - radio = $('').css('display', 'none'); - groupBlock.append(radio, $('' + name + ': ' + desc + '')); - groupBlock.children('span').css({ - 'display': 'block', - 'margin': '5px', - 'text-align': 'left' - }); - col.append(groupBlock); - } -} - -/** - * Load OS images into column - * - * @param col Table column where OS images will be placed - */ -function loadOSImages(col) { - // Get group names and description and append to group column - var imgNames = $.cookie('srv_imagenames').split(','); - var imgBlock, radio, args, name, desc; - for (var i in imgNames) { - args = imgNames[i].split(':'); - name = args[0]; - desc = args[1]; - - // Create block for each image - imgBlock = $('
        ').css({ - 'border': '1px solid', - 'max-width': '200px', - 'margin': '5px auto', - 'padding': '5px', - 'display': 'block', - 'vertical-align': 'middle', - 'cursor': 'pointer', - 'white-space': 'normal' - }).click(function(){ - $(this).children('input:radio').attr('checked', 'checked'); - $(this).parents('td').find('div').attr('class', 'ui-state-default'); - $(this).attr('class', 'ui-state-active'); - }); - radio = $('').css('display', 'none'); - imgBlock.append(radio, $('' + name + ': ' + desc + '')); - imgBlock.children('span').css({ - 'display': 'block', - 'margin': '5px', - 'text-align': 'left' - }); - col.append(imgBlock); - } -} - -/** - * Set a cookie for zVM host names (service page) - * - * @param data Data from HTTP request - */ -function setzVMCookies(data) { - if (data.rsp) { - var zvms = new Array(); - for ( var i = 0; i < data.rsp.length; i++) { - zvms.push(data.rsp[i]); - } - - // Set cookie to expire in 60 minutes - var exDate = new Date(); - exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); - $.cookie('srv_zvms', zvms, { expires: exDate }); - } -} - -/** - * Set a cookie for disk pool names of a given node - * - * @param data Data from HTTP request - */ -function setDiskPoolCookies(data) { - if (data.rsp) { - var node = data.msg; - var pools = data.rsp[0].split(node + ': '); - for (var i in pools) { - pools[i] = jQuery.trim(pools[i]); - } - - // Set cookie to expire in 60 minutes - var exDate = new Date(); - exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); - $.cookie(node + 'diskpools', pools, { expires: exDate }); - } -} - -/** - * Set a cookie for zFCP pool names of a given node - * - * @param data Data from HTTP request - */ -function setZfcpPoolCookies(data) { - if (data.rsp) { - var node = data.msg; - var pools = data.rsp[0].split(node + ': '); - for (var i in pools) { - pools[i] = jQuery.trim(pools[i]); - } - - // Set cookie to expire in 60 minutes - var exDate = new Date(); - exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); - $.cookie(node + 'zfcppools', pools, { expires: exDate }); - } -} - -/** - * Create virtual machine (service page) - * - * @param tabId Tab ID - * @param group Group - * @param hcp Hardware control point - * @param img OS image - */ -function createzVM(tabId, group, hcp, img, owner) { - // Submit request to create VM - // webportal provzlinux [group] [hcp] [image] [owner] - var iframe = createIFrame('lib/srv_cmd.php?cmd=webportal&tgt=&args=provzlinux;' + group + ';' + hcp + ';' + img + ';' + owner + '&msg=&opts=flush'); - iframe.prependTo($('#' + tabId)); -} - -/** - * Query the profiles that exists - * - * @param panelId Panel ID - */ -function queryProfiles(panelId) { - $.ajax( { - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'tabdump', - tgt : '', - args : 'osimage', - msg : panelId - }, - - success : function(data) { - var panelId = data.msg; - setOSImageCookies(data); - configProfilePanel(panelId); - } - }); -} - -/** - * Panel to configure directory entries and disks for a profile - * - * @param panelId Panel ID - */ -function configProfilePanel(panelId) { - // Wipe panel clean - $('#' + panelId).empty(); - - // Add info bar - $('#' + panelId).append(createInfoBar('Create, edit, and delete profiles for the self-service portal. It is important to note the default z/VM user ID for any profile should be LXUSR.')); - - // Create table - var tableId = 'zvmProfileTable'; - var table = new DataTable(tableId); - table.init(['', 'Profile', 'Disk pool', 'Disk size', 'Directory entry']); - - // Insert profiles into table - var profiles = $.cookie('profiles').split(','); - profiles.push('default'); // Add default profile - for (var i in profiles) { - if (profiles[i]) { - // Columns are: profile, selectable, description, disk pool, disk size, and directory entry - var cols = new Array(profiles[i], '', '', ''); - - // Add remove button where id = user name - cols.unshift(''); - - // Add row - table.add(cols); - } - } - - // Append datatable to tab - $('#' + panelId).append(table.object()); - - // Turn into datatable - $('#' + tableId).dataTable({ - 'iDisplayLength': 50, - 'bLengthChange': false, - "sScrollX": "100%", - "bAutoWidth": true - }); - - // Create action bar - var actionBar = $('
        ').css("width", "400px"); - - // Create a profile - var createLnk = $('Create'); - createLnk.click(function() { - profileDialog(); - }); - - // Edit a profile - var editLnk = $('Edit'); - editLnk.click(function() { - var profiles = $('#' + tableId + ' input[type=checkbox]:checked'); - for (var i in profiles) { - var profile = profiles.eq(i).attr('name'); - if (profile) { - // Column order is: profile, selectable, disk pool, disk size, and directory entry - var cols = profiles.eq(i).parents('tr').find('td'); - var pool = cols.eq(2).text(); - var size = cols.eq(3).text(); - var entry = cols.eq(4).html().replace(new RegExp('
        ', 'g'), '\n'); - - editProfileDialog(profile, pool, size, entry); - } - } - }); - - // Delete a profile - var deleteLnk = $('Delete'); - deleteLnk.click(function() { - var profiles = getNodesChecked(tableId); - if (profiles) { - openDeleteProfileDialog(profiles); - } - }); - - // Refresh profiles table - var refreshLnk = $('Refresh'); - refreshLnk.click(function() { - queryProfiles(panelId); - }); - - // Create an action menu - var actionsMenu = createMenu([createLnk, editLnk, deleteLnk, refreshLnk]); - actionsMenu.superfish(); - actionsMenu.css('display', 'inline-block'); - actionBar.append(actionsMenu); - - // Set correct theme for action menu - actionsMenu.find('li').hover(function() { - setMenu2Theme($(this)); - }, function() { - setMenu2Normal($(this)); - }); - - // Create a division to hold actions menu - var menuDiv = $(''); - $('#' + tableId + '_wrapper').prepend(menuDiv); - menuDiv.append(actionBar); - $('#' + tableId + '_filter').appendTo(menuDiv); - - // Resize accordion - $('#' + tableId).parents('.ui-accordion').accordion('resize'); - - // Query directory entries and disk pool/size for each profile - for (var i in profiles) { - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'getdefaultuserentry;' + profiles[i], - msg : 'out=' + panelId + ';profile=' + profiles[i] - }, - - success: insertDirectoryEntry - }); - - $.ajax({ - url : 'lib/cmd.php', - dataType : 'json', - data : { - cmd : 'webrun', - tgt : '', - args : 'getzdiskinfo;' + profiles[i], - msg : 'out=' + panelId + ';profile=' + profiles[i] - }, - - success: insertDiskInfo - }); - } -} - -/** - * Insert the directory entry into the profile table - * - * @param data Data from HTTP request - */ -function insertDirectoryEntry(data) { - var tableId = 'zvmProfileTable'; - var args = data.msg.split(';'); - - var profile = args[1].replace('profile=', ''); - - // Do not continue if there is nothing - if (!data.rsp.length) - return; - - var entry = data.rsp[0].replace(new RegExp('\n', 'g'), '
        '); - - // Get the row containing the profile - var rowPos = findRow(profile, '#' + tableId, 1); - if (rowPos < 0) - return; - - // Update the directory entry column - var dTable = $('#' + tableId).dataTable(); - dTable.fnUpdate(entry, rowPos, 4, false); - - // Adjust table styling - $('#' + tableId + ' td:nth-child(5)').css({ - 'text-align': 'left' - }); - adjustColumnSize(tableId); -} - -/** - * Insert the disk info into the profile table - * - * @param data Data from HTTP request - */ -function insertDiskInfo(data) { - var tableId = 'zvmProfileTable'; - var args = data.msg.split(';'); - - var profile = args[1].replace('profile=', ''); - - // Do not continue if there is nothing - if (!data.rsp.length) - return; - - // Get the row containing the profile - var rowPos = findRow(profile, '#' + tableId, 1); - if (rowPos < 0) - return; - - // Update the disk info columns - var dTable = $('#' + tableId).dataTable(); - - var tmp = ""; - var pool = ""; - var eckdSize = 0; - var info = data.rsp[0].split('\n'); - for (var i in info) { - if (info[i].indexOf('diskpool') > -1) { - tmp = info[i].split('='); - pool = jQuery.trim(tmp[1]); - - dTable.fnUpdate(pool, rowPos, 2, false); - } if (info[i].indexOf('eckd_size') > -1) { - tmp = info[i].split('='); - eckdSize = jQuery.trim(tmp[1]); - - dTable.fnUpdate(eckdSize, rowPos, 3, false); - } - } - - // Adjust table styling - adjustColumnSize(tableId); -} - -/** - * Open profile dialog - */ -function profileDialog() { - // Create form to add profile - var dialogId = 'zvmCreateProfile'; - var profileForm = $('
        '); - - // Create info bar - var info = createInfoBar('Configure the default settings for a profile'); - profileForm.append(info); - - // Insert profiles into select - var profileSelect = $(''); - var profiles = $.cookie('profiles').split(','); - profiles.push('default'); // Add default profile - for (var i in profiles) { - if (profiles[i]) { - profileSelect.append($('')); - } - } - - profileForm.append($('
        ').append(profileSelect)); - profileForm.append('
        '); - profileForm.append('
        '); - profileForm.append('
        '); + for ( var i = 1; i < userEntry.length; i++) { + userEntry[i] = jQuery.trim(userEntry[i]); + txtArea.append(userEntry[i]); + + if (i < userEntry.length) { + txtArea.append('\n'); + } + } + txtArea.attr('readonly', 'readonly'); + fieldSet.append(txtArea); + + /** + * Edit user entry + */ + txtArea.bind('dblclick', function(event) { + txtArea.attr('readonly', ''); + txtArea.css( { + 'border-width' : '1px' + }); + + saveBtn.show(); + cancelBtn.show(); + saveBtn.css('display', 'inline-table'); + cancelBtn.css('display', 'inline-table'); + }); + + /** + * Save + */ + var saveBtn = createButton('Save').hide(); + saveBtn.bind('click', function(event) { + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); + + // Replace user entry + var newUserEntry = jQuery.trim(txtArea.val()) + '\n'; + + // Replace user entry + $.ajax( { + url : 'lib/zCmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--replacevs', + att : newUserEntry, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process and save it in a cookie + incrementNodeProcess(node); + + txtArea.attr('readonly', 'readonly'); + txtArea.css( { + 'border-width' : '0px' + }); + + // Disable save button + $(this).hide(); + cancelBtn.hide(); + }); + + /** + * Cancel + */ + var cancelBtn = createButton('Cancel').hide(); + cancelBtn.bind('click', function(event) { + txtArea.attr('readonly', 'readonly'); + txtArea.css( { + 'border-width' : '0px' + }); + + cancelBtn.hide(); + saveBtn.hide(); + }); + + // Create info bar + var infoBar = createInfoBar('Double click on the directory entry to edit it.'); + + // Append user entry into division + $('#' + ueDivId).append(infoBar); + $('#' + ueDivId).append(fieldSet); + $('#' + ueDivId).append(saveBtn); + $('#' + ueDivId).append(cancelBtn); +} + +/** + * Increment number of processes running against a node + * + * @param node Node to increment running processes + */ +function incrementNodeProcess(node) { + // Get current processes + var procs = $.cookie(node + 'processes'); + if (procs) { + // One more process + procs = parseInt(procs) + 1; + $.cookie(node + 'processes', procs); + } else { + $.cookie(node + 'processes', 1); + } +} + +/** + * Update provision new node status + * + * @param data Data returned from HTTP request + */ +function updateZProvisionNewStatus(data) { + // Parse ajax response + var rsp = data.rsp; + var args = data.msg.split(';'); + var lastCmd = args[0].replace('cmd=', ''); + var out2Id = args[1].replace('out=', ''); + + // IDs for status bar, tab, and loader + var statBarId = 'zProvisionStatBar' + out2Id; + var tabId = 'zvmProvisionTab' + out2Id; + var loaderId = 'zProvisionLoader' + out2Id; + + var node = $('#' + tabId + ' input[name=nodeName]').val(); + + /** + * (2) Create user entry + */ + if (lastCmd == 'nodeadd') { + if (rsp.length) { + $('#' + loaderId).hide(); + $('#' + statBarId).find('div').append('
        (Error) Failed to create node definition
        '); + } else { + $('#' + statBarId).find('div').append('
        Node definition created for ' + node + '
        '); + + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // Create user entry + var userEntry = $('#' + tabId + ' textarea').val(); + $.ajax( { + url : 'lib/zCmd.php', + dataType : 'json', + data : { + cmd : 'mkvm', + tgt : node, + args : '', + att : userEntry, + msg : 'cmd=mkvm;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + /** + * (3) Update /etc/hosts + */ + else if (lastCmd == 'mkvm') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // If there was an error, quit + if (containErrors(prg.html())) { + $('#' + loaderId).hide(); + } else { + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makehosts', + tgt : '', + args : '', + msg : 'cmd=makehosts;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + /** + * (4) Update DNS + */ + else if (lastCmd == 'makehosts') { + // If there was an error, quit + if (rsp.length) { + $('#' + loaderId).hide(); + $('#' + statBarId).find('div').append('
        (Error) Failed to update /etc/hosts
        '); + } else { + $('#' + statBarId).find('div').append('
        /etc/hosts updated
        '); + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makedns', + tgt : '', + args : '', + msg : 'cmd=makedns;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + /** + * (5) Add disk + */ + else if (lastCmd == 'makedns') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // If there was an error, quit + if (containErrors(prg.html())) { + $('#' + loaderId).hide(); + } else { + // Set cookie for number of disks + var diskRows = $('#' + tabId + ' table:eq(0):visible tbody tr'); + $.cookie('disks2add' + out2Id, diskRows.length); + if (diskRows.length > 0) { + for ( var i = 0; i < diskRows.length; i++) { + var diskArgs = diskRows.eq(i).find('td'); + var type = diskArgs.eq(1).find('select').val(); + var address = diskArgs.eq(2).find('input').val(); + var size = diskArgs.eq(3).find('input').val(); + var mode = diskArgs.eq(4).find('select').val(); + var pool = diskArgs.eq(5).find('select').val(); + var password = diskArgs.eq(6).find('input').val(); + + // Create ajax arguments + var args = ''; + if (type == '3390') { + args = '--add' + type + ';' + pool + ';' + address + + ';' + size + ';' + mode + ';' + password + ';' + + password + ';' + password; + } else if (type == '9336') { + var blkSize = '512'; + args = '--add' + type + ';' + pool + ';' + address + ';' + + blkSize + ';' + size + ';' + mode + ';' + password + ';' + + password + ';' + password; + } + + // Attach disk to node + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : args, + msg : 'cmd=chvm-disk;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + // Set cookie for number of zFCP devices + var zfcpRows = $('#' + tabId + ' table:eq(1):visible tbody tr'); + $.cookie('zfcp2add' + out2Id, zfcpRows.length); + if (zfcpRows.length > 0) { + for ( var i = 0; i < zfcpRows.length; i++) { + var diskArgs = zfcpRows.eq(i).find('td'); + var address = diskArgs.eq(1).find('input').val(); + var size = diskArgs.eq(2).find('input').val(); + var pool = diskArgs.eq(3).find('select').val(); + var tag = diskArgs.eq(4).find('input').val(); + var portName = diskArgs.eq(5).find('input').val(); + var unitNo = diskArgs.eq(6).find('input').val(); + + // This is either true or false + var loaddev = diskArgs.eq(7).find('input').attr('checked'); + if (loaddev) { + loaddev = "1"; + } else { + loaddev = "0"; + } + + // Create ajax arguments + var args = '--addzfcp;' + pool + ';' + address + ';' + loaddev + ';' + size; + if (tag && tag != "null") { + args += ';' + tag; + } if (portName && tag != "null") { + args += ';' + portName; + } if (unitNo && tag != "null") { + args += ';' + unitNo; + } + + // Attach zFCP device to node + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : args, + msg : 'cmd=chvm-zfcp;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + // Done if no disks to add + if (diskRows.length < 1 && zfcpRows.length < 1) { + $('#' + loaderId).hide(); + } + } + } + + /** + * (6) Set operating system for given node + */ + else if (lastCmd == 'chvm-disk' || lastCmd == 'chvm-zfcp') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // If there was an error, quit + if (containErrors(prg.html())) { + $('#' + loaderId).hide(); + } else { + // Set cookie for number of disks + // One less disk to add + var disks2add = $.cookie('disks2add' + out2Id); + if (lastCmd == 'chvm-disk') { + if (disks2add > 0) { + disks2add--; + $.cookie('disks2add' + out2Id, disks2add); + } + } + + var zfcp2add = $.cookie('zfcp2add' + out2Id); + if (lastCmd == 'chvm-zfcp') { + if (zfcp2add > 0) { + zfcp2add--; + $.cookie('zfcp2add' + out2Id, zfcp2add); + } + } + + // Only set operating system if there are no more disks to add + if (zfcp2add < 1 && disks2add < 1) { + // If an operating system image is given + var osImage = $('#' + tabId + ' select[name=os]:visible').val(); + if (osImage) { + // Get operating system, architecture, provision method, and profile + var tmp = osImage.split('-'); + var os = tmp[0]; + var arch = tmp[1]; + var profile = tmp[3]; + + // If the last disk is added + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeadd', + tgt : '', + args : node + ';noderes.netboot=zvm;nodetype.os=' + + os + ';nodetype.arch=' + arch + + ';nodetype.profile=' + profile, + msg : 'cmd=noderes;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } else { + $('#' + loaderId).hide(); + } + } + } + } + + /** + * (7) Update DHCP + */ + else if (lastCmd == 'noderes') { + // If there was an error, do not continue + if (rsp.length) { + $('#' + loaderId).hide(); + $('#' + statBarId).find('div').append('
        (Error) Failed to set operating system
        '); + } else { + $('#' + statBarId).find('div').append('
        Operating system for ' + node + ' set
        '); + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makedhcp', + tgt : '', + args : '-a', + msg : 'cmd=makedhcp;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + /** + * (8) Prepare node for boot + */ + else if (lastCmd == 'makedhcp') { + // Prepare node for boot + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeset', + tgt : node, + args : 'install', + msg : 'cmd=nodeset;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + + /** + * (9) Boot node to network + */ + else if (lastCmd == 'nodeset') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // If there was an error + // Do not continue + if (containErrors(prg.html())) { + $('#' + loaderId).hide(); + } else { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'rnetboot', + tgt : node, + args : 'ipl=000C', + msg : 'cmd=rnetboot;out=' + out2Id + }, + + success : updateZProvisionNewStatus + }); + } + } + + /** + * (10) Done + */ + else if (lastCmd == 'rnetboot') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + if (prg.html().indexOf('Error') < 0) { + $('#' + statBarId).find('div').append('
        Open a VNC viewer to see the installation progress.  It might take a couple of minutes before you can connect.
        '); + } + + // Hide loader + $('#' + loaderId).hide(); + } +} + +/** + * Update the provision existing node status + * + * @param data Data returned from HTTP request + */ +function updateZProvisionExistingStatus(data) { + // Get ajax response + var rsp = data.rsp; + var args = data.msg.split(';'); + + // Get command invoked + var cmd = args[0].replace('cmd=', ''); + // Get provision tab instance + var inst = args[1].replace('out=', ''); + + // Get provision tab and status bar ID + var statBarId = 'zProvisionStatBar' + inst; + var tabId = 'zvmProvisionTab' + inst; + + /** + * (2) Prepare node for boot + */ + if (cmd == 'nodeadd') { + // Get operating system + var bootMethod = $('#' + tabId + ' select[name=bootMethod]').val(); + + // Get nodes that were checked + var dTableId = 'zNodesDatatable' + inst; + var tgts = getNodesChecked(dTableId); + + // Prepare node for boot + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeset', + tgt : tgts, + args : bootMethod, + msg : 'cmd=nodeset;out=' + inst + }, + + success : updateZProvisionExistingStatus + }); + } + + /** + * (3) Boot node from network + */ + else if (cmd == 'nodeset') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + // If there was an error, do not continue + if (containErrors(prg.html())) { + var loaderId = 'zProvisionLoader' + inst; + $('#' + loaderId).remove(); + return; + } + + // Get nodes that were checked + var dTableId = 'zNodesDatatable' + inst; + var tgts = getNodesChecked(dTableId); + + // Boot node from network + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'rnetboot', + tgt : tgts, + args : 'ipl=000C', + msg : 'cmd=rnetboot;out=' + inst + }, + + success : updateZProvisionExistingStatus + }); + } + + /** + * (4) Done + */ + else if (cmd == 'rnetboot') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + statBarId).find('div').append(prg); + + var loaderId = 'zProvisionLoader' + inst; + $('#' + loaderId).remove(); + } +} + +/** + * Update zVM node status + * + * @param data Data returned from HTTP request + */ +function updateZNodeStatus(data) { + var node = data.msg; + var rsp = data.rsp; + + // Get cookie for number processes performed against this node + var actions = $.cookie(node + 'processes'); + // One less process + actions = actions - 1; + $.cookie(node + 'processes', actions); + + if (actions < 1) { + // Hide loader when there are no more processes + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).hide(); + } + + var statBarId = node + 'StatusBar'; + + // Write ajax response to status bar + var prg = writeRsp(rsp, '[A-Za-z0-9._-]+:'); + $('#' + statBarId).find('div').append(prg); +} + +/** + * Update clone status + * + * @param data Data returned from HTTP request + */ +function updateZCloneStatus(data) { + // Get ajax response + var rsp = data.rsp; + var args = data.msg.split(';'); + var cmd = args[0].replace('cmd=', ''); + + // Get provision instance + var inst = args[1].replace('inst=', ''); + // Get output division ID + var out2Id = args[2].replace('out=', ''); + + /** + * (2) Update /etc/hosts + */ + if (cmd == 'nodeadd') { + var node = args[3].replace('node=', ''); + + // If there was an error, do not continue + if (rsp.length) { + $('#' + out2Id).find('img').hide(); + $('#' + out2Id).find('div').append('
        (Error) Failed to create node definition
        '); + } else { + $('#' + out2Id).find('div').append('
        Node definition created for ' + node + '
        '); + + // If last node definition was created + var tmp = inst.split('/'); + if (tmp[0] == tmp[1]) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makehosts', + tgt : '', + args : '', + msg : 'cmd=makehosts;inst=' + inst + ';out=' + out2Id + }, + + success : updateZCloneStatus + }); + } + } + } + + /** + * (3) Update DNS + */ + else if (cmd == 'makehosts') { + // If there was an error, do not continue + if (rsp.length) { + $('#' + out2Id).find('img').hide(); + $('#' + out2Id).find('div').append('
        (Error) Failed to update /etc/hosts
        '); + } else { + $('#' + out2Id).find('div').append('
        /etc/hosts updated
        '); + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'makedns', + tgt : '', + args : '', + msg : 'cmd=makedns;inst=' + inst + ';out=' + out2Id + }, + + success : updateZCloneStatus + }); + } + } + + /** + * (4) Clone + */ + else if (cmd == 'makedns') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + out2Id).find('div').append(prg); + + // Get clone tab + var tabId = out2Id.replace('CloneStatusBar', 'CloneTab'); + + // If a node range is given + var tgtNodeRange = $('#' + tabId + ' input[name=tgtNode]').val(); + var tgtNodes = ''; + if (tgtNodeRange.indexOf('-') > -1) { + var tmp = tgtNodeRange.split('-'); + + // Get node base name + var nodeBase = tmp[0].match(/[a-zA-Z]+/); + // Get the starting index + var nodeStart = parseInt(tmp[0].match(/\d+/)); + // Get the ending index + var nodeEnd = parseInt(tmp[1].match(/\d+/)); + for ( var i = nodeStart; i <= nodeEnd; i++) { + // Do not append comma for last node + if (i == nodeEnd) { + tgtNodes += nodeBase + i.toString(); + } else { + tgtNodes += nodeBase + i.toString() + ','; + } + } + } else { + tgtNodes = tgtNodeRange; + } + + // Get other inputs + var srcNode = $('#' + tabId + ' input[name=srcNode]').val(); + hcp = $('#' + tabId + ' input[name=newHcp]').val(); + var group = $('#' + tabId + ' input[name=newGroup]').val(); + var diskPool = $('#' + tabId + ' input[name=diskPool]').val(); + var diskPw = $('#' + tabId + ' input[name=diskPw]').val(); + if (!diskPw) { + diskPw = ''; + } + + // Clone + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'mkvm', + tgt : tgtNodes, + args : srcNode + ';pool=' + diskPool + ';pw=' + diskPw, + msg : 'cmd=mkvm;inst=' + inst + ';out=' + out2Id + }, + + success : updateZCloneStatus + }); + } + + /** + * (5) Done + */ + else if (cmd == 'mkvm') { + // Write ajax response to status bar + var prg = writeRsp(rsp, ''); + $('#' + out2Id).find('div').append(prg); + + // Hide loader + $('#' + out2Id).find('img').hide(); + } +} + +/** + * Get zVM resources + * + * @param data Data from HTTP request + */ +function getZResources(data) { + var tabId = 'zvmResourceTab'; + var info = createInfoBar('Manage storage and networks'); + $('#' + tabId).append(info); + + // Do not continue if there is no output + if (data.rsp.length) { + // Push hardware control points into an array + var node, hcp; + var hcpHash = new Object(); + for (var i in data.rsp) { + node = data.rsp[i][0]; + hcp = data.rsp[i][1]; + hcpHash[hcp] = 1; + } + + // Create an array for hardware control points + var hcps = new Array(); + for (var key in hcpHash) { + // Get the short host name + hcp = key.split('.')[0]; + hcps.push(hcp); + } + + // Set hardware control point cookie + $.cookie('hcp', hcps); + + // Delete loader + $('#' + tabId).find('img[src="images/loader.gif"]').remove(); + + // Create accordion panel for disk + var resourcesAccordion = $('
        '); + var diskSection = $('
        '); + var diskLnk = $('

        Disks

        ').click(function () { + // Do not load panel again if it is already loaded + if ($('#zvmDiskResource').children().length) + return; + else + $('#zvmDiskResource').append(createLoader('')); + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Query the disk pools for each + for (var i in hcps) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--diskpoolnames', + msg : hcps[i] + }, + + success : getDiskPool + }); + } + }); + + // Create accordion panel for zFCP devices + var zfcpSection = $('
        '); + var zfcpLnk = $('

        zFCP

        ').click(function () { + // Do not load panel again if it is already loaded + if ($('#zfcpResource').children().length) + return; + else + $('#zfcpResource').append(createLoader('')); + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + for ( var i in hcps) { + // Gather networks from hardware control points + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--zfcppoolnames', + msg : hcps[i] + }, + + success : getZfcpPool + }); + } + }); + + // Create accordion panel for network + var networkSection = $('
        '); + var networkLnk = $('

        Networks

        ').click(function () { + // Do not load panel again if it is already loaded + if ($('#zvmNetworkResource').children().length) + return; + else + $('#zvmNetworkResource').append(createLoader('')); + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + for ( var i in hcps) { + // Gather networks from hardware control points + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--getnetworknames', + msg : hcps[i] + }, + + success : getNetwork + }); + } + }); + + resourcesAccordion.append(diskLnk, diskSection, zfcpLnk, zfcpSection, networkLnk, networkSection); + + // Append accordion to tab + $('#' + tabId).append(resourcesAccordion); + resourcesAccordion.accordion(); + diskLnk.trigger('click'); + } +} + +/** + * Get node attributes from HTTP request data + * + * @param propNames Hash table of property names + * @param keys Property keys + * @param data Data from HTTP request + * @return Hash table of property values + */ +function getAttrs(keys, propNames, data) { + // Create hash table for property values + var attrs = new Object(); + + // Go through inventory and separate each property out + var curKey = null; // Current property key + var addLine; // Add a line to the current property? + for ( var i = 1; i < data.length; i++) { + addLine = true; + + // Loop through property keys + // Does this line contains one of the properties? + for ( var j = 0; j < keys.length; j++) { + // Find property name + if (data[i].indexOf(propNames[keys[j]]) > -1) { + attrs[keys[j]] = new Array(); + + // Get rid of property name in the line + data[i] = data[i].replace(propNames[keys[j]], ''); + // Trim the line + data[i] = jQuery.trim(data[i]); + + // Do not insert empty line + if (data[i].length > 0) { + attrs[keys[j]].push(data[i]); + } + + curKey = keys[j]; + addLine = false; // This line belongs to a property + } + } + + // Line does not contain a property + // Must belong to previous property + if (addLine && data[i].length > 1) { + data[i] = jQuery.trim(data[i]); + attrs[curKey].push(data[i]); + } + } + + return attrs; +} + +/** + * Create add processor dialog + * + * @param node Node to add processor to + */ +function openAddProcDialog(node) { + // Create form to add processor + var addProcForm = $('
        '); + // Create info bar + var info = createInfoBar('Add a temporary processor to this virtual server.'); + addProcForm.append(info); + addProcForm.append('
        '); + addProcForm.append('
        '); + + // Create drop down for processor type + var procType = $('
        '); + procType.append(''); + var typeSelect = $(''); + typeSelect.append('' + + '' + + '' + + '' + ); + procType.append(typeSelect); + addProcForm.append(procType); + + // Open dialog to add processor + addProcForm.dialog({ + title:'Add processor', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var node = $(this).find('input[name=procNode]').val(); + var address = $(this).find('input[name=procAddress]').val(); + var type = $(this).find('select[name=procType]').val(); + + // If inputs are not complete, show warning message + if (!node || !address || !type) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Add processor + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--addprocessoractive;' + address + ';' + type, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + var statusId = node + 'StatusBar'; + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).show(); + $('#' + statusId).show(); + + // Close dialog + $(this).dialog( "close" ); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add disk dialog + * + * @param node Node to add disk to + * @param hcp Hardware control point of node + */ +function openAddDiskDialog(node, hcp) { + // Get list of disk pools + var cookie = $.cookie(hcp + 'diskpools'); + var pools = cookie.split(','); + + // Create form to add disk + var addDiskForm = $('
        '); + // Create info bar + var info = createInfoBar('Add a ECKD|3390 or FBA|9336 disk to this virtual server.'); + addDiskForm.append(info); + addDiskForm.append('
        '); + addDiskForm.append('
        '); + addDiskForm.append('
        '); + addDiskForm.append('
        '); + + // Create drop down for disk pool + var diskPool = $('
        '); + diskPool.append(''); + var poolSelect = $(''); + for ( var i = 0; i < pools.length; i++) { + poolSelect.append(''); + } + diskPool.append(poolSelect); + addDiskForm.append(diskPool); + + // Create drop down for disk mode + var diskMode = $('
        '); + diskMode.append(''); + var modeSelect = $(''); + modeSelect.append('' + + '' + + '' + + '' + + '' + + '' + + '' + ); + diskMode.append(modeSelect); + addDiskForm.append(diskMode); + + addDiskForm.append('
        '); + + // Open dialog to add disk + addDiskForm.dialog({ + title:'Add disk', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var node = $(this).find('input[name=diskNode]').val(); + var type = $(this).find('select[name=diskType]').val(); + var address = $(this).find('input[name=diskAddress]').val(); + var size = $(this).find('input[name=diskSize]').val(); + var pool = $(this).find('select[name=diskPool]').val(); + var mode = $(this).find('select[name=diskMode]').val(); + var password = $(this).find('input[name=diskPassword]').val(); + + // If inputs are not complete, show warning message + if (!node || !type || !address || !size || !pool || !mode) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Add disk + if (type == '3390') { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--add3390;' + pool + ';' + address + ';' + size + + ';' + mode + ';' + password + ';' + password + ';' + password, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + var statusId = node + 'StatusBar'; + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).show(); + $('#' + statusId).show(); + } else if (type == '9336') { + // Default block size for FBA volumes = 512 + var blkSize = '512'; + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--add9336;' + pool + ';' + address + ';' + blkSize + ';' + size + + ';' + mode + ';' + password + ';' + password + ';' + password, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + var statusId = node + 'StatusBar'; + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).show(); + $('#' + statusId).show(); + } + + // Close dialog + $(this).dialog( "close" ); + } // End of else + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add zFCP device dialog + * + * @param node Node to add disk to + * @param hcp Hardware control point of node + * @param zvm The z/VM system of node + */ +function openAddZfcpDialog(node, hcp, zvm) { + // Get list of disk pools + var cookie = $.cookie(hcp + 'zfcppools'); + var pools = cookie.split(','); + + // Create form to add disk + var addZfcpForm = $('
        '); + // Create info bar + var info = createInfoBar('Add a SCSI|FCP disk to this virtual server.'); + addZfcpForm.append(info); + addZfcpForm.append('
        '); + addZfcpForm.append('
        '); + addZfcpForm.append('
        '); + addZfcpForm.append('
        '); + + // Create drop down for disk pool + var diskPool = $('
        '); + diskPool.append(''); + var poolSelect = $(''); + for ( var i = 0; i < pools.length; i++) { + poolSelect.append(''); + } + diskPool.append(poolSelect); + addZfcpForm.append(diskPool); + + // Tag to identify where device will be used + addZfcpForm.append('
        '); + + // Create advanced link to set advanced zFCP properties + var advancedLnk = $('
        '); + addZfcpForm.append(advancedLnk); + var advanced = $('
        ').hide(); + addZfcpForm.append(advanced); + + var portName = $('
        '); + var unitNo = $('
        '); + advanced.append(portName, unitNo); + + var wwpns = $.cookie(zvm + 'wwpns'); + if (wwpns) { + // Turn on auto complete + portName.find('input').autocomplete({ + source: wwpns.split(',') + }); + } + + // Toggle port name and unit number when clicking on advanced link + advancedLnk.click(function() { + advanced.toggle(); + }); + + // Open dialog to add disk + addZfcpForm.dialog({ + title:'Add zFCP device', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var node = $(this).find('input[name=diskNode]').val(); + var address = $(this).find('input[name=diskAddress]').val(); + var loaddev = $(this).find('input[name=diskLoaddev]'); + var size = $(this).find('input[name=diskSize]').val(); + var pool = $(this).find('select[name=diskPool]').val(); + var tag = $(this).find('select[name=diskTag]').val(); + var portName = $(this).find('select[name=diskPortName]').val(); + var unitNo = $(this).find('select[name=diskUnitNo]').val(); + + // If inputs are not complete, show warning message + if (!node || !address || !size || !pool) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + if (loaddev.attr('checked')) { + loaddev = 1; + } else { + loaddev = 0; + } + + var args = '--addzfcp;' + pool + ';' + address + ';' + loaddev + ';' + size; + + if (tag && tag != "null") { + args += ';' + tag; + } if (portName && tag != "null") { + args += ';' + portName; + } if (unitNo && tag != "null") { + args += ';' + unitNo; + } + + // Add zFCP device + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : args, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + var statusId = node + 'StatusBar'; + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).show(); + $('#' + statusId).show(); + + // Close dialog + $(this).dialog( "close" ); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create dedicate device dialog + * + * @param node Node to dedicate device to + * @param hcp Hardware control point of node + */ +function openDedicateDeviceDialog(node, hcp) { + // Create form to add disk + var dedicateForm = $('
        '); + // Create info bar + var info = createInfoBar('Add a dedicated device to the configuration'); + dedicateForm.append(info); + + dedicateForm.append('
        '); + dedicateForm.append('
        '); + dedicateForm.append('
        '); + dedicateForm.append('
        '); + + // Open dialog to add dedicated device + dedicateForm.dialog({ + title:'Add dedicated device', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var node = $(this).find('input[name=diskNode]').val(); + var vAddress = $(this).find('input[name=virtualAddress]').val(); + var rAddress = $(this).find('input[name=realAddress]').val() + var mode = $(this).find('select[name=mode]').val(); + + // If inputs are not complete, show warning message + if (!node || !vAddress || !rAddress || !mode) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + var args = '--dedicatedevice;' + vAddress + ';' + rAddress + ';' + mode; + + // Add zFCP device + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : args, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + var statusId = node + 'StatusBar'; + var statusBarLoaderId = node + 'StatusBarLoader'; + $('#' + statusBarLoaderId).show(); + $('#' + statusId).show(); + + // Close dialog + $(this).dialog( "close" ); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add ECKD to system dialog + * + * @param hcp Hardware control point of node + */ +function openAddEckd2SystemDialog(hcp) { + var dialogId = 'zvmAddEckd2System'; + + // Create form to add disk + var addE2SForm = $('
        '); + + // Create info bar + var info = createInfoBar('Dynamically add an ECKD disk to a running z/VM system.'); + addE2SForm.append(info); + addE2SForm.append('
        '); + + // Open dialog to add disk + addE2SForm.dialog({ + title:'Add ECKD to system', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var devnum = $(this).find('input[name=devNum]').val(); + + // If inputs are not complete, show warning message + if (!devnum) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : hcp, + args : "--addeckd;" + devnum, + msg : dialogId + }, + + success : updateResourceDialog + }); + + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add page or spool dialog + * + * @param hcp Hardware control point of node + */ +function openAddPageSpoolDialog(hcp) { + var dialogId = 'zvmAddPageSpool'; + + // Create form to add disk + var addPageSpoolForm = $('
        '); + + // Create info bar + var info = createInfoBar('Indicate a full-pack minidisk is to be shared by the users of many real and virtual systems.'); + addPageSpoolForm.append(info); + + var diskFS = $('
        Disk
        '); + addPageSpoolForm.append(diskFS); + var diskAttr = $('
        '); + diskFS.append($('
        ')); + diskFS.append(diskAttr); + + diskAttr.append('
        '); + diskAttr.append('
        '); + diskAttr.append('
        '); + + var optionFS = $('
        Optional
        ') + addPageSpoolForm.append(optionFS); + var optionAttr = $('
        '); + optionFS.append($('
        ')); + optionFS.append(optionAttr); + + optionAttr.append('
        '); + optionAttr.append('
        '); + optionAttr.append('
        '); + optionAttr.append('
        '); + optionAttr.append('
        '); + + // Open dialog to add disk + addPageSpoolForm.dialog({ + title:'Add page or spool', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + var volAddr = $(this).find('input[name=volAddr]').val(); + var volLabel = $(this).find('input[name=volLabel]').val(); + var volUse = $(this).find('select[name=volUse]').val(); + var systemConfigName = $(this).find('input[name=systemConfigName]').val(); + var systemConfigType = $(this).find('input[name=systemConfigType]').val(); + var parmDiskOwner = $(this).find('input[name=parmDiskOwner]').val(); + var parmDiskNumber = $(this).find('input[name=parmDiskNumber]').val(); + var parmDiskPass = $(this).find('input[name=parmDiskPass]').val(); + + // If inputs are not complete, show warning message + if (!volAddr || !volLabel || !volUse) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + var pageSpoolArgs = volAddr + ";" + volLabel + ";" + volUse + ";"; + if (systemConfigName) { + pageSpoolArgs += systemConfigName + ";"; + } if (systemConfigType) { + pageSpoolArgs += systemConfigType + ";"; + } if (parmDiskOwner) { + pageSpoolArgs += parmDiskOwner + ";"; + } if (parmDiskNumber) { + pageSpoolArgs += parmDiskNumber + ";"; + } if (parmDiskPass) { + pageSpoolArgs += parmDiskPass + ";"; + } + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : hcp, + args : '--addpagespool;' + pageSpoolArgs, + msg : dialogId + }, + + success : updateResourceDialog + }); + + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Open dialog to share disk + * + * @param disks2share Disks selected in table + */ +function openShareDiskDialog(disks2share) { + // Create form to share disk + var dialogId = 'zvmShareDisk'; + var shareDiskForm = $('
        '); + + // Create info bar + var info = createInfoBar('Indicate a full-pack minidisk is to be shared by the users of many real and virtual systems.'); + shareDiskForm.append(info); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + // Set region input based on those selected on table (if any) + var volAddr = $('
        '); + var shareEnable = $('
        '); + shareDiskForm.append(hcp, volAddr, shareEnable); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Append options for hardware control points + for (var i in hcps) { + hcpSelect.append($('')); + } + + // Open dialog to delete disk + shareDiskForm.dialog({ + title:'Share disk', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var hcp = $(this).find('select[name=hcp]').val(); + var volAddr = $(this).find('input[name=volAddr]').val(); + var shareEnable = $(this).find('select[name=shareEnable]').val(); + + // If inputs are not complete, show warning message + if (!volAddr || !shareEnable) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + // Remove disk from pool + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : hcp, + args : "--sharevolume;" + volAddr + ";" + shareEnable, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add SCSI 2 system dialog + * + * @param hcp Hardware control point of node + */ +function openAddScsi2SystemDialog(hcp) { + var dialogId = 'zvmAddScsi2System'; + + // Create form to add disk + var addS2SForm = $('
        '); + + // Create info bar + var info = createInfoBar('Dynamically add an SCSI disk to a running z/VM system.'); + addS2SForm.append(info); + + var devNum = $('
        '); + var devPathLabel = $(''); + var devPathCount = 1; + var pathDiv = $('
        '); + + var devPathDiv = $('
        '); + var devPathTable = $('
        '); + var devPathHeader = $(' FCP Device WWPN LUN'); + // Adjust header width + devPathHeader.find('th').css( { + 'width' : '120px' + }); + devPathHeader.find('th').eq(0).css( { + 'width' : '20px' + }); + var devPathBody = $(''); + var devPathFooter = $(''); + + // Create a row + var devPathRow = $(''); + + // Add blank column (remove button replacement) + devPathRow.append(''); + + // Create FCP device number input + var fcpDevNum = $(''); + devPathRow.append(fcpDevNum); + + // Create FCP WWPN input + var fcpWwpn = $(''); + devPathRow.append(fcpWwpn); + + var wwpns = ""; + if ($.cookie('zvms')) { + zvms = $.cookie('zvms').split(','); + var zvm; + for (var i in zvms) { + var args = zvms[i].split(':'); + var zvm = args[0].toLowerCase(); + var iHcp = args[1]; + + wwpns += "," + $.cookie(zvm + 'wwpns'); + } + + wwpns = wwpns.replace(',,', ','); + fcpWwpn.find('input').autocomplete({ + source: wwpns.split(',') + }); + } + + // Create FCP LUN input + var fcpLun = $(''); + devPathRow.append(fcpLun); + + devPathBody.append(devPathRow); + + var addDevPathLink = $('Add path'); + addDevPathLink.bind('click', function(event){ + devPathCount = devPathCount + 1; + // Create a row + var devPathRow = $(''); + + // Add remove button + var removeBtn = $('').css({ + "float": "left", + "cursor": "pointer" + }); + var col = $('').append(removeBtn); + removeBtn.bind('click', function(event) { + $(this).parent().parent().remove(); + }); + devPathRow.append(col); + + // Create FCP device number input + var fcpDevNum = $(''); + devPathRow.append(fcpDevNum); + + // Create FCP WWPN input + var fcpWwpn = $(''); + devPathRow.append(fcpWwpn); + fcpWwpn.find('input').autocomplete({ + source: wwpns.split(',') + }); + + // Create FCP LUN input + var fcpLun = $(''); + devPathRow.append(fcpLun); + + devPathBody.append(devPathRow); + }); + devPathFooter.append(addDevPathLink); + devPathTable.append(devPathHeader); + devPathTable.append(devPathBody); + devPathTable.append(devPathFooter); + devPathDiv.append(devPathLabel); + devPathDiv.append(devPathTable); + + var option = $('
        '); + var persist = $('
        '); + addS2SForm.append(devNum, devPathDiv, option, persist); + + addS2SForm.find('div input[title]').tooltip({ + position: "center right", + offset: [-2, 10], + effect: "fade", + opacity: 0.7, + predelay: 800, + events: { + def: "mouseover,mouseout", + input: "mouseover,mouseout", + widget: "focus mouseover,blur mouseout", + tooltip: "mouseover,mouseout" + } + }); + + // Open dialog to add disk + addS2SForm.dialog({ + title:'Add SCSI to running system', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 675, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + var num = $(this).find('input[name=devNum]').val(); + var pathArray = ""; + $('.devPath').each(function(index) { + pathArray += $(this).find('input[name=fcpDevNum]').val() + ' '; + pathArray += $(this).find('input[name=fcpWwpn]').val() + ' '; + pathArray += $(this).find('input[name=fcpLun]').val() + '; '; + }); + path_Array = pathArray + "'"; + var option = $(this).find('select[name=option]').val(); + var persist = $(this).find('select[name=persist]').val(); + + // If inputs are not complete, show warning message + if (!num || !pathArray || !option || !persist) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : hcp, + args : "--addscsi|" + num + "|" + pathArray + "|" + option + "|" + persist, + msg : dialogId + }, + + success : updateResourceDialog + }); + + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Delete a real SCSI disk + * + * @param hcp Hardware control point of node + */ +function openRemoveScsiDialog(hcp) { + var dialogId = 'zvmRemoveScsiDialog'; + // Create form to add disk + var removeScsiForm = $('
        '); + // Create info bar + var info = createInfoBar('Delete a real SCSI disk'); + removeScsiForm.append(info); + removeScsiForm.append('
        '); + removeScsiForm.append('
        '); + addNicForm.append('
        '); + + // Create drop down for NIC types + var nicType = $('
        '); + nicType.append(''); + var nicTypeSelect = $(''); + nicTypeSelect.append('' + + '' + + '' + ); + nicType.append(nicTypeSelect); + addNicForm.append(nicType); + + // Create drop down for network types + var networkType = $('
        '); + networkType.append(''); + var networkTypeSelect = $(''); + networkTypeSelect.append('' + + '' + + '' + ); + networkType.append(networkTypeSelect); + addNicForm.append(networkType); + + // Create drop down for network names + var gLansQdioSelect = $(''); + var gLansHipersSelect = $(''); + var vswitchSelect = $(''); + for ( var i = 0; i < networks.length; i++) { + var network = networks[i].split(' '); + var networkOption = $(''); + if (network[0] == 'VSWITCH') { + vswitchSelect.append(networkOption); + } else if (network[0] == 'LAN:QDIO') { + gLansQdioSelect.append(networkOption); + } else if (network[0] == 'LAN:HIPERS') { + gLansHipersSelect.append(networkOption); + } + } + + // Hide network name drop downs until the NIC type and network type is selected + // QDIO Guest LAN drop down + var guestLanQdio = $('
        ').hide(); + guestLanQdio.append(''); + guestLanQdio.append(gLansQdioSelect); + addNicForm.append(guestLanQdio); + + // HIPERS Guest LAN drop down + var guestLanHipers = $('
        ').hide(); + guestLanHipers.append(''); + guestLanHipers.append(gLansHipersSelect); + addNicForm.append(guestLanHipers); + + // VSWITCH drop down + var vswitch = $('
        ').hide(); + vswitch.append(''); + vswitch.append(vswitchSelect); + addNicForm.append(vswitch); + + // Show network names on change + networkTypeSelect.change(function(){ + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + // Get NIC type and network type + var nicType = $(this).parent().parent().find('select[name=nicType]').val(); + var networkType = $(this).val(); + + // Hide network name drop downs + var guestLanQdio = $(this).parent().parent().find('select[name=nicLanQdioName]').parent(); + var guestLanHipers = $(this).parent().parent().find('select[name=nicLanHipersName]').parent(); + var vswitch = $(this).parent().parent().find('select[name=nicVSwitchName]').parent(); + guestLanQdio.hide(); + guestLanHipers.hide(); + vswitch.hide(); + + // Show correct network name + if (networkType == 'Guest LAN' && nicType == 'QDIO') { + guestLanQdio.show(); + } else if (networkType == 'Guest LAN' && nicType == 'HiperSockets') { + guestLanHipers.show(); + } else if (networkType == 'Virtual Switch') { + if (nicType == 'QDIO') { + vswitch.show(); + } else { + // No such thing as HIPERS VSWITCH + var warn = createWarnBar('The selected choices are not valid.'); + warn.prependTo($(this).parent().parent()); + } + } + }); + + // Show network names on change + nicTypeSelect.change(function(){ + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + // Get NIC type and network type + var nicType = $(this).val(); + var networkType = $(this).parent().parent().find('select[name=nicNetworkType]').val(); + + // Hide network name drop downs + var guestLanQdio = $(this).parent().parent().find('select[name=nicLanQdioName]').parent(); + var guestLanHipers = $(this).parent().parent().find('select[name=nicLanHipersName]').parent(); + var vswitch = $(this).parent().parent().find('select[name=nicVSwitchName]').parent(); + guestLanQdio.hide(); + guestLanHipers.hide(); + vswitch.hide(); + + // Show correct network name + if (networkType == 'Guest LAN' && nicType == 'QDIO') { + guestLanQdio.show(); + } else if (networkType == 'Guest LAN' && nicType == 'HiperSockets') { + guestLanHipers.show(); + } else if (networkType == 'Virtual Switch') { + if (nicType == 'QDIO') { + vswitch.show(); + } else { + // No such thing as HIPERS VSWITCH + var warn = createWarnBar('The selected choices are not valid.'); + warn.prependTo($(this).parent().parent()); + } + } + }); + + // Open dialog to add NIC + addNicForm.dialog({ + title:'Add NIC', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + var ready = true; + var errMsg = ''; + + // Get inputs + var node = $(this).find('input[name=nicNode]').val(); + var nicType = $(this).find('select[name=nicType]').val(); + var networkType = $(this).find('select[name=nicNetworkType]').val(); + var address = $(this).find('input[name=nicAddress]').val(); + + // If inputs are not complete, show warning message + if (!node || !nicType || !networkType || !address) { + errMsg = 'Please provide a value for each missing field.
        '; + ready = false; + } + + // If a HIPERS VSWITCH is selected, show warning message + if (nicType == 'HiperSockets' && networkType == 'Virtual Switch') { + errMsg += 'The selected choices are not valid.'; + ready = false; + } + + // If there are errors + if (!ready) { + // Show warning message + var warn = createWarnBar(errMsg); + warn.prependTo($(this)); + } else { + // Add guest LAN + if (networkType == 'Guest LAN') { + var temp; + if (nicType == 'QDIO') { + temp = $(this).find('select[name=nicLanQdioName]').val().split(' '); + } else { + temp = $(this).find('select[name=nicLanHipersName]').val().split(' '); + } + + var lanOwner = temp[0]; + var lanName = temp[1]; + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--addnic;' + address + ';' + nicType + ';3', + msg : 'node=' + node + ';addr=' + address + ';lan=' + + lanName + ';owner=' + lanOwner + }, + success : connect2GuestLan + }); + } + + // Add virtual switch + else if (networkType == 'Virtual Switch' && nicType == 'QDIO') { + var temp = $(this).find('select[name=nicVSwitchName]').val().split(' '); + var vswitchName = temp[1]; + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--addnic;' + address + ';' + nicType + ';3', + msg : 'node=' + node + ';addr=' + address + ';vsw=' + + vswitchName + }, + + success : connect2VSwitch + }); + } + + // Increment node process + incrementNodeProcess(node); + + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); + + // Close dialog + $(this).dialog( "close" ); + } // End of else + }, + "Cancel": function(){ + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Create add vSwitch/VLAN dialog + * + * @param hcp Hardware control point of node + */ +function openAddVswitchVlanDialog(hcp) { + var dialogId = 'zvmAddVswitchVlan'; + + // Create form to add disk + var addVswitchForm = $('
        '); + + // Create info bar + var info = createInfoBar('Create a virtual switch or virtual network LAN.'); + + var netFS = $('
        '); + var netLegend = $('Network'); + netFS.append(netLegend); + + var typeFS = $('
        ').hide(); + var typeLegend = $('Network'); + typeFS.append(typeLegend); + + addVswitchForm.append(info, netFS, typeFS); + var netAttr = $('
        '); + netFS.append($('
        ')); + netFS.append(netAttr); + + var networkTypeDiv = $('
        '); + var networkType = $('
        '); + networkTypeDiv.append(networkType) + netAttr.append(networkTypeDiv); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + netAttr.append(hcp); + + var typeAttr = $('
        '); + typeFS.append($('
        ')); + typeFS.append(typeAttr); + + // Create vSwitch parameters + var vswitchOptions = $('
        ').hide(); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + vswitchOptions.append($('
        ')); + + // Create VLAN parameters + var vlanOptions = $('
        ').hide(); + vlanOptions.append($('
        ')); + vlanOptions.append($('
        ')); + vlanOptions.append($('
        ')); + vlanOptions.append($('
        ')); + + typeAttr.append(vswitchOptions, vlanOptions); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Append options for hardware control points + for (var i in hcps) { + hcpSelect.append($('')); + } + + networkType.change(function() { + typeFS.show(); + if ($(this).val() == "vswitch") { + typeFS.find("legend").text("vSwitch"); + vswitchOptions.show(); + vlanOptions.hide(); + } else if ($(this).val() == "vlan") { + typeFS.find("legend").text("VLAN"); + vswitchOptions.hide(); + vlanOptions.show(); + } else { + typeFS.find("legend").text(""); + vswitchOptions.hide(); + vlanOptions.hide(); + typeFS.hide(); + } + }); + + // Open dialog to add vSwitch or VLAN + addVswitchForm.dialog({ + title:'Add vSwitch or VLAN', + modal: true, + close: function() { + $(this).remove(); + }, + width: 750, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + var networkType = $(this).find('select[name=networkType]').val(); + if (networkType == "vswitch"){ + var networkArgs = "--addvswitch;"; + var hcp = $(this).find('select[name=hcp]').val(); + var switchName = $(this).find('input[name=switchName]').val(); + var deviceAddress = $(this).find('input[name=deviceAddress]').val(); + var portName = $(this).find('input[name=switchName]').val(); + var controllerName = $(this).find('input[name=controllerName]').val(); + var connection = $(this).find('select[name=connection]').val(); + var queueMemoryLimit = $(this).find('input[name=queueMemoryLimit]').val(); + var routingValue = $(this).find('select[name=routingValue]').val(); + var transportType = $(this).find('select[name=transportType]').val(); + var vlanId = $(this).find('input[name=vlanId]').val(); + var portType = $(this).find('select[name=portType]').val(); + var updateSysConfig = $(this).find('select[name=updateSysConfig]').val(); + var gvrp = $(this).find('select[name=gvrp]').val(); + var nativeVlanId = $(this).find('input[name=nativeVlanId]').val(); + + if (switchName) + networkArgs += ";" + switchName; + if (deviceAddress) + networkArgs += ";" + deviceAddress; + if (portName) + networkArgs += ";" + portName; + if (controllerName) + networkArgs += ";" + controllerName; + if (connection) + networkArgs += ";" + connection; + if (queueMemoryLimit) + networkArgs += ";" + queueMemoryLimit; + if (routingValue) + networkArgs += ";" + routingValue; + if (transportType) + networkArgs += ";" + transportType; + if (vlanId) + networkArgs += ";" + vlanId; + if (portType) + networkArgs += ";" + portType; + if (updateSysConfig) + networkArgs += ";" + updateSysConfig; + if (gvrp) + networkArgs += ";" + gvrpValue; + if (nativeVlanId) + networkArgs += ";" + nativeVlanId; + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : hcp, + args : networkArgs, + msg : dialogId + }, + + success : updateResourceDialog + }); + } else if (networkType == "vlan") { + var networkArgs = "--addvlan;"; + var hcp = $(this).find('select[name=hcp]').val(); + var vlanName = $(this).find('input[name=vlanName]').val(); + var vlanOwner = $(this).find('input[name=vlanOwner]').val(); + var vlanType = $(this).find('select[name=vlanType]').val(); + var vlanTransport = $(this).find('select[name=vlanTransport]').val(); + + if (!vlanName || !vlanOwner || !vlanType || !vlanTransport) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + networkArgs += ";" + vlanName; + networkArgs += ";" + vlanOwner; + networkArgs += ";" + vlanType; + networkArgs += ";" + vlanTransport; + + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : hcp, + args : networkArgs, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + } // End of else if + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Open dialog to delete network + * + * @param node type name for removing network + */ +function openRemoveVswitchVlanDialog(networkList) { + var names = ''; + for (var i in networkList) { + var networkArgs = networkList[i].split(';'); + networkArgs[2] = jQuery.trim(networkArgs[2]); + names += networkArgs[2] + ', '; + } + names = names.substring(0, names.length - 2); // Delete last two characters + + var confirmDialog = $('

        Are you sure you want to remove ' + names + '?

        '); + confirmDialog.dialog({ + title: "Confirm", + modal: true, + width: 400, + buttons: { + "Ok": function() { + for (var i in networkList) { + var networkArgs = networkList[i].split(';'); + var node = networkArgs[0]; + var type = networkArgs[1]; + var name = jQuery.trim(networkArgs[2]); + + if (type.toLowerCase() == "vswitch") { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : node, + args : '--removevswitch;' + name, + msg : '' + } + }); + } else if (type.toLowerCase() == "vlan") { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chhypervisor', + tgt : node, + args : '--removevlan;' + name + ';' + owner, + msg : '' + } + }); + } + } + $(this).dialog("close"); + }, + "Cancel": function() { + $(this).dialog("close"); + } + } + }); +} + +/** + * Remove processor + * + * @param node Node where processor is attached + * @param address Virtual address of processor + */ +function removeProcessor(node, address) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--removeprocessor;' + address, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); +} + +/** + * Remove disk + * + * @param node Node where disk is attached + * @param address Virtual address of disk + */ +function removeDisk(node, address) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--removedisk;' + address, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); +} + +/** + * Remove zFCP device + * + * @param node Node where disk is attached + * @param address Virtual address of zFCP device + * @param wwpn World wide port name of zFCP device + * @param lun Logical unit number of zFCP device + */ +function removeZfcp(node, address, wwpn, lun) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--removezfcp;' + address + ';' + wwpn + ';' + lun, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); +} + +/** + * Remove NIC + * + * @param node Node where NIC is attached + * @param address Virtual address of NIC + */ +function removeNic(node, nic) { + var args = nic.split('.'); + var address = args[0]; + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--removenic;' + address, + msg : node + }, + + success : updateZNodeStatus + }); + + // Increment node process + incrementNodeProcess(node); + + // Show loader + $('#' + node + 'StatusBarLoader').show(); + $('#' + node + 'StatusBar').show(); +} + +/** + * Set a cookie for the network names of a given node + * + * @param data Data from HTTP request + */ +function setNetworkCookies(data) { + if (data.rsp.length) { + var node = data.msg; + var networks = data.rsp[0].split(node + ': '); + + // Set cookie to expire in 60 minutes + var exDate = new Date(); + exDate.setTime(exDate.getTime() + (60 * 60 * 1000)); + $.cookie(node + 'networks', networks, { expires: exDate }); + } +} + +/** + * Get contents of each disk pool + * + * @param data HTTP request data + */ +function getDiskPool(data) { + if (data.rsp.length && data.rsp[0].indexOf("Failed") == -1) { + var hcp = data.msg; + var pools = data.rsp[0].split(hcp + ': '); + + // Get contents of each disk pool + for ( var i in pools) { + if (pools[i]) { + pools[i] = jQuery.trim(pools[i]); + + // Get used space + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcp, + args : '--diskpool;' + pools[i] + ';used', + msg : 'hcp=' + hcp + ';pool=' + pools[i] + ';stat=used' + }, + + success : loadDiskPoolTable + }); + + // Get free space + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcp, + args : '--diskpool;' + pools[i] + ';free', + msg : 'hcp=' + hcp + ';pool=' + pools[i] + ';stat=free' + }, + + success : loadDiskPoolTable + }); + } // End of if + } // End of for + } +} + +/** + * Get contents of each zFCP pool + * + * @param data HTTP request data + */ +function getZfcpPool(data) { + if (data.rsp.length && data.rsp[0].indexOf("Failed") == -1) { + var hcp = data.msg; + var pools = data.rsp[0].split(hcp + ': '); + + // Get contents of each disk pool + for ( var i in pools) { + if (pools[i]) { + pools[i] = jQuery.trim(pools[i]); + + // Query used and free space + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcp, + args : '--zfcppool;' + pools[i] + ';all', + msg : 'hcp=' + hcp + ';pool=' + pools[i] + }, + + success : loadZfcpPoolTable + }); + } // End of if + } // End of for + } else { + // Load empty table + loadZfcpPoolTable(null); + } +} + +/** + * Get details of each network + * + * @param data HTTP request data + */ +function getNetwork(data) { + if (data.rsp.length && data.rsp[0].indexOf("Failed") == -1) { + var hcp = data.msg; + var networks = data.rsp[0].split(hcp + ': '); + + // Loop through each network + for ( var i = 1; i < networks.length; i++) { + var args = networks[i].split(' '); + var type = args[0]; + var name = args[2]; + + // Get network details + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcp, + args : '--getnetwork;' + name, + msg : 'hcp=' + hcp + ';type=' + type + ';network=' + name + }, + + success : loadNetworkTable + }); + } // End of for + } // End of if +} + +/** + * Load disk pool contents into a table + * + * @param data HTTP request data + */ +function loadDiskPoolTable(data) { + // Remove loader + var panelId = 'zvmDiskResource'; + $('#' + panelId).find('img[src="images/loader.gif"]').remove(); + + // Do not continue if the call failed + if (!data.rsp.length && data.rsp[0].indexOf("Failed") > 0) { + return; + } + + var args = data.msg.split(';'); + var hcp = args[0].replace('hcp=', ''); + var pool = args[1].replace('pool=', ''); + var stat = args[2].replace('stat=', ''); + var tmp = data.rsp[0].split(hcp + ': '); + + // Resource tab ID + var info = $('#' + panelId).find('.ui-state-highlight'); + // If there is no info bar + if (!info.length) { + // Create info bar + info = createInfoBar('Below are disks that are defined in the EXTENT CONTROL file.'); + $('#' + panelId).append(info); + } + + // Get datatable + var tableId = 'zDiskDataTable'; + var dTable = getDiskDataTable(); + if (!dTable) { + // Create a datatable + var table = new DataTable(tableId); + // Resource headers: volume ID, device type, start address, and size + table.init( [ '', 'zHCP', 'Pool', 'Status', 'Region', 'Device type', 'Starting address', 'Size' ]); + + // Append datatable to panel + $('#' + panelId).append(table.object()); + + // Turn into datatable + dTable = $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + setDiskDataTable(dTable); + } + + // Skip index 0 and 1 because it contains nothing + for ( var i = 2; i < tmp.length; i++) { + tmp[i] = jQuery.trim(tmp[i]); + var diskAttrs = tmp[i].split(' '); + dTable.fnAddData( [ '', hcp, pool, stat, diskAttrs[0], diskAttrs[1], diskAttrs[2], diskAttrs[3] ]); + } + + // Create actions menu + if (!$('#zvmResourceActions').length) { + // Empty filter area + $('#' + tableId + '_length').empty(); + + // Add disk to pool + var addLnk = $('Add'); + addLnk.bind('click', function(event){ + openAddDisk2PoolDialog(); + }); + + // Delete disk from pool + var removeLnk = $('Remove'); + removeLnk.bind('click', function(event){ + var disks = getNodesChecked(tableId); + openRemoveDiskFromPoolDialog(disks); + }); + + // Refresh table + var refreshLnk = $('Refresh'); + refreshLnk.bind('click', function(event){ + $('#zvmDiskResource').empty().append(createLoader('')); + setDiskDataTable(''); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Query the disk pools for each + for (var i in hcps) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--diskpoolnames', + msg : hcps[i] + }, + + success : getDiskPool + }); + } + }); + + // Add ECKD to system + var addEckdLnk = $('Add ECKD'); + addEckdLnk.bind('click', function(event){ + openAddEckd2SystemDialog(hcp); + }); + + // Add Page or Spool + var addPageSpoolLnk = $('Add page/spool') + addPageSpoolLnk.bind('click', function(event){ + openAddPageSpoolDialog(hcp); + }); + + // Indicate disk is to be shared with various users + var shareLnk = $('Share disk'); + shareLnk.bind('click', function(event){ + var disks = getNodesChecked(tableId); + openShareDiskDialog(disks); + }); + + // Advanced menu + var advancedLnk = 'Advanced'; + var advancedMenu = createMenu([addEckdLnk, addPageSpoolLnk, shareLnk]); + + // Create action bar + var actionBar = $('
        ').css("width", "450px"); + + // Create an action menu + var actionsMenu = createMenu([addLnk, removeLnk, refreshLnk, [advancedLnk, advancedMenu]]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_length').prepend(menuDiv); + $('#' + tableId + '_length').css({ + 'padding': '0px', + 'width': '500px' + }); + $('#' + tableId + '_filter').css('padding', '10px'); + menuDiv.append(actionBar); + } + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); +} + +/** + * Load zFCP pool contents into a table + * + * @param data HTTP request data + */ +function loadZfcpPoolTable(data) { + // Delete loader + var panelId = 'zfcpResource'; + $('#' + panelId).find('img[src="images/loader.gif"]').remove(); + + // Do not continue if the call failed + if (!data.rsp.length && data.rsp[0].indexOf("Failed") > 0) { + return; + } + + var args, hcp, pool, tmp; + args = data.msg.split(';'); + hcp = args[0].replace('hcp=', ''); + pool = args[1].replace('pool=', ''); + tmp = data.rsp[0].split(hcp + ': '); + + // Resource tab ID + var info = $('#' + panelId).find('.ui-state-highlight'); + // If there is no info bar, create info bar + if (!info.length) { + info = createInfoBar('Below are devices that are defined internally in the zFCP pools.'); + $('#' + panelId).append(info); + } + + // Get datatable + var tableId = 'zFcpDataTable'; + var dTable = getZfcpDataTable(); + if (!dTable) { + // Create a datatable + var table = new DataTable(tableId); + // Resource headers: status, WWPN, LUN, size, owner, channel, tag + table.init( [ '', 'zHCP', 'Pool', 'Status', 'Port name', 'Unit number', 'Size', 'Range', 'Owner', 'Channel', 'Tag' ]); + + // Append datatable to panel + $('#' + panelId).append(table.object()); + + // Turn into datatable + dTable = $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + setZfcpDataTable(dTable); + } + + if (data) { + // Skip index 0 and 1 because it contains nothing + var key = ""; + for ( var i = 2; i < tmp.length; i++) { + tmp[i] = jQuery.trim(tmp[i]); + var diskAttrs = tmp[i].split(','); + var key = hcp + '-' + pool + '-' + diskAttrs[2]; + dTable.fnAddData( [ '', hcp, pool, diskAttrs[0], diskAttrs[1], diskAttrs[2], diskAttrs[3], diskAttrs[4], diskAttrs[5], diskAttrs[6], diskAttrs[7] ]); + } + } + + // Create actions menu + if (!$('#zFcpResourceActions').length) { + // Empty filter area + $('#' + tableId + '_length').empty(); + + // Add disk to pool + var addLnk = $('Add'); + addLnk.bind('click', function(event){ + openAddZfcp2PoolDialog(); + }); + + // Delete disk from pool + var removeLnk = $('Remove'); + removeLnk.bind('click', function(event){ + var disks = getNodesChecked(tableId); + openRemoveZfcpFromPoolDialog(disks); + }); + + // Refresh table + var refreshLnk = $('Refresh'); + refreshLnk.bind('click', function(event){ + $('#zfcpResource').empty().append(createLoader('')); + setZfcpDataTable(''); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Query the disk pools for each + for (var i in hcps) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--zfcppoolnames', + msg : hcps[i] + }, + + success : getZfcpPool + }); + } + }); + + // Add SCSI to system + var addScsiLnk = $('Add SCSI'); + addScsiLnk.bind('click', function(event){ + openAddScsi2SystemDialog(hcp); + }); + + // Remove SCSI + var removeScsiLnk = $('Remove SCSI'); + removeScsiLnk.bind('click', function(event){ + openRemoveScsiDialog(hcp); + }); + + // Advanced menu + var advancedLnk = 'Advanced'; + var advancedMenu = createMenu([addScsiLnk, removeScsiLnk]); + + // Create action bar + var actionBar = $('
        ').css("width", "450px"); + + // Create an action menu + var actionsMenu = createMenu([addLnk, removeLnk, refreshLnk, [advancedLnk, advancedMenu]]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_length').prepend(menuDiv); + $('#' + tableId + '_length').css({ + 'padding': '0px', + 'width': '500px' + }); + $('#' + tableId + '_filter').css('padding', '10px'); + menuDiv.append(actionBar); + } + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); +} + +/** + * Open dialog to remove disk from pool + * + * @param disks2remove Disks selected in table + */ +function openRemoveDiskFromPoolDialog(disks2remove) { + // Create form to delete disk from pool + var dialogId = 'zvmDeleteDiskFromPool'; + var deleteDiskForm = $('
        '); + + // Create info bar + var info = createInfoBar('Remove a disk from a disk pool defined in the EXTENT CONTROL.'); + deleteDiskForm.append(info); + var action = $('
        '); + var actionSelect = $(''); + action.append(actionSelect); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + + // Set region input based on those selected on table (if any) + var region = $('
        '); + var group = $('
        '); + deleteDiskForm.append(action, hcp, region, group); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Append options for hardware control points + for (var i in hcps) { + hcpSelect.append($('')); + } + + actionSelect.change(function() { + if ($(this).val() == '1' || $(this).val() == '3') { + region.show(); + group.hide(); + } else if ($(this).val() == '2') { + region.show(); + group.show(); + } else if ($(this).val() == '7') { + region.val('FOOBAR'); + region.hide(); + group.show(); + } + }); + + // Open dialog to delete disk + deleteDiskForm.dialog({ + title:'Delete disk from pool', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var action = $(this).find('select[name=action]').val(); + var hcp = $(this).find('select[name=hcp]').val(); + var region = $(this).find('input[name=region]').val(); + var group = $(this).find('input[name=group]').val(); + + // If inputs are not complete, show warning message + if (!action || !hcp) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + var args; + if (action == '2' || action == '7') + args = region + ';' + group; + else + args = group; + + // Remove disk from pool + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : hcp, + args : '--removediskfrompool;' + action + ';' + args, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Open dialog to add disk to pool + */ +function openAddDisk2PoolDialog() { + // Create form to add disk to pool + var dialogId = 'zvmAddDisk2Pool'; + var addDiskForm = $('
        '); + // Create info bar + var info = createInfoBar('Add a disk to a disk pool defined in the EXTENT CONTROL. The disk has to already be attached to SYSTEM.'); + addDiskForm.append(info); + var action = $('
        '); + var actionSelect = $(''); + action.append(actionSelect); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + var region = $('
        '); + var volume = $('
        '); + var group = $('
        '); + addDiskForm.append(action, hcp, region, volume, group); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Append options for hardware control points + for (var i in hcps) { + hcpSelect.append($('')); + } + + actionSelect.change(function() { + if ($(this).val() == '4') { + volume.show(); + } else if ($(this).val() == '5') { + volume.hide(); + } + }); + + // Open dialog to add disk + addDiskForm.dialog({ + title:'Add disk to pool', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + // Get inputs + var action = $(this).find('select[name=action]').val(); + var hcp = $(this).find('select[name=hcp]').val(); + var region = $(this).find('input[name=region]').val(); + var volume = $(this).find('input[name=volume]').val(); + var group = $(this).find('input[name=group]').val(); + + // If inputs are not complete, show warning message + if (!action || !hcp || !region || !group) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + var args; + if (action == '4') + args = region + ';' + volume + ';' + group; + else + args = region + ';' + group; + + // Add disk to pool + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : hcp, + args : '--adddisk2pool;' + action + ';' + args, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Open dialog to remove zFCP from pool + * + * @param devices2remove Comman separated devices selected in table + */ +function openRemoveZfcpFromPoolDialog(devices2remove) { + // Create form to delete device from pool + var dialogId = 'zvmDeleteZfcpFromPool'; + var deleteDiskForm = $('
        '); + + // Verify disks are in the same zFCP pool + var devices = devices2remove.split(','); + var tmp, tgtPool, tgtHcp; + var tgtUnitNo = ""; + for (var i in devices) { + tmp = devices[i].split('-'); + + if (tgtPool && tmp[1] != tgtPool) { + openDialog("warn", "Please select devices in the same zFCP"); + return; + } else { + tgtPool = tmp[1]; + } + + tgtHcp = tmp[0]; // Assume it is just one zHCP. Otherwise, this cannot be done on multiple zHCPs. + tgtUnitNo += tmp[2] + ","; + } + + // Strip out last comma + tgtUnitNo = tgtUnitNo.slice(0, -1); + + // Create info bar + var info = createInfoBar('Remove a zFCP device that is defined in a zFCP pool.'); + deleteDiskForm.append(info); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + + var pool = $('
        '); + var unitNo = $('
        '); + deleteDiskForm.append(hcp, pool, unitNo); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) { + hcps = $.cookie('hcp').split(','); + } else { + hcps.push($.cookie('hcp')); + } + + // Append options for hardware control points + for (var i in hcps) { + hcpSelect.append($('')); + } + hcpSelect.val(tgtHcp); + + // Open dialog to delete device + deleteDiskForm.dialog({ + title:'Delete device from pool', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Remove any warning messages + $(this).find('.ui-state-error').remove(); + + var hcp = $(this).find('select[name=hcp]').val(); + var pool = $(this).find('input[name=zfcpPool]').val(); + var unitNo = $(this).find('input[name=unitNo]').val(); + + // If inputs are not complete, show warning message + if (!hcp || !pool || !unitNo) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : hcp, + args : '--removezfcpfrompool;' + pool + ';' + unitNo, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Open dialog to add zFCP to pool + */ +function openAddZfcp2PoolDialog() { + // Create form to add disk to pool + var dialogId = 'zvmAddDisk2Pool'; + var addDiskForm = $('
        '); + var info = createInfoBar('Add a device to a zFCP pool defined in xCAT.'); + addDiskForm.append(info); + + var hcp = $('
        '); + var hcpSelect = $(''); + hcp.append(hcpSelect); + + var pool = $('
        '); + var status = $('
        '); + var portName = $('
        '); + var unitNo = $('
        '); + var size = $('
        '); + var range = $('
        '); + var owner = $('
        '); + addDiskForm.append(hcp, pool, status, portName, unitNo, size, range, owner); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) { + hcps = $.cookie('hcp').split(','); + } else { + hcps.push($.cookie('hcp')); + } + + hcpSelect.append($('')); + for (var i in hcps) { + hcpSelect.append($('')); + } + + // Open dialog to add disk + addDiskForm.dialog({ + title:'Add device to pool', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 500, + buttons: { + "Ok": function(){ + // Delete any warning messages + $(this).find('.ui-state-error').remove(); + + var tgtHcp = $(this).find('select[name=hcp]').val(); + var tgtPool = $(this).find('input[name=zfcpPool]').val(); + var tgtStatus = $(this).find('select[name=zfcpStatus]').val(); + var tgtPortName = $(this).find('input[name=zfcpPortName]').val(); + var tgtUnitNo = $(this).find('input[name=zfcpUnitNo]').val(); + var tgtSize = $(this).find('input[name=zfcpSize]').val(); + var tgtRange = $(this).find('input[name=zfcpRange]').val(); + + // Device owner is optional + var tgtOwner = ""; + if ($(this).find('input[name=zfcpOwner]').val()) { + tgtOwner = $(this).find('input[name=zfcpOwner]').val(); + } + + // If inputs are not complete, show warning message + if (!tgtHcp || !tgtPool || !tgtStatus || !tgtPortName || !tgtUnitNo || !tgtSize) { + var warn = createWarnBar('Please provide a value for each missing field.'); + warn.prependTo($(this)); + } else { + // Change dialog buttons + $(this).dialog('option', 'buttons', { + 'Close': function() {$(this).dialog("close");} + }); + + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : tgtHcp, + args : '--addzfcp2pool|' + tgtPool + '|' + tgtStatus + '|"' + tgtPortName + '"|' + tgtUnitNo + '|' + tgtSize + "| " + tgtRange + '|' + tgtOwner, + msg : dialogId + }, + + success : updateResourceDialog + }); + } + }, + "Cancel": function() { + $(this).dialog( "close" ); + } + } + }); +} + +/** + * Update resource dialog + * + * @param data HTTP request data + */ +function updateResourceDialog(data) { + var dialogId = data.msg; + var infoMsg; + + // Create info message + if (jQuery.isArray(data.rsp)) { + infoMsg = ''; + for (var i in data.rsp) { + infoMsg += data.rsp[i] + '
        '; + } + } else { + infoMsg = data.rsp; + } + + // Create info bar with close button + var infoBar = $('
        ').css('margin', '5px 0px'); + var icon = $('').css({ + 'display': 'inline-block', + 'margin': '10px 5px' + }); + + // Create close button to close info bar + var close = $('').css({ + 'display': 'inline-block', + 'float': 'right' + }).click(function() { + $(this).parent().remove(); + }); + + var msg = $('
        ' + infoMsg + '
        ').css({ + 'display': 'inline-block', + 'width': '90%' + }); + + infoBar.append(icon, msg, close); + infoBar.prependTo($('#' + dialogId)); +} + +/** + * Select all checkboxes in the datatable + * + * @param event Event on element + * @param obj Object triggering event + */ +function selectAllDisk(event, obj) { + // This will ascend from + var tableObj = obj.parents('.datatable'); + var status = obj.attr('checked'); + tableObj.find(' :checkbox').attr('checked', status); + + // Handle datatable scroll + tableObj = obj.parents('.dataTables_scroll'); + if (tableObj.length) { + tableObj.find(' :checkbox').attr('checked', status); + } + + event.stopPropagation(); +} + +/** + * Load network details into a table + * + * @param data HTTP request data + */ +function loadNetworkTable(data) { + // Remove loader + var panelId = 'zvmNetworkResource'; + $('#' + panelId).find('img[src="images/loader.gif"]').remove(); + + var args = data.msg.split(';'); + var hcp = args[0].replace('hcp=', ''); + var type = args[1].replace('type=', ''); + var name = args[2].replace('network=', ''); + var tmp = data.rsp[0].split(hcp + ': '); + + // Resource tab ID + var info = $('#' + panelId).find('.ui-state-highlight'); + // If there is no info bar + if (!info.length) { + // Create info bar + info = createInfoBar('Below are LANs/VSWITCHes available to use.'); + $('#' + panelId).append(info); + } + + // Get datatable + var dTable = getNetworkDataTable(); + if (!dTable) { + // Create table + var tableId = 'zNetworkDataTable'; + var table = new DataTable(tableId); + table.init( [ '', 'HCP', 'Type', 'Name', 'Details' ]); + + // Append datatable to tab + $('#' + panelId).append(table.object()); + + // Turn into datatable + dTable = $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + setNetworkDataTable(dTable); + + // Set the column width + var cols = table.object().find('thead tr th'); + cols.eq(0).css('width', '20px'); // HCP column + cols.eq(1).css('width', '20px'); // Type column + cols.eq(2).css('width', '20px'); // Name column + cols.eq(3).css({'width': '600px'}); // Details column + } + + // Skip index 0 because it contains nothing + var details = '
        ';
        +    for ( var i = 1; i < tmp.length; i++) {
        +        details += tmp[i];
        +    }
        +    details += '
        '; + + dTable.fnAddData([ '', '
        ' + hcp + '
        ', '
        ' + type + '
        ', '
        ' + name + '
        ', details ]); + + // Create actions menu + if (!$('#networkResourceActions').length) { + // Empty filter area + $('#' + tableId + '_length').empty(); + + // Add Vswitch/Vlan + var addLnk = $('Add'); + addLnk.bind('click', function(event){ + openAddVswitchVlanDialog(); + }); + + // Remove Vswitch/Vlan + var removeLnk = $('Remove'); + removeLnk.bind('click', function(event){ + var networkList = getNodesChecked(tableId).split(','); + if (networkList) { + openRemoveVswitchVlanDialog(networkList); + } + }); + + // Refresh table + var refreshLnk = $('Refresh'); + refreshLnk.bind('click', function(event){ + $('#zvmNetworkResource').empty().append(createLoader('')); + setNetworkDataTable(''); + + // Create a array for hardware control points + var hcps = new Array(); + if ($.cookie('hcp').indexOf(',') > -1) + hcps = $.cookie('hcp').split(','); + else + hcps.push($.cookie('hcp')); + + // Query networks + for (var i in hcps) { + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : hcps[i], + args : '--getnetworknames', + msg : hcps[i] + }, + + success : getNetwork + }); + } + }); + + // Create action bar + var actionBar = $('
        ').css("width", "450px"); + + // Create an action menu + var actionsMenu = createMenu([addLnk, removeLnk, refreshLnk]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_length').prepend(menuDiv); + $('#' + tableId + '_length').css({ + 'padding': '0px', + 'width': '500px' + }); + $('#' + tableId + '_filter').css('padding', '10px'); + menuDiv.append(actionBar); + } + + // Resize accordion + $('#zvmResourceAccordion').accordion('resize'); +} + +/** + * Connect a NIC to a Guest LAN + * + * @param data Data from HTTP request + */ +function connect2GuestLan(data) { + var rsp = data.rsp; + var args = data.msg.split(';'); + var node = args[0].replace('node=', ''); + var address = args[1].replace('addr=', ''); + var lanName = args[2].replace('lan=', ''); + var lanOwner = args[3].replace('owner=', ''); + + // Write ajax response to status bar + var prg = writeRsp(rsp, node + ': '); + $('#' + node + 'StatusBar').find('div').append(prg); + + // Connect NIC to Guest LAN + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--connectnic2guestlan;' + address + ';' + lanName + ';' + + lanOwner, + msg : node + }, + + success : updateZNodeStatus + }); +} + +/** + * Connect a NIC to a VSwitch + * + * @param data Data from HTTP request + */ +function connect2VSwitch(data) { + var rsp = data.rsp; + var args = data.msg.split(';'); + var node = args[0].replace('node=', ''); + var address = args[1].replace('addr=', ''); + var vswitchName = args[2].replace('vsw=', ''); + + // Write ajax response to status bar + var prg = writeRsp(rsp, node + ': '); + $('#' + node + 'StatusBar').find('div').append(prg); + + // Connect NIC to VSwitch + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'chvm', + tgt : node, + args : '--connectnic2vswitch;' + address + ';' + vswitchName, + msg : node + }, + + success : updateZNodeStatus + }); +} + +/** + * Create provision existing node division + * + * @param inst Provision tab instance + * @return Provision existing node division + */ +function createZProvisionExisting(inst) { + // Create provision existing and hide it + var provExisting = $('
        ').hide(); + + var vmFS = $('
        '); + var vmLegend = $('Virtual Machine'); + vmFS.append(vmLegend); + provExisting.append(vmFS); + + var vmAttr = $('
        '); + vmFS.append($('
        ')); + vmFS.append(vmAttr); + + var osFS = $('
        '); + var osLegend = $('Operating System'); + osFS.append(osLegend); + provExisting.append(osFS); + + var osAttr = $('
        '); + osFS.append($('
        ')); + osFS.append(osAttr); + + // Create group input + var group = $('
        '); + var groupLabel = $(''); + group.append(groupLabel); + + // Turn on auto complete for group + var groupNames = $.cookie('groups'); + if (groupNames) { + // Split group names into an array + var tmp = groupNames.split(','); + + // Create drop down for groups + var groupSelect = $(''); + groupSelect.append(''); + for (var i in tmp) { + // Add group into drop down + var opt = $(''); + groupSelect.append(opt); + } + group.append(groupSelect); + + // Create node datatable + groupSelect.change(function(){ + // Get group selected + var thisGroup = $(this).val(); + // If a valid group is selected + if (thisGroup) { + createNodesDatatable(thisGroup, 'zNodesDatatableDIV' + inst); + } + }); + } else { + // If no groups are cookied + var groupInput = $(''); + group.append(groupInput); + } + vmAttr.append(group); + + // Create node input + var node = $('
        '); + var nodeLabel = $(''); + var nodeDatatable = $('

        Select a group to view its nodes

        '); + node.append(nodeLabel); + node.append(nodeDatatable); + vmAttr.append(node); + + // Create operating system image input + var os = $('
        '); + var osLabel = $(''); + var osSelect = $(''); + osSelect.append($('')); + + var imageNames = $.cookie('imagenames').split(','); + if (imageNames) { + imageNames.sort(); + for (var i in imageNames) { + osSelect.append($('')); + } + } + os.append(osLabel); + os.append(osSelect); + osAttr.append(os); + + // Create boot method drop down + var bootMethod = $('
        '); + var methoddLabel = $(''); + var methodSelect = $(''); + methodSelect.append('' + + '' + + '' + + '' + + '' + ); + bootMethod.append(methoddLabel); + bootMethod.append(methodSelect); + osAttr.append(bootMethod); + + // Generate tooltips + provExisting.find('div input[title]').tooltip({ + position: "center right", + offset: [-2, 10], + effect: "fade", + opacity: 0.7, + predelay: 800, + events: { + def: "mouseover,mouseout", + input: "mouseover,mouseout", + widget: "focus mouseover,blur mouseout", + tooltip: "mouseover,mouseout" + } + }); + + /** + * Provision existing + */ + var provisionBtn = createButton('Provision'); + provisionBtn.bind('click', function(event) { + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + var ready = true; + var errMsg = ''; + + // Get provision tab ID + var thisTabId = $(this).parent().parent().parent().attr('id'); + // Get provision tab instance + var inst = thisTabId.replace('zvmProvisionTab', ''); + + // Get nodes that were checked + var dTableId = 'zNodesDatatable' + inst; + var tgts = getNodesChecked(dTableId); + if (!tgts) { + errMsg += 'You need to select a node.
        '; + ready = false; + } + + // Check operating system image + var os = $('#' + thisTabId + ' select[name=os]:visible'); + if (!os.val()) { + errMsg += 'You need to select a operating system image.'; + os.css('border', 'solid #FF0000 1px'); + ready = false; + } else { + os.css('border', 'solid #BDBDBD 1px'); + } + + // If all inputs are valid, ready to provision + if (ready) { + // Disable provision button + $(this).attr('disabled', 'true'); + + // Show loader + $('#zProvisionStatBar' + inst).show(); + $('#zProvisionLoader' + inst).show(); + + // Disable all inputs + var inputs = $('#' + thisTabId + ' input:visible'); + inputs.attr('disabled', 'disabled'); + + // Disable all selects + var selects = $('#' + thisTabId + ' select'); + selects.attr('disabled', 'disabled'); + + // Get operating system image + var osImage = $('#' + thisTabId + ' select[name=os]:visible').val(); + var tmp = osImage.split('-'); + var os = tmp[0]; + var arch = tmp[1]; + var profile = tmp[3]; + + /** + * (1) Set operating system + */ + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeadd', + tgt : '', + args : tgts + ';noderes.netboot=zvm;nodetype.os=' + os + ';nodetype.arch=' + arch + ';nodetype.profile=' + profile, + msg : 'cmd=nodeadd;out=' + inst + }, + + success : updateZProvisionExistingStatus + }); + } else { + // Show warning message + var warn = createWarnBar(errMsg); + warn.prependTo($(this).parent().parent()); + } + }); + provExisting.append(provisionBtn); + + return provExisting; +} + +/** + * Create provision new node division + * + * @param inst Provision tab instance + * @return Provision new node division + */ +function createZProvisionNew(inst) { + // Create provision new node division + var provNew = $('
        '); + + // Create VM fieldset + var vmFS = $('
        '); + var vmLegend = $('Virtual Machine'); + vmFS.append(vmLegend); + provNew.append(vmFS); + + var vmAttr = $('
        '); + vmFS.append($('
        ')); + vmFS.append(vmAttr); + + // Create OS fieldset + var osFS = $('
        '); + var osLegend = $('Operating System'); + osFS.append(osLegend); + provNew.append(osFS); + + // Create hardware fieldset + var hwFS = $('
        '); + var hwLegend = $('Hardware'); + hwFS.append(hwLegend); + provNew.append(hwFS); + + var hwAttr = $('
        '); + hwFS.append($('
        ')); + hwFS.append(hwAttr); + + var osAttr = $('
        '); + osFS.append($('
        ')); + osFS.append(osAttr); + + // Create group input + var group = $('
        '); + var groupLabel = $(''); + var groupInput = $(''); + // Get groups on-focus + groupInput.one('focus', function(){ + var groupNames = $.cookie('groups'); + if (groupNames) { + // Turn on auto complete + $(this).autocomplete({ + source: groupNames.split(',') + }); + } + }); + group.append(groupLabel); + group.append(groupInput); + vmAttr.append(group); + + // Create node input + var nodeName = $('
        '); + var nodeLabel = $(''); + var nodeInput = $(''); + nodeName.append(nodeLabel); + nodeName.append(nodeInput); + vmAttr.append(nodeName); + + // Create user ID input + var userId = $('
        '); + vmAttr.append(userId); + + // Create hardware control point input + var hcpDiv = $('
        '); + var hcpLabel = $(''); + var hcpInput = $(''); + hcpInput.blur(function() { + if ($(this).val()) { + var args = $(this).val().split('.'); + if (!$.cookie(args[0] + 'diskpools')) { + // Get disk pools + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : args[0], + args : '--diskpoolnames', + msg : args[0] + }, + + success : setDiskPoolCookies + }); + } + + if (!$.cookie(args[0] + 'zfcppools')) { + // Get zFCP pools + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'lsvm', + tgt : args[0], + args : '--zfcppoolnames', + msg : args[0] + }, + + success : setZfcpPoolCookies + }); + } + } + }); + hcpDiv.append(hcpLabel); + hcpDiv.append(hcpInput); + vmAttr.append(hcpDiv); + + // Create an advanced link to set IP address and hostname + var advancedLnk = $('
        '); + vmAttr.append(advancedLnk); + var advanced = $('
        ').hide(); + vmAttr.append(advanced); + + var ip = $('
        '); + advanced.append(ip); + var hostname = $('
        '); + advanced.append(hostname); + + // Show IP address and hostname inputs on-click + advancedLnk.click(function() { + advanced.toggle(); + }); + + // Create operating system image input + var os = $('
        '); + var osLabel = $(''); + var osSelect = $(''); + osSelect.append($('')); + + var imageNames = $.cookie('imagenames').split(','); + if (imageNames) { + imageNames.sort(); + for (var i in imageNames) { + osSelect.append($('')); + } + } + os.append(osLabel); + os.append(osSelect); + osAttr.append(os); + + // Create user entry input + var defaultChkbox = $('').click(function() { + // Remove any warning messages + $(this).parents('.form').find('.ui-state-error').remove(); + + // Get tab ID + var thisTabId = $(this).parents('.ui-tabs-panel').attr('id'); + + // Get objects for HCP, user ID, and OS + var userId = $('#' + thisTabId + ' input[name=userId]'); + var os = $('#' + thisTabId + ' select[name=os]'); + + // Get default user entry when clicked + if ($(this).attr('checked')) { + if (!os.val() || !userId.val()) { + // Show warning message + var warn = createWarnBar('Please specify the operating system and user ID before checking this box'); + warn.prependTo($(this).parents('.form')); + + // Highlight empty fields + jQuery.each([os, userId], function() { + if (!$(this).val()) { + $(this).css('border', 'solid #FF0000 1px'); + } + }); + } else { + // Un-highlight empty fields + jQuery.each([os, userId], function() { + $(this).css('border', 'solid #BDBDBD 1px'); + }); + + // Get profile name + var tmp = os.val().split('-'); + var profile = tmp[3]; + + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'getdefaultuserentry;' + profile, + msg : thisTabId + }, + + success:function(data) { + // Populate user entry + var tabId = data.msg; + var entry = new String(data.rsp); + var userId = $('#' + tabId + ' input[name=userId]').val(); + entry = entry.replace(new RegExp('LXUSR', 'g'), userId); + $('#' + tabId + ' textarea:visible').val(entry); + } + }); + } + } else { + $('#' + thisTabId + ' textarea:visible').val(''); + + // Un-highlight empty fields + jQuery.each([os, userId], function() { + $(this).css('border', 'solid #BDBDBD 1px'); + }); + } + }); + var userEntry = $('
        '); + userEntry.append($('').append(defaultChkbox, 'Use default')); + hwAttr.append(userEntry); + + // Create disk table + var diskDiv = $('
        '); + var diskLabel = $(''); + var diskTable = $('
        '); + var diskHeader = $(' Type Address Size Mode Pool Password '); + // Adjust header width + diskHeader.find('th').css( { + 'width' : '80px' + }); + diskHeader.find('th').eq(0).css( { + 'width' : '20px' + }); + var diskBody = $(''); + var diskFooter = $(''); + + /** + * Add disks + */ + var addDiskLink = $('Add disk'); + addDiskLink.bind('click', function(event) { + // Get list of disk pools + var thisTabId = $(this).parents('.tab').attr('id'); + var thisHcp = $('#' + thisTabId + ' input[name=hcp]').val(); + var definedPools = null; + if (thisHcp) { + // Get node without domain name + var temp = thisHcp.split('.'); + definedPools = $.cookie(temp[0] + 'diskpools').split(','); + } + + // Create a row + var diskRow = $(''); + + // Add remove button + var removeBtn = $(''); + var col = $('').append(removeBtn); + removeBtn.bind('click', function(event) { + diskRow.remove(); + }); + diskRow.append(col); + + // Create disk type drop down + var diskType = $(''); + var diskTypeSelect = $(''); + diskTypeSelect.append('' + + '' + ); + diskType.append(diskTypeSelect); + diskRow.append(diskType); + + // Create disk address input + var diskAddr = $(''); + diskRow.append(diskAddr); + + // Create disk size input + var diskSize = $(''); + diskRow.append(diskSize); + + // Create disk mode input + var diskMode = $(''); + var diskModeSelect = $(''); + diskModeSelect.append('' + + '' + + '' + + '' + + '' + + '' + + '' + ); + diskMode.append(diskModeSelect); + diskRow.append(diskMode); + + // Create disk pool drop down + var diskPool = $(''); + var diskPoolSelect = $(''); + for (var i in definedPools) { + diskPoolSelect.append(''); + } + diskPool.append(diskPoolSelect); + diskRow.append(diskPool); + + // Create disk password input + var diskPw = $(''); + diskRow.append(diskPw); + + diskBody.append(diskRow); + + // Generate tooltips + diskBody.find('td input[title]').tooltip({ + position: "top right", + offset: [-4, 4], + effect: "fade", + opacity: 0.7, + predelay: 800, + events: { + def: "mouseover,mouseout", + input: "mouseover,mouseout", + widget: "focus mouseover,blur mouseout", + tooltip: "mouseover,mouseout" + } + }); + }); + + // Create disk table + diskFooter.append(addDiskLink); + diskTable.append(diskHeader); + diskTable.append(diskBody); + diskTable.append(diskFooter); + + diskDiv.append(diskLabel); + diskDiv.append(diskTable); + hwAttr.append(diskDiv); + + // Create zFCP table + var zfcpDiv = $('
        '); + var zfcpLabel = $(''); + var zfcpTable = $('
        '); + var zfcpHeader = $(' Address Size Pool Tag Port Name Unit # LOADDEV'); + // Adjust header width + zfcpHeader.find('th').css( { + 'width' : '80px' + }); + zfcpHeader.find('th').eq(0).css( { + 'width' : '20px' + }); + var zfcpBody = $(''); + var zfcpFooter = $(''); + + /** + * Add zFCP devices + */ + var addZfcpLink = $('Add zFCP'); + addZfcpLink.bind('click', function(event) { + // Get list of disk pools + var thisTabId = $(this).parents('.tab').attr('id'); + var thisHcp = $('#' + thisTabId + ' input[name=hcp]').val(); + var definedPools = null; + if (thisHcp) { + // Get node without domain name + var temp = thisHcp.split('.'); + definedPools = $.cookie(temp[0] + 'zfcppools').split(','); + } + + // Create a row + var zfcpRow = $(''); + + // Add remove button + var removeBtn = $(''); + var col = $('').append(removeBtn); + removeBtn.bind('click', function(event) { + zfcpRow.remove(); + }); + zfcpRow.append(col); + + // Create disk address input + var zfcpAddr = $(''); + zfcpRow.append(zfcpAddr); + + // Create disk size input + var zfcpSize = $(''); + zfcpRow.append(zfcpSize); + + // Create zFCP pool drop down + var zfcpPool = $(''); + var zfcpPoolSelect = $(''); + for (var i in definedPools) { + zfcpPoolSelect.append(''); + } + zfcpPool.append(zfcpPoolSelect); + zfcpRow.append(zfcpPool); + + // Create disk tag + var zfcpTag = $(''); + zfcpRow.append(zfcpTag); + + // Create device port name + var zfcpPortName = $(''); + zfcpRow.append(zfcpPortName); + + // Create device unit number + var zfcpUnitNo = $(''); + zfcpRow.append(zfcpUnitNo); + + // Create LOADDEV checkbox + var zfcpLoaddev = $(''); + zfcpRow.append(zfcpLoaddev); + + zfcpBody.append(zfcpRow); + + // Generate tooltips + zfcpBody.find('td input[title]').tooltip({ + position: "top right", + offset: [-4, 4], + effect: "fade", + opacity: 0.7, + predelay: 800, + events: { + def: "mouseover,mouseout", + input: "mouseover,mouseout", + widget: "focus mouseover,blur mouseout", + tooltip: "mouseover,mouseout" + } + }); + }); + + zfcpFooter.append(addZfcpLink); + zfcpTable.append(zfcpHeader); + zfcpTable.append(zfcpBody); + zfcpTable.append(zfcpFooter); + + zfcpDiv.append(zfcpLabel); + zfcpDiv.append(zfcpTable); + hwAttr.append(zfcpDiv); + + // Generate tooltips + provNew.find('div input[title]').tooltip({ + position: "center right", + offset: [-2, 10], + effect: "fade", + opacity: 0.7, + predelay: 800, + events: { + def: "mouseover,mouseout", + input: "mouseover,mouseout", + widget: "focus mouseover,blur mouseout", + tooltip: "mouseover,mouseout" + } + }); + + /** + * Provision new + */ + var provisionBtn = createButton('Provision'); + provisionBtn.bind('click', function(event) { + // Remove any warning messages + $(this).parent().parent().find('.ui-state-error').remove(); + + var ready = true; + var errMsg = ''; + + // Get tab ID + var thisTabId = $(this).parents('.ui-tabs-panel').attr('id'); + // Get provision tab instance + var inst = thisTabId.replace('zvmProvisionTab', ''); + + // Check node name, userId, hardware control point, and group + // Check disks and zFCP devices + var inputs = $('#' + thisTabId + ' input:visible'); + for ( var i = 0; i < inputs.length; i++) { + // Do not check some inputs + if (!inputs.eq(i).val() + && inputs.eq(i).attr('type') != 'password' + && inputs.eq(i).attr('name') != 'zfcpTag' + && inputs.eq(i).attr('name') != 'zfcpPortName' + && inputs.eq(i).attr('name') != 'zfcpUnitNo') { + inputs.eq(i).css('border', 'solid #FF0000 1px'); + ready = false; + } else { + inputs.eq(i).css('border', 'solid #BDBDBD 1px'); + } + } + + var selects = $('#' + thisTabId + ' select:visible'); + for ( var i = 0; i < selects.length; i++) { + if (!selects.eq(i).val() && selects.eq(i).attr('name') != 'os') { + selects.eq(i).css('border', 'solid #FF0000 1px'); + ready = false; + } else { + selects.eq(i).css('border', 'solid #BDBDBD 1px'); + } + } + + // Check user entry + var thisUserEntry = $('#' + thisTabId + ' textarea:visible'); + thisUserEntry.val(thisUserEntry.val().toUpperCase()); + if (!thisUserEntry.val()) { + thisUserEntry.css('border', 'solid #FF0000 1px'); + ready = false; + } else { + thisUserEntry.css('border', 'solid #BDBDBD 1px'); + } + + // Show error message for missing inputs + if (!ready) { + errMsg = errMsg + 'Please provide a value for each missing field.
        '; + } + + // Check if user entry contains user ID + var thisUserId = $('#' + thisTabId + ' input[name=userId]:visible'); + var pos = thisUserEntry.val().indexOf('USER ' + thisUserId.val().toUpperCase()); + if (pos < 0) { + errMsg = errMsg + 'The directory entry does not contain the correct user ID.
        '; + ready = false; + } + + // If no operating system is specified, create only user entry + os = $('#' + thisTabId + ' select[name=os]:visible'); + + // Check number of disks + var diskRows = $('#' + thisTabId + ' table tr'); + // If an OS is given, disks are needed + if (os.val() && (diskRows.length < 1)) { + errMsg = errMsg + 'You need to add at some disks.
        '; + ready = false; + } + + // If inputs are valid, ready to provision + if (ready) { + if (!os.val()) { + // If no OS is given, create a virtual server + var msg = ''; + if (diskRows.length > 0) { + msg = 'Do you want to create a virtual server without an operating system?'; + } else { + // If no disks are given, create a virtual server (no disk) + msg = 'Do you want to create a virtual server without an operating system or disks?'; + } + + // Open dialog to confirm + var confirmDialog = $('

        ' + msg + '

        '); + confirmDialog.dialog({ + title:'Confirm', + modal: true, + close: function(){ + $(this).remove(); + }, + width: 400, + buttons: { + "Ok": function(){ + // Disable provision button + provisionBtn.attr('disabled', 'true'); + + // Show loader + $('#zProvisionStatBar' + inst).show(); + $('#zProvisionLoader' + inst).show(); + + // Disable add disk button + addDiskLink.attr('disabled', 'true'); + + // Disable close button on disk table + $('#' + thisTabId + ' table span').unbind('click'); + + // Disable all inputs + var inputs = $('#' + thisTabId + ' input'); + inputs.attr('disabled', 'disabled'); + + // Disable all selects + var selects = $('#' + thisTabId + ' select'); + selects.attr('disabled', 'disabled'); + + // Add a new line at the end of the user entry + var textarea = $('#' + thisTabId + ' textarea'); + var tmp = jQuery.trim(textarea.val()); + textarea.val(tmp + '\n'); + textarea.attr('readonly', 'readonly'); + textarea.css( { + 'background-color' : '#F2F2F2' + }); + + // Get node name + var node = $('#' + thisTabId + ' input[name=nodeName]').val(); + // Get userId + var userId = $('#' + thisTabId + ' input[name=userId]').val(); + // Get hardware control point + var hcp = $('#' + thisTabId + ' input[name=hcp]').val(); + // Get group + var group = $('#' + thisTabId + ' input[name=group]').val(); + // Get IP address and hostname + var ip = $('#' + thisTabId + ' input[name=ip]').val(); + var hostname = $('#' + thisTabId + ' input[name=hostname]').val(); + + // Generate arguments to sent + var args = node + ';zvm.hcp=' + hcp + + ';zvm.userid=' + userId + + ';nodehm.mgt=zvm' + + ';groups=' + group; + if (ip) + args += ';hosts.ip=' + ip; + + if (hostname) + args += ';hosts.hostnames=' + hostname; + + /** + * (1) Define node + */ + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeadd', + tgt : '', + args : args, + msg : 'cmd=nodeadd;out=' + inst + }, + + success : updateZProvisionNewStatus + }); + + $(this).dialog("close"); + }, + "Cancel": function() { + $(this).dialog("close"); + } + } + }); + } else { + /** + * Create a virtual server and install OS + */ + + // Disable provision button + $(this).attr('disabled', 'true'); + + // Show loader + $('#zProvisionStatBar' + inst).show(); + $('#zProvisionLoader' + inst).show(); + + // Disable add disk button + addDiskLink.attr('disabled', 'true'); + + // Disable close button on disk table + $('#' + thisTabId + ' table span').unbind('click'); + + // Disable all inputs + var inputs = $('#' + thisTabId + ' input'); + inputs.attr('disabled', 'disabled'); + inputs.css( { + 'background-color' : '#F2F2F2' + }); + + // Disable all selects + var selects = $('#' + thisTabId + ' select'); + selects.attr('disabled', 'disabled'); + selects.css( { + 'background-color' : '#F2F2F2' + }); + + // Add a new line at the end of the user entry + var textarea = $('#' + thisTabId + ' textarea'); + var tmp = jQuery.trim(textarea.val()); + textarea.val(tmp + '\n'); + textarea.attr('readonly', 'readonly'); + textarea.css( { + 'background-color' : '#F2F2F2' + }); + + // Get node name + var node = $('#' + thisTabId + ' input[name=nodeName]').val(); + // Get userId + var userId = $('#' + thisTabId + ' input[name=userId]').val(); + // Get hardware control point + var hcp = $('#' + thisTabId + ' input[name=hcp]').val(); + // Get group + var group = $('#' + thisTabId + ' input[name=group]').val(); + // Get IP address and hostname + var ip = $('#' + thisTabId + ' input[name=ip]').val(); + var hostname = $('#' + thisTabId + ' input[name=hostname]').val(); + + // Generate arguments to sent + var args = node + ';zvm.hcp=' + hcp + + ';zvm.userid=' + userId + + ';nodehm.mgt=zvm' + + ';groups=' + group; + if (ip) + args += ';hosts.ip=' + ip; + + if (hostname) + args += ';hosts.hostnames=' + hostname; + + /** + * (1) Define node + */ + $.ajax( { + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'nodeadd', + tgt : '', + args : args, + msg : 'cmd=nodeadd;out=' + inst + }, + + success : updateZProvisionNewStatus + }); + } + } else { + // Show warning message + var warn = createWarnBar(errMsg); + warn.prependTo($(this).parent().parent()); + } + }); + provNew.append(provisionBtn); + + return provNew; +} + +/** + * Load WWPNs + */ +function loadWwpns() { + if (!$.cookie('zvms')) { + return; + } + + // Retrieve WWPNs found on z/VM system + var zvms = $.cookie('zvms').split(','); + for (var i in zvms) { + args = zvms[i].split(':'); + zvm = args[0].toLowerCase(); + hcp = args[1]; + + if (!$.cookie(zvm + 'wwpns')) { + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'rinv', + tgt : zvm, + args : '--wwpn', + msg : zvm + }, + + success : function(data) { + setWwpnCookies(data); + } + }); + } + } +} + +/** + * Load zVMs into column (service page) + * + * @param col Table column where OS images will be placed + */ +function loadzVMs(col) { + // Get group names and description and append to group column + if (!$.cookie('zvms')) { + var infoBar = createInfoBar('No selectable z/VM available'); + col.append(infoBar); + return; + } + + var zNames = $.cookie('zvms').split(','); + + var radio, zBlock, args, zvm, hcp; + for (var i in zNames) { + args = zNames[i].split(':'); + zvm = args[0]; + hcp = args[1]; + + // Create block for each group + zBlock = $('
        ').css({ + 'border': '1px solid', + 'max-width': '200px', + 'margin': '5px auto', + 'padding': '5px', + 'display': 'block', + 'vertical-align': 'middle', + 'cursor': 'pointer', + 'white-space': 'normal' + }).click(function(){ + $(this).children('input:radio').attr('checked', 'checked'); + $(this).parents('td').find('div').attr('class', 'ui-state-default'); + $(this).attr('class', 'ui-state-active'); + }); + radio = $('').css('display', 'none'); + zBlock.append(radio, $('' + zvm + ' managed by ' + hcp + '')); + zBlock.children('span').css({ + 'display': 'block', + 'margin': '5px', + 'text-align': 'left' + }); + col.append(zBlock); + } +} + +/** + * Load groups into column + * + * @param col Table column where OS images will be placed + */ +function loadSrvGroups(col) { + // Get group names and description and append to group column + if (!$.cookie('srv_groups')) { + var infoBar = createInfoBar('No selectable group available'); + col.append(infoBar); + return; + } + + var groupNames = $.cookie('srv_groups').split(','); + + var groupBlock, radio, args, name, ip, hostname, desc; + for (var i in groupNames) { + args = groupNames[i].split(':'); + name = args[0]; + ip = args[1]; + hostname = args[2]; + desc = args[3]; + + // Create block for each group + groupBlock = $('
        ').css({ + 'border': '1px solid', + 'max-width': '200px', + 'margin': '5px auto', + 'padding': '5px', + 'display': 'block', + 'vertical-align': 'middle', + 'cursor': 'pointer', + 'white-space': 'normal' + }).click(function(){ + $(this).children('input:radio').attr('checked', 'checked'); + $(this).parents('td').find('div').attr('class', 'ui-state-default'); + $(this).attr('class', 'ui-state-active'); + }); + radio = $('').css('display', 'none'); + groupBlock.append(radio, $('' + name + ': ' + desc + '')); + groupBlock.children('span').css({ + 'display': 'block', + 'margin': '5px', + 'text-align': 'left' + }); + col.append(groupBlock); + } +} + +/** + * Load OS images into column + * + * @param col Table column where OS images will be placed + */ +function loadOSImages(col) { + // Get group names and description and append to group column + if (!$.cookie('srv_imagenames')) { + var infoBar = createInfoBar('No selectable image available'); + col.append(infoBar); + return; + } + + var imgNames = $.cookie('srv_imagenames').split(','); + + var imgBlock, radio, args, name, desc; + for (var i in imgNames) { + args = imgNames[i].split(':'); + name = args[0]; + desc = args[1]; + + // Create block for each image + imgBlock = $('
        ').css({ + 'border': '1px solid', + 'max-width': '200px', + 'margin': '5px auto', + 'padding': '5px', + 'display': 'block', + 'vertical-align': 'middle', + 'cursor': 'pointer', + 'white-space': 'normal' + }).click(function(){ + $(this).children('input:radio').attr('checked', 'checked'); + $(this).parents('td').find('div').attr('class', 'ui-state-default'); + $(this).attr('class', 'ui-state-active'); + }); + radio = $('').css('display', 'none'); + imgBlock.append(radio, $('' + name + ': ' + desc + '')); + imgBlock.children('span').css({ + 'display': 'block', + 'margin': '5px', + 'text-align': 'left' + }); + col.append(imgBlock); + } +} + +/** + * Set a cookie for zVM host names (service page) + * + * @param data Data from HTTP request + */ +function setzVMCookies(data) { + if (data.rsp[0].length) { + var zvms = new Array(); + var hosts = data.rsp[0].split("\n"); + for ( var i = 0; i < hosts.length; i++) { + if (hosts[i] != null && hosts[i] != "") { + zvms.push(hosts[i]); + } + } + + // Set cookie to expire in 60 minutes + var exDate = new Date(); + exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); + $.cookie('zvms', zvms, { expires: exDate }); + } +} + +/** + * Set a cookie for disk pool names of a given node + * + * @param data Data from HTTP request + */ +function setDiskPoolCookies(data) { + if (data.rsp[0].length) { + var node = data.msg; + var pools = data.rsp[0].split(node + ': '); + for (var i in pools) { + pools[i] = jQuery.trim(pools[i]); + } + + // Set cookie to expire in 60 minutes + var exDate = new Date(); + exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); + $.cookie(node + 'diskpools', pools, { expires: exDate }); + } +} + +/** + * Set a cookie for zFCP pool names of a given node + * + * @param data Data from HTTP request + */ +function setZfcpPoolCookies(data) { + if (data.rsp[0].length) { + var node = data.msg; + var pools = data.rsp[0].split(node + ': '); + for (var i in pools) { + pools[i] = jQuery.trim(pools[i]); + } + + // Set cookie to expire in 60 minutes + var exDate = new Date(); + exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); + $.cookie(node + 'zfcppools', pools, { expires: exDate }); + } +} + +/** + * Set a cookie for WWPNs of z/VM system + * + * @param data Data from HTTP request + */ +function setWwpnCookies(data) { + if (data.rsp[0].length) { + var zvm = data.msg; + var wwpns = data.rsp[0].split(zvm + ': '); + for (var i in wwpns) { + wwpns[i] = jQuery.trim(wwpns[i]); + } + + // Set cookie to expire in 60 minutes + var exDate = new Date(); + exDate.setTime(exDate.getTime() + (240 * 60 * 1000)); + $.cookie(zvm + 'wwpns', wwpns, { expires: exDate }); + } +} + +/** + * Create virtual machine (service page) + * + * @param tabId Tab ID + * @param group Group + * @param hcp Hardware control point + * @param img OS image + */ +function createzVM(tabId, group, hcp, img, owner) { + // Submit request to create VM + // webportal provzlinux [group] [hcp] [image] [owner] + var iframe = createIFrame('lib/srv_cmd.php?cmd=webportal&tgt=&args=provzlinux;' + group + ';' + hcp + ';' + img + ';' + owner + '&msg=&opts=flush'); + iframe.prependTo($('#' + tabId)); +} + +/** + * Query the profiles that exists + * + * @param panelId Panel ID + */ +function queryProfiles(panelId) { + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'tabdump', + tgt : '', + args : 'osimage', + msg : panelId + }, + + success : function(data) { + var panelId = data.msg; + setOSImageCookies(data); + configProfilePanel(panelId); + } + }); +} + +/** + * Panel to configure directory entries and disks for a profile + * + * @param panelId Panel ID + */ +function configProfilePanel(panelId) { + // Wipe panel clean + $('#' + panelId).empty(); + + // Add info bar + $('#' + panelId).append(createInfoBar('Create, edit, and delete profiles for the self-service portal. It is important to note the default z/VM user ID for any profile should be LXUSR.')); + + // Create table + var tableId = 'zvmProfileTable'; + var table = new DataTable(tableId); + table.init(['', 'Profile', 'Disk pool', 'Disk size', 'Directory entry']); + + // Insert profiles into table + var profiles = $.cookie('profiles').split(','); + profiles.push('default'); // Add default profile + for (var i in profiles) { + if (profiles[i]) { + // Columns are: profile, selectable, description, disk pool, disk size, and directory entry + var cols = new Array(profiles[i], '', '', ''); + + // Add remove button where id = user name + cols.unshift(''); + + // Add row + table.add(cols); + } + } + + // Append datatable to tab + $('#' + panelId).append(table.object()); + + // Turn into datatable + $('#' + tableId).dataTable({ + 'iDisplayLength': 50, + 'bLengthChange': false, + "bScrollCollapse": true, + "sScrollY": "400px", + "sScrollX": "110%", + "bAutoWidth": true, + "oLanguage": { + "oPaginate": { + "sNext": "", + "sPrevious": "" + } + } + }); + + // Create action bar + var actionBar = $('
        ').css("width", "450px"); + + // Create a profile + var createLnk = $('Create'); + createLnk.click(function() { + profileDialog(); + }); + + // Edit a profile + var editLnk = $('Edit'); + editLnk.click(function() { + var profiles = $('#' + tableId + ' input[type=checkbox]:checked'); + for (var i in profiles) { + var profile = profiles.eq(i).attr('name'); + if (profile) { + // Column order is: profile, selectable, disk pool, disk size, and directory entry + var cols = profiles.eq(i).parents('tr').find('td'); + var pool = cols.eq(2).text(); + var size = cols.eq(3).text(); + var entry = cols.eq(4).html().replace(new RegExp('
        ', 'g'), '\n'); + + editProfileDialog(profile, pool, size, entry); + } + } + }); + + // Delete a profile + var deleteLnk = $('Delete'); + deleteLnk.click(function() { + var profiles = getNodesChecked(tableId); + if (profiles) { + openDeleteProfileDialog(profiles); + } + }); + + // Refresh profiles table + var refreshLnk = $('Refresh'); + refreshLnk.click(function() { + queryProfiles(panelId); + }); + + // Create an action menu + var actionsMenu = createMenu([createLnk, editLnk, deleteLnk, refreshLnk]); + actionsMenu.superfish(); + actionsMenu.css('display', 'inline-block'); + actionBar.append(actionsMenu); + + // Set correct theme for action menu + actionsMenu.find('li').hover(function() { + setMenu2Theme($(this)); + }, function() { + setMenu2Normal($(this)); + }); + + // Create a division to hold actions menu + var menuDiv = $(''); + $('#' + tableId + '_wrapper').prepend(menuDiv); + menuDiv.append(actionBar); + $('#' + tableId + '_filter').appendTo(menuDiv); + + // Resize accordion + $('#' + tableId).parents('.ui-accordion').accordion('resize'); + + // Query directory entries and disk pool/size for each profile + for (var i in profiles) { + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'getdefaultuserentry;' + profiles[i], + msg : 'out=' + panelId + ';profile=' + profiles[i] + }, + + success: insertDirectoryEntry + }); + + $.ajax({ + url : 'lib/cmd.php', + dataType : 'json', + data : { + cmd : 'webrun', + tgt : '', + args : 'getzdiskinfo;' + profiles[i], + msg : 'out=' + panelId + ';profile=' + profiles[i] + }, + + success: insertDiskInfo + }); + } +} + +/** + * Insert the directory entry into the profile table + * + * @param data Data from HTTP request + */ +function insertDirectoryEntry(data) { + var tableId = 'zvmProfileTable'; + var args = data.msg.split(';'); + + var profile = args[1].replace('profile=', ''); + + // Do not continue if there is nothing + if (!data.rsp.length) + return; + + var entry = data.rsp[0].replace(new RegExp('\n', 'g'), '
        '); + + // Get the row containing the profile + var rowPos = findRow(profile, '#' + tableId, 1); + if (rowPos < 0) + return; + + // Update the directory entry column + var dTable = $('#' + tableId).dataTable(); + dTable.fnUpdate(entry, rowPos, 4, false); + + // Adjust table styling + $('#' + tableId + ' td:nth-child(5)').css({ + 'text-align': 'left' + }); + adjustColumnSize(tableId); +} + +/** + * Insert the disk info into the profile table + * + * @param data Data from HTTP request + */ +function insertDiskInfo(data) { + var tableId = 'zvmProfileTable'; + var args = data.msg.split(';'); + + var profile = args[1].replace('profile=', ''); + + // Do not continue if there is nothing + if (!data.rsp.length) + return; + + // Get the row containing the profile + var rowPos = findRow(profile, '#' + tableId, 1); + if (rowPos < 0) + return; + + // Update the disk info columns + var dTable = $('#' + tableId).dataTable(); + + var tmp = ""; + var pool = ""; + var eckdSize = 0; + var info = data.rsp[0].split('\n'); + for (var i in info) { + if (info[i].indexOf('diskpool') > -1) { + tmp = info[i].split('='); + pool = jQuery.trim(tmp[1]); + + dTable.fnUpdate(pool, rowPos, 2, false); + } if (info[i].indexOf('eckd_size') > -1) { + tmp = info[i].split('='); + eckdSize = jQuery.trim(tmp[1]); + + dTable.fnUpdate(eckdSize, rowPos, 3, false); + } + } + + // Adjust table styling + adjustColumnSize(tableId); +} + +/** + * Open profile dialog + */ +function profileDialog() { + // Create form to add profile + var dialogId = 'zvmCreateProfile'; + var profileForm = $('
        '); + + // Create info bar + var info = createInfoBar('Configure the default settings for a profile'); + profileForm.append(info); + + // Insert profiles into select + var profileSelect = $(''); + var profiles = $.cookie('profiles').split(','); + profiles.push('default'); // Add default profile + for (var i in profiles) { + if (profiles[i]) { + profileSelect.append($('')); + } + } + + profileForm.append($('
        ').append(profileSelect)); + profileForm.append('
        '); + profileForm.append('
        '); + profileForm.append('