From 16b3bd1a0bae7bb6015c80383b3c473bb81e9f64 Mon Sep 17 00:00:00 2001 From: Kevin Scott Adams Date: Sat, 11 May 2019 11:13:54 -0400 Subject: [PATCH] Update the FreeNAS-API related files to the latest Proxmox VE - Updated apidoc.js.patch to reflect pve-docs: 5.4-2 - New apidoc-5.4-2_1.js.patch - Updated pvemanagerlib.js.patch to reflect pve-manager: 5.4-5 - New pvemanagerlib-5.4-5_1.js.patch - Updated ZFSPlugin.pm.patch to reflect libpve-storage-perl: 5.0-42 - New ZFSPlugin-5.0-42.pm.patch - Revised the README.md --- README.md | 27 ++- perl5/PVE/Storage/.gitignore | 2 + perl5/PVE/Storage/ZFSPlugin-5.0-42_1.pm.patch | 147 ++++++++++++++ perl5/PVE/Storage/ZFSPlugin.pm.patch | 4 +- pve-docs/api-viewer/apidoc-5.4-2_1.js.patch | 79 ++++++++ pve-docs/api-viewer/apidoc.js.patch | 10 +- pve-manager/js/pvemanagerlib-5.4-5_1.js.patch | 189 ++++++++++++++++++ pve-manager/js/pvemanagerlib.js.patch | 22 +- 8 files changed, 454 insertions(+), 26 deletions(-) create mode 100644 perl5/PVE/Storage/ZFSPlugin-5.0-42_1.pm.patch create mode 100644 pve-docs/api-viewer/apidoc-5.4-2_1.js.patch create mode 100644 pve-manager/js/pvemanagerlib-5.4-5_1.js.patch diff --git a/README.md b/README.md index c23f304..d436953 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,27 @@ Please be aware that this plugin uses the FreeNAS APIs and NOT the ssh/scp interface like the other plugins use, but... -You will still need to configure the SSH connector for listing the ZFS Pools because this is currently being done in a Proxmox module (ZFSPoolPlugin.pm). To configure this please follow the steps at https://pve.proxmox.com/wiki/Storage:_ZFS_over_iSCSI that have to do with SSH between Proxmox VE and FreeNAS. The code segment should start out ‘mkdir /etc/pve/priv/zfs’. +You will still need to configure the SSH connector for listing the ZFS Pools because this is currently being done in a Proxmox module (ZFSPoolPlugin.pm). To configure this please follow the steps at https://pve.proxmox.com/wiki/Storage:_ZFS_over_iSCSI that have to do with SSH between Proxmox VE and FreeNAS. The code segment should start out �mkdir /etc/pve/priv/zfs�. I am currently in development to remove this depencancy from the ZFSPoolPlugin.pm so it is done in the FreeNAS.pm. -1. First use the following commands to patch the needed files for the FreeNAS Interface +1. Install the perl REST Client and git packages from the repository. + ```bash + apt-get install librest-client-perl git + ``` + +1. Issue the following (You can be in any directory you'd like but I use /root) + ```bash + git clone https://github.com/TheGrandWazoo/freenas-proxmox.git + ``` + +1. Next issue the following commands to patch the needed files for the FreeNAS Interface ```bash patch -b /usr/share/pve-manager/js/pvemanagerlib.js < pve-manager/js/pvemanagerlib.js.patch patch -b /usr/share/perl5/PVE/Storage/ZFSPlugin.pm < perl5/PVE/Storage/ZFSPlugin.pm.patch patch -b /usr/share/pve-docs/api-viewer/apidoc.js < pve-docs/api-viewer/apidoc.js.patch ``` -1. Install the perl REST Client package from the repository. - ```bash - apt-get install librest-client-perl - ``` - 1. Use the following command to copy the needed file for the FreeNAS connector. ```bash cp perl5/PVE/Storage/LunCmd/FreeNAS.pm /usr/share/perl5/PVE/Storage/LunCmd/FreeNAS.pm @@ -30,4 +35,10 @@ I am currently in development to remove this depencancy from the ZFSPoolPlugin.p systemctl restart pvestatd ``` -1. Refresh the Proxmox GUI in your browser to load the new Javascript code. +1. Remember to follow the instructions mentioned above for the SSH keys. + +1. Refresh the Proxmox GUI in your browser to load the new Javascript code. + +1. Add your new FreeNAS ZFS-over-iSCSI storage using the FreeNAS-API. + +1. Thanks for your support. diff --git a/perl5/PVE/Storage/.gitignore b/perl5/PVE/Storage/.gitignore index bafa238..5eba4e6 100644 --- a/perl5/PVE/Storage/.gitignore +++ b/perl5/PVE/Storage/.gitignore @@ -1,2 +1,4 @@ /ZFSPlugin.pm /ZFSPoolPlugin.pm +/ZFSPlugin-new.pm +/ZFSPlugin-newver.patch diff --git a/perl5/PVE/Storage/ZFSPlugin-5.0-42_1.pm.patch b/perl5/PVE/Storage/ZFSPlugin-5.0-42_1.pm.patch new file mode 100644 index 0000000..5bb7925 --- /dev/null +++ b/perl5/PVE/Storage/ZFSPlugin-5.0-42_1.pm.patch @@ -0,0 +1,147 @@ +--- ZFSPlugin.pm.orig 2019-04-30 09:54:55.000000000 -0400 ++++ ZFSPlugin.pm 2019-05-11 10:32:36.326734352 -0400 +@@ -10,6 +10,7 @@ + + use base qw(PVE::Storage::ZFSPoolPlugin); + use PVE::Storage::LunCmd::Comstar; ++use PVE::Storage::LunCmd::FreeNAS; + use PVE::Storage::LunCmd::Istgt; + use PVE::Storage::LunCmd::Iet; + use PVE::Storage::LunCmd::LIO; +@@ -26,13 +27,14 @@ + modify_lu => 1, + add_view => 1, + list_view => 1, ++ list_extent => 1, + list_lu => 1, + }; + + my $zfs_unknown_scsi_provider = sub { + my ($provider) = @_; + +- die "$provider: unknown iscsi provider. Available [comstar, istgt, iet, LIO]"; ++ die "$provider: unknown iscsi provider. Available [comstar, freenas, istgt, iet, LIO]"; + }; + + my $zfs_get_base = sub { +@@ -40,6 +42,8 @@ + + if ($scfg->{iscsiprovider} eq 'comstar') { + return PVE::Storage::LunCmd::Comstar::get_base; ++ } elsif ($scfg->{iscsiprovider} eq 'freenas') { ++ return PVE::Storage::LunCmd::FreeNAS::get_base; + } elsif ($scfg->{iscsiprovider} eq 'istgt') { + return PVE::Storage::LunCmd::Istgt::get_base; + } elsif ($scfg->{iscsiprovider} eq 'iet') { +@@ -62,6 +66,8 @@ + if ($lun_cmds->{$method}) { + if ($scfg->{iscsiprovider} eq 'comstar') { + $msg = PVE::Storage::LunCmd::Comstar::run_lun_command($scfg, $timeout, $method, @params); ++ } elsif ($scfg->{iscsiprovider} eq 'freenas') { ++ $msg = PVE::Storage::LunCmd::FreeNAS::run_lun_command($scfg, $timeout, $method, @params); + } elsif ($scfg->{iscsiprovider} eq 'istgt') { + $msg = PVE::Storage::LunCmd::Istgt::run_lun_command($scfg, $timeout, $method, @params); + } elsif ($scfg->{iscsiprovider} eq 'iet') { +@@ -160,6 +166,15 @@ + return $class->zfs_request($scfg, undef, 'list_view', $guid); + } + ++# Part of the multipath enhancement ++sub zfs_get_wwid_number { ++ my ($class, $scfg, $guid) = @_; ++ ++ die "could not find lun_number for guid $guid" if !$guid; ++ ++ return $class->zfs_request($scfg, undef, 'list_extent', $guid); ++} ++ + # Configuration + + sub type { +@@ -178,6 +193,24 @@ + description => "iscsi provider", + type => 'string', + }, ++ # This is for FreeNAS iscsi and API intergration ++ # And some enhancements asked by the community ++ freenas_user => { ++ description => "FreeNAS API Username", ++ type => 'string', ++ }, ++ freenas_password => { ++ description => "FreeNAS API Password", ++ type => 'string', ++ }, ++ freenas_use_ssl => { ++ description => "FreeNAS API access via SSL", ++ type => 'boolean', ++ }, ++ freenas_apiv4_host => { ++ description => "FreeNAS API Host", ++ type => 'string', ++ }, + # this will disable write caching on comstar and istgt. + # it is not implemented for iet. iet blockio always operates with + # writethrough caching when not in readonly mode +@@ -205,14 +238,18 @@ + nodes => { optional => 1 }, + disable => { optional => 1 }, + portal => { fixed => 1 }, +- target => { fixed => 1 }, +- pool => { fixed => 1 }, ++ target => { fixed => 0 }, ++ pool => { fixed => 0 }, + blocksize => { fixed => 1 }, + iscsiprovider => { fixed => 1 }, + nowritecache => { optional => 1 }, + sparse => { optional => 1 }, + comstar_hg => { optional => 1 }, + comstar_tg => { optional => 1 }, ++ freenas_user => { optional => 1 }, ++ freenas_password => { optional => 1 }, ++ freenas_use_ssl => { optional => 1 }, ++ freenas_apiv4_host => { optional => 1 }, + lio_tpg => { optional => 1 }, + content => { optional => 1 }, + bwlimit => { optional => 1 }, +@@ -237,6 +274,40 @@ + + my $path = "iscsi://$portal/$target/$lun"; + ++ # Multipath enhancement ++ eval { ++ my $wwid = $class->zfs_get_wwid_number($scfg, $guid); ++# syslog(info,"JD: path get_lun_number guid $guid"); ++ ++ if ($wwid =~ /^([-\@\w.]+)$/) { ++ $wwid = $1; # $data now untainted ++ } else { ++ die "Bad data in '$wwid'"; # log this somewhere ++ } ++ my $wwid_end = substr $wwid, 16; ++ ++ my $mapper = ''; ++ sleep 3; ++ run_command("iscsiadm -m session --rescan"); ++ sleep 3; ++ my $line = `multipath -ll | grep \"$wwid_end\"`; ++ my ($mapper_device) = split(' ', $line); ++ $mapper_device = "" unless $mapper_device; ++ $mapper .= $mapper_device; ++ ++ if ($mapper =~ /^([-\@\w.]+)$/) { ++ $mapper = $1; # $data now untainted ++ } else { ++ $mapper = ''; ++ } ++ ++# syslog(info,"Multipath mapper found: $mapper\n"); ++ if ($mapper ne "") { ++ $path = "/dev/mapper/$mapper"; ++ sleep 5; ++ } ++ }; ++ + return ($path, $vmid, $vtype); + } + diff --git a/perl5/PVE/Storage/ZFSPlugin.pm.patch b/perl5/PVE/Storage/ZFSPlugin.pm.patch index fa40368..5bb7925 100644 --- a/perl5/PVE/Storage/ZFSPlugin.pm.patch +++ b/perl5/PVE/Storage/ZFSPlugin.pm.patch @@ -1,5 +1,5 @@ ---- ZFSPlugin.pm.orig 2019-02-07 09:14:12.000000000 -0500 -+++ ZFSPlugin.pm 2019-02-26 20:53:29.096598801 -0500 +--- ZFSPlugin.pm.orig 2019-04-30 09:54:55.000000000 -0400 ++++ ZFSPlugin.pm 2019-05-11 10:32:36.326734352 -0400 @@ -10,6 +10,7 @@ use base qw(PVE::Storage::ZFSPoolPlugin); diff --git a/pve-docs/api-viewer/apidoc-5.4-2_1.js.patch b/pve-docs/api-viewer/apidoc-5.4-2_1.js.patch new file mode 100644 index 0000000..a054d90 --- /dev/null +++ b/pve-docs/api-viewer/apidoc-5.4-2_1.js.patch @@ -0,0 +1,79 @@ +--- apidoc.js.orig 2019-04-08 02:02:09.000000000 -0400 ++++ apidoc.js 2019-05-11 10:34:28.305764709 -0400 +@@ -34385,6 +34385,31 @@ + "type" : "string", + "typetext" : "" + }, ++ "freenas_user" : { ++ "description" : "FreeNAS user for API access", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, ++ "freenas_password" : { ++ "description" : "FreeNAS password for API access", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, ++ "freenas_use_ssl" : { ++ "description" : "FreeNAS API access via SSL", ++ "optional" : 1, ++ "type" : "boolean", ++ "typetext" : "" ++ }, ++ "freenas_apiv4_host" : { ++ "description" : "FreeNAS API Host via IPv4", ++ "format" : "address", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, +@@ -34541,6 +34566,12 @@ + "type" : "boolean", + "typetext" : "" + }, ++ "target" : { ++ "description" : "iSCSI target.", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ +@@ -34748,6 +34779,31 @@ + "optional" : 1, + "type" : "string", + "typetext" : "" ++ }, ++ "freenas_user" : { ++ "description" : "FreeNAS user for API access", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, ++ "freenas_password" : { ++ "description" : "FreeNAS password for API access", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" ++ }, ++ "freenas_use_ssl" : { ++ "description" : "FreeNAS API access via SSL", ++ "optional" : 1, ++ "type" : "boolean", ++ "typetext" : "" ++ }, ++ "freenas_apiv4_host" : { ++ "description" : "FreeNAS API Host via IPv4", ++ "format" : "address", ++ "optional" : 1, ++ "type" : "string", ++ "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", diff --git a/pve-docs/api-viewer/apidoc.js.patch b/pve-docs/api-viewer/apidoc.js.patch index ff25121..a054d90 100644 --- a/pve-docs/api-viewer/apidoc.js.patch +++ b/pve-docs/api-viewer/apidoc.js.patch @@ -1,6 +1,6 @@ ---- apidoc.js.orig 2019-02-20 06:20:05.000000000 -0500 -+++ apidoc.js 2019-02-26 20:51:26.857204965 -0500 -@@ -33709,6 +33709,31 @@ +--- apidoc.js.orig 2019-04-08 02:02:09.000000000 -0400 ++++ apidoc.js 2019-05-11 10:34:28.305764709 -0400 +@@ -34385,6 +34385,31 @@ "type" : "string", "typetext" : "" }, @@ -32,7 +32,7 @@ "fuse" : { "description" : "Mount CephFS through FUSE.", "optional" : 1, -@@ -33865,6 +33890,12 @@ +@@ -34541,6 +34566,12 @@ "type" : "boolean", "typetext" : "" }, @@ -45,7 +45,7 @@ "transport" : { "description" : "Gluster transport: tcp or rdma", "enum" : [ -@@ -34071,6 +34102,31 @@ +@@ -34748,6 +34779,31 @@ "optional" : 1, "type" : "string", "typetext" : "" diff --git a/pve-manager/js/pvemanagerlib-5.4-5_1.js.patch b/pve-manager/js/pvemanagerlib-5.4-5_1.js.patch new file mode 100644 index 0000000..32a982a --- /dev/null +++ b/pve-manager/js/pvemanagerlib-5.4-5_1.js.patch @@ -0,0 +1,189 @@ +--- pvemanagerlib.js.orig 2019-04-24 07:28:11.000000000 -0400 ++++ pvemanagerlib.js 2019-05-11 10:33:38.130198999 -0400 +@@ -6094,6 +6094,7 @@ + alias: ['widget.pveiScsiProviderSelector'], + comboItems: [ + ['comstar', 'Comstar'], ++ ['freenas', 'FreeNAS-API'], + [ 'istgt', 'istgt'], + [ 'iet', 'IET'], + [ 'LIO', 'LIO'] +@@ -31483,6 +31484,7 @@ + data: { + isLIO: false, + isComstar: true, ++ isFreeNAS: false, + hasWriteCacheOption: true + } + }, +@@ -31495,10 +31497,26 @@ + } + }, + changeISCSIProvider: function(f, newVal, oldVal) { ++ var me = this; + var vm = this.getViewModel(); + vm.set('isLIO', newVal === 'LIO'); + vm.set('isComstar', newVal === 'comstar'); +- vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'istgt'); ++ vm.set('isFreeNAS', newVal === 'freenas'); ++ vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'freenas' || newVal === 'istgt'); ++ if (newVal !== 'freenas') { ++ me.lookupReference('freenas_use_ssl_field').setValue(false); ++ me.lookupReference('freenas_apiv4_host_field').setValue(''); ++ me.lookupReference('freenas_user_field').setValue(''); ++ me.lookupReference('freenas_user_field').allowBlank = true; ++ me.lookupReference('freenas_password_field').setValue(''); ++ me.lookupReference('freenas_password_field').allowBlank = true; ++ me.lookupReference('freenas_confirmpw_field').setValue(''); ++ me.lookupReference('freenas_confirmpw_field').allowBlank = true; ++ } else { ++ me.lookupReference('freenas_user_field').allowBlank = false; ++ me.lookupReference('freenas_password_field').allowBlank = false; ++ me.lookupReference('freenas_confirmpw_field').allowBlank = false; ++ } + } + }, + +@@ -31516,6 +31534,7 @@ + }, + + setValues: function diff(values) { ++ values.freenas_confirmpw = values.freenas_password; + values.writecache = values.nowritecache ? 0 : 1; + this.callParent([values]); + }, +@@ -31532,7 +31551,7 @@ + allowBlank: false + }, + { +- xtype: me.isCreate ? 'textfield' : 'displayfield', ++ xtype: 'textfield', + name: 'pool', + value: '', + fieldLabel: gettext('Pool'), +@@ -31542,11 +31561,11 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'blocksize', + value: '4k', +- fieldLabel: gettext('Block Size'), ++ fieldLabel: gettext('ZFS Block Size'), + allowBlank: false + }, + { +- xtype: me.isCreate ? 'textfield' : 'displayfield', ++ xtype: 'textfield', + name: 'target', + value: '', + fieldLabel: gettext('Target'), +@@ -31557,8 +31576,33 @@ + name: 'comstar_tg', + value: '', + fieldLabel: gettext('Target group'), +- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, ++ bind: { ++ hidden: '{!isComstar}' ++ }, + allowBlank: true ++ }, ++ { ++ xtype: 'proxmoxcheckbox', ++ name: 'freenas_use_ssl', ++ reference: 'freenas_use_ssl_field', ++ inputId: 'freenas_use_ssl_field', ++ checked: false, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ uncheckedValue: 0, ++ fieldLabel: gettext('API use SSL') ++ }, ++ { ++ xtype: 'textfield', ++ name: 'freenas_user', ++ reference: 'freenas_user_field', ++ inputId: 'freenas_user_field', ++ value: '', ++ fieldLabel: gettext('API Username'), ++ bind: { ++ hidden: '{!isFreeNAS}' ++ } + } + ]; + +@@ -31589,7 +31633,9 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'comstar_hg', + value: '', +- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, ++ bind: { ++ hidden: '{!isComstar}' ++ }, + fieldLabel: gettext('Host group'), + allowBlank: true + }, +@@ -31597,9 +31643,62 @@ + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'lio_tpg', + value: '', +- bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' }, +- allowBlank: false, +- fieldLabel: gettext('Target portal group') ++ bind: { ++ hidden: '{!isLIO}' ++ }, ++ fieldLabel: gettext('Target portal group'), ++ allowBlank: true ++ }, ++ { ++ xtype: 'proxmoxtextfield', ++ name: 'freenas_apiv4_host', ++ reference: 'freenas_apiv4_host_field', ++ value: '', ++ editable: true, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('API IPv4 Host'), ++ }, ++ { ++ xtype: 'proxmoxtextfield', ++ name: 'freenas_password', ++ reference: 'freenas_password_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('API Password'), ++ change: function(f, value) { ++ if (f.rendered) { ++ f.up().down('field[name=freenas_confirmpw]').validate(); ++ } ++ } ++ }, ++ { ++ xtype: 'proxmoxtextfield', ++ name: 'freenas_confirmpw', ++ reference: 'freenas_confirmpw_field', ++ inputType: me.isCreate ? '' : 'password', ++ value: '', ++ editable: true, ++ submitValue: false, ++ emptyText: Proxmox.Utils.noneText, ++ bind: { ++ hidden: '{!isFreeNAS}' ++ }, ++ fieldLabel: gettext('Confirm Password'), ++ validator: function(value) { ++ var pw = this.up().down('field[name=freenas_password]').getValue(); ++ if (pw !== value) { ++ return "Passwords do not match!"; ++ } ++ return true; ++ } + } + ]; + diff --git a/pve-manager/js/pvemanagerlib.js.patch b/pve-manager/js/pvemanagerlib.js.patch index cfb2f99..32a982a 100644 --- a/pve-manager/js/pvemanagerlib.js.patch +++ b/pve-manager/js/pvemanagerlib.js.patch @@ -1,6 +1,6 @@ ---- pvemanagerlib.js.orig 2019-02-20 13:40:43.000000000 -0500 -+++ pvemanagerlib.js 2019-02-26 20:49:41.032327478 -0500 -@@ -5920,6 +5920,7 @@ +--- pvemanagerlib.js.orig 2019-04-24 07:28:11.000000000 -0400 ++++ pvemanagerlib.js 2019-05-11 10:33:38.130198999 -0400 +@@ -6094,6 +6094,7 @@ alias: ['widget.pveiScsiProviderSelector'], comboItems: [ ['comstar', 'Comstar'], @@ -8,7 +8,7 @@ [ 'istgt', 'istgt'], [ 'iet', 'IET'], [ 'LIO', 'LIO'] -@@ -30182,6 +30183,7 @@ +@@ -31483,6 +31484,7 @@ data: { isLIO: false, isComstar: true, @@ -16,7 +16,7 @@ hasWriteCacheOption: true } }, -@@ -30194,10 +30196,26 @@ +@@ -31495,10 +31497,26 @@ } }, changeISCSIProvider: function(f, newVal, oldVal) { @@ -44,7 +44,7 @@ } }, -@@ -30215,6 +30233,7 @@ +@@ -31516,6 +31534,7 @@ }, setValues: function diff(values) { @@ -52,7 +52,7 @@ values.writecache = values.nowritecache ? 0 : 1; this.callParent([values]); }, -@@ -30231,7 +30250,7 @@ +@@ -31532,7 +31551,7 @@ allowBlank: false }, { @@ -61,7 +61,7 @@ name: 'pool', value: '', fieldLabel: gettext('Pool'), -@@ -30241,11 +30260,11 @@ +@@ -31542,11 +31561,11 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'blocksize', value: '4k', @@ -75,7 +75,7 @@ name: 'target', value: '', fieldLabel: gettext('Target'), -@@ -30256,8 +30275,33 @@ +@@ -31557,8 +31576,33 @@ name: 'comstar_tg', value: '', fieldLabel: gettext('Target group'), @@ -110,7 +110,7 @@ } ]; -@@ -30288,7 +30332,9 @@ +@@ -31589,7 +31633,9 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'comstar_hg', value: '', @@ -121,7 +121,7 @@ fieldLabel: gettext('Host group'), allowBlank: true }, -@@ -30296,9 +30342,62 @@ +@@ -31597,9 +31643,62 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'lio_tpg', value: '',