File Coverage

lib/Rex/Commands/LVM.pm
Criterion Covered Total %
statement 17 90 18.8
branch 0 26 0.0
condition 0 3 0.0
subroutine 6 13 46.1
pod 3 7 42.8
total 26 139 18.7


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Commands::LVM - Get LVM Information
8              
9             =head1 DESCRIPTION
10              
11             With this module you can get information of your lvm setup.
12              
13             Version <= 1.0: All these functions will not be reported.
14              
15             All these functions are not idempotent.
16              
17             =head1 SYNOPSIS
18              
19             use Rex::Commands::LVM;
20              
21             my @physical_devices = pvs;
22             my @volume_groups = vgs;
23             my @logical_volumes = lvs;
24              
25              
26              
27             =head1 EXPORTED FUNCTIONS
28              
29             =cut
30              
31             package Rex::Commands::LVM;
32              
33 1     1   14 use v5.12.5;
  1         4  
34 1     1   7 use warnings;
  1         2  
  1         62  
35              
36             our $VERSION = '1.14.3'; # VERSION
37              
38             require Rex::Exporter;
39 1     1   6 use base qw(Rex::Exporter);
  1         10  
  1         94  
40 1     1   8 use vars qw(@EXPORT);
  1         2  
  1         71  
41              
42             @EXPORT = qw(pvs vgs lvs pvcreate vgcreate lvcreate vgextend);
43              
44 1     1   9 use Rex::Helper::Run;
  1         3  
  1         73  
45 1     1   6 use Rex::Commands::Mkfs;
  1         3  
  1         21  
46              
47             =head2 pvs
48              
49             Get Information for all your physical volumes.
50              
51             use Data::Dumper;
52             use Rex::Commands::LVM;
53              
54             task "lvm", sub {
55             my @physical_volumes = pvs;
56              
57             for my $physical_volume (@physical_volumes) {
58             say Dumper($physical_volume);
59             }
60             };
61              
62             =cut
63              
64             sub pvs {
65              
66 0     0 1   my @lines =
67             i_run 'pvdisplay --units b --columns --separator "|" --noheadings',
68             fail_ok => 1,
69             no_stderr => 1;
70 0 0         if ( $? != 0 ) {
71 0           die("Error running pvdisplay");
72             }
73              
74 0           my @ret;
75 0           for my $line (@lines) {
76 0           chomp $line;
77 0           $line =~ s/^\s+//g;
78 0           my ( $phy_vol, $vol_group, $format, $attr, $psize, $pfree ) =
79             split( /\|/, $line );
80 0           $pfree =~ s/B$//;
81 0           $psize =~ s/B$//;
82              
83 0           push(
84             @ret,
85             {
86             physical_volume => $phy_vol,
87             volume_group => $vol_group,
88             format => $format,
89             attributes => $attr,
90             size => $psize,
91             free => $pfree,
92             }
93             );
94             }
95              
96 0           return @ret;
97              
98             }
99              
100             =head2 vgs
101              
102             Get Information for all your volume groups.
103              
104             use Data::Dumper;
105             use Rex::Commands::LVM;
106              
107             task "lvm", sub {
108             my @volume_groups = vgs;
109              
110             for my $volume_group (@volume_groups) {
111             say Dumper($volume_group);
112             }
113             };
114              
115             =cut
116              
117             sub vgs {
118              
119 0     0 1   my ($vg) = @_;
120              
121 0           my $cmd =
122             'vgdisplay --units b --columns --separator "|" --noheadings -o "pv_name,vg_name,vg_size,vg_free,vg_attr"';
123 0 0         if ($vg) {
124 0           $cmd .= " $vg";
125             }
126              
127 0           my @lines = i_run $cmd, fail_ok => 1, no_stderr => 1;
128 0 0         if ( $? != 0 ) {
129 0           die("Error running vgdisplay");
130             }
131              
132 0           my @ret;
133 0           for my $line (@lines) {
134 0           chomp $line;
135 0           $line =~ s/^\s+//g;
136 0           my ( $pv_name, $vg_name, $vg_size, $vg_free, $vg_attr ) =
137             split( /\|/, $line );
138 0           $vg_free =~ s/B$//;
139 0           $vg_size =~ s/B$//;
140              
141 0           push(
142             @ret,
143             {
144             physical_volume => $pv_name,
145             volume_group => $vg_name,
146             size => $vg_size,
147             free => $vg_free,
148             attributes => $vg_attr,
149             }
150             );
151             }
152              
153 0           return @ret;
154              
155             }
156              
157             =head2 lvs
158              
159             Get Information for all your logical volumes.
160              
161             use Data::Dumper;
162             use Rex::Commands::LVM;
163              
164             task "lvm", sub {
165             my @logical_volumes = lvs;
166              
167             for my $logical_volume (@logical_volumes) {
168             say Dumper($logical_volume);
169             }
170             };
171              
172             =cut
173              
174             sub lvs {
175              
176 0     0 1   my ($vg) = @_;
177              
178 0           my $cmd =
179             'lvdisplay --units b --columns --separator "|" -o "lv_name,vg_name,lv_attr,lv_size" --noheading';
180 0 0         if ($vg) {
181 0           $cmd .= " " . $vg;
182             }
183              
184 0           my @lines = i_run $cmd, fail_ok => 1, no_stderr => 1;
185 0 0         if ( $? != 0 ) {
186 0           die("Error running lvdisplay");
187             }
188              
189 0           my @ret;
190 0           for my $line (@lines) {
191 0           chomp $line;
192 0           $line =~ s/^\s+//g;
193              
194 0           my ( $lv_name, $vg_name, $lv_attr, $lv_size ) = split( /\|/, $line );
195 0           $lv_size =~ s/B$//;
196 0           push(
197             @ret,
198             {
199             name => $lv_name,
200             path => "/dev/$vg_name/$lv_name",
201             attributes => $lv_attr,
202             size => $lv_size,
203             }
204             );
205             }
206              
207 0           return @ret;
208             }
209              
210             sub pvcreate {
211 0     0 0   my ($dev) = @_;
212 0           my $s = i_run "pvcreate $dev", fail_ok => 1, stderr_to_stdout => 1;
213 0 0         if ( $? != 0 ) {
214 0           die("Error creating pv.\n$s\n");
215             }
216              
217 0           return 1;
218             }
219              
220             sub vgcreate {
221 0     0 0   my ( $vgname, @devices ) = @_;
222              
223 0           my $s = i_run "vgcreate $vgname " . join( " ", @devices ),
224             fail_ok => 1,
225             stderr_to_stdout => 1;
226 0 0         if ( $? != 0 ) {
227 0           die("Error creating vg.\n$s\n");
228             }
229              
230 0           return 1;
231             }
232              
233             sub lvcreate {
234 0     0 0   my ( $lvname, %option ) = @_;
235              
236 0 0 0       if ( !exists $option{size} || !exists $option{onvg} ) {
237 0           die("Missing parameter size or onvg.");
238             }
239              
240 0 0         unless ( $lvname =~ m/^[a-z0-9\-\._]+$/i ) {
241 0           die("Error in lvname. Allowed characters a-z, 0-9 and _-. .");
242             }
243              
244 0           my $size = $option{size};
245 0 0         if ( $size =~ m/^[0-9]+$/ ) { $size .= "M"; }
  0            
246 0           my $onvg = $option{onvg};
247              
248 0           my $s = i_run "lvcreate -n $lvname -L $size $onvg",
249             fail_ok => 1,
250             stderr_to_stdout => 1;
251              
252 0 0         if ( $? != 0 ) {
253 0           die("Error creating lv.\n$s\n");
254             }
255              
256 0           my $lv_path = $option{onvg} . "/" . $lvname;
257              
258 0 0         mkfs "$lv_path", fstype => $option{fstype} if ( $option{fstype} );
259              
260 0           return $lv_path;
261             }
262              
263             sub vgextend {
264 0     0 0   my ( $vgname, @devices ) = @_;
265              
266 0           my $s = i_run "vgextend $vgname " . join( " ", @devices ),
267             fail_ok => 1,
268             stderr_to_stdout => 1;
269              
270 0 0         if ( $? != 0 ) {
271 0           die("Error extending vg.\n$s\n");
272             }
273              
274 0           return 1;
275             }
276              
277             1;