[pve-devel] [PATCH] zfs : add nexenta api for iscsi lun creation

Alexandre Derumier aderumier at odiso.com
Mon Nov 18 06:12:07 CET 2013


Nexenta gui need to use api to create iscsi lun, or it'll thrown error.

This patch readd nexenta api only for lun creation.(as ssh commands are faster).

we just need to defined optionnal properties:

/etc/pve/storage.cfg
--------------------
iscsiprovider comstar
login nexentaapilogin
password nexentaapipassword
ssl

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/Storage/LunCmd/Comstar.pm |   80 ++++++++++++++++++++++++++++++++++++++---
 PVE/Storage/ZFSPlugin.pm      |   26 +++++++++++---
 2 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/PVE/Storage/LunCmd/Comstar.pm b/PVE/Storage/LunCmd/Comstar.pm
index 45ad6a5..eaee4c0 100644
--- a/PVE/Storage/LunCmd/Comstar.pm
+++ b/PVE/Storage/LunCmd/Comstar.pm
@@ -3,6 +3,10 @@ package PVE::Storage::LunCmd::Comstar;
 use strict;
 use warnings;
 use Digest::MD5 qw(md5_hex);
+use HTTP::Request;
+use LWP::UserAgent;
+use MIME::Base64;
+use JSON;
 use PVE::Tools qw(run_command file_read_firstline trim dir_glob_regex dir_glob_foreach);
 use Data::Dumper;
 
@@ -10,6 +14,44 @@ my @ssh_opts = ('-o', 'BatchMode=yes');
 my @ssh_cmd = ('/usr/bin/ssh', @ssh_opts);
 my $id_rsa_path = '/etc/pve/priv/zfs';
 
+sub nexenta_request {
+    my ($scfg, $method, $object, @params) = @_;
+
+    my $apicall = { method => $method, object => $object, params => [ @params ] };
+
+    my $json = encode_json($apicall);
+
+    my $uri = ($scfg->{ssl} ? "https" : "http") . "://" . $scfg->{portal} . ":2000/rest/nms/";
+    my $req = HTTP::Request->new('POST', $uri);
+
+    $req->header('Content-Type' => 'application/json');
+    $req->content($json);
+    my $token = encode_base64("$scfg->{login}:$scfg->{password}");
+    $req->header(Authorization => "Basic $token");
+
+    my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
+    my $res = $ua->request($req);
+    die $res->content if !$res->is_success;
+
+    my $obj = eval { from_json($res->content); };
+    die "JSON not valid. Content: " . $res->content if ($@);
+    die "Nexenta API Error: $obj->{error}->{message}\n" if $obj->{error}->{message};
+    return $obj->{result};
+}
+
+sub nexenta_create_lu {
+    my ($scfg, $zvol) = @_;
+
+    nexenta_request($scfg, 'create_lu', 'scsidisk', "$scfg->{pool}/$zvol", {});
+}
+
+sub nexenta_import_lu {
+    my ($scfg, $zvol) = @_;
+
+    nexenta_request($scfg, 'import_lu', 'scsidisk', "$scfg->{pool}/$zvol");
+}
+
+
 my $get_lun_cmd_map = sub {
     my ($method) = @_;
 
@@ -35,6 +77,16 @@ sub get_base {
     return '/dev/zvol/rdsk';
 }
 
+sub get_vol_name {
+    my ($path) = @_;
+
+    my $base = get_base();
+    if ($path =~ /^$base(\/.+)?\/(.+)/) {
+	return $2;
+    }
+    die "$path: Illegal path";
+}
+
 sub run_lun_command {
     my ($scfg, $timeout, $method, @params) = @_;
 
@@ -50,11 +102,29 @@ sub run_lun_command {
     };
 
     if ($method eq 'create_lu') {
-        my $prefix = '600144f';
-        my $digest = md5_hex($params[0]);
-        $digest =~ /(\w{7}(.*))/;
-        $guid = "$prefix$2";
-        @params = ('-p', 'wcd=false', '-p', "guid=$guid", @params);
+
+	if($scfg->{login} && $scfg->{password}){
+	    my $zvol = get_vol_name($params[0]);
+	    nexenta_create_lu($scfg, $zvol);
+	    return;
+	}else{
+
+	    my $prefix = '600144f';
+            my $digest = md5_hex($params[0]);
+            $digest =~ /(\w{7}(.*))/;
+            $guid = "$prefix$2";
+            @params = ('-p', 'wcd=false', '-p', "guid=$guid", @params);
+	}
+
+    } elsif ($method eq 'import_lu') {
+
+	if($scfg->{login} && $scfg->{password}){
+
+	    my $zvol = get_vol_name($params[0]);
+            nexenta_import_lu($scfg, $zvol);
+            return;
+	}
+
     } elsif ($method eq 'modify_lu') {
         @params = ('-s', @params);
     } elsif ($method eq 'list_view') {
diff --git a/PVE/Storage/ZFSPlugin.pm b/PVE/Storage/ZFSPlugin.pm
index d077cfb..da73004 100644
--- a/PVE/Storage/ZFSPlugin.pm
+++ b/PVE/Storage/ZFSPlugin.pm
@@ -56,6 +56,10 @@ sub zfs_request {
 
     $timeout = 5 if !$timeout;
 
+    unless (-e "$id_rsa_path/$scfg->{portal}_id_rsa") {
+	die "you need to generate an ssh key";
+    }
+
     if ($lun_cmds->{$method}) {
         if ($scfg->{iscsiprovider} eq 'comstar') {
             $msg = PVE::Storage::LunCmd::Comstar::run_lun_command($scfg, $timeout, $method, @params);
@@ -320,10 +324,21 @@ sub properties {
         description => "iscsi provider",
         type => 'string',
     },
-        blocksize => {
-            description => "block size",
-            type => 'string',
-        }
+    blocksize => {
+	description => "block size",
+	type => 'string',
+    },
+    ssl => {
+	description => "enable ssl",
+	type => 'boolean',
+    },
+    login => {
+	description => "login",
+	type => 'string',
+    },
+    password => {
+	description => "password",
+	type => 'string'}
     };
 }
 
@@ -336,6 +351,9 @@ sub options {
     pool => { fixed => 1 },
     blocksize => { fixed => 1 },
     iscsiprovider => { fixed => 1 },
+    login => { optional => 1 },
+    password => { optional => 1 },
+    ssl => { optional => 1 },
     content => { optional => 1 },
     };
 }
-- 
1.7.10.4




More information about the pve-devel mailing list