Warn the user when selecting /dev/random or disabling speed limits.

'hardware_counts' is used since technically more than one RNG could be
attached to a QEMU machine. It is limited to 1 however, since the
usefulness of such a setup is more than questionable, considering the
linux kernel only ever uses one hwrng at a time anyway.

Signed-off-by: Stefan Reiter <s.rei...@proxmox.com>
---
 www/manager6/Makefile             |   1 +
 www/manager6/Utils.js             |   2 +-
 www/manager6/qemu/HardwareView.js |  23 ++++++
 www/manager6/qemu/RNGEdit.js      | 124 ++++++++++++++++++++++++++++++
 4 files changed, 149 insertions(+), 1 deletion(-)
 create mode 100644 www/manager6/qemu/RNGEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index eb7ac004..41615430 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -160,6 +160,7 @@ JSSRC=                                                      
\
        qemu/IPConfigEdit.js                            \
        qemu/SystemEdit.js                              \
        qemu/AudioEdit.js                               \
+       qemu/RNGEdit.js                                 \
        lxc/Network.js                                  \
        lxc/Resources.js                                \
        lxc/FeaturesEdit.js                             \
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index 68edc275..0d4bbad8 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1215,7 +1215,7 @@ Ext.define('PVE.Utils', { utilities: {
        }
     },
 
-    hardware_counts: { net: 32, usb: 5, hostpci: 16, audio: 1, efidisk: 1, 
serial: 4 },
+    hardware_counts: { net: 32, usb: 5, hostpci: 16, audio: 1, efidisk: 1, 
serial: 4, rng: 1 },
 
     cleanEmptyObjectKeys: function (obj) {
        var propName;
diff --git a/www/manager6/qemu/HardwareView.js 
b/www/manager6/qemu/HardwareView.js
index a78e7dd4..595afd10 100644
--- a/www/manager6/qemu/HardwareView.js
+++ b/www/manager6/qemu/HardwareView.js
@@ -301,6 +301,13 @@ Ext.define('PVE.qemu.HardwareView', {
                header: gettext('Unused Disk') + ' ' + i.toString()
            };
        }
+       rows.rng0 = {
+           group: 45,
+           iconCls: 'cogs',
+           editor: caps.nodes['Sys.Console'] ? 'PVE.qemu.RNGEdit' : undefined,
+           never_delete: caps.nodes['Sys.Console'] ? false : true,
+           header: gettext("VirtIO RNG")
+       };
 
        var sorterFn = function(rec1, rec2) {
            var v1 = rec1.data.key;
@@ -563,6 +570,7 @@ Ext.define('PVE.qemu.HardwareView', {
            me.down('#addaudio').setDisabled(noVMConfigHWTypePerm || 
isAtLimit('audio'));
            me.down('#addserial').setDisabled(noVMConfigHWTypePerm || 
isAtLimit('serial'));
            me.down('#addnet').setDisabled(noVMConfigNetPerm || 
isAtLimit('net'));
+           me.down('#addrng').setDisabled(noSysConsolePerm || 
isAtLimit('rng'));
            efidisk_menuitem.setDisabled(isAtLimit('efidisk'));
            me.down('#addci').setDisabled(noSysConsolePerm || hasCloudInit);
 
@@ -723,6 +731,21 @@ Ext.define('PVE.qemu.HardwareView', {
                                    win.on('destroy', me.reload, me);
                                    win.show();
                                }
+                           },
+                           {
+                               text: gettext("VirtIO RNG"),
+                               itemId: 'addrng',
+                               iconCls: 'fa fa-fw fa-cogs black',
+                               disabled: !caps.nodes['Sys.Console'],
+                               handler: function() {
+                                   var win = Ext.create('PVE.qemu.RNGEdit', {
+                                       url: '/api2/extjs/' + baseurl,
+                                       isCreate: true,
+                                       isAdd: true
+                                   });
+                                   win.on('destroy', me.reload, me);
+                                   win.show();
+                               }
                            }
                        ]
                    })
diff --git a/www/manager6/qemu/RNGEdit.js b/www/manager6/qemu/RNGEdit.js
new file mode 100644
index 00000000..f112eb1f
--- /dev/null
+++ b/www/manager6/qemu/RNGEdit.js
@@ -0,0 +1,124 @@
+Ext.define('PVE.qemu.RNGInputPanel', {
+    extend: 'Proxmox.panel.InputPanel',
+    xtype: 'pveRNGInputPanel',
+
+    // FIXME: enable once we bumped doc-gen so this ref is included
+    //onlineHelp: 'qm_virtio_rng',
+
+    onGetValues: function(values) {
+       if (values.max_bytes === "") {
+           values.max_bytes = "0";
+       } else if (values.max_bytes === "1024" && values.period === "") {
+           delete values.max_bytes;
+       }
+
+       var ret = PVE.Parser.printPropertyString(values);
+
+       return {
+           rng0: ret
+       };
+    },
+
+    setValues: function(values) {
+       if (values.max_bytes == 0) {
+           values.max_bytes = null;
+       }
+
+       this.callParent(arguments);
+    },
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+       control: {
+           '#max_bytes': {
+               change: function(el, newVal) {
+                   let limitWarning = this.lookupReference('limitWarning');
+                   limitWarning.setHidden(!!newVal);
+               }
+           },
+           '#source': {
+               change: function(el, newVal) {
+                   let limitWarning = this.lookupReference('sourceWarning');
+                   limitWarning.setHidden(newVal !== '/dev/random');
+               }
+           }
+       }
+    },
+
+    items: [{
+       itemId: 'source',
+       name: 'source',
+       xtype: 'proxmoxKVComboBox',
+       value: '/dev/urandom',
+       fieldLabel: gettext('Entropy source'),
+       labelWidth: 130,
+       comboItems: [
+           ['/dev/urandom', '/dev/urandom'],
+           ['/dev/random', '/dev/random'],
+           ['/dev/hwrng', '/dev/hwrng']
+       ]
+    },
+    {
+       xtype: 'numberfield',
+       itemId: 'max_bytes',
+       name: 'max_bytes',
+       minValue: 0,
+       step: 1,
+       value: 1024,
+       fieldLabel: gettext('Limit (Bytes/Period)'),
+       labelWidth: 130,
+       emptyText: gettext('unlimited')
+    },
+    {
+       xtype: 'numberfield',
+       name: 'period',
+       minValue: 1,
+       step: 1,
+       fieldLabel: gettext('Period') + ' (ms)',
+       labelWidth: 130,
+       emptyText: gettext('1000')
+    },
+    {
+       xtype: 'displayfield',
+       reference: 'sourceWarning',
+       value: gettext('Using /dev/random as entropy source is discouraged, as 
it can lead to host entropy starvation. /dev/urandom is preferred, and does not 
lead to a decrease in security in practice.'),
+       userCls: 'pmx-hint',
+       hidden: true
+    },
+    {
+       xtype: 'displayfield',
+       reference: 'limitWarning',
+       value: gettext('Disabling the limiter can potentially allow a guest to 
overload the host. Proceed with caution.'),
+       userCls: 'pmx-hint',
+       hidden: true
+    }]
+});
+
+Ext.define('PVE.qemu.RNGEdit', {
+    extend: 'Proxmox.window.Edit',
+
+    subject: gettext('VirtIO RNG'),
+
+    items: [{
+       xtype: 'pveRNGInputPanel'
+    }],
+
+    initComponent : function() {
+       var me = this;
+
+       me.callParent();
+
+       if (!me.isCreate) {
+           me.load({
+               success: function(response) {
+                   me.vmconfig = response.result.data;
+
+                   var rng0 = me.vmconfig.rng0;
+                   if (rng0) {
+                       me.setValues(PVE.Parser.parsePropertyString(rng0));
+                   }
+               }
+           });
+       }
+    }
+});
-- 
2.20.1


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to