New Directory structure

- Just preping for a new install process.
This commit is contained in:
Kevin Scott Adams 2019-09-24 07:55:10 -04:00
parent 4b46f2240f
commit 5d40ce4de6
33 changed files with 4481 additions and 0 deletions

4
stable-5/perl5/PVE/Storage/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/ZFSPlugin.pm
/ZFSPoolPlugin.pm
/ZFSPlugin-new.pm
/ZFSPlugin-newver.patch

View File

@ -0,0 +1,546 @@
package PVE::Storage::LunCmd::FreeNAS;
use strict;
use warnings;
use Data::Dumper;
use PVE::SafeSyslog;
use IO::Socket::SSL;
use REST::Client;
use MIME::Base64;
use JSON;
# Max LUNS per target on the iSCSI server
my $MAX_LUNS = 255;
#
#
#
sub get_base {
return '/dev/zvol';
}
#
#
#
sub run_lun_command {
my ($scfg, $timeout, $method, @params) = @_;
if(!defined($scfg->{'freenas_user'}) || !defined($scfg->{'freenas_password'})) {
die "Undefined freenas_user and/or freenas_password.";
}
syslog("info","FreeNAS::lun_command : $method(@params)");
if($method eq "create_lu") {
return run_create_lu($scfg, $timeout, $method, @params);
}
if($method eq "delete_lu") {
return run_delete_lu($scfg, $timeout, $method, @params);
}
if($method eq "import_lu") {
return run_create_lu($scfg, $timeout, $method, @params);
}
if($method eq "modify_lu") {
return run_modify_lu($scfg, $timeout, $method, @params);
}
if($method eq "add_view") {
return run_add_view($scfg, $timeout, $method, @params);
}
if($method eq "list_view") {
return run_list_view($scfg, $timeout, $method, @params);
}
if($method eq "list_extent") {
return run_list_extent($scfg, $timeout, $method, @params);
}
if($method eq "list_lu") {
return run_list_lu($scfg, $timeout, $method, "name", @params);
}
syslog("error","FreeNAS::lun_command : unknown method $method");
return undef;
}
#
#
#
sub run_add_view {
return '';
}
#
# a modify_lu occur by example on a zvol resize. we just need to destroy and recreate the lun with the same zvol.
# Be careful, the first param is the new size of the zvol, we must shift params
#
sub run_modify_lu {
my ($scfg, $timeout, $method, @params) = @_;
shift(@params);
run_delete_lu($scfg, $timeout, $method, @params);
return run_create_lu($scfg, $timeout, $method, @params);
}
#
#
#
sub run_list_view {
my ($scfg, $timeout, $method, @params) = @_;
return run_list_lu($scfg, $timeout, $method, "lun-id", @params);
}
#
#
#
sub run_list_lu {
my ($scfg, $timeout, $method, $result_value_type, @params) = @_;
my $object = $params[0];
my $result = undef;
my $luns = freenas_list_lu($scfg);
foreach my $lun (@$luns) {
if ($lun->{'iscsi_target_extent_path'} =~ /^$object$/) {
$result = $result_value_type eq "lun-id" ? $lun->{'iscsi_lunid'} : $lun->{'iscsi_target_extent_path'};
syslog("info","FreeNAS::list_lu($object):$result_value_type : lun found $result");
last;
}
}
if(!defined($result)) {
syslog("info","FreeNAS::list_lu($object):$result_value_type : lun not found");
}
return $result;
}
#
#
#
sub run_list_extent {
my ($scfg, $timeout, $method, @params) = @_;
my $object = $params[0];
my $result = undef;
my $luns = freenas_list_lu($scfg);
foreach my $lun (@$luns) {
if ($lun->{'iscsi_target_extent_path'} =~ /^$object$/) {
$result = $lun->{'iscsi_target_extent_naa'};
syslog("info","FreeNAS::list_extent($object): naa found $result");
last;
}
}
if (!defined($result)) {
syslog("info","FreeNAS::list_extent($object): naa not found");
}
return $result;
}
#
#
#
sub run_create_lu {
my ($scfg, $timeout, $method, @params) = @_;
my $lun_path = $params[0];
my $lun_id = freenas_get_first_available_lunid($scfg);
die "Maximum number of LUNs per target is $MAX_LUNS" if scalar $lun_id >= $MAX_LUNS;
die "$params[0]: LUN $lun_path exists" if defined(run_list_lu($scfg, $timeout, $method, "name", @params));
my $target_id = freenas_get_targetid($scfg);
die "Unable to find the target id for $scfg->{target}" if !defined($target_id);
# Create the extent
my $extent = freenas_iscsi_create_extent($scfg, $lun_path);
# Associate the new extent to the target
my $link = freenas_iscsi_create_target_to_extent($scfg, $target_id, $extent->{'id'}, $lun_id);
if (defined($link)) {
syslog("info","FreeNAS::create_lu(lun_path=$lun_path, lun_id=$lun_id) : sucessfull");
} else {
die "Unable to create lun $lun_path";
}
return "";
}
#
#
#
sub run_delete_lu {
my ($scfg, $timeout, $method, @params) = @_;
my $lun_path = $params[0];
my $luns = freenas_list_lu($scfg);
my $lun = undef;
my $link = undef;
foreach my $item (@$luns) {
if($item->{'iscsi_target_extent_path'} =~ /^$lun_path$/) {
$lun = $item;
last;
}
}
die "Unable to find the lun $lun_path for $scfg->{target}" if !defined($lun);
my $target_id = freenas_get_targetid($scfg);
die "Unable to find the target id for $scfg->{target}" if !defined($target_id);
# find the target to extent
my $target2extents = freenas_iscsi_get_target_to_extent($scfg);
foreach my $item (@$target2extents) {
if($item->{'iscsi_target'} == $target_id &&
$item->{'iscsi_lunid'} == $lun->{'iscsi_lunid'} &&
$item->{'iscsi_extent'} == $lun->{'id'}) {
$link = $item;
last;
}
}
die "Unable to find the link for the lun $lun_path for $scfg->{target}" if !defined($link);
# Remove the link
my $remove_link = freenas_iscsi_remove_target_to_extent($scfg, $link->{'id'});
# Remove the extent
my $remove_extent = freenas_iscsi_remove_extent($scfg, $lun->{'id'});
if($remove_link == 1 && $remove_extent == 1) {
syslog("info","FreeNAS::delete_lu(lun_path=$lun_path) : sucessfull");
} else {
die "Unable to delete lun $lun_path";
}
return "";
}
#
### FREENAS API CALLING ###
#
sub freenas_api_call {
my ($scfg, $method, $path, $data) = @_;
my $client = undef;
my $scheme = $scfg->{freenas_use_ssl} ? "https" : "http";
my $apihost = defined($scfg->{freenas_apiv4_host}) ? $scfg->{freenas_apiv4_host} : $scfg->{portal};
my $apiping = '/api/v1.0/system/version/';
$client = REST::Client->new();
$client->setHost($scheme . '://' . $apihost);
$client->addHeader('Content-Type' , 'application/json');
$client->addHeader('Authorization' , 'Basic ' . encode_base64($scfg->{freenas_user} . ':' . $scfg->{freenas_password}));
# If using SSL, don't verify SSL certs
if ($scfg->{freenas_use_ssl}) {
$client->getUseragent()->ssl_opts(verify_hostname => 0);
$client->getUseragent()->ssl_opts(SSL_verify_mode => SSL_VERIFY_NONE);
}
# Check if the APIs are accessable via the selected host and scheme
my $code = $client->request('GET', $apiping)->responseCode();
if ($code != 200) {
freenas_api_log_error($client, "freenas_api_call");
die "Unable to connect to the FreeNAS API service at '" . $apihost . "' using the '" . $scheme . "' protocol";
}
syslog("info","FreeNAS::api_call : setup : sucessfull");
if ($method eq 'GET') {
$client->GET($path);
}
if ($method eq 'DELETE') {
$client->DELETE($path);
}
if ($method eq 'POST') {
$client->POST($path, encode_json($data));
}
return $client
}
#
# Writes the Response and Content to SysLog
#
sub freenas_api_log_error {
my ($client, $method) = @_;
syslog("info","[ERROR]FreeNAS::API::" . $method . " : Response code: " . $client->responseCode());
syslog("info","[ERROR]FreeNAS::API::" . $method . " : Response content: " . $client->responseContent());
return 1;
}
#
#
#
sub freenas_iscsi_get_globalconfiguration {
my ($scfg) = @_;
my $client = freenas_api_call($scfg, 'GET', "/api/v1.0/services/iscsi/globalconfiguration/", undef);
my $code = $client->responseCode();
if ($code == 200) {
my $result = decode_json($client->responseContent());
syslog("info","FreeNAS::API::get_globalconfig : target_basename=" . $result->{'iscsi_basename'});
return $result;
} else {
freenas_api_log_error($client, "get_globalconfig");
return undef;
}
}
#
# Returns a list of all extents.
# http://api.freenas.org/resources/iscsi/index.html#get--api-v1.0-services-iscsi-extent-
#
sub freenas_iscsi_get_extent {
my ($scfg) = @_;
my $client = freenas_api_call($scfg, 'GET', "/api/v1.0/services/iscsi/extent/?limit=0", undef);
my $code = $client->responseCode();
if ($code == 200) {
my $result = decode_json($client->responseContent());
syslog("info","FreeNAS::API::get_extent : sucessfull");
return $result;
} else {
freenas_api_log_error($client, "get_extent");
return undef;
}
}
#
# Create an extent on FreeNas
# http://api.freenas.org/resources/iscsi/index.html#create-resource
# Parameters:
# - target config (scfg)
# - lun_path
#
sub freenas_iscsi_create_extent {
my ($scfg, $lun_path) = @_;
my $name = $lun_path;
$name =~ s/^.*\///; # all from last /
$name = $scfg->{'pool'} . '/' . $name;
my $device = $lun_path;
$device =~ s/^\/dev\///; # strip /dev/
my $request = {
"iscsi_target_extent_type" => "Disk",
"iscsi_target_extent_name" => $name,
"iscsi_target_extent_disk" => $device,
};
my $client = freenas_api_call($scfg, 'POST', "/api/v1.0/services/iscsi/extent/", $request);
my $code = $client->responseCode();
if ($code == 201) {
my $result = decode_json($client->responseContent());
syslog("info", "FreeNAS::API::create_extent(lun_path=" . $result->{'iscsi_target_extent_path'} . ") : sucessfull");
return $result;
} else {
freenas_api_log_error($client, "create_extent");
return undef;
}
}
#
# Remove an extent by it's id
# http://api.freenas.org/resources/iscsi/index.html#delete-resource
# Parameters:
# - scfg
# - extent_id
#
sub freenas_iscsi_remove_extent {
my ($scfg, $extent_id) = @_;
my $client = freenas_api_call($scfg, 'DELETE', "/api/v1.0/services/iscsi/extent/$extent_id/", undef);
my $code = $client->responseCode();
if ($code == 204) {
syslog("info","FreeNAS::API::remove_extent(extent_id=$extent_id) : sucessfull");
return 1;
} else {
freenas_api_log_error($client, "remove_extent");
return 0;
}
}
#
# Returns a list of all targets
# http://api.freenas.org/resources/iscsi/index.html#get--api-v1.0-services-iscsi-target-
#
sub freenas_iscsi_get_target {
my ($scfg) = @_;
my $client = freenas_api_call($scfg, 'GET', "/api/v1.0/services/iscsi/target/?limit=0", undef);
my $code = $client->responseCode();
if ($code == 200) {
my $result = decode_json($client->responseContent());
syslog("info","FreeNAS::API::get_target() : sucessfull");
return $result;
} else {
freenas_api_log_error($client, "get_target");
return undef;
}
}
#
# Returns a list of associated extents to targets
# http://api.freenas.org/resources/iscsi/index.html#get--api-v1.0-services-iscsi-targettoextent-
#
sub freenas_iscsi_get_target_to_extent {
my ($scfg) = @_;
my $client = freenas_api_call($scfg, 'GET', "/api/v1.0/services/iscsi/targettoextent/?limit=0", undef);
my $code = $client->responseCode();
if ($code == 200) {
my $result = decode_json($client->responseContent());
syslog("info","FreeNAS::API::get_target_to_extent() : sucessfull");
# If 'iscsi_lunid' is undef then it is set to 'Auto' in FreeNAS
# which should be '0' in our eyes.
# This gave Proxmox 5.x and FreeNAS 11.1 a few issues.
foreach my $item (@$result) {
if (!defined($item->{'iscsi_lunid'})) {
$item->{'iscsi_lunid'} = 0;
syslog("info", "FreeNAS::API::get_target_to_extent() : change undef iscsi_lunid to 0");
}
}
return $result;
} else {
freenas_api_log_error($client, "get_target_to_extent");
return undef;
}
}
#
# Associate a FreeNas extent to a FreeNas Target
# http://api.freenas.org/resources/iscsi/index.html#post--api-v1.0-services-iscsi-targettoextent-
# Parameters:
# - target config (scfg)
# - FreeNas Target ID
# - FreeNas Extent ID
# - Lun ID
#
sub freenas_iscsi_create_target_to_extent {
my ($scfg, $target_id, $extent_id, $lun_id) = @_;
my $request = {
"iscsi_target" => $target_id,
"iscsi_extent" => $extent_id,
"iscsi_lunid" => $lun_id
};
my $client = freenas_api_call($scfg, 'POST', "/api/v1.0/services/iscsi/targettoextent/", $request);
my $code = $client->responseCode();
if ($code == 201) {
my $result = decode_json($client->responseContent());
syslog("info","FreeNAS::API::create_target_to_extent(target_id=$target_id, extent_id=$extent_id, lun_id=$lun_id) : sucessfull");
return $result;
} else {
freenas_api_log_error($client, "create_target_to_extent");
return undef;
}
}
#
# Remove a Target to extent by it's id
# http://api.freenas.org/resources/iscsi/index.html#delete--api-v1.0-services-iscsi-targettoextent-(int-id)-
# Parameters:
# - scfg
# - link_id
#
sub freenas_iscsi_remove_target_to_extent {
my ($scfg, $link_id) = @_;
my $client = freenas_api_call($scfg, 'DELETE', "/api/v1.0/services/iscsi/targettoextent/$link_id/", undef);
my $code = $client->responseCode();
if ($code == 204) {
syslog("info","FreeNAS::API::remove_target_to_extent(link_id=$link_id) : sucessfull");
return 1;
} else {
freenas_api_log_error($client, "remove_target_to_extent");
return 0;
}
}
#
# Returns all luns associated to the current target defined by $scfg->{target}
# This method returns an array reference like "freenas_iscsi_get_extent" do
# but with an additionnal hash entry "iscsi_lunid" retrieved from "freenas_iscsi_get_target_to_extent"
#
sub freenas_list_lu {
my ($scfg) = @_;
my $targets = freenas_iscsi_get_target($scfg);
my $target_id = freenas_get_targetid($scfg);
my @luns = ();
my $iscsi_lunid = undef;
if(defined($target_id)) {
my $target2extents = freenas_iscsi_get_target_to_extent($scfg);
my $extents = freenas_iscsi_get_extent($scfg);
foreach my $item (@$target2extents) {
if($item->{'iscsi_target'} == $target_id) {
foreach my $node (@$extents) {
if($node->{'id'} == $item->{'iscsi_extent'}) {
if ($item->{'iscsi_lunid'} =~ /(\d+)/) {
$iscsi_lunid = "$1";
} else {
syslog("info", "FreeNAS::API::freenas_list_lu : iscsi_lunid did not pass tainted testing");
next;
}
$node->{'iscsi_lunid'} .= $iscsi_lunid;
push(@luns , $node);
}
}
}
}
}
syslog("info", "FreeNAS::API::freenas_list_lu : sucessfull");
return \@luns;
}
#
# Returns the first available "lunid" (in all targets namespaces)
#
sub freenas_get_first_available_lunid {
my ($scfg) = @_;
my $target_id = freenas_get_targetid($scfg);
my $target2extents = freenas_iscsi_get_target_to_extent($scfg);
my @luns = ();
foreach my $item (@$target2extents) {
push(@luns, $item->{'iscsi_lunid'}) if ($item->{'iscsi_target'} == $target_id);
}
my @sorted_luns = sort {$a <=> $b} @luns;
my $lun_id = 0;
# find the first hole, if not, give the +1 of the last lun
foreach my $lun (@sorted_luns) {
last if $lun != $lun_id;
$lun_id = $lun_id + 1;
}
syslog("info", "FreeNAS::API::freenas_get_first_available_lunid : return $lun_id");
return $lun_id;
}
#
# Returns the target id on FreeNas of the currently configured target of this PVE storage
#
sub freenas_get_targetid {
my ($scfg) = @_;
my $global = freenas_iscsi_get_globalconfiguration($scfg);
my $targets = freenas_iscsi_get_target($scfg);
my $target_id = undef;
foreach my $target (@$targets) {
my $iqn = $global->{'iscsi_basename'} . ':' . $target->{'iscsi_target_name'};
if($iqn eq $scfg->{target}) {
$target_id = $target->{'id'};
last;
}
}
return $target_id;
}
1;

View File

@ -0,0 +1,140 @@
--- ZFSPlugin.pm.orig 2018-10-03 11:02:46.000000000 -0400
+++ ZFSPlugin.pm 2018-10-28 21:27:44.794732848 -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;
@@ -32,7 +33,7 @@
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 +41,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 +65,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 +165,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 +192,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 +237,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 +273,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);
}

View File

@ -0,0 +1,10 @@
--- ZFSPlugin-5.0-33.pm 2018-12-15 09:29:56.586101170 -0500
+++ ZFSPlugin.pm 2018-12-15 09:24:08.393984276 -0500
@@ -27,6 +27,7 @@
modify_lu => 1,
add_view => 1,
list_view => 1,
+ list_extent => 1,
list_lu => 1,
};

View File

@ -0,0 +1,147 @@
--- ZFSPlugin.pm.orig 2018-11-27 07:23:15.000000000 -0500
+++ ZFSPlugin.pm 2018-12-15 09:24:08.393984276 -0500
@@ -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);
}

View File

@ -0,0 +1,147 @@
--- ZFSPlugin-5.0-34.pm 2018-12-21 12:52:21.764194866 -0500
+++ ZFSPlugin.pm 2018-12-21 12:53:08.663665081 -0500
@@ -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);
}

View File

@ -0,0 +1,147 @@
--- ZFSPlugin.pm.orig 2019-02-07 09:14:12.000000000 -0500
+++ ZFSPlugin.pm 2019-02-26 20:53:29.096598801 -0500
@@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,147 @@
--- ZFSPlugin.pm.orig 2019-06-25 06:54:50.000000000 -0400
+++ ZFSPlugin.pm 2019-07-16 13:36:48.817831174 -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);
}

View File

@ -0,0 +1 @@
/apidoc.js

View File

@ -0,0 +1,66 @@
--- apidoc.js.orig 2018-08-19 10:18:11.715767285 -0400
+++ apidoc.js.new 2018-08-19 10:17:09.364282178 -0400
@@ -27584,6 +27584,31 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"content" : {
"description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n",
"format" : "pve-storage-content-list",
@@ -27948,6 +27973,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"content" : {
"description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n",

View File

@ -0,0 +1,79 @@
--- apidoc-5.2-9.js 2018-11-10 14:28:44.022355849 -0500
+++ apidoc.js 2018-11-10 15:49:38.873720011 -0500
@@ -32448,6 +32448,31 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -32604,6 +32629,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -32810,6 +32841,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

View File

@ -0,0 +1,79 @@
--- apidoc-5.3-1.js 2018-12-21 12:46:55.459865478 -0500
+++ apidoc.js 2018-12-06 15:50:21.487987807 -0500
@@ -33477,6 +33477,31 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -33633,6 +33658,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -33840,6 +33871,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

View File

@ -0,0 +1,79 @@
--- 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 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -33865,6 +33890,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -34071,6 +34102,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

View File

@ -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" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -34541,6 +34566,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -34748,6 +34779,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

1
stable-5/pve-manager/js/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/pvemanagerlib.js

View File

@ -0,0 +1,167 @@
--- pvemanagerlib-5.2-10.js 2018-10-23 07:18:18.058603386 -0400
+++ pvemanagerlib.js 2018-10-23 15:29:52.573563883 -0400
@@ -5597,6 +5597,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -28583,6 +28584,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -28595,10 +28597,19 @@
}
},
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_password_field').setValue('');
+ me.lookupReference('freenas_confirmpw_field').setValue('');
+ }
}
},
@@ -28616,6 +28627,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -28632,7 +28644,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -28646,7 +28658,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'target',
value: '',
fieldLabel: gettext('Target'),
@@ -28657,8 +28669,28 @@
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: '',
+ allowBlank: false,
+ fieldLabel: gettext('API Username'),
+ bind: { hidden: '{!isFreeNAS}' },
}
];
@@ -28689,7 +28721,7 @@
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
},
@@ -28697,9 +28729,60 @@
xtype: me.isCreate ? 'textfield' : 'displayfield',
name: 'lio_tpg',
value: '',
- bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' },
+ bind: { hidden: '{!isLIO}' },
+ fieldLabel: gettext('Target portal group'),
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'freenas_apiv4_host',
+ reference: 'freenas_apiv4_host_field',
+ value: '',
+ editable: true,
+ allowBlank: true,
+ emptyText: Proxmox.Utils.noneText,
+ bind: { hidden: '{!isFreeNAS}' },
+ fieldLabel: gettext('API IPv4 Host'),
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'freenas_password',
+ reference: 'freenas_password_field',
+ inputType: me.isCreate ? '' : 'password',
+ value: '',
+ editable: true,
+ deleteEmpty: true,
+ allowBlank: false,
+ 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,
+ deleteEmpty: true,
allowBlank: false,
- fieldLabel: gettext('Target portal group')
+ 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;
+ }
}
];

View File

@ -0,0 +1,86 @@
--- pvemanagerlib.js.orig 2018-07-30 23:13:28.045035059 -0400
+++ pvemanagerlib.js.new 2018-08-19 10:42:58.494724196 -0400
@@ -5379,6 +5379,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET']
]
@@ -27361,7 +27362,23 @@
value: '',
fieldLabel: gettext('Target group'),
allowBlank: true
- }
+ },
+ {
+ xtype: 'proxmoxcheckbox',
+ name: 'freenas_use_ssl',
+ checked: false,
+ uncheckedValue: 0,
+ hidden: me.iscsiprovider !== "freenas",
+ fieldLabel: gettext('FreeNAS API use SSL')
+ },
+ {
+ xtype: me.isCreate ? 'textfield' : 'displayfield',
+ name: 'freenas_user',
+ value: '',
+ hidden: me.iscsiprovider !== "freenas",
+ fieldLabel: gettext('FreeNAS User'),
+ allowBlank: true
+ },
];
me.column2 = [
@@ -27370,7 +27387,26 @@
name: 'iscsiprovider',
value: 'comstar',
fieldLabel: gettext('iSCSI Provider'),
- allowBlank: false
+ allowBlank: false,
+ listeners: {
+ change: function(f, value) {
+ if (value === "freenas") {
+ me.down('field[name=freenas_use_ssl]').setHidden(false);
+ me.down('field[name=freenas_apiv4_host]').setHidden(false);
+ me.down('field[name=freenas_user]').setHidden(false);
+ me.down('field[name=freenas_password]').setHidden(false);
+ } else {
+ me.down('field[name=freenas_use_ssl]').setHidden(true);
+ me.down('field[name=freenas_use_ssl]').setValue(false);
+ me.down('field[name=freenas_apiv4_host]').setHidden(true);
+ me.down('field[name=freenas_apiv4_host]').setValue(false);
+ me.down('field[name=freenas_user]').setHidden(true);
+ me.down('field[name=freenas_user]').setValue('');
+ me.down('field[name=freenas_password]').setHidden(true);
+ me.down('field[name=freenas_password]').setValue('');
+ }
+ }
+ }
},
{
xtype: 'proxmoxcheckbox',
@@ -27392,6 +27428,22 @@
value: '',
fieldLabel: gettext('Host group'),
allowBlank: true
+ },
+ {
+ xtype: me.isCreate ? 'textfield' : 'displayfield',
+ name: 'freenas_apiv4_host',
+ value: '',
+ hidden: me.iscsiprovider !== "freenas",
+ fieldLabel: gettext('API IPv4 Host'),
+ allowBlank: true
+ },
+ {
+ xtype: me.isCreate ? 'textfield' : 'displayfield',
+ name: 'freenas_password',
+ value: '',
+ hidden: me.iscsiprovider !== "freenas",
+ fieldLabel: gettext('FreeNAS Password'),
+ allowBlank: true
}
];

View File

@ -0,0 +1,102 @@
--- pvemanagerlib.js.5.2-8.js 2018-08-30 20:10:52.957313992 -0400
+++ pvemanagerlib.js.new 2018-09-01 16:20:05.131908768 -0400
@@ -28578,6 +28578,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -28590,11 +28591,18 @@
}
},
changeISCSIProvider: function(f, newVal, oldVal) {
+ var me = this;
var vm = this.getViewModel();
vm.set('isLIO', newVal === 'LIO');
vm.set('isComstar', newVal === 'comstar');
vm.set('isFreeNAS', newVal === 'freenas');
- vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'istgt');
+ 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_password_field').setValue('');
+ }
}
},
@@ -28653,16 +28661,28 @@
name: 'comstar_tg',
value: '',
fieldLabel: gettext('Target group'),
- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' },
+ bind: me.isCreate ? { hidden: '{!isComstar}' } : { hidden: '{!isComstar}' },
allowBlank: true
},
{
+ xtype: 'proxmoxcheckbox',
+ name: 'freenas_use_ssl',
+ reference: 'freenas_use_ssl_field',
+ inputId: 'freenas_use_ssl_field',
+ checked: false,
+ bind: me.isCreate ? { hidden: '{!isFreeNAS}' } : { hidden: '{!isFreeNAS}' },
+ uncheckedValue: 0,
+ fieldLabel: gettext('API use SSL')
+ },
+ {
xtype: me.isCreate ? 'textfield' : 'displayfield',
name: 'freenas_user',
+ reference: 'freenas_user_field',
+ inputId: 'freenas_user_field',
value: '',
- fieldLabel: gettext('FreeNAS User'),
+ fieldLabel: gettext('API Username'),
bind: me.isCreate ? { hidden: '{!isFreeNAS}' } : { hidden: '{!isFreeNAS}' },
- allowBlank: true
+ allowBlank: me.isFreeNAS ? false : true
}
];
@@ -28693,7 +28713,7 @@
xtype: me.isCreate ? 'textfield' : 'displayfield',
name: 'comstar_hg',
value: '',
- bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' },
+ bind: me.isCreate ? { hidden: '{!isComstar}' } : { hidden: '{!isComstar}' },
fieldLabel: gettext('Host group'),
allowBlank: true
},
@@ -28701,9 +28721,27 @@
xtype: me.isCreate ? 'textfield' : 'displayfield',
name: 'lio_tpg',
value: '',
- bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' },
- allowBlank: false,
- fieldLabel: gettext('Target portal group')
+ bind: me.isCreate ? { hidden: '{!isLIO}' } : { hidden: '{!isLIO}' },
+ fieldLabel: gettext('Target portal group'),
+ allowBlank: true
+ },
+ {
+ xtype: me.isCreate ? 'textfield' : 'displayfield',
+ name: 'freenas_apiv4_host',
+ reference: 'freenas_apiv4_host_field',
+ value: '',
+ bind: me.isCreate ? { hidden: '{!isFreeNAS}' } : { hidden: '{!isFreeNAS}' },
+ fieldLabel: gettext('API IPv4 Host'),
+ allowBlank: true
+ },
+ {
+ xtype: me.isCreate ? 'textfield' : 'displayfield',
+ name: 'freenas_password',
+ reference: 'freenas_password_field',
+ value: '',
+ bind: me.isCreate ? { hidden: '{!isFreeNAS}' } : { hidden: '{!isFreeNAS}' },
+ fieldLabel: gettext('API Password'),
+ allowBlank: true
}
];

View File

@ -0,0 +1,169 @@
--- pvemanagerlib-5.2-9.js 2018-10-16 07:17:21.915593478 -0400
+++ pvemanagerlib.js 2018-10-21 21:52:20.781740237 -0400
@@ -5597,6 +5597,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -28574,6 +28575,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -28586,10 +28588,19 @@
}
},
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_password_field').setValue('');
+ me.lookupReference('freenas_confirmpw_field').setValue('');
+ }
}
},
@@ -28607,6 +28618,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -28623,7 +28635,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -28637,7 +28649,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'target',
value: '',
fieldLabel: gettext('Target'),
@@ -28648,8 +28660,28 @@
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: '',
+ allowBlank: false,
+ fieldLabel: gettext('API Username'),
+ bind: { hidden: '{!isFreeNAS}' },
}
];
@@ -28680,7 +28712,7 @@
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
},
@@ -28688,9 +28720,61 @@
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,
+ deleteEmpty: true,
+ allowBlank: true,
+ emptyText: Proxmox.Utils.noneText,
+ bind: { hidden: '{!isFreeNAS}' },
+ fieldLabel: gettext('API IPv4 Host'),
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'freenas_password',
+ reference: 'freenas_password_field',
+ inputType: me.isCreate ? '' : 'password',
+ value: '',
+ editable: true,
+ deleteEmpty: true,
+ allowBlank: false,
+ 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,
+ deleteEmpty: true,
+ allowBlank: false,
+ 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;
+ }
}
];

View File

@ -0,0 +1,189 @@
--- 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 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -30182,6 +30183,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -30194,10 +30196,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;
+ }
}
},
@@ -30215,6 +30233,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -30231,7 +30250,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -30241,11 +30260,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'),
@@ -30256,8 +30275,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}'
+ }
}
];
@@ -30288,7 +30332,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
},
@@ -30296,9 +30342,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;
+ }
}
];

View File

@ -0,0 +1,172 @@
--- pvemanagerlib-5.3-5.js 2018-12-21 12:34:35.727962756 -0500
+++ pvemanagerlib.js 2018-12-21 12:43:02.370462786 -0500
@@ -5854,6 +5854,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -29983,6 +29984,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -29995,10 +29997,19 @@
}
},
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_password_field').setValue('');
+ me.lookupReference('freenas_confirmpw_field').setValue('');
+ }
}
},
@@ -30016,6 +30027,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -30032,7 +30044,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -30042,11 +30054,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'),
@@ -30057,8 +30069,28 @@
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: '',
+ allowBlank: false,
+ fieldLabel: gettext('API Username'),
+ bind: { hidden: '{!isFreeNAS}' },
}
];
@@ -30089,7 +30121,7 @@
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
},
@@ -30097,9 +30129,60 @@
xtype: me.isCreate ? 'textfield' : 'displayfield',
name: 'lio_tpg',
value: '',
- bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' },
+ bind: { hidden: '{!isLIO}' },
+ fieldLabel: gettext('Target portal group'),
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'freenas_apiv4_host',
+ reference: 'freenas_apiv4_host_field',
+ value: '',
+ editable: true,
+ allowBlank: true,
+ emptyText: Proxmox.Utils.noneText,
+ bind: { hidden: '{!isFreeNAS}' },
+ fieldLabel: gettext('API IPv4 Host'),
+ allowBlank: true
+ },
+ {
+ xtype: 'proxmoxtextfield',
+ name: 'freenas_password',
+ reference: 'freenas_password_field',
+ inputType: me.isCreate ? '' : 'password',
+ value: '',
+ editable: true,
+ deleteEmpty: true,
+ allowBlank: false,
+ 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,
+ deleteEmpty: true,
allowBlank: false,
- fieldLabel: gettext('Target portal group')
+ 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;
+ }
}
];

View File

@ -0,0 +1,191 @@
--- pvemanagerlib-5.3-6.js 2018-12-21 12:54:58.650421078 -0500
+++ pvemanagerlib.js 2019-02-01 13:52:17.906074280 -0500
@@ -5894,6 +5894,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -30085,6 +30086,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -30097,10 +30099,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;
+ }
}
},
@@ -30118,6 +30136,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -30134,7 +30153,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -30144,11 +30163,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'),
@@ -30159,8 +30178,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}'
+ }
}
];
@@ -30191,7 +30235,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
},
@@ -30199,9 +30245,64 @@
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,
+ deleteEmpty: 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,
+ deleteEmpty: true,
+ 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;
+ }
}
];

View File

@ -0,0 +1,189 @@
--- pvemanagerlib.js.orig 2019-01-11 04:23:42.000000000 -0500
+++ pvemanagerlib.js 2019-02-05 07:30:18.168655803 -0500
@@ -5894,6 +5894,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -30085,6 +30086,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -30097,10 +30099,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;
+ }
}
},
@@ -30118,6 +30136,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -30134,7 +30153,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -30144,11 +30163,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'),
@@ -30159,8 +30178,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}'
+ }
}
];
@@ -30191,7 +30235,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
},
@@ -30199,9 +30245,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;
+ }
}
];

View File

@ -0,0 +1,189 @@
--- pvemanagerlib.js.orig 2019-07-09 03:52:19.000000000 -0400
+++ pvemanagerlib.js 2019-07-16 13:59:37.658409977 -0400
@@ -6094,6 +6094,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -31700,6 +31701,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -31712,10 +31714,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;
+ }
}
},
@@ -31733,6 +31751,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -31749,7 +31768,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -31759,11 +31778,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'),
@@ -31774,8 +31793,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}'
+ }
}
];
@@ -31806,7 +31850,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
},
@@ -31814,9 +31860,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;
+ }
}
];

View File

@ -0,0 +1,189 @@
--- pvemanagerlib.js.orig 2019-07-26 04:14:56.000000000 -0400
+++ pvemanagerlib.js 2019-08-05 16:02:38.484913553 -0400
@@ -6094,6 +6094,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -31722,6 +31723,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -31734,10 +31736,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;
+ }
}
},
@@ -31755,6 +31773,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -31771,7 +31790,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -31781,11 +31800,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'),
@@ -31796,8 +31815,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}'
+ }
}
];
@@ -31828,7 +31872,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
},
@@ -31836,9 +31882,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;
+ }
}
];

View File

@ -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;
+ }
}
];

View File

@ -0,0 +1,147 @@
--- ZFSPlugin.pm.orig 2019-07-25 07:34:52.000000000 -0400
+++ ZFSPlugin.pm 2019-08-07 13:28:29.268383007 -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);
}

View File

@ -0,0 +1,147 @@
--- ZFSPlugin.pm.orig 2019-07-25 07:34:52.000000000 -0400
+++ ZFSPlugin.pm 2019-08-07 13:28:29.268383007 -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);
}

View File

@ -0,0 +1,79 @@
--- apidoc.js.orig 2019-07-15 15:45:00.000000000 -0400
+++ apidoc.js 2019-08-07 13:28:29.292382229 -0400
@@ -35001,6 +35001,31 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -35157,6 +35182,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -35362,6 +35393,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

View File

@ -0,0 +1,79 @@
--- apidoc.js.orig 2019-07-15 15:45:00.000000000 -0400
+++ apidoc.js 2019-08-07 13:28:29.292382229 -0400
@@ -35001,6 +35001,31 @@
"type" : "string",
"typetext" : "<string>"
},
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"fuse" : {
"description" : "Mount CephFS through FUSE.",
"optional" : 1,
@@ -35157,6 +35182,12 @@
"type" : "boolean",
"typetext" : "<boolean>"
},
+ "target" : {
+ "description" : "iSCSI target.",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
"transport" : {
"description" : "Gluster transport: tcp or rdma",
"enum" : [
@@ -35362,6 +35393,31 @@
"optional" : 1,
"type" : "string",
"typetext" : "<string>"
+ },
+ "freenas_user" : {
+ "description" : "FreeNAS user for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_password" : {
+ "description" : "FreeNAS password for API access",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
+ },
+ "freenas_use_ssl" : {
+ "description" : "FreeNAS API access via SSL",
+ "optional" : 1,
+ "type" : "boolean",
+ "typetext" : "<boolean>"
+ },
+ "freenas_apiv4_host" : {
+ "description" : "FreeNAS API Host via IPv4",
+ "format" : "address",
+ "optional" : 1,
+ "type" : "string",
+ "typetext" : "<string>"
},
"fuse" : {
"description" : "Mount CephFS through FUSE.",

View File

@ -0,0 +1,189 @@
--- pvemanagerlib.js.orig 2019-07-23 13:21:08.000000000 -0400
+++ pvemanagerlib.js 2019-08-07 13:28:29.304381840 -0400
@@ -6182,6 +6182,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -32977,6 +32978,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -32989,10 +32991,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;
+ }
}
},
@@ -33010,6 +33028,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -33026,7 +33045,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -33036,11 +33055,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'),
@@ -33051,8 +33070,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}'
+ }
}
];
@@ -33083,7 +33127,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
},
@@ -33091,9 +33137,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;
+ }
}
];

View File

@ -0,0 +1,189 @@
--- pvemanagerlib.js.orig 2019-07-23 13:21:08.000000000 -0400
+++ pvemanagerlib.js 2019-08-07 13:28:29.304381840 -0400
@@ -6182,6 +6182,7 @@
alias: ['widget.pveiScsiProviderSelector'],
comboItems: [
['comstar', 'Comstar'],
+ ['freenas', 'FreeNAS-API'],
[ 'istgt', 'istgt'],
[ 'iet', 'IET'],
[ 'LIO', 'LIO']
@@ -32977,6 +32978,7 @@
data: {
isLIO: false,
isComstar: true,
+ isFreeNAS: false,
hasWriteCacheOption: true
}
},
@@ -32989,10 +32991,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;
+ }
}
},
@@ -33010,6 +33028,7 @@
},
setValues: function diff(values) {
+ values.freenas_confirmpw = values.freenas_password;
values.writecache = values.nowritecache ? 0 : 1;
this.callParent([values]);
},
@@ -33026,7 +33045,7 @@
allowBlank: false
},
{
- xtype: me.isCreate ? 'textfield' : 'displayfield',
+ xtype: 'textfield',
name: 'pool',
value: '',
fieldLabel: gettext('Pool'),
@@ -33036,11 +33055,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'),
@@ -33051,8 +33070,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}'
+ }
}
];
@@ -33083,7 +33127,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
},
@@ -33091,9 +33137,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;
+ }
}
];