File Coverage

lib/Rex/Box/KVM.pm
Criterion Covered Total %
statement 33 73 45.2
branch 0 8 0.0
condition 0 6 0.0
subroutine 12 18 66.6
pod 6 6 100.0
total 51 111 45.9


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Box::KVM - Rex/Boxes KVM Module
8              
9             =head1 DESCRIPTION
10              
11             This is a Rex/Boxes module to use KVM VMs. You need to have libvirt installed.
12              
13             =head1 EXAMPLES
14              
15             To use this module inside your Rexfile you can use the following commands.
16              
17             use Rex::Commands::Box;
18             set box => "KVM";
19              
20             task "prepare_box", sub {
21             box {
22             my ($box) = @_;
23              
24             $box->name("mybox");
25             $box->url("http://box.rexify.org/box/ubuntu-server-12.10-amd64.kvm.qcow2");
26              
27             $box->network(1 => {
28             name => "default",
29             });
30              
31             $box->auth(
32             user => "root",
33             password => "box",
34             );
35              
36             $box->setup("setup_task");
37             };
38             };
39              
40             If you want to use a YAML file you can use the following template.
41              
42             type: KVM
43             vms:
44             vmone:
45             url: http://box.rexify.org/box/ubuntu-server-12.10-amd64.kvm.qcow2
46             setup: setup_task
47              
48             And then you can use it the following way in your Rexfile.
49              
50             use Rex::Commands::Box init_file => "file.yml";
51              
52             task "prepare_vms", sub {
53             boxes "init";
54             };
55              
56             =head1 METHODS
57              
58             See also the Methods of Rex::Box::Base. This module inherits all methods of it.
59              
60             =cut
61              
62             package Rex::Box::KVM;
63              
64 1     1   20 use v5.12.5;
  1         9  
65 1     1   5 use warnings;
  1         1  
  1         27  
66 1     1   5 use Data::Dumper;
  1         1  
  1         43  
67 1     1   5 use Rex::Box::Base;
  1         2  
  1         7  
68 1     1   29 use Rex::Commands -no => [qw/auth/];
  1         2  
  1         18  
69 1     1   9 use Rex::Commands::Fs;
  1         4  
  1         15  
70 1     1   8 use Rex::Commands::Virtualization;
  1         4  
  1         10  
71 1     1   6 use Rex::Commands::SimpleCheck;
  1         2  
  1         9  
72              
73             our $VERSION = '1.14.2.2'; # TRIAL VERSION
74              
75             BEGIN {
76 1     1   18 LWP::UserAgent->use;
77             }
78              
79 1     1   7 use Time::HiRes qw(tv_interval gettimeofday);
  1         3  
  1         9  
80 1     1   158 use File::Basename qw(basename);
  1         5  
  1         66  
81              
82 1     1   6 use base qw(Rex::Box::Base);
  1         2  
  1         700  
83              
84             set virtualization => "LibVirt";
85              
86             $|++;
87              
88             ################################################################################
89             # BEGIN of class methods
90             ################################################################################
91              
92             =head2 new(name => $vmname)
93              
94             Constructor if used in OO mode.
95              
96             my $box = Rex::Box::KVM->new(name => "vmname");
97              
98             =cut
99              
100             sub new {
101 0     0 1   my $class = shift;
102 0   0       my $proto = ref($class) || $class;
103 0           my $self = $proto->SUPER::new(@_);
104              
105 0   0       bless( $self, ref($class) || $class );
106              
107 0           return $self;
108             }
109              
110             =head2 memory($memory_size)
111              
112             Sets the memory of a VM in megabyte.
113              
114             =cut
115              
116             sub memory {
117 0     0 1   my ( $self, $mem ) = @_;
118 0           $self->{memory} = $mem * 1024; # libvirt wants kilobytes
119             }
120              
121             sub import_vm {
122 0     0 1   my ($self) = @_;
123              
124             # check if machine already exists
125 0           my $vms = vm list => "all";
126              
127 0           my $vm_exists = 0;
128 0           for my $vm ( @{$vms} ) {
  0            
129 0 0         if ( $vm->{name} eq $self->{name} ) {
130 0           Rex::Logger::debug("VM already exists. Don't import anything.");
131 0           $vm_exists = 1;
132             }
133             }
134              
135 0 0         if ( !$vm_exists ) {
136              
137             # if not, create it
138 0           $self->_download;
139              
140 0           my $filename = basename( $self->{url} );
141              
142 0           Rex::Logger::info("Importing VM ./tmp/$filename");
143              
144             my @options = (
145             import => $self->{name},
146             file => "./tmp/$filename",
147 0           %{$self},
  0            
148             );
149              
150 0 0         if (Rex::Config::get_use_rex_kvm_agent) {
151 0           my $tcp_port = int( rand(40000) ) + 10000;
152              
153 0           push @options, 'serial_devices',
154             [
155             {
156             type => 'tcp',
157             host => '127.0.0.1',
158             port => $tcp_port,
159             },
160             ];
161              
162 0           Rex::Logger::info(
163             "Binding a serial device to TCP port $tcp_port for rex-kvm-agent");
164             }
165              
166 0           vm @options;
167              
168             #unlink "./tmp/$filename";
169             }
170              
171 0           my $vminfo = vm info => $self->{name};
172              
173 0 0         if ( $vminfo->{State} eq "shut off" ) {
174 0           $self->start;
175             }
176              
177 0           $self->{info} = vm guestinfo => $self->{name};
178             }
179              
180             sub list_boxes {
181 0     0 1   my ($self) = @_;
182              
183 0           my $vms = vm list => "all";
184              
185 0           return @{$vms};
  0            
186             }
187              
188             =head2 info
189              
190             Returns a hashRef of vm information.
191              
192             =cut
193              
194             sub info {
195 0     0 1   my ($self) = @_;
196 0           $self->ip;
197 0           return $self->{info};
198             }
199              
200             =head2 ip
201              
202             This method return the ip of a vm on which the ssh daemon is listening.
203              
204             =cut
205              
206             sub ip {
207 0     0 1   my ($self) = @_;
208 0           $self->{info} = vm guestinfo => $self->{name};
209 0           return $self->{info}->{network}->[0]->{ip};
210             }
211              
212             1;