File Coverage

blib/lib/Net/OpenVPN/Launcher.pm
Criterion Covered Total %
statement 26 54 48.1
branch 1 24 4.1
condition 0 3 0.0
subroutine 11 14 78.5
pod 1 1 100.0
total 39 96 40.6


line stmt bran cond sub pod time code
1             package Net::OpenVPN::Launcher;
2 2     2   141398 use strict;
  2         5  
  2         63  
3 2     2   9 use warnings;
  2         4  
  2         53  
4 2     2   6826 use Moo;
  2         38629  
  2         13  
5 2     2   6464 use Method::Signatures;
  2         188957  
  2         15  
6 2     2   2417 use IPC::Cmd qw(can_run);
  2         94373  
  2         141  
7 2     2   13 use Carp qw/croak/;
  2         5  
  2         95  
8 2     2   1943 use sigtrap qw(die normal-signals);
  2         2362  
  2         13  
9              
10             =head1 VERSION
11              
12             Version 0.12
13              
14             =cut
15              
16             our $VERSION = '0.12';
17              
18             =head1 NAME
19              
20             Net::OpenVPN::Launcher - start, stop and restart OpenVPN as a sub-process.
21              
22             =head1 SYNOPSIS
23              
24             use Net::OpenVPN::Launcher;
25              
26             my $pm = Net::OpenVPN::Launcher->new;
27              
28             $pm->start($filepath_to_config_file);
29              
30             # do some stuff
31              
32             # now stop the first instance of OpenVPN and start another
33             $pm->start($filepath_to_alt_config_file);
34              
35             # do some stuff
36              
37             $pm->stop;
38              
39             =head1 DESCRIPTION
40              
41             L<Net::OpenVPN::Launcher> is an object oriented module that provides methods to start, stop and restart OpenVPN. It's useful because it runs OpenVPN processes as a non-blocking sub-process. This allows you to start and stop several OpenVPN processes within the same Perl program.
42              
43              
44             =head1 SYSTEM REQUIREMENTS
45              
46             =over
47              
48             =item *
49              
50             OpenVPN needs to be installed and in $PATH (or in bin, in $PATH).
51              
52             =item *
53              
54             This module has been tested on OpenVPN version 2.2.1 - it should work with most versions of OpenVPN.
55              
56             =item *
57              
58             Currently only works with Linux-like operating systems.
59              
60             =item *
61              
62             By default OpenVPN needs to be run with root privileges, hence any Perl program using this module will need to be run as root unless OpenVPN has been configured to run under user privileges.
63              
64             =back
65              
66             =head1 METHODS
67              
68             =head2 start
69              
70             Initialises OpenVPN with a config file. Requires a filepath to an OpenVPN config file. See the OpenVPN L<documentation|http://openvpn.net/index.php/open-source/documentation/manuals/427-openvpn-22.html> for example config files and options.
71              
72             $pm->start('openvpn.conf');
73              
74             =cut
75              
76 2 0   2   358944 method start ($config_filepath) {
  0 0   0   0  
  0         0  
  0         0  
  0         0  
77             # check that config filepath exists
78 0         0 open( my $config, '<', $config_filepath );
79 0 0       0 croak "config filepath $config_filepath not readable"
80             unless -e $config_filepath;
81              
82 0         0 $self->config($config_filepath);
83              
84             # check openvpn is installed
85 0         0 my $openvpn_path = can_run('openvpn');
86 0 0       0 croak "openvpn binary not found" unless $openvpn_path;
87              
88             # stop existing process
89 0 0       0 $self->stop if $self->openvpn_pid;
90              
91             # run openvpn in child process
92 0         0 my $pid = fork();
93 0 0       0 unless ($pid) {
94 0         0 exec "$openvpn_path $config_filepath";
95             }
96 0         0 $self->openvpn_pid($pid);
97 0         0 return 1;
98             }
99              
100             =head2 restart
101              
102             Restarts the existing OpenVPN process with the same configuration file as before.
103              
104             $pm->restart;
105              
106             =cut
107              
108 2 0   2   1523 method restart {
  0     0   0  
  0         0  
109 0 0 0     0 unless ($self->config && $self->openvpn_pid) {
110 0         0 croak "Error: no running OpenVPN process found";
111             }
112 0         0 $self->start($self->config);
113 0         0 return 1;
114             }
115              
116             =head2 stop
117              
118             Kills the OpenVPN process.
119              
120             $pm->stop;
121              
122             =cut
123              
124 2 0   2   1197 method stop {
  0     0   0  
  0         0  
125 0 0       0 if ( $self->openvpn_pid ) {
126             # check if UID has permission to kill the openvpn process
127 0 0       0 kill 0, $self->openvpn_pid
128             ? kill 9, $self->openvpn_pid
129             : croak 'Error: unable to kill the openvpn PID: '
130             . $self->openvpn_pid;
131             }
132             else {
133 0         0 croak 'Error: no PID found for openvpn process';
134             }
135 0         0 sleep(1);
136 0         0 return 1;
137             }
138              
139             =head1 INTERNAL METHODS
140              
141             =head2 DEMOLISH
142              
143             This method is called on object destruction and it will call the stop method if any active openvpn processes are found. This means it is not necessary to call the stop method when exiting the program.
144              
145             =cut
146              
147             sub DEMOLISH {
148 1     1 1 118981 my $self = shift;
149 1 50       6 $self->stop if $self->openvpn_pid;
150             }
151              
152             =head2 config
153              
154             This is a getter/setter method for the filepath to the OpenVPN configuration file.
155              
156             =cut
157              
158             has config => ( is => 'rw' );
159              
160             =head2 openvpn_pid
161              
162             This is a getter/setter method for the PID of the openvpn process.
163              
164             =cut
165              
166             has openvpn_pid => (
167             is => 'rw',
168             isa => sub {
169             die "$_[0] is not a number" unless $_[0] =~ /[0-9]+/;
170             },
171             );
172              
173             1;
174              
175             =head1 AUTHOR
176              
177             David Farrell, C<< <davidnmfarrell at gmail.com> >>, L<perltricks.com|http://perltricks.com>
178              
179             =head1 BUGS
180              
181             Please report any bugs or feature requests to C<bug-net-openvpn-proxymanager at rt.cpan.org>, or through
182             the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Net-OpenVPN-Launcher>. I will be notified, and then you'll automatically be notified of
183             progress on your bug as I make changes.
184              
185             =head1 SUPPORT
186              
187             You can find documentation for this module with the perldoc command.
188              
189             perldoc Net::OpenVPN::Launcher
190              
191              
192             You can also look for information at:
193              
194             =over 4
195              
196             =item * RT: CPAN's request tracker (report bugs here)
197              
198             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Net-OpenVPN-Launcher>
199              
200             =item * AnnoCPAN: Annotated CPAN documentation
201              
202             L<http://annocpan.org/dist/Net-OpenVPN-Launcher>
203              
204             =item * CPAN Ratings
205              
206             L<http://cpanratings.perl.org/d/Net-OpenVPN-Launcher>
207              
208             =item * Search CPAN
209              
210             L<http://search.cpan.org/dist/Net-OpenVPN-Launcher/>
211              
212             =back
213              
214             =head1 LICENSE AND COPYRIGHT
215              
216             Copyright 2013 David Farrell.
217              
218             This program is free software; you can redistribute it and/or modify it
219             under the terms of the the Artistic License (2.0). You may obtain a
220             copy of the full license at:
221              
222             L<http://www.perlfoundation.org/artistic_license_2_0>
223              
224             Any use, modification, and distribution of the Standard or Modified
225             Versions is governed by this Artistic License. By using, modifying or
226             distributing the Package, you accept this license. Do not use, modify,
227             or distribute the Package, if you do not accept this license.
228              
229             If your Modified Version has been derived from a Modified Version made
230             by someone other than you, you are nevertheless required to ensure that
231             your Modified Version complies with the requirements of this license.
232              
233             This license does not grant you the right to use any trademark, service
234             mark, tradename, or logo of the Copyright Holder.
235              
236             This license includes the non-exclusive, worldwide, free-of-charge
237             patent license to make, have made, use, offer to sell, sell, import and
238             otherwise transfer the Package with respect to any patent claims
239             licensable by the Copyright Holder that are necessarily infringed by the
240             Package. If you institute patent litigation (including a cross-claim or
241             counterclaim) against any party alleging that the Package constitutes
242             direct or contributory patent infringement, then this Artistic License
243             to you shall terminate on the date that such litigation is filed.
244              
245             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
246             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
247             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
248             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
249             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
250             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
251             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
252             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
253              
254             =cut
255