So you moved this from pve-storage (in your previous [WIP] patch) to the qemu package. But I'm still wondering if the common parts can be factored out into public functions in the pve-storage package. I also see you didn't copy over the ssh code, so you won't be able to upload disks to VMs on different hosts when in a cluster?
On Mon, Feb 15, 2016 at 02:33:49PM +0100, Timo Grodzinski wrote: > 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' }, This is a tricky one. We have VM.Config.Disk on VMs which should probably be used here. > + 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 ); In vzdump the use of pigz is optional as pigz might not be available it should probably be optional here, too. > + 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 > _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel