File Coverage

lib/Rex/Commands/Sysctl.pm
Criterion Covered Total %
statement 23 59 38.9
branch 0 16 0.0
condition 0 3 0.0
subroutine 8 14 57.1
pod 1 4 25.0
total 32 96 33.3


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Commands::Sysctl - Manipulate sysctl
8              
9             =head1 DESCRIPTION
10              
11             With this module you can set and get sysctl parameters.
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::Sysctl;
20              
21             my $data = sysctl "net.ipv4.tcp_keepalive_time";
22             sysctl "net.ipv4.tcp_keepalive_time" => 1800;
23              
24             =head1 EXPORTED FUNCTIONS
25              
26             =cut
27              
28             package Rex::Commands::Sysctl;
29              
30 36     36   482 use v5.12.5;
  36         120  
31 36     36   392 use warnings;
  36         90  
  36         1795  
32              
33             our $VERSION = '1.14.3'; # VERSION
34              
35 36     36   676 use Rex::Logger;
  36         115  
  36         235  
36 36     36   1400 use Rex::Commands::Run;
  36         83  
  36         273  
37 36     36   241 use Rex::Helper::Run;
  36         82  
  36         2509  
38 36     36   251 use Rex::Commands::File;
  36         79  
  36         287  
39              
40             require Rex::Exporter;
41              
42 36     36   342 use base qw(Rex::Exporter);
  36         76  
  36         3054  
43 36     36   246 use vars qw(@EXPORT);
  36         89  
  36         23485  
44              
45             @EXPORT = qw(sysctl);
46              
47             =head2 sysctl($key [, $val [, %options]])
48              
49             This function will read the sysctl key $key.
50              
51             If $val is given, then this function will set the sysctl key $key.
52              
53             task "tune", "server01", sub {
54             if( sysctl("net.ipv4.ip_forward") == 0 ) {
55             sysctl "net.ipv4.ip_forward" => 1;
56             }
57             };
58              
59             If both $val and ensure option are used, the sysctl key is modified and the value may persist in /etc/sysctl.conf depending if ensure option is "present" or "absent".
60              
61             With ensure => "present", if the key already exists in the file, it will be updated to the new value.
62              
63             task "forwarding", "server01", sub {
64             sysctl "net.ipv4.ip_forward" => 1, ensure => "present";
65             }
66              
67             =cut
68              
69             sub sysctl_save {
70 0     0 0   my ( $key, $value ) = @_;
71 0           my $sysctl = get_sysctl_command();
72              
73             append_or_amend_line "/etc/sysctl.conf",
74             line => "$key=$value",
75             regexp => qr{\Q$key=},
76 0     0     on_change => sub { i_run "$sysctl -p" };
  0            
77             }
78              
79             sub sysctl_remove {
80 0     0 0   my ( $key, $value ) = @_;
81 0           my $sysctl = get_sysctl_command();
82              
83             delete_lines_according_to "$key=$value", "/etc/sysctl.conf",
84 0     0     on_change => sub { i_run "$sysctl -p" };
  0            
85             }
86              
87             sub sysctl {
88              
89 0     0 1   my ( $key, $val, %options ) = @_;
90 0           my $sysctl = get_sysctl_command();
91              
92 0 0         if ( defined $val ) {
93              
94 0           Rex::Logger::debug("Setting sysctl key $key to $val");
95 0           my $ret = i_run "$sysctl -n $key";
96              
97 0 0         if ( $ret ne $val ) {
98 0           i_run "$sysctl -w $key=$val", fail_ok => 1;
99 0 0         if ( $? != 0 ) {
100 0           die("Sysctl failed $key -> $val");
101             }
102             }
103             else {
104 0           Rex::Logger::debug("$key has already value $val");
105             }
106              
107 0 0 0       if ( $options{ensure} || $options{persistent} ) {
108 0 0         if ( $options{ensure} eq "present" ) {
    0          
109 0           Rex::Logger::debug("Writing $key=$val to sysctl.conf");
110 0           sysctl_save $key, $val;
111             }
112             elsif ( $options{ensure} eq "absent" ) {
113 0           Rex::Logger::debug("Removing $key=$val of sysctl.conf");
114 0           sysctl_remove $key, $val;
115             }
116             else {
117             Rex::Logger::info(
118 0           "Error : " . $options{ensure} . " is not a known ensure parameter" );
119             }
120             }
121              
122             }
123             else {
124              
125 0           my $ret = i_run "$sysctl -n $key", fail_ok => 1;
126 0 0         if ( $? == 0 ) {
127 0           return $ret;
128             }
129             else {
130 0           Rex::Logger::info( "Error getting sysctl key: $key", "warn" );
131 0           die("Error getting sysctl key: $key");
132             }
133              
134             }
135              
136             }
137              
138             sub get_sysctl_command {
139 0     0 0   my $sysctl = can_run( '/sbin/sysctl', '/usr/sbin/sysctl' );
140              
141 0 0         if ( !defined $sysctl ) {
142 0           my $message = q(Couldn't find sysctl executable);
143 0           Rex::Logger::info( $message, 'error' );
144 0           die($message);
145             }
146              
147 0           return $sysctl;
148             }
149              
150             1;