-// fixme: howto avoid jslint type confusion?
-/*jslint confusion: true */
Ext.define('PVE.qemu.CreateWizard', {
extend: 'PVE.window.Wizard',
alias: 'widget.pveQemuCreateWizard',
+ mixins: ['Proxmox.Mixin.CBind'],
- initComponent: function() {
- var me = this;
+ viewModel: {
+ data: {
+ nodename: '',
+ current: {
+ scsihw: '',
+ },
+ },
+ formulas: {
+ cgroupMode: function(get) {
+ const nodeInfo = PVE.data.ResourceStore.getNodes().find(
+ node => node.node === get('nodename'),
+ );
+ return nodeInfo ? nodeInfo['cgroup-mode'] : 2;
+ },
+ },
+ },
- var summarystore = Ext.create('Ext.data.Store', {
- model: 'KeyValue',
- sorters: [
- {
- property : 'key',
- direction: 'ASC'
+ cbindData: {
+ nodename: undefined,
+ },
+
+ subject: gettext('Virtual Machine'),
+
+ // fot the special case that we have 2 cdrom drives
+ //
+ // emulates part of the backend bootorder logic, but includes all
+ // cdrom drives since we don't know which one the user put in a bootable iso
+ // and hardcodes the known values (ide0/2, net0)
+ calculateBootOrder: function(values) {
+ // user selected windows + second cdrom
+ if (values.ide0 && values.ide0.match(/media=cdrom/)) {
+ let disk;
+ PVE.Utils.forEachBus(['ide', 'scsi', 'virtio', 'sata'], (type, id) => {
+ let confId = type + id;
+ if (!values[confId]) {
+ return undefined;
}
- ]
- });
-
- var cdpanel = Ext.create('PVE.qemu.CDInputPanel', {
- title: gettext('CD/DVD'),
- confid: 'ide2',
- fieldDefaults: {
- labelWidth: 160
- },
- insideWizard: true
- });
+ if (values[confId].match(/media=cdrom/)) {
+ return undefined;
+ }
+ disk = confId;
+ return false; // abort loop
+ });
- var hdpanel = Ext.create('PVE.qemu.HDInputPanel', {
- title: gettext('Hard Disk'),
- create: true,
- insideWizard: true
- });
+ let order = [];
+ if (disk) {
+ order.push(disk);
+ }
+ order.push('ide0', 'ide2');
+ if (values.net0) {
+ order.push('net0');
+ }
- var networkpanel = Ext.create('PVE.qemu.NetworkInputPanel', {
- title: gettext('Network'),
- insideWizard: true
- });
+ return `order=${order.join(';')}`;
+ }
+ return undefined;
+ },
- Ext.applyIf(me, {
- subject: gettext('Virtual Machine'),
- items: [
+ items: [
+ {
+ xtype: 'inputpanel',
+ title: gettext('General'),
+ onlineHelp: 'qm_general_settings',
+ column1: [
{
- xtype: 'inputpanel',
- title: gettext('General'),
- onlineHelp: 'chapter-qm.html#_general_settings',
- column1: [
- {
- xtype: 'pveNodeSelector',
- name: 'nodename',
- selectCurNode: true,
- fieldLabel: gettext('Node'),
- allowBlank: false,
- onlineValidator: true,
- listeners: {
- change: function(f, value) {
- networkpanel.setNodename(value);
- hdpanel.setNodename(value);
- cdpanel.setNodename(value);
- }
- }
- },
- {
- xtype: 'pveVMIDSelector',
- name: 'vmid',
- value: '',
- loadNextFreeVMID: true,
- validateExists: false
- },
- {
- xtype: 'textfield',
- name: 'name',
- vtype: 'DnsName',
- value: '',
- fieldLabel: gettext('Name'),
- allowBlank: true
- }
- ],
- column2: [
- {
- xtype: 'pvePoolSelector',
- fieldLabel: gettext('Resource Pool'),
- name: 'pool',
- value: '',
- allowBlank: true
- }
- ],
- onGetValues: function(values) {
- if (!values.name) {
- delete values.name;
- }
- if (!values.pool) {
- delete values.pool;
- }
- return values;
- }
+ xtype: 'pveNodeSelector',
+ name: 'nodename',
+ cbind: {
+ selectCurNode: '{!nodename}',
+ preferredValue: '{nodename}',
+ },
+ bind: {
+ value: '{nodename}',
+ },
+ fieldLabel: gettext('Node'),
+ allowBlank: false,
+ onlineValidator: true,
},
{
- title: gettext('OS'),
- xtype: 'pveQemuOSTypePanel',
- insideWizard: true
+ xtype: 'pveGuestIDSelector',
+ name: 'vmid',
+ guestType: 'qemu',
+ value: '',
+ loadNextFreeID: true,
+ validateExists: false,
+ },
+ {
+ xtype: 'textfield',
+ name: 'name',
+ vtype: 'DnsName',
+ value: '',
+ fieldLabel: gettext('Name'),
+ allowBlank: true,
+ },
+ ],
+ column2: [
+ {
+ xtype: 'pvePoolSelector',
+ fieldLabel: gettext('Resource Pool'),
+ name: 'pool',
+ value: '',
+ allowBlank: true,
+ },
+ ],
+ advancedColumn1: [
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'onboot',
+ uncheckedValue: 0,
+ defaultValue: 0,
+ deleteDefaultValue: true,
+ fieldLabel: gettext('Start at boot'),
+ },
+ ],
+ advancedColumn2: [
+ {
+ xtype: 'textfield',
+ name: 'order',
+ defaultValue: '',
+ emptyText: 'any',
+ labelWidth: 120,
+ fieldLabel: gettext('Start/Shutdown order'),
},
- cdpanel,
- hdpanel,
{
- xtype: 'pveQemuProcessorPanel',
- title: gettext('CPU')
+ xtype: 'textfield',
+ name: 'up',
+ defaultValue: '',
+ emptyText: 'default',
+ labelWidth: 120,
+ fieldLabel: gettext('Startup delay'),
},
{
- xtype: 'pveQemuMemoryPanel',
+ xtype: 'textfield',
+ name: 'down',
+ defaultValue: '',
+ emptyText: 'default',
+ labelWidth: 120,
+ fieldLabel: gettext('Shutdown timeout'),
+ },
+ ],
+
+ advancedColumnB: [
+ {
+ xtype: 'pveTagFieldSet',
+ name: 'tags',
+ maxHeight: 150,
+ },
+ ],
+
+ onGetValues: function(values) {
+ ['name', 'pool', 'onboot', 'agent'].forEach(function(field) {
+ if (!values[field]) {
+ delete values[field];
+ }
+ });
+
+ var res = PVE.Parser.printStartup({
+ order: values.order,
+ up: values.up,
+ down: values.down,
+ });
+
+ if (res) {
+ values.startup = res;
+ }
+
+ delete values.order;
+ delete values.up;
+ delete values.down;
+
+ return values;
+ },
+ },
+ {
+ xtype: 'container',
+ layout: 'hbox',
+ defaults: {
+ flex: 1,
+ padding: '0 10',
+ },
+ title: gettext('OS'),
+ items: [
+ {
+ xtype: 'pveQemuCDInputPanel',
+ bind: {
+ nodename: '{nodename}',
+ },
+ confid: 'ide2',
insideWizard: true,
- title: gettext('Memory')
},
- networkpanel,
{
- title: gettext('Confirm'),
- layout: 'fit',
- items: [
- {
- title: gettext('Settings'),
- xtype: 'grid',
- store: summarystore,
- columns: [
- {header: 'Key', width: 150, dataIndex: 'key'},
- {header: 'Value', flex: 1, dataIndex: 'value'}
- ]
- }
+ xtype: 'pveQemuOSTypePanel',
+ insideWizard: true,
+ bind: {
+ nodename: '{nodename}',
+ },
+ },
+ ],
+ },
+ {
+ xtype: 'pveQemuSystemPanel',
+ title: gettext('System'),
+ isCreate: true,
+ insideWizard: true,
+ },
+ {
+ xtype: 'pveMultiHDPanel',
+ bind: {
+ nodename: '{nodename}',
+ },
+ title: gettext('Disks'),
+ },
+ {
+ xtype: 'pveQemuProcessorPanel',
+ insideWizard: true,
+ title: gettext('CPU'),
+ },
+ {
+ xtype: 'pveQemuMemoryPanel',
+ insideWizard: true,
+ title: gettext('Memory'),
+ },
+ {
+ xtype: 'pveQemuNetworkInputPanel',
+ bind: {
+ nodename: '{nodename}',
+ },
+ title: gettext('Network'),
+ insideWizard: true,
+ },
+ {
+ title: gettext('Confirm'),
+ layout: 'fit',
+ items: [
+ {
+ xtype: 'grid',
+ store: {
+ model: 'KeyValue',
+ sorters: [{
+ property: 'key',
+ direction: 'ASC',
+ }],
+ },
+ columns: [
+ { header: 'Key', width: 150, dataIndex: 'key' },
+ { header: 'Value', flex: 1, dataIndex: 'value' },
],
- listeners: {
- show: function(panel) {
- var form = me.down('form').getForm();
- var kv = me.getValues();
- var data = [];
- Ext.Object.each(kv, function(key, value) {
- if (key === 'delete') { // ignore
- return;
- }
- var html = Ext.htmlEncode(Ext.JSON.encode(value));
- data.push({ key: key, value: value });
- });
- summarystore.suspendEvents();
- summarystore.removeAll();
- summarystore.add(data);
- summarystore.sort();
- summarystore.resumeEvents();
- summarystore.fireEvent('datachanged', summarystore);
+ },
+ ],
+ dockedItems: [
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'start',
+ dock: 'bottom',
+ margin: '5 0 0 0',
+ boxLabel: gettext('Start after created'),
+ },
+ ],
+ listeners: {
+ show: function(panel) {
+ let wizard = this.up('window');
+ var kv = wizard.getValues();
+ var data = [];
- }
- },
- onSubmit: function() {
- var kv = me.getValues();
- delete kv['delete'];
-
- var nodename = kv.nodename;
- delete kv.nodename;
-
- PVE.Utils.API2Request({
- url: '/nodes/' + nodename + '/qemu',
- waitMsgTarget: me,
- method: 'POST',
- params: kv,
- success: function(response){
- me.close();
- },
- failure: function(response, opts) {
- Ext.Msg.alert(gettext('Error'), response.htmlStatus);
- }
- });
+ let boot = wizard.calculateBootOrder(kv);
+ if (boot) {
+ kv.boot = boot;
}
- }
- ]
- });
- me.callParent();
- }
-});
+ Ext.Object.each(kv, function(key, value) {
+ if (key === 'delete') { // ignore
+ return;
+ }
+ data.push({ key: key, value: value });
+ });
+ var summarystore = panel.down('grid').getStore();
+ summarystore.suspendEvents();
+ summarystore.removeAll();
+ summarystore.add(data);
+ summarystore.sort();
+ summarystore.resumeEvents();
+ summarystore.fireEvent('refresh');
+ },
+ },
+ onSubmit: function() {
+ var wizard = this.up('window');
+ var kv = wizard.getValues();
+ delete kv.delete;
+
+ var nodename = kv.nodename;
+ delete kv.nodename;
+
+ let boot = wizard.calculateBootOrder(kv);
+ if (boot) {
+ kv.boot = boot;
+ }
+ Proxmox.Utils.API2Request({
+ url: '/nodes/' + nodename + '/qemu',
+ waitMsgTarget: wizard,
+ method: 'POST',
+ params: kv,
+ success: function(response) {
+ wizard.close();
+ },
+ failure: function(response, opts) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ },
+ });
+ },
+ },
+ ],
+});