* [pve-devel] Extend API for cloud-init MTU and userdata @ 2020-08-11 19:02 Marius Schellenberger 2020-08-11 19:02 ` [pve-devel] [PATCH] api: cloud-init support for mtu " Marius Schellenberger 2020-08-11 19:02 ` [pve-devel] [PATCH] ui: added cloud-init mtu and userdata options Marius Schellenberger 0 siblings, 2 replies; 4+ messages in thread From: Marius Schellenberger @ 2020-08-11 19:02 UTC (permalink / raw) To: pve-devel To fully automate virtual machine creation and configuration via the Proxmox API, I added configuration support for MTU and userdata to the cloud-init options. ^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] [PATCH] api: cloud-init support for mtu and userdata 2020-08-11 19:02 [pve-devel] Extend API for cloud-init MTU and userdata Marius Schellenberger @ 2020-08-11 19:02 ` Marius Schellenberger 2020-08-28 15:46 ` Mira Limbeck 2020-08-11 19:02 ` [pve-devel] [PATCH] ui: added cloud-init mtu and userdata options Marius Schellenberger 1 sibling, 1 reply; 4+ messages in thread From: Marius Schellenberger @ 2020-08-11 19:02 UTC (permalink / raw) To: pve-devel Extended the PVE API to configure cloud-init userdata and network interface MTU. Signed-off-by: Marius Schellenberger <proxmox@giftfish.de> --- PVE/API2/Qemu.pm | 1 + PVE/QemuServer.pm | 18 +++++++++++++++++- PVE/QemuServer/Cloudinit.pm | 31 +++++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 8da616a..5d149a5 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -324,6 +324,7 @@ my $cloudinitoptions = { cipassword => 1, citype => 1, ciuser => 1, + ciuserdata => 1, nameserver => 1, searchdomain => 1, sshkeys => 1, diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index a9c0dac..974a070 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -727,6 +727,12 @@ my $confdesc_cloudinit = { description => 'cloud-init: Specify custom files to replace the automatically generated ones at start.', format => 'pve-qm-cicustom', }, + ciuserdata => { + optional => 1, + type => 'string', + format => 'urlencoded', + description => 'cloud-init: Specify custom user-data as urlencoded base64 string to replace the automatically generated one at start. When set, the following options have no effect: `ciuser`, `cipassword`, `sshkeys`', + }, searchdomain => { optional => 1, type => 'string', @@ -932,6 +938,12 @@ my $ipconfig_fmt = { optional => 1, requires => 'ip6', }, + mtu => { + type => 'string', + format_description => 'MTU', + description => 'MTU value for interface.', + optional => 1, + }, }; PVE::JSONSchema::register_format('pve-qm-ipconfig', $ipconfig_fmt); my $ipconfigdesc = { @@ -1701,7 +1713,7 @@ sub parse_net { return $res; } -# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip +# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip,mtu=mtu sub parse_ipconfig { my ($data) = @_; @@ -1711,6 +1723,10 @@ sub parse_ipconfig { return undef; } + if ($res->{mtu} && !$res->{ip} && !$res->{ip6}) { + warn 'mtu specified without specifying an IP or IPv6 address'; + return undef; + } if ($res->{gw} && !$res->{ip}) { warn 'gateway specified without specifying an IP address'; return undef; diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm index 439de99..a47e0ce 100644 --- a/PVE/QemuServer/Cloudinit.pm +++ b/PVE/QemuServer/Cloudinit.pm @@ -6,6 +6,7 @@ use warnings; use File::Path; use Digest::SHA; use URI::Escape; +use MIME::Base64 qw(decode_base64); use PVE::Tools qw(run_command file_set_contents); use PVE::Storage; @@ -111,6 +112,11 @@ sub get_dns_conf { sub cloudinit_userdata { my ($conf, $vmid) = @_; + my $userdata = $conf->{ciuserdata}; + if (defined($userdata) && $userdata ne "") { + return decode_base64(uri_unescape($userdata)); + } + my ($hostname, $fqdn) = get_hostname_fqdn($conf, $vmid); my $content = "#cloud-config\n"; @@ -176,7 +182,9 @@ sub configdrive2_network { (my $id = $iface) =~ s/^net//; next if !$conf->{"ipconfig$id"}; my $net = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); + next if !defined($net); $id = "eth$id"; + my $mtu = $net->{mtu}; $content .="auto $id\n"; if ($net->{ip}) { @@ -189,6 +197,9 @@ sub configdrive2_network { $content .= " netmask $mask\n"; $content .= " gateway $net->{gw}\n" if $net->{gw}; } + if (defined($mtu) && $mtu ne "") { + $content .= " mtu $mtu\n"; + } } if ($net->{ip6}) { if ($net->{ip6} =~ /^(auto|dhcp)$/) { @@ -200,6 +211,9 @@ sub configdrive2_network { $content .= " netmask $mask\n"; $content .= " gateway $net->{gw6}\n" if $net->{gw6}; } + if (defined($mtu) && $mtu ne "") { + $content .= " mtu $mtu\n"; + } } } @@ -261,6 +275,7 @@ sub nocloud_network_v2 { my $net = PVE::QemuServer::parse_net($conf->{$iface}); my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); + next if !defined($ipconfig); my $mac = $net->{macaddr} or die "network interface '$iface' has no mac address\n"; @@ -295,6 +310,10 @@ sub nocloud_network_v2 { if (defined(my $gw = $ipconfig->{gw6})) { $content .= "${i}gateway6: '$gw'\n"; } + my $mtu = $ipconfig->{mtu}; + if (defined($mtu) && $mtu ne "") { + $content .= "${i}mtu: $mtu\n"; + } next if $dns_done; $dns_done = 1; @@ -332,14 +351,22 @@ sub nocloud_network { my $net = PVE::QemuServer::parse_net($conf->{$iface}); my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); + next if !defined($ipconfig); my $mac = lc($net->{macaddr}) or die "network interface '$iface' has no mac address\n"; + my $mtu = $ipconfig->{mtu}; + $content .= "${i}- type: physical\n" . "${i} name: eth$id\n" - . "${i} mac_address: '$mac'\n" - . "${i} subnets:\n"; + . "${i} mac_address: '$mac'\n"; + + if (defined($mtu) && $mtu ne "") { + $content .= "${i} mtu: $mtu\n"; + } + + $content .= "${i} subnets:\n"; $i .= ' '; if (defined(my $ip = $ipconfig->{ip})) { if ($ip eq 'dhcp') { -- 2.27.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [pve-devel] [PATCH] api: cloud-init support for mtu and userdata 2020-08-11 19:02 ` [pve-devel] [PATCH] api: cloud-init support for mtu " Marius Schellenberger @ 2020-08-28 15:46 ` Mira Limbeck 0 siblings, 0 replies; 4+ messages in thread From: Mira Limbeck @ 2020-08-28 15:46 UTC (permalink / raw) To: pve-devel Thank you for the patch. Seems to be the exactly the same as the one you sent some time ago: https://lists.proxmox.com/pipermail/pve-devel/2020-July/044241.html Was this intentional? On 8/11/20 9:02 PM, Marius Schellenberger wrote: > Extended the PVE API to configure cloud-init userdata and network > interface MTU. > > Signed-off-by: Marius Schellenberger <proxmox@giftfish.de> > --- > PVE/API2/Qemu.pm | 1 + > PVE/QemuServer.pm | 18 +++++++++++++++++- > PVE/QemuServer/Cloudinit.pm | 31 +++++++++++++++++++++++++++++-- > 3 files changed, 47 insertions(+), 3 deletions(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 8da616a..5d149a5 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -324,6 +324,7 @@ my $cloudinitoptions = { > cipassword => 1, > citype => 1, > ciuser => 1, > + ciuserdata => 1, > nameserver => 1, > searchdomain => 1, > sshkeys => 1, > diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm > index a9c0dac..974a070 100644 > --- a/PVE/QemuServer.pm > +++ b/PVE/QemuServer.pm > @@ -727,6 +727,12 @@ my $confdesc_cloudinit = { > description => 'cloud-init: Specify custom files to replace the automatically generated ones at start.', > format => 'pve-qm-cicustom', > }, > + ciuserdata => { > + optional => 1, > + type => 'string', > + format => 'urlencoded', > + description => 'cloud-init: Specify custom user-data as urlencoded base64 string to replace the automatically generated one at start. When set, the following options have no effect: `ciuser`, `cipassword`, `sshkeys`', > + }, > searchdomain => { > optional => 1, > type => 'string', > @@ -932,6 +938,12 @@ my $ipconfig_fmt = { > optional => 1, > requires => 'ip6', > }, > + mtu => { > + type => 'string', > + format_description => 'MTU', > + description => 'MTU value for interface.', > + optional => 1, > + }, > }; > PVE::JSONSchema::register_format('pve-qm-ipconfig', $ipconfig_fmt); > my $ipconfigdesc = { > @@ -1701,7 +1713,7 @@ sub parse_net { > return $res; > } > > -# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip > +# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip,mtu=mtu > sub parse_ipconfig { > my ($data) = @_; > > @@ -1711,6 +1723,10 @@ sub parse_ipconfig { > return undef; > } > > + if ($res->{mtu} && !$res->{ip} && !$res->{ip6}) { > + warn 'mtu specified without specifying an IP or IPv6 address'; > + return undef; > + } > if ($res->{gw} && !$res->{ip}) { > warn 'gateway specified without specifying an IP address'; > return undef; > diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm > index 439de99..a47e0ce 100644 > --- a/PVE/QemuServer/Cloudinit.pm > +++ b/PVE/QemuServer/Cloudinit.pm > @@ -6,6 +6,7 @@ use warnings; > use File::Path; > use Digest::SHA; > use URI::Escape; > +use MIME::Base64 qw(decode_base64); > > use PVE::Tools qw(run_command file_set_contents); > use PVE::Storage; > @@ -111,6 +112,11 @@ sub get_dns_conf { > sub cloudinit_userdata { > my ($conf, $vmid) = @_; > > + my $userdata = $conf->{ciuserdata}; > + if (defined($userdata) && $userdata ne "") { > + return decode_base64(uri_unescape($userdata)); > + } > + > my ($hostname, $fqdn) = get_hostname_fqdn($conf, $vmid); > > my $content = "#cloud-config\n"; > @@ -176,7 +182,9 @@ sub configdrive2_network { > (my $id = $iface) =~ s/^net//; > next if !$conf->{"ipconfig$id"}; > my $net = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); > + next if !defined($net); > $id = "eth$id"; > + my $mtu = $net->{mtu}; > > $content .="auto $id\n"; > if ($net->{ip}) { > @@ -189,6 +197,9 @@ sub configdrive2_network { > $content .= " netmask $mask\n"; > $content .= " gateway $net->{gw}\n" if $net->{gw}; > } > + if (defined($mtu) && $mtu ne "") { > + $content .= " mtu $mtu\n"; > + } > } > if ($net->{ip6}) { > if ($net->{ip6} =~ /^(auto|dhcp)$/) { > @@ -200,6 +211,9 @@ sub configdrive2_network { > $content .= " netmask $mask\n"; > $content .= " gateway $net->{gw6}\n" if $net->{gw6}; > } > + if (defined($mtu) && $mtu ne "") { > + $content .= " mtu $mtu\n"; > + } > } > } > > @@ -261,6 +275,7 @@ sub nocloud_network_v2 { > > my $net = PVE::QemuServer::parse_net($conf->{$iface}); > my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); > + next if !defined($ipconfig); > > my $mac = $net->{macaddr} > or die "network interface '$iface' has no mac address\n"; > @@ -295,6 +310,10 @@ sub nocloud_network_v2 { > if (defined(my $gw = $ipconfig->{gw6})) { > $content .= "${i}gateway6: '$gw'\n"; > } > + my $mtu = $ipconfig->{mtu}; > + if (defined($mtu) && $mtu ne "") { > + $content .= "${i}mtu: $mtu\n"; > + } > > next if $dns_done; > $dns_done = 1; > @@ -332,14 +351,22 @@ sub nocloud_network { > > my $net = PVE::QemuServer::parse_net($conf->{$iface}); > my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"}); > + next if !defined($ipconfig); > > my $mac = lc($net->{macaddr}) > or die "network interface '$iface' has no mac address\n"; > > + my $mtu = $ipconfig->{mtu}; > + > $content .= "${i}- type: physical\n" > . "${i} name: eth$id\n" > - . "${i} mac_address: '$mac'\n" > - . "${i} subnets:\n"; > + . "${i} mac_address: '$mac'\n"; > + > + if (defined($mtu) && $mtu ne "") { > + $content .= "${i} mtu: $mtu\n"; > + } > + > + $content .= "${i} subnets:\n"; > $i .= ' '; > if (defined(my $ip = $ipconfig->{ip})) { > if ($ip eq 'dhcp') { ^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] [PATCH] ui: added cloud-init mtu and userdata options 2020-08-11 19:02 [pve-devel] Extend API for cloud-init MTU and userdata Marius Schellenberger 2020-08-11 19:02 ` [pve-devel] [PATCH] api: cloud-init support for mtu " Marius Schellenberger @ 2020-08-11 19:02 ` Marius Schellenberger 1 sibling, 0 replies; 4+ messages in thread From: Marius Schellenberger @ 2020-08-11 19:02 UTC (permalink / raw) To: pve-devel Added options to configure the cloud-init MTU and userdata fields via the Web-UI. Signed-off-by: Marius Schellenberger <proxmox@giftfish.de> --- www/manager6/Makefile | 1 + www/manager6/Parser.js | 6 ++ www/manager6/Utils.js | 8 +++ www/manager6/qemu/CloudInit.js | 10 ++++ www/manager6/qemu/IPConfigEdit.js | 6 ++ www/manager6/qemu/UserDataEdit.js | 94 +++++++++++++++++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 www/manager6/qemu/UserDataEdit.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index 4288acdd..096454fd 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -201,6 +201,7 @@ JSSRC= \ qemu/Smbios1Edit.js \ qemu/SystemEdit.js \ qemu/USBEdit.js \ + qemu/UserDataEdit.js \ sdn/Browser.js \ sdn/ControllerView.js \ sdn/Status.js \ diff --git a/www/manager6/Parser.js b/www/manager6/Parser.js index b793a28e..580ed2ec 100644 --- a/www/manager6/Parser.js +++ b/www/manager6/Parser.js @@ -275,6 +275,8 @@ Ext.define('PVE.Parser', { statics: { res.ip6 = match_res[1]; } else if ((match_res = p.match(/^gw6=(\S+)$/)) !== null) { res.gw6 = match_res[1]; + } else if ((match_res = p.match(/^mtu=(\S+)$/)) !== null) { + res.mtu = match_res[1]; } else { errors = true; return false; // break @@ -307,6 +309,10 @@ Ext.define('PVE.Parser', { statics: { str += c + "gw6=" + cfg.gw6; c = ","; } + if (cfg.mtu) { + str += c + "mtu=" + cfg.mtu; + c = ","; + } return str; }, diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index bf9ceda9..7b3ffec3 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1351,6 +1351,14 @@ Ext.define('PVE.Utils', { utilities: { reader.readAsText(file); }, + loadUserDataFromFile: function(file, callback) { + var reader = new FileReader(); + reader.onload = function(evt) { + callback(evt.target.result); + }; + reader.readAsText(file); + }, + diskControllerMaxIDs: { ide: 4, sata: 6, diff --git a/www/manager6/qemu/CloudInit.js b/www/manager6/qemu/CloudInit.js index a588f09b..ac960672 100644 --- a/www/manager6/qemu/CloudInit.js +++ b/www/manager6/qemu/CloudInit.js @@ -253,6 +253,16 @@ Ext.define('PVE.qemu.CloudInit', { never_delete: true, defaultValue: gettext('use host settings') }, + ciuserdata: { + header: 'User-Data', + iconCls: 'fa fa-code', + editor: caps.vms['VM.Config.Network'] ? 'PVE.qemu.UserDataEdit' : undefined, + never_delete: true, + defaultValue: '', + renderer: function(value) { + return value || Proxmox.Utils.noneText; + } + }, sshkeys: { header: gettext('SSH public key'), iconCls: 'fa fa-key', diff --git a/www/manager6/qemu/IPConfigEdit.js b/www/manager6/qemu/IPConfigEdit.js index 934a86be..f1e2fc92 100644 --- a/www/manager6/qemu/IPConfigEdit.js +++ b/www/manager6/qemu/IPConfigEdit.js @@ -66,6 +66,12 @@ Ext.define('PVE.qemu.IPConfigPanel', { fieldLabel: gettext('Network Device'), value: me.netid }, + { + xtype: 'textfield', + name: 'mtu', + value: me.ipconfig.mtu, + fieldLabel: 'MTU' + }, { layout: { type: 'hbox', diff --git a/www/manager6/qemu/UserDataEdit.js b/www/manager6/qemu/UserDataEdit.js new file mode 100644 index 00000000..465f5b8f --- /dev/null +++ b/www/manager6/qemu/UserDataEdit.js @@ -0,0 +1,94 @@ +Ext.define('PVE.qemu.UserDataInputPanel', { + extend: 'Proxmox.panel.InputPanel', + xtype: 'pveQemuUserDataInputPanel', + + insideWizard: false, + + onGetValues: function(values) { + var me = this; + if (!values.ciuserdata.length) { + values = {}; + values['delete'] = 'ciuserdata'; + return values; + } else { + var fileheader = "#cloud-config" + var data = values.ciuserdata.split('\n'); + if (data[0] != fileheader) { + values.ciuserdata = fileheader + '\n' + values.ciuserdata; + } + values.ciuserdata = encodeURIComponent(btoa(values.ciuserdata)); + } + return values; + }, + + items: [ + { + xtype: 'textarea', + itemId: 'ciuserdata', + name: 'ciuserdata', + height: 250 + }, + { + xtype: 'filebutton', + itemId: 'filebutton', + name: 'file', + text: gettext('Load User-Data File'), + fieldLabel: 'test', + listeners: { + change: function(btn, e, value) { + var me = this.up('inputpanel'); + e = e.event; + Ext.Array.each(e.target.files, function(file) { + PVE.Utils.loadUserDataFromFile(file, function(res) { + var dataField = me.down('#ciuserdata'); + var old = dataField.getValue(); + dataField.setValue(old + '\n' + res); + }); + }); + btn.reset(); + } + } + } + ], + + initComponent: function() { + var me = this; + + me.callParent(); + if (!window.FileReader) { + me.down('#filebutton').setVisible(false); + } + + } +}); + +Ext.define('PVE.qemu.UserDataEdit', { + extend: 'Proxmox.window.Edit', + + width: 800, + + initComponent : function() { + var me = this; + + var ipanel = Ext.create('PVE.qemu.UserDataInputPanel'); + + Ext.apply(me, { + subject: 'User-Data', + items: [ ipanel ] + }); + + me.callParent(); + + if (!me.create) { + me.load({ + success: function(response, options) { + var data = response.result.data; + if (data.ciuserdata) { + data.ciuserdata = atob(decodeURIComponent(data.ciuserdata)); + ipanel.setValues(data); + } + } + }); + } + } +}); -- 2.27.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-08-28 15:46 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-08-11 19:02 [pve-devel] Extend API for cloud-init MTU and userdata Marius Schellenberger 2020-08-11 19:02 ` [pve-devel] [PATCH] api: cloud-init support for mtu " Marius Schellenberger 2020-08-28 15:46 ` Mira Limbeck 2020-08-11 19:02 ` [pve-devel] [PATCH] ui: added cloud-init mtu and userdata options Marius Schellenberger
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox