Signed-off-by: Timo Grodzinski <t.grodzin...@profihost.ag> --- PVE/API2/Qemu.pm | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 226e597..47a0a56 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -3,6 +3,7 @@ package PVE::API2::Qemu; use strict; use warnings; use Cwd 'abs_path'; +use File::Basename; use Net::SSLeay; use UUID; @@ -2492,6 +2493,128 @@ __PACKAGE__->register_method({ }}); __PACKAGE__->register_method({ + name => 'upload_image', + path => '{vmid}/upload_image', + method => 'POST', + proxyto => 'node', + description => "Upload vm disk images.", + permissions => { user => 'all' }, + protected => 1, + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option( 'pve-node' ), + vmid => get_standard_option( 'pve-vmid' ), + disk => { + type => 'string', + description => "The target disk where you want to upload.", + enum => [ PVE::QemuServer::disknames() ], + }, + filename => { + description => "The name of the file to create.", + type => 'string', + }, + tmpfilename => { + description => +"The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trustet port on localhost.", + type => 'string', + optional => 1, + }, + }, + }, + returns => { type => "string" }, + code => sub { + my ( $param ) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $authuser = $rpcenv->get_user(); + + my $node = extract_param( $param, 'node' ); + + my $vmid = extract_param( $param, 'vmid' ); + die "vm $vmid is running\n" if PVE::QemuServer::check_running( $vmid ); + + my $digest = extract_param( $param, 'digest' ); + + my $conf = PVE::QemuServer::load_config( $vmid ); + die "checksum missmatch (file change by other user?)\n" if $digest && $digest ne $conf->{digest}; + + my $disk = extract_param( $param, 'disk' ); + die "disk '$disk' does not exist\n" if !$conf->{$disk}; + + my $tmpfilename = extract_param( $param, 'tmpfilename' ); + die "missing temporary file name\n" if !$tmpfilename; + + my $size = -s $tmpfilename; + die "temporary file '$tmpfilename' does not exists\n" if !defined( $size ); + + my $filename = extract_param( $param, 'filename' ); + + chomp $filename; + $filename =~ s/^.*[\/\\]//; + $filename =~ s/[;:,=\s\x80-\xff]/_/g; + + my @allowed_extensions = map { ( $_, "$_.gz" ) } qw(raw qcow qcow2 cow vdi vmdk vpc cloop); + raise_param_exc( { filename => "extension must be one of " . join ', ', map ".$_", @allowed_extensions } ) + if !grep { $filename =~ m![^/]+\.$_$! } @allowed_extensions; + + my $storecfg = PVE::Storage::config(); + + my $drive = PVE::QemuServer::parse_drive( $disk, $conf->{$disk} ); + + my $worker = sub { + my ( $upid ) = @_; + + my $dirname = dirname( $tmpfilename ); + my $file = "$dirname/$filename"; + my $new_filename; + + eval { + + # rename file (pigz wont work without .gz extension) + rename( $tmpfilename, $file ); + + # parallel gunzip if file has .gz extension + if ( $filename =~ /(.*?)\.gz$/i ) { + + print "\nextracting file...\n"; + + $new_filename = $1; + + my @unzip_cmd = ( 'unpigz', $file ); + print "running '" . PVE::Tools::cmd2string( \@unzip_cmd ) . "'\n"; + eval { PVE::Tools::run_command( \@unzip_cmd, errmsg => 'Extract failed' ); }; + die "extracting file failed: $@\n" if $@; + + print "extracted file successfully\n"; + $filename = $new_filename; + $file = "$dirname/$new_filename"; + } + + my $img_volid = PVE::Storage::path_to_volume_id( $storecfg, $file ); + die "cannot get volume id for file '$file'\n" if !$img_volid; + + my $err; + my $newdrive = eval { PVE::QemuServer::import_disk( $storecfg, $vmid, $img_volid, $drive ) }; + die "error with disk import: $@\n" if $@; + + }; + + unlink $file; + unlink $new_filename if defined $new_filename; + + print "\nimport successfull\n"; + + }; + + my $upid = $rpcenv->fork_worker( 'imgupload', undef, $authuser, $worker ); + + return $upid; + + }}); + +__PACKAGE__->register_method({ name => 'migrate_vm', path => '{vmid}/migrate', method => 'POST', -- 2.1.4 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel