1# 2# (c) Jan Gehring <jan.gehring@gmail.com> 3# 4# vim: set ts=2 sw=2 tw=0: 5# vim: set expandtab: 6 7package Rex::Virtualization::LibVirt::import; 8 9use 5.010001; 10use strict; 11use warnings; 12 13our $VERSION = '1.13.4'; # VERSION 14 15use Rex::Logger; 16use Rex::Helper::Run; 17use Rex::Commands::Fs; 18use File::Basename; 19use Rex::Virtualization::LibVirt::create; 20use Data::Dumper; 21 22# 23# %opt = (cpus => 2, memory => 512) 24# 25sub execute { 26 my ( $class, $arg1, %opt ) = @_; 27 28 unless ($arg1) { 29 die("You have to define the vm name!"); 30 } 31 32 my $dom = $arg1; 33 Rex::Logger::debug( "importing: $dom -> " . $opt{file} ); 34 35 my $cwd = i_run "pwd"; 36 chomp $cwd; 37 38 my $dir = dirname $opt{file}; 39 my ( undef, undef, $suffix ) = fileparse( $opt{file}, qr{\.[^.]*} ); 40 $opt{storage_path} = $cwd . '/storage' unless ( $opt{storage_path} ); 41 my $file = $opt{storage_path} . '/' . $dom . $suffix; 42 i_run "mkdir -p $opt{storage_path}"; 43 44 my $format = "qcow2"; 45 46 my @serial_devices; 47 if ( exists $opt{serial_devices} ) { 48 @serial_devices = @{ $opt{serial_devices} }; 49 } 50 51 if ( $opt{file} =~ m/\.ova$/ ) { 52 Rex::Logger::debug("Importing ova file. Try to convert with qemu-img"); 53 $file =~ s/\.[a-z]+$//; 54 55 my @vmdk = grep { m/\.vmdk$/ } i_run "tar -C '$dir' -vxf '$opt{file}'"; 56 57 Rex::Logger::debug("converting '$cwd/tmp/$vmdk[0]' -> '$file.qcow2'"); 58 i_run "qemu-img convert -O qcow2 '$cwd/tmp/$vmdk[0]' '$file.qcow2'", 59 fail_ok => 1; 60 61 if ( $? != 0 ) { 62 Rex::Logger::info( 63 "Can't import and convert $opt{file}. You qemu-img version seems not " 64 . " to support this format.", 65 "warn" 66 ); 67 die("Error importing VM $opt{file}"); 68 } 69 70 $file = "$file.qcow2"; 71 } 72 else { 73 Rex::Logger::debug("Importing kvm compatible file."); 74 Rex::Logger::debug("Copying $opt{file} -> $file"); 75 cp $opt{file}, $file; 76 if ( $file =~ m/\.gz$/ ) { 77 Rex::Logger::debug("Extracting gzip'ed file $file"); 78 i_run "gunzip -q -f '$file'"; 79 $file =~ s/\.gz$//; 80 } 81 } 82 83 my ($format_out) = grep { m/^file format:/ } i_run "qemu-img info '$file'", 84 fail_ok => 1; 85 if ( $format_out =~ m/^file format: (.*)$/i ) { 86 $format = $1; 87 } 88 89 my @network = values %{ $opt{__network} }; 90 if ( scalar @network == 0 ) { 91 92 # create default network 93 push @network, 94 { 95 type => "network", 96 network => "default", 97 }; 98 } 99 100 for (@network) { 101 $_->{type} ||= "network"; 102 $_->{type} = "bridge" if ( $_->{type} && $_->{type} eq "bridged" ); 103 $_->{type} = "network" if ( $_->{type} eq "nat" ); 104 if ( $_->{type} eq "network" && !exists $_->{network} ) { 105 $_->{network} = "default"; 106 } 107 } 108 109 Rex::Virtualization::LibVirt::create->execute( 110 $dom, 111 storage => [ 112 { 113 file => "$file", 114 dev => "vda", 115 driver_type => $format, 116 }, 117 ], 118 network => \@network, 119 serial_devices => \@serial_devices, 120 memory => $opt{memory}, 121 cpus => $opt{cpus}, 122 ); 123 124 if ( exists $opt{__forward_port} ) { 125 126 # currently not supported 127 Rex::Logger::info( 128 "Port-forwarding is currently not supported for KVM boxes.", "warn" ); 129 } 130 131} 132 1331; 134