# # Copyright (c) 2013 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary PV ComponentState Module ## @author praveent@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here ################################################################################ =head1 NAME NACL::CS::Client::PV =head1 DESCRIPTION C is a derived class of L. It represents the state of PV element. A related class is L, which represents access to a PV element. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the PV element are the individual attributes of the PV ComponentState =over =item C<< "pv_name" >> Filled in for Linux CLI. =item C<< "pv_size" >> Filled in for Linux CLI. =item C<< "vg_name" >> Filled in for Linux CLI. =item C<< "pe_size" >> Filled in for Linux CLI. =item C<< "allocated_pe" >> Filled in for Linux CLI. =item C<< "free_pe" >> Filled in for Linux CLI. =item C<< "allocatable" >> Filled in for Linux CLI. =item C<< "pv_uuid" >> Filled in for Linux CLI. =item C<< "total_pe" >> Filled in for Linux CLI. =item C<< "library_version" >> Filled in for Linux CLI. =item C<< "driver_version" >> Filled in for Linux CLI. =item C<< "lvm_version" >> Filled in for Linux CLI. =item C<< "number_of_lv" >> Filled in for Linux CLI. =item C<< "pv_status" >> Filled in for Linux CLI. =item C<< "pv_size_kb" >> Filled in for Linux CLI. =item C<< "pv_number" >> Filled in for Linux CLI. =item C<< "pv_not_allocatable" >> Filled in for Linux CLI. =item C<< "pv_free" >> Filled in for Linux CLI. =item C<< "attr" >> Filled in for Linux CLI. =item C<< "fmt" >> Filled in for Linux CLI. =item C<< "physical_segments" >> (Array) Note that for array fields, the accessor method can be invoked in either scalar or list context. my $physical_segments = $obj->physical_segments(); $physical_segments contains a reference to the array of values my @physical_segments = $obj->physical_segments(); @physical_segments contains the array of values Filled in for Linux CLI. =back =cut ################### # Package package NACL::CS::Client::PV; ################### # Everytime use strict; use warnings; ################### # Module includes use Params::Validate qw (validate validate_with HASHREF ARRAYREF OBJECT); use NACL::ComponentUtils qw (_optional_scalars Dumper); use NACL::APISet::Exceptions::UnexpectedOutputException qw(:try); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use base 'NACL::CS::ComponentState::Client'; use Class::MethodMaker [ scalar => "pv_name", scalar => "pv_size", scalar => "vg_name", scalar => "pe_size", scalar => "allocated_pe", scalar => "free_pe", scalar => "allocatable", scalar => "pv_uuid", scalar => "total_pe", scalar => "library_version", scalar => "driver_version", scalar => "lvm_version", scalar => "number_of_lv", scalar => "pv_status", scalar => "pv_size_kb", scalar => "pv_number", scalar => "pv_not_allocatable", scalar => "pv_free", scalar => "attr", scalar => "fmt", array => "physical_segments", scalar => "logical_extents", scalar => "logical_volume", ]; =head1 METHODS =head2 fetch my $physical_volume = NACL::CS::Client::PV->fetch(command_interface=>$ci,...); my @physical_volumes = NACL::CS::Client::PV->fetch(command_interface=>$ci,...); see L Supports Linux CLI. Invokes "pvdisplay" command for Linux CLI. =cut sub fetch { $Log->enter() if $may_enter; my ( $pkg, @opts ) = @_; my @state_objs = $pkg->SUPER::fetch( @opts, choices => [ { method => "_fetch_linux_cli", interface => "CLI", set => 'Linux' }, ], exception_text => 'No physical volumes found' ); $Log->exit() if $may_exit; return wantarray ? @state_objs : $state_objs[0]; } ## end sub fetch sub _fetch_linux_cli { $Log->enter() if $may_enter; my ( $pkg, @opts ) = @_; my %opts = validate @opts, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $requested_fields = $opts{requested_fields}; my $filter = $opts{filter}; my ( @pvdisplay_args, @state_objs, @final_object ); # Provide a large timeout so that the command will not timeout if there is # a lot of output to display my $timeout = $opts{'timeout'} || 1200; push @pvdisplay_args, ( 'connectrec-timeout' => $timeout ); my @orig_requested_fields = @{ $opts{requested_fields} }; my %orig_filter = %{ $opts{filter} }; $pkg->_remove_relational_regex_filters( filter => \%orig_filter, requested_fields => \@orig_requested_fields ); $requested_fields = \@orig_requested_fields; $filter = \%orig_filter; if ( defined $filter->{pv_name} ) { push @pvdisplay_args, ( "physical-volumes" => $filter->{pv_name} ); } my ( $response, $caught_exception, $obj ); my %temp_hash; try { $response = $apiset->pvdisplay(@pvdisplay_args); } catch NACL::APISet::Exceptions::UnexpectedOutputException with { # A caught exception indicates that the device being looked for # does not exist. We catch the exception and return immediately. The # 'fetch' frontend decides whether to throw a NoElementsFound # exception based on the value of 'allow_empty' $caught_exception = 1; }; if ($caught_exception) { $Log->exit() if $may_exit; return; } my $output = $response->get_parsed_output(); foreach my $row (@$output) { my $state_base_field_settings = $pkg->_hash_copy( source => $row, copy => [qw( pv_name total_pe vg_name pv_size pv_uuid allocatable free_pe pe_size allocated_pe )], ); $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $state_base_field_settings); push @state_objs, $obj; } ## end foreach my $row (@$output) my %commands = $pkg->_handle_commands_returning_common_fields( common_fields => [qw( pv_name total_pe vg_name pv_size pv_uuid allocatable free_pe pe_size allocated_pe )], commands => { 'pvdisplay_version' => [ qw( library_version driver_version lvm_version ) ], 'pvdisplay_colon' => [ qw( number_of_lv pv_status pv_size_kb pv_number pv_not_allocatable ) ], 'pvdisplay_Columns' => [ qw( pv_free attr fmt ) ], 'pvdisplay_maps' => [ qw( physical_segments logical_extents logical_volume ) ], }, preferred_command => 'pvdisplay', requested_fields => $requested_fields, filter => $filter ); if ( exists $commands{'pvdisplay_version'} ) { my @show_args; push @show_args, ('version' => 1); my $pvdisplay_response = $apiset->pvdisplay(@show_args); my $pvdisplay_show_output = $pvdisplay_response->get_parsed_output(); foreach my $show_info (@{$pvdisplay_show_output}) { my $device_info = $pkg->_hash_copy( source => $show_info, copy => [qw( library_version driver_version lvm_version )], ); $obj->_set_fields(row => $device_info); push @state_objs, $obj; } } if ( exists $commands{'pvdisplay_colon'} ) { my @show_args; push @show_args, ('colon' => 1); if (defined $filter->{pv_name}) { push @show_args, ( "physical-volumes" => $filter->{pv_name}); } my $pvdisplay_response = $apiset->pvdisplay(@show_args); my $pvdisplay_show_output = $pvdisplay_response->get_parsed_output(); foreach my $show_info (@{$pvdisplay_show_output}) { my $device_info = $pkg->_hash_copy( source => $show_info, copy => [qw( number_of_lv pv_status pv_size_kb pv_number pv_not_allocatable )], ); $obj->_set_fields(row => $device_info); push @state_objs, $obj; } } if ( exists $commands{'pvdisplay_Columns'} ) { my @show_args; push @show_args, ('columns' => 1); if (defined $filter->{pv_name}) { push @show_args, ( "physical-volumes" => $filter->{pv_name}); } my $pvdisplay_response = $apiset->pvdisplay(@show_args); my $pvdisplay_show_output = $pvdisplay_response->get_parsed_output(); foreach my $show_info (@{$pvdisplay_show_output}) { my $device_info = $pkg->_hash_copy( source => $show_info, copy => [qw( pv_free attr fmt )], ); $obj->_set_fields(row => $device_info); push @state_objs, $obj; } } if ( exists $commands{'pvdisplay_maps'} ) { my @show_args; push @show_args, ('maps' => 1); if (defined $filter->{pv_name}) { push @show_args, ( "physical-volumes" => $filter->{pv_name}); } my $pvdisplay_response = $apiset->pvdisplay(@show_args); my $pvdisplay_show_output = $pvdisplay_response->get_parsed_output(); foreach my $show_info (@{$pvdisplay_show_output}) { my $device_info = $pkg->_hash_copy( source => $show_info, copy => [qw( physical_segments logical_extents logical_volume )], ); $obj->_set_fields(row => $device_info); push @state_objs, $obj; } } $Log->exit() if $may_exit; return @state_objs; } 1;