]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/Utils.js
3 // avoid errors related to Accessible Rich Internet Applications
4 // (access for people with disabilities)
5 // TODO reenable after all components are upgraded
6 Ext
. enableAria
= false ;
7 Ext
. enableAriaButtons
= false ;
8 Ext
. enableAriaPanels
= false ;
10 // avoid errors when running without development tools
11 if (! Ext
. isDefined ( Ext
. global
. console
)) {
16 console
. log ( "Starting PVE Manager" );
18 Ext
. Ajax
. defaultHeaders
= {
19 'Accept' : 'application/json'
22 Ext
. define ( 'PVE.Utils' , { utilities
: {
24 // this singleton contains miscellaneous utilities
26 toolkit
: undefined , // (extjs|touch), set inside Toolkit.js
28 bus_match
: /^(ide|sata|virtio|scsi)\d+$/ ,
42 'c' : gettext ( 'Community' ),
43 'b' : gettext ( 'Basic' ),
44 's' : gettext ( 'Standard' ),
45 'p' : gettext ( 'Premium' )
48 noSubKeyHtml
: 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="http://www.proxmox.com/products/proxmox-ve/subscription-service-plans">www.proxmox.com</a> to get a list of available options.' ,
52 { desc
: '4.X/3.X/2.6 Kernel' , val
: 'l26' },
53 { desc
: '2.4 Kernel' , val
: 'l24' }
55 'Microsoft Windows' : [
56 { desc
: '10/2016' , val
: 'win10' },
57 { desc
: '8.x/2012/2012r2' , val
: 'win8' },
58 { desc
: '7/2008r2' , val
: 'win7' },
59 { desc
: 'Vista/2008' , val
: 'w2k8' },
60 { desc
: 'XP/2003' , val
: 'wxp' },
61 { desc
: '2000' , val
: 'w2k' }
64 { desc
: '-' , val
: 'solaris' }
67 { desc
: '-' , val
: 'other' }
71 get_health_icon : function ( state
, circle
) {
72 if ( circle
=== undefined ) {
76 if ( state
=== undefined ) {
80 var icon
= 'faded fa-question' ;
83 icon
= 'good fa-check' ;
86 icon
= 'warning fa-exclamation' ;
89 icon
= 'critical fa-times' ;
103 'HEALTH_WARN' : 'warning' ,
104 'HEALTH_ERR' : 'critical'
107 render_ceph_health : function ( healthObj
) {
109 iconCls
: PVE
. Utils
. get_health_icon (),
113 if (! healthObj
|| ! healthObj
. status
) {
117 var health
= PVE
. Utils
. map_ceph_health
[ healthObj
. status
];
119 state
. iconCls
= PVE
. Utils
. get_health_icon ( health
, true );
120 state
. text
= healthObj
. status
;
125 render_zfs_health : function ( value
) {
126 if ( typeof value
== 'undefined' ){
129 var iconCls
= 'question-circle' ;
133 iconCls
= 'check-circle good' ;
137 iconCls
= 'exclamation-circle warning' ;
142 iconCls
= 'times-circle critical' ;
147 return '<i class="fa fa-' + iconCls
+ '"></i> ' + value
;
151 get_kvm_osinfo : function ( value
) {
152 var info
= { base
: 'Other' }; // default
154 Ext
. each ( Object
. keys ( PVE
. Utils
. kvm_ostypes
), function ( k
) {
155 Ext
. each ( PVE
. Utils
. kvm_ostypes
[ k
], function ( e
) {
156 if ( e
. val
=== value
) {
157 info
= { desc
: e
. desc
, base
: k
};
165 render_kvm_ostype : function ( value
) {
166 var osinfo
= PVE
. Utils
. get_kvm_osinfo ( value
);
167 if ( osinfo
. desc
&& osinfo
. desc
!== '-' ) {
168 return osinfo
. base
+ ' ' + osinfo
. desc
;
174 render_hotplug_features : function ( value
) {
177 if (! value
|| ( value
=== '0' )) {
178 return gettext ( 'Disabled' );
182 value
= 'disk,network,usb' ;
185 Ext
. each ( value
. split ( ',' ), function ( el
) {
187 fa
. push ( gettext ( 'Disk' ));
188 } else if ( el
=== 'network' ) {
189 fa
. push ( gettext ( 'Network' ));
190 } else if ( el
=== 'usb' ) {
192 } else if ( el
=== 'memory' ) {
193 fa
. push ( gettext ( 'Memory' ));
194 } else if ( el
=== 'cpu' ) {
195 fa
. push ( gettext ( 'CPU' ));
201 return fa
. join ( ', ' );
204 render_qga_features : function ( value
) {
206 return Proxmox
. Utils
. defaultText
+ ' (' + Proxmox
. Utils
. disabledText
+ ')' ;
208 var props
= PVE
. Parser
. parsePropertyString ( value
, 'enabled' );
209 if (! PVE
. Parser
. parseBoolean ( props
. enabled
)) {
210 return Proxmox
. Utils
. disabledText
;
213 delete props
. enabled
;
214 var agentstring
= Proxmox
. Utils
. enabledText
;
216 Ext
. Object
. each ( props
, function ( key
, value
) {
218 agentstring
+= ', ' + key
+ ': ' ;
220 if ( PVE
. Parser
. parseBoolean ( value
)) {
221 agentstring
+= Proxmox
. Utils
. enabledText
;
223 agentstring
+= Proxmox
. Utils
. disabledText
;
230 render_qemu_bios : function ( value
) {
232 return Proxmox
. Utils
. defaultText
+ ' (SeaBIOS)' ;
233 } else if ( value
=== 'seabios' ) {
235 } else if ( value
=== 'ovmf' ) {
236 return "OVMF (UEFI)" ;
242 render_scsihw : function ( value
) {
244 return Proxmox
. Utils
. defaultText
+ ' (LSI 53C895A)' ;
245 } else if ( value
=== 'lsi' ) {
246 return 'LSI 53C895A' ;
247 } else if ( value
=== 'lsi53c810' ) {
249 } else if ( value
=== 'megasas' ) {
250 return 'MegaRAID SAS 8708EM2' ;
251 } else if ( value
=== 'virtio-scsi-pci' ) {
252 return 'VirtIO SCSI' ;
253 } else if ( value
=== 'virtio-scsi-single' ) {
254 return 'VirtIO SCSI single' ;
255 } else if ( value
=== 'pvscsi' ) {
256 return 'VMware PVSCSI' ;
262 // fixme: auto-generate this
263 // for now, please keep in sync with PVE::Tools::kvmkeymaps
268 'de-ch' : 'German (Swiss)' ,
269 'en-gb' : 'English (UK)' ,
270 'en-us' : 'English (USA)' ,
274 //fo: 'Faroe Islands',
276 'fr-be' : 'French (Belgium)' ,
277 'fr-ca' : 'French (Canada)' ,
278 'fr-ch' : 'French (Swiss)' ,
288 //'nl-be': 'Dutch (Belgium)',
292 'pt-br' : 'Portuguese (Brazil)' ,
301 std
: gettext ( 'Standard VGA' ),
302 vmware
: gettext ( 'VMware compatible' ),
304 qxl2
: 'SPICE dual monitor' ,
305 qxl3
: 'SPICE three monitors' ,
306 qxl4
: 'SPICE four monitors' ,
307 serial0
: gettext ( 'Serial terminal' ) + ' 0' ,
308 serial1
: gettext ( 'Serial terminal' ) + ' 1' ,
309 serial2
: gettext ( 'Serial terminal' ) + ' 2' ,
310 serial3
: gettext ( 'Serial terminal' ) + ' 3'
313 render_kvm_language : function ( value
) {
314 if (! value
|| value
=== '__default__' ) {
315 return Proxmox
. Utils
. defaultText
;
317 var text
= PVE
. Utils
. kvm_keymaps
[ value
];
319 return text
+ ' (' + value
+ ')' ;
324 kvm_keymap_array : function () {
325 var data
= [[ '__default__' , PVE
. Utils
. render_kvm_language ( '' )]];
326 Ext
. Object
. each ( PVE
. Utils
. kvm_keymaps
, function ( key
, value
) {
327 data
. push ([ key
, PVE
. Utils
. render_kvm_language ( value
)]);
334 '__default__' : Proxmox
. Utils
. defaultText
+ ' (HTML5)' ,
335 'vv' : 'SPICE (remote-viewer)' ,
336 'html5' : 'HTML5 (noVNC)' ,
337 'xtermjs' : 'xterm.js'
340 render_console_viewer : function ( value
) {
341 value
= value
|| '__default__' ;
342 if ( PVE
. Utils
. console_map
[ value
]) {
343 return PVE
. Utils
. console_map
[ value
];
348 console_viewer_array : function () {
349 return Ext
. Array
. map ( Object
. keys ( PVE
. Utils
. console_map
), function ( v
) {
350 return [ v
, PVE
. Utils
. render_console_viewer ( v
)];
354 render_kvm_vga_driver : function ( value
) {
356 return Proxmox
. Utils
. defaultText
;
358 var vga
= PVE
. Parser
. parsePropertyString ( value
, 'type' );
359 var text
= PVE
. Utils
. kvm_vga_drivers
[ vga
. type
];
361 text
= Proxmox
. Utils
. defaultText
;
364 return text
+ ' (' + value
+ ')' ;
369 kvm_vga_driver_array : function () {
370 var data
= [[ '__default__' , PVE
. Utils
. render_kvm_vga_driver ( '' )]];
371 Ext
. Object
. each ( PVE
. Utils
. kvm_vga_drivers
, function ( key
, value
) {
372 data
. push ([ key
, PVE
. Utils
. render_kvm_vga_driver ( value
)]);
378 render_kvm_startup : function ( value
) {
379 var startup
= PVE
. Parser
. parseStartup ( value
);
382 if ( startup
. order
=== undefined ) {
385 res
+= startup
. order
;
387 if ( startup
. up
!== undefined ) {
388 res
+= ',up=' + startup
. up
;
390 if ( startup
. down
!== undefined ) {
391 res
+= ',down=' + startup
. down
;
397 extractFormActionError : function ( action
) {
399 switch ( action
. failureType
) {
400 case Ext
. form
. action
. Action
. CLIENT_INVALID
:
401 msg
= gettext ( 'Form fields may not be submitted with invalid values' );
403 case Ext
. form
. action
. Action
. CONNECT_FAILURE
:
404 msg
= gettext ( 'Connection error' );
405 var resp
= action
. response
;
406 if ( resp
. status
&& resp
. statusText
) {
407 msg
+= " " + resp
. status
+ ": " + resp
. statusText
;
410 case Ext
. form
. action
. Action
. LOAD_FAILURE
:
411 case Ext
. form
. action
. Action
. SERVER_INVALID
:
412 msg
= Proxmox
. Utils
. extractRequestError ( action
. result
, true );
418 format_duration_short : function ( ut
) {
421 return ut
. toFixed ( 1 ) + 's' ;
426 return mins
. toFixed ( 1 ) + 'm' ;
430 var hours
= ut
/ 3600 ;
431 return hours
. toFixed ( 1 ) + 'h' ;
434 var days
= ut
/ 86400 ;
435 return days
. toFixed ( 1 ) + 'd' ;
439 'images' : gettext ( 'Disk image' ),
440 'backup' : gettext ( 'VZDump backup file' ),
441 'vztmpl' : gettext ( 'Container template' ),
442 'iso' : gettext ( 'ISO image' ),
443 'rootdir' : gettext ( 'Container' )
448 name
: Proxmox
. Utils
. directoryText
,
449 ipanel
: 'DirInputPanel' ,
454 ipanel
: 'LVMInputPanel' ,
459 ipanel
: 'LvmThinInputPanel' ,
464 ipanel
: 'NFSInputPanel' ,
469 ipanel
: 'CIFSInputPanel' ,
474 ipanel
: 'GlusterFsInputPanel' ,
479 ipanel
: 'IScsiInputPanel' ,
484 ipanel
: 'SheepdogInputPanel' ,
490 ipanel
: 'CephFSInputPanel' ,
494 name
: 'CephFS (PVE)' ,
495 ipanel
: 'CephFSInputPanel' ,
501 ipanel
: 'RBDInputPanel' ,
506 ipanel
: 'RBDInputPanel' ,
511 name
: 'ZFS over iSCSI' ,
512 ipanel
: 'ZFSInputPanel' ,
517 ipanel
: 'ZFSPoolInputPanel' ,
526 format_storage_type : function ( value
, md
, record
) {
527 if ( value
=== 'rbd' ) {
528 value
= (! record
|| record
. get ( 'monhost' ) ? 'rbd' : 'pveceph' );
529 } else if ( value
=== 'cephfs' ) {
530 value
= (! record
|| record
. get ( 'monhost' ) ? 'cephfs' : 'pvecephfs' );
533 var schema
= PVE
. Utils
. storageSchema
[ value
];
537 return Proxmox
. Utils
. unknownText
;
540 format_ha : function ( value
) {
541 var text
= Proxmox
. Utils
. noneText
;
544 text
= value
. state
|| Proxmox
. Utils
. noneText
;
546 text
+= ', ' + Proxmox
. Utils
. groupText
+ ': ' ;
547 text
+= value
. group
|| Proxmox
. Utils
. noneText
;
553 format_content_types : function ( value
) {
554 return value
. split ( ',' ). sort (). map ( function ( ct
) {
555 return PVE
. Utils
. contentTypes
[ ct
] || ct
;
559 render_storage_content : function ( value
, metaData
, record
) {
560 var data
= record
. data
;
561 if ( Ext
. isNumber ( data
. channel
) &&
562 Ext
. isNumber ( data
. id
) &&
563 Ext
. isNumber ( data
. lun
)) {
565 Ext
. String
. leftPad ( data
. channel
, 2 , '0' ) +
566 " ID " + data
. id
+ " LUN " + data
. lun
;
568 return data
. volid
. replace ( /^.*:(.*\/)?/ , '' );
571 render_serverity : function ( value
) {
572 return PVE
. Utils
. log_severity_hash
[ value
] || value
;
575 render_cpu : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
577 if (!( record
. data
. uptime
&& Ext
. isNumeric ( value
))) {
581 var maxcpu
= record
. data
. maxcpu
|| 1 ;
583 if (! Ext
. isNumeric ( maxcpu
) && ( maxcpu
>= 1 )) {
587 var per
= value
* 100 ;
589 return per
. toFixed ( 1 ) + '% of ' + maxcpu
. toString () + ( maxcpu
> 1 ? 'CPUs' : 'CPU' );
592 render_size : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
593 /*jslint confusion: true */
595 if (! Ext
. isNumeric ( value
)) {
599 return Proxmox
. Utils
. format_size ( value
);
602 render_bandwidth : function ( value
) {
603 if (! Ext
. isNumeric ( value
)) {
607 return Proxmox
. Utils
. format_size ( value
) + '/s' ;
610 render_timestamp_human_readable : function ( value
) {
611 return Ext
. Date
. format ( new Date ( value
* 1000 ), 'l d F Y H:i:s' );
614 render_duration : function ( value
) {
615 if ( value
=== undefined ) {
618 return PVE
. Utils
. format_duration_short ( value
);
621 calculate_mem_usage : function ( data
) {
622 if (! Ext
. isNumeric ( data
. mem
) ||
628 return ( data
. mem
/ data
. maxmem
);
631 render_mem_usage_percent : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
632 if (! Ext
. isNumeric ( value
) || value
=== - 1 ) {
636 // we got no percentage but bytes
638 var maxmem
= record
. data
. maxmem
;
639 if (! record
. data
. uptime
||
641 ! Ext
. isNumeric ( mem
)) {
645 return (( mem
* 100 )/ maxmem
). toFixed ( 1 ) + " %" ;
647 return ( value
* 100 ). toFixed ( 1 ) + " %" ;
650 render_mem_usage : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
653 var maxmem
= record
. data
. maxmem
;
655 if (! record
. data
. uptime
) {
659 if (!( Ext
. isNumeric ( mem
) && maxmem
)) {
663 return PVE
. Utils
. render_size ( value
);
666 calculate_disk_usage : function ( data
) {
668 if (! Ext
. isNumeric ( data
. disk
) ||
669 data
. type
=== 'qemu' ||
670 ( data
. type
=== 'lxc' && data
. uptime
=== 0 ) ||
671 data
. maxdisk
=== 0 ) {
675 return ( data
. disk
/ data
. maxdisk
);
678 render_disk_usage_percent : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
679 if (! Ext
. isNumeric ( value
) || value
=== - 1 ) {
683 return ( value
* 100 ). toFixed ( 1 ) + " %" ;
686 render_disk_usage : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
689 var maxdisk
= record
. data
. maxdisk
;
690 var type
= record
. data
. type
;
692 if (! Ext
. isNumeric ( disk
) ||
695 ( type
=== 'lxc' && record
. data
. uptime
=== 0 )) {
699 return PVE
. Utils
. render_size ( value
);
702 get_object_icon_class : function ( type
, record
) {
706 if ( type
=== 'type' ) {
708 objType
= record
. groupbyid
;
709 } else if ( record
. template
) {
711 objType
= 'template' ;
715 status
= record
. status
+ ' ha-' + record
. hastate
;
718 var defaults
= PVE
. tree
. ResourceTree
. typeDefaults
[ objType
];
719 if ( defaults
&& defaults
. iconCls
) {
720 var retVal
= defaults
. iconCls
+ ' ' + status
;
727 render_resource_type : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
729 var cls
= PVE
. Utils
. get_object_icon_class ( value
, record
. data
);
731 var fa
= '<i class="fa-fw x-grid-icon-custom ' + cls
+ '"></i> ' ;
735 render_support_level : function ( value
, metaData
, record
) {
736 return PVE
. Utils
. support_level_hash
[ value
] || '-' ;
739 render_upid : function ( value
, metaData
, record
) {
740 var type
= record
. data
. type
;
741 var id
= record
. data
. id
;
743 return Proxmox
. Utils
. format_task_description ( type
, id
);
746 /* render functions for new status panel */
748 render_usage : function ( val
) {
749 return ( val
* 100 ). toFixed ( 2 ) + '%' ;
752 render_cpu_usage : function ( val
, max
) {
753 return Ext
. String
. format ( gettext ( '{0}% of {1}' ) +
754 ' ' + gettext ( 'CPU(s)' ), ( val
* 100 ). toFixed ( 2 ), max
);
757 render_size_usage : function ( val
, max
) {
759 return gettext ( 'N/A' );
761 return ( val
* 100 / max
). toFixed ( 2 ) + '% ' + '(' +
762 Ext
. String
. format ( gettext ( '{0} of {1}' ),
763 PVE
. Utils
. render_size ( val
), PVE
. Utils
. render_size ( max
)) + ')' ;
766 /* this is different for nodes */
767 render_node_cpu_usage : function ( value
, record
) {
768 return PVE
. Utils
. render_cpu_usage ( value
, record
. cpus
);
771 /* this is different for nodes */
772 render_node_size_usage : function ( record
) {
773 return PVE
. Utils
. render_size_usage ( record
. used
, record
. total
);
776 render_optional_url : function ( value
) {
778 if ( value
&& ( match
= value
. match ( /^https?:\/\// )) !== null ) {
779 return '<a target="_blank" href="' + value
+ '">' + value
+ '</a>' ;
784 render_san : function ( value
) {
786 if ( Ext
. isArray ( value
)) {
787 value
. forEach ( function ( val
) {
788 if (! Ext
. isNumber ( val
)) {
792 return names
. join ( '<br>' );
797 render_full_name : function ( firstname
, metaData
, record
) {
798 var first
= firstname
|| '' ;
799 var last
= record
. data
. lastname
|| '' ;
800 return Ext
. htmlEncode ( first
+ " " + last
);
803 windowHostname : function () {
804 return window
. location
. hostname
. replace ( Proxmox
. Utils
. IP6_bracket_match
,
805 function ( m
, addr
, offset
, original
) { return addr
; });
808 openDefaultConsoleWindow : function ( consoles
, vmtype
, vmid
, nodename
, vmname
) {
809 var dv
= PVE
. Utils
. defaultViewer ( consoles
);
810 PVE
. Utils
. openConsoleWindow ( dv
, vmtype
, vmid
, nodename
, vmname
);
813 openConsoleWindow : function ( viewer
, vmtype
, vmid
, nodename
, vmname
) {
814 // kvm, lxc, shell, upgrade
816 if ( vmid
== undefined && ( vmtype
=== 'kvm' || vmtype
=== 'lxc' )) {
817 throw "missing vmid" ;
821 throw "no nodename specified" ;
824 if ( viewer
=== 'html5' ) {
825 PVE
. Utils
. openVNCViewer ( vmtype
, vmid
, nodename
, vmname
);
826 } else if ( viewer
=== 'xtermjs' ) {
827 Proxmox
. Utils
. openXtermJsViewer ( vmtype
, vmid
, nodename
, vmname
);
828 } else if ( viewer
=== 'vv' ) {
830 var params
= { proxy
: PVE
. Utils
. windowHostname () };
831 if ( vmtype
=== 'kvm' ) {
832 url
= '/nodes/' + nodename
+ '/qemu/' + vmid
. toString () + '/spiceproxy' ;
833 PVE
. Utils
. openSpiceViewer ( url
, params
);
834 } else if ( vmtype
=== 'lxc' ) {
835 url
= '/nodes/' + nodename
+ '/lxc/' + vmid
. toString () + '/spiceproxy' ;
836 PVE
. Utils
. openSpiceViewer ( url
, params
);
837 } else if ( vmtype
=== 'shell' ) {
838 url
= '/nodes/' + nodename
+ '/spiceshell' ;
839 PVE
. Utils
. openSpiceViewer ( url
, params
);
840 } else if ( vmtype
=== 'upgrade' ) {
841 url
= '/nodes/' + nodename
+ '/spiceshell' ;
843 PVE
. Utils
. openSpiceViewer ( url
, params
);
846 throw "unknown viewer type" ;
850 defaultViewer : function ( consoles
) {
852 var allowSpice
, allowXtermjs
;
854 if ( consoles
=== true ) {
857 } else if ( typeof consoles
=== 'object' ) {
858 allowSpice
= consoles
. spice
;
859 allowXtermjs
= !! consoles
. xtermjs
;
861 var vncdefault
= 'html5' ;
862 var dv
= PVE
. VersionInfo
. console
|| vncdefault
;
863 if (( dv
=== 'vv' && ! allowSpice
) || ( dv
=== 'xtermjs' && ! allowXtermjs
)) {
870 openVNCViewer : function ( vmtype
, vmid
, nodename
, vmname
) {
871 var url
= Ext
. urlEncode ({
872 console
: vmtype
, // kvm, lxc, upgrade or shell
879 var nw
= window
. open ( "?" + url
, '_blank' , "innerWidth=745,innerheight=427" );
883 openSpiceViewer : function ( url
, params
){
885 var downloadWithName = function ( uri
, name
) {
886 var link
= Ext
. DomHelper
. append ( document
. body
, {
889 css
: 'display:none;visibility:hidden;height:0px;'
892 // Note: we need to tell android the correct file name extension
893 // but we do not set 'download' tag for other environments, because
894 // It can have strange side effects (additional user prompt on firefox)
895 var andriod
= navigator
. userAgent
. match ( /Android/i ) ? true : false ;
897 link
. download
= name
;
900 if ( link
. fireEvent
) {
901 link
. fireEvent ( 'onclick' );
903 var evt
= document
. createEvent ( "MouseEvents" );
904 evt
. initMouseEvent ( 'click' , true , true , window
, 1 , 0 , 0 , 0 , 0 , false , false , false , false , 0 , null );
905 link
. dispatchEvent ( evt
);
909 Proxmox
. Utils
. API2Request ({
913 failure : function ( response
, opts
){
914 Ext
. Msg
. alert ( 'Error' , response
. htmlStatus
);
916 success : function ( response
, opts
){
917 var raw
= "[virt-viewer] \n " ;
918 Ext
. Object
. each ( response
. result
. data
, function ( k
, v
) {
919 raw
+= k
+ "=" + v
+ " \n " ;
921 var url
= 'data:application/x-virt-viewer;charset=UTF-8,' +
922 encodeURIComponent ( raw
);
924 downloadWithName ( url
, "pve-spice.vv" );
929 openTreeConsole : function ( tree
, record
, item
, index
, e
) {
931 var nodename
= record
. data
. node
;
932 var vmid
= record
. data
. vmid
;
933 var vmname
= record
. data
. name
;
934 if ( record
. data
. type
=== 'qemu' && ! record
. data
. template
) {
935 Proxmox
. Utils
. API2Request ({
936 url
: '/nodes/' + nodename
+ '/qemu/' + vmid
+ '/status/current' ,
937 failure : function ( response
, opts
) {
938 Ext
. Msg
. alert ( 'Error' , response
. htmlStatus
);
940 success : function ( response
, opts
) {
941 var allowSpice
= !! response
. result
. data
. spice
;
942 PVE
. Utils
. openDefaultConsoleWindow ( allowSpice
, 'kvm' , vmid
, nodename
, vmname
);
945 } else if ( record
. data
. type
=== 'lxc' && ! record
. data
. template
) {
946 PVE
. Utils
. openDefaultConsoleWindow ( true , 'lxc' , vmid
, nodename
, vmname
);
950 // test automation helper
951 call_menu_handler : function ( menu
, text
) {
953 var list
= menu
. query ( 'menuitem' );
955 Ext
. Array
. each ( list
, function ( item
) {
956 if ( item
. text
=== text
) {
967 createCmdMenu : function ( v
, record
, item
, index
, event
) {
969 if (!( v
instanceof Ext
. tree
. View
)) {
973 var template
= !! record
. data
. template
;
974 var type
= record
. data
. type
;
977 if ( type
=== 'qemu' || type
== 'lxc' ) {
978 menu
= Ext
. create ( 'PVE.menu.TemplateMenu' , {
982 } else if ( type
=== 'qemu' ||
985 menu
= Ext
. create ( 'PVE.' + type
+ '.CmdMenu' , {
987 nodename
: record
. data
. node
993 menu
. showAt ( event
. getXY ());
996 // helper for deleting field which are set to there default values
997 delete_if_default : function ( values
, fieldname
, default_val
, create
) {
998 if ( values
[ fieldname
] === '' || values
[ fieldname
] === default_val
) {
1000 if ( values
[ 'delete' ]) {
1001 values
[ 'delete' ] += ',' + fieldname
;
1003 values
[ 'delete' ] = fieldname
;
1007 delete values
[ fieldname
];
1011 loadSSHKeyFromFile : function ( file
, callback
) {
1012 // ssh-keygen produces 740 bytes for an average 4096 bit rsa key, with
1013 // a user@host comment, 1420 for 8192 bits; current max is 16kbit
1014 // assume: 740*8 for max. 32kbit (5920 byte file)
1015 // round upwards to nearest nice number => 8192 bytes, leaves lots of comment space
1016 if ( file
. size
> 8192 ) {
1017 Ext
. Msg
. alert ( gettext ( 'Error' ), gettext ( "Invalid file size: " ) + file
. size
);
1023 var reader
= new FileReader ();
1024 reader
. onload = function ( evt
) {
1025 callback ( evt
. target
. result
);
1027 reader
. readAsText ( file
);
1030 bus_counts
: { ide
: 4 , sata
: 6 , scsi
: 16 , virtio
: 16 },
1032 // types is either undefined (all busses), an array of busses, or a single bus
1033 forEachBus : function ( types
, func
) {
1034 var busses
= Object
. keys ( PVE
. Utils
. bus_counts
);
1035 var i
, j
, count
, cont
;
1037 if ( Ext
. isArray ( types
)) {
1039 } else if ( Ext
. isDefined ( types
)) {
1043 // check if we only have valid busses
1044 for ( i
= 0 ; i
< busses
. length
; i
++) {
1045 if (! PVE
. Utils
. bus_counts
[ busses
[ i
]]) {
1046 throw "invalid bus: '" + busses
[ i
] + "'" ;
1050 for ( i
= 0 ; i
< busses
. length
; i
++) {
1051 count
= PVE
. Utils
. bus_counts
[ busses
[ i
]];
1052 for ( j
= 0 ; j
< count
; j
++) {
1053 cont
= func ( busses
[ i
], j
);
1054 if (! cont
&& cont
!== undefined ) {
1061 mp_counts
: { mps
: 256 , unused
: 256 },
1063 forEachMP : function ( func
, includeUnused
) {
1065 for ( i
= 0 ; i
< PVE
. Utils
. mp_counts
. mps
; i
++) {
1066 cont
= func ( 'mp' , i
);
1067 if (! cont
&& cont
!== undefined ) {
1072 if (! includeUnused
) {
1076 for ( i
= 0 ; i
< PVE
. Utils
. mp_counts
. unused
; i
++) {
1077 cont
= func ( 'unused' , i
);
1078 if (! cont
&& cont
!== undefined ) {
1086 constructor : function () {
1088 Ext
. apply ( me
, me
. utilities
);