diff --git a/iscsi-client/delete_conns.cgi b/iscsi-client/delete_conns.cgi index 7d27a867c..b9836e314 100755 --- a/iscsi-client/delete_conns.cgi +++ b/iscsi-client/delete_conns.cgi @@ -52,10 +52,12 @@ if (!$in{'confirm'}) { print &ui_confirmation_form( "delete_conns.cgi", @delconns == 1 && $delconns[0]->{'device'} ? - &text('dconns_rusure2', $delconns[0]->{'ip'}, - $delconns[0]->{'device'}) : + &text('dconns_rusure2', + "".$delconns[0]->{'ip'}."", + "".$delconns[0]->{'device'}."") : @delconns == 1 ? - &text('dconns_rusure1', $delconns[0]->{'ip'}) : + &text('dconns_rusure1', + "".$delconns[0]->{'ip'}."") : &text('dconns_rusure', scalar(@delconns)), [ map { [ "d", $_ ] } @d ], [ [ "confirm", $text{'dconns_confirm'} ] ], @@ -78,7 +80,7 @@ else { 'target' => $delconns[0]->{'target'} }); } else { - &webmin_log("delete", "connection", scalar(@delconns)); + &webmin_log("delete", "connections", scalar(@delconns)); } &redirect("list_conns.cgi"); } diff --git a/iscsi-client/delete_ifaces.cgi b/iscsi-client/delete_ifaces.cgi new file mode 100755 index 000000000..2a8d3c83c --- /dev/null +++ b/iscsi-client/delete_ifaces.cgi @@ -0,0 +1,52 @@ +#!/usr/local/bin/perl +# Remove one or more interfaces + +use strict; +use warnings; +require './iscsi-client-lib.pl'; +our (%text, %in); +&ReadParse(); +&error_setup($text{'difaces_err'}); + +# Get the interfaces +my $ifaces = &list_iscsi_ifaces(); +ref($ifaces) || &error(&text('ifaces_elist', $ifaces)); +my @d = split(/\0/, $in{'d'}); +my @delifaces; +foreach my $d (@d) { + my ($iface) = grep { $_->{'name'} eq $d } @$ifaces; + push(@delifaces, $iface) if ($iface); + } +@delifaces || &error($text{'difaces_enone'}); + +if (!$in{'confirm'}) { + &ui_print_header(undef, $text{'difaces_title'}, ""); + + # Ask the user if he is sure + print &ui_confirmation_form( + "delete_ifaces.cgi", + @delifaces == 1 ? + &text('difaces_rusure1', + "".$delifaces[0]->{'name'}."") : + &text('difaces_rusure', scalar(@delifaces)), + [ map { [ "d", $_ ] } @d ], + [ [ "confirm", $text{'difaces_confirm'} ] ]); + + &ui_print_footer("list_ifaces.cgi", $text{'ifaces_return'}); + } +else { + # Delete each one + foreach my $iface (@delifaces) { + my $err = &delete_iscsi_iface($iface); + &error(&text('difaces_edelete', $iface->{'name'}, $err)) + if ($err); + } + + if (@delifaces == 1) { + &webmin_log("delete", "iface", $delifaces[0]->{'name'}); + } + else { + &webmin_log("delete", "ifaces", scalar(@delifaces)); + } + &redirect("list_ifaces.cgi"); + } diff --git a/iscsi-client/iscsi-client-lib.pl b/iscsi-client/iscsi-client-lib.pl index d59a8a83d..64f253471 100644 --- a/iscsi-client/iscsi-client-lib.pl +++ b/iscsi-client/iscsi-client-lib.pl @@ -288,6 +288,7 @@ my ($iface, $target); foreach my $l (@lines) { if ($l =~ /^Iface:\s+(\S+)/) { $iface = { 'name' => $1, + 'builtin' => ($1 eq "default" || $1 eq "iser"), 'targets' => [ ] }; push(@rv, $iface); } @@ -301,7 +302,60 @@ foreach my $l (@lines) { $target->{'port'} = $2; } } +# Fetch more info for each interface +foreach my $iface (@rv) { + &clean_language(); + my $out = &backquote_command( + "$config{'iscsiadm'} -m iface -I $iface->{'name'} 2>/dev/null"); + &reset_environment(); + foreach my $il (split(/\r?\n/, $out)) { + if ($il !~ /^#/ && $il =~ /^(iface.\S+)\s*=\s*(\S+)/) { + $iface->{$1} = $2 eq "" ? undef : $2; + } + } + } return \@rv; } +# create_iscsi_interface(&iface) +# Create a new interface from the given hash +sub create_iscsi_interface +{ +my ($iface) = @_; + +# Create the initial interface +my $cmd = "$config{'iscsiadm'} -m iface -o create". + " -I ".quotemeta($iface->{'name'}); +&clean_language(); +my $out = &backquote_command("$cmd 2>&1"); +&reset_environment(); +return $out if ($?); + +# Apply various params +foreach my $k (grep { /^iface\./ } keys %$iface) { + my $cmd = "$config{'iscsiadm'} -m iface -o update". + " -I ".quotemeta($iface->{'name'}). + " -n ".quotemeta($k)." -v ".quotemeta($iface->{$k}); + &clean_language(); + my $out = &backquote_command("$cmd 2>&1"); + &reset_environment(); + return "Failed to set $k : $out" if ($?); + } + +return undef; +} + +# delete_iscsi_iface(&iface) +# Delete one iSCSI interface +sub delete_iscsi_iface +{ +my ($iface) = @_; +my $cmd = "$config{'iscsiadm'} -m iface -o delete". + " -I ".quotemeta($iface->{'name'}); +&clean_language(); +my $out = &backquote_command("$cmd 2>&1"); +&reset_environment(); +return $? ? $out : undef; +} + 1; diff --git a/iscsi-client/lang/en b/iscsi-client/lang/en index 920e94b9f..676a1f46f 100644 --- a/iscsi-client/lang/en +++ b/iscsi-client/lang/en @@ -69,6 +69,7 @@ iscsi_equeue=Missing or non-numeric maximum commands queued per device ifaces_title=iSCSI Interfaces ifaces_elist=Failed to list interfaces : $1 ifaces_name=Interface name +ifaces_transport=Transport ifaces_uses=Used by ifaces_none=No iSCSI interfaces are currently active. ifaces_return=interfaces list @@ -76,6 +77,18 @@ ifaces_header=Add iSCSI interface ifaces_delete=Remove Selected Interfaces ifaces_on=Target $1 on $2 ifaces_nouses=No connections +ifaces_ipaddress=Source IP address +ifaces_hwaddress=MAC address +ifaces_ifacename=Source interface +ifaces_ipaddressdef=Automatic + +difaces_err=Failed to remove interfaces +difaces_enone=None selected +difaces_edelete=Removal of interface $1 failed : $2 +difaces_title=Remove iSCSI Interfaces +difaces_rusure=Are you sure you want to remove the $1 selected interfaces? +difaces_rusure1=Are you sure you want to remove the interface $1? +difaces_confirm=Remove Interfaces conns_title=iSCSI Connections conns_elist=Failed to list connections : $1 @@ -152,3 +165,6 @@ log_delete_connection=Removed connection to $1 for $2 log_delete_connections=Removed $1 connections log_atboot=Enabled iSCSI client at boot time log_delboot=Disabled iSCSI client at boot time +log_add_iface=Added interface $1 +log_delete_iface=Removed interface $1 +log_delete_ifaces=Removed $1 interfaces diff --git a/iscsi-client/list_ifaces.cgi b/iscsi-client/list_ifaces.cgi index 0c75f80b9..b8af821b2 100755 --- a/iscsi-client/list_ifaces.cgi +++ b/iscsi-client/list_ifaces.cgi @@ -15,14 +15,16 @@ if (@$ifaces) { my @tds = ( "width=5" ); print &ui_form_start("delete_ifaces.cgi"); print &ui_columns_start( - [ "", $text{'ifaces_name'}, $text{'ifaces_uses'} ], + [ "", $text{'ifaces_name'}, $text{'ifaces_transport'}, + $text{'ifaces_uses'} ], 100, 0, \@tds); foreach my $c (@$ifaces) { my $uses = join(" | ", map { &text('ifaces_on', $_->{'target'}, $_->{'ip'}) } @{$c->{'targets'}}); print &ui_checked_columns_row([ $c->{'name'}, + uc($c->{'iface.transport_name'}), $uses || "$text{'ifaces_nouses'}", - ], \@tds, "d", $c->{'name'}); + ], \@tds, "d", $c->{'name'}, 0, $c->{'builtin'}); } print &ui_columns_end(); print &ui_form_end([ [ undef, $text{'ifaces_delete'} ] ]); @@ -39,7 +41,35 @@ print &ui_table_start($text{'ifaces_header'}, undef, 2); print &ui_table_row($text{'ifaces_name'}, &ui_textbox("name", undef, 40)); -# XXX?? +# Transport type +print &ui_table_row($text{'ifaces_transport'}, + &ui_select("transport", "tcp", + [ [ "tcp", "TCP" ], + [ "iser", "ISER" ], + [ "cxgb3i", "Chelsio CXGB3I" ], + [ "bnx2i", "Broadcom BNX2I" ], + [ "be2iscsi", "ServerEngines BE2ISCSI" ] ])); + +# Source IP address +print &ui_table_row($text{'ifaces_ipaddress'}, + &ui_opt_textbox("ipaddress", undef, 20, $text{'ifaces_ipaddressdef'})); + +# MAC address +print &ui_table_row($text{'ifaces_hwaddress'}, + &ui_opt_textbox("hwaddress", undef, 30, $text{'ifaces_ipaddressdef'})); + +# Source interface +my @active; +if (&foreign_check("net")) { + &foreign_require("net"); + @active = grep { $_->{'name'} ne 'lo' } &net::active_interfaces(); + } +if (@active) { + print &ui_table_row($text{'ifaces_ifacename'}, + &ui_select("ifacename", undef, + [ map { $_->{'fullname'} } + grep { $_->{'virtual'} eq '' } @active ])); + } print &ui_table_end(); print &ui_form_end([ [ undef, $text{'create'} ] ]); diff --git a/iscsi-client/log_parser.pl b/iscsi-client/log_parser.pl index 506e23011..9c82f73ad 100755 --- a/iscsi-client/log_parser.pl +++ b/iscsi-client/log_parser.pl @@ -15,6 +15,12 @@ if ($type eq "connection") { elsif ($type eq "connections") { return &text('log_'.$action.'_'.$type, $object); } +elsif ($type eq "iface") { + return &text('log_'.$action.'_'.$type, &html_escape($object)); + } +elsif ($type eq "ifaces") { + return &text('log_'.$action.'_'.$type, $object); + } else { return $text{'log_'.$action}; }