File Coverage

lib/Rex/Box/Docker.pm
Criterion Covered Total %
statement 36 81 44.4
branch 0 12 0.0
condition 0 12 0.0
subroutine 13 20 65.0
pod 6 7 85.7
total 55 132 41.6


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Box::Docker - Rex/Boxes Docker Module
8              
9             =head1 DESCRIPTION
10              
11             This is a Rex/Boxes module to use Docker Images. You need to have dockerd 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 => "Docker";
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.tar.gz");
26             $box->url("debian:latest");
27              
28             $box->network(1 => {
29             name => "default",
30             });
31              
32             $box->auth(
33             user => "root",
34             password => "box",
35             );
36              
37             $box->setup("setup_task");
38             };
39             };
40              
41             If you want to use a YAML file you can use the following template.
42              
43             type: Docker
44             vms:
45             vmone:
46             url: debian:latest
47             setup: setup_task
48              
49             And then you can use it the following way in your Rexfile.
50              
51             use Rex::Commands::Box init_file => "file.yml";
52              
53             task "prepare_vms", sub {
54             boxes "init";
55             };
56              
57             =head1 METHODS
58              
59             See also the Methods of Rex::Box::Base. This module inherits all methods of it.
60              
61             =cut
62              
63             package Rex::Box::Docker;
64              
65 1     1   132372 use v5.12.5;
  1         18  
66 1     1   7 use warnings;
  1         1  
  1         34  
67 1     1   673 use Data::Dumper;
  1         7130  
  1         75  
68 1     1   387 use Rex::Box::Base;
  1         3  
  1         11  
69 1     1   43 use Rex::Commands -no => [qw/auth/];
  1         2  
  1         13  
70 1     1   7 use Rex::Commands::Fs;
  1         4  
  1         7  
71 1     1   8 use Rex::Commands::Virtualization;
  1         2  
  1         7  
72 1     1   5 use Rex::Commands::SimpleCheck;
  1         2  
  1         7  
73 1     1   15 use Rex::Virtualization::Docker::create;
  1         3  
  1         14  
74              
75             our $VERSION = '1.14.3'; # VERSION
76              
77             BEGIN {
78 1     1   66 LWP::UserAgent->use;
79             }
80              
81 1     1   6 use Time::HiRes qw(tv_interval gettimeofday);
  1         2  
  1         10  
82 1     1   144 use File::Basename qw(basename);
  1         4  
  1         46  
83              
84 1     1   5 use base qw(Rex::Box::Base);
  1         1  
  1         867  
85              
86             set virtualization => "Docker";
87              
88             $|++;
89              
90             ################################################################################
91             # BEGIN of class methods
92             ################################################################################
93              
94             =head2 new(name => $vmname)
95              
96             Constructor if used in OO mode.
97              
98             my $box = Rex::Box::Docker->new(name => "vmname");
99              
100             =cut
101              
102             sub new {
103 0     0 1   my $class = shift;
104 0   0       my $proto = ref($class) || $class;
105 0           my $self = $proto->SUPER::new(@_);
106              
107 0   0       bless( $self, ref($class) || $class );
108              
109 0           return $self;
110             }
111              
112             =head2 memory($memory_size)
113              
114             Sets the memory of a VM in megabyte.
115              
116             =cut
117              
118             sub memory {
119 0     0 1   my ( $self, $mem ) = @_;
120 0           Rex::Logger::debug("Memory option not supported.");
121             }
122              
123             sub import_vm {
124 0     0 1   my ($self) = @_;
125              
126             # check if machine already exists
127 0           my $vms = vm list => "all";
128              
129 0           my $vm_exists = 0;
130              
131 0           for my $vm ( @{$vms} ) {
  0            
132 0 0         if ( $vm->{name} eq $self->{name} ) {
133 0           Rex::Logger::debug("VM already exists. Don't import anything.");
134 0           $vm_exists = 1;
135             }
136             }
137              
138 0 0         if ( !$vm_exists ) {
139              
140             # if not, create it
141 0           my ($filename);
142 0 0         if ( $self->{url} =~ m/^(http|https):/ ) {
143 0           $self->_download;
144 0           $filename = "./tmp/" . basename( $self->{url} );
145 0           Rex::Logger::info("Importing VM ./tmp/$filename");
146             my @options = (
147             import => $self->{name},
148             file => $filename,
149 0           %{$self},
  0            
150             );
151 0           vm @options;
152             }
153             else {
154 0           vm import => $self->{name}, file => $self->{url}, %{$self};
  0            
155             }
156             }
157              
158 0           my $vminfo = vm info => $self->{name};
159              
160 0 0         unless ( $vminfo->{State}->{Running} ) {
161 0           $self->start;
162             }
163              
164 0           $self->{info} = vm guestinfo => $self->{name};
165             }
166              
167             sub list_boxes {
168 0     0 1   my ($self) = @_;
169              
170 0           my $vms = vm list => "all";
171              
172 0           return @{$vms};
  0            
173             }
174              
175             =head2 info
176              
177             Returns a hashRef of vm information.
178              
179             =cut
180              
181             sub info {
182 0     0 1   my ($self) = @_;
183 0           $self->ip;
184 0           return $self->{info};
185             }
186              
187             =head2 ip
188              
189             This method return the ip of a vm on which the ssh daemon is listening.
190              
191             =cut
192              
193             sub ip {
194 0     0 1   my ($self) = @_;
195 0           $self->{info} = vm guestinfo => $self->{name};
196              
197 0 0 0       if ( $self->{info}->{redirects}
      0        
198             && $self->{info}->{redirects}->{tcp}
199             && $self->{info}->{redirects}->{tcp}->{22} )
200             {
201             return (
202             $self->{info}->{redirects}->{tcp}->{22}->[0]->{ip} eq "0.0.0.0"
203             ? "127.0.0.1"
204             : $self->{info}->{redirects}->{tcp}->{22}->[0]->{ip}
205             )
206             . ":"
207 0 0         . $self->{info}->{redirects}->{tcp}->{22}->[0]->{port};
208             }
209             else {
210 0           return $self->{info}->{network}->[0]->{ip};
211             }
212             }
213              
214             sub create {
215 0     0 0   my ($self) = @_;
216             my @options = (
217             forward_port => [
218             $self->{__forward_port}->{ssh}->[0] . ":"
219             . $self->{__forward_port}->{ssh}->[1]
220             ],
221             image => $self->{url},
222 0           );
223              
224 0           Rex::Virtualization::Docker::create->execute( $self->{name}, @options );
225             }
226              
227             1;