]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/CLI/pvesm.pm
import: add -delete-snapshot parameter
[pve-storage.git] / PVE / CLI / pvesm.pm
index bb122ce346b4689e02890a2f55bb9f26cfd23ca7..8af4e7fd46bcac53aedfc52ffe187547f1a2d249 100755 (executable)
@@ -21,8 +21,14 @@ use PVE::CLIHandler;
 
 use base qw(PVE::CLIHandler);
 
+my $KNOWN_EXPORT_FORMATS = ['zfs'];
+
 my $nodename = PVE::INotify::nodename();
 
+sub setup_environment {
+    PVE::RPCEnvironment->setup_default_cli_env();
+}
+
 __PACKAGE__->register_method ({
     name => 'path',
     path => 'path',
@@ -34,6 +40,7 @@ __PACKAGE__->register_method ({
            volume => {
                description => "Volume identifier",
                type => 'string', format => 'pve-volume-id',
+               completion => \&PVE::Storage::complete_volume,
            },
        },
     },
@@ -52,6 +59,43 @@ __PACKAGE__->register_method ({
 
     }});
 
+__PACKAGE__->register_method ({
+    name => 'extractconfig',
+    path => 'extractconfig',
+    method => 'GET',
+    description => "Extract configuration from vzdump backup archive.",
+    permissions => {
+       description => "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.",
+       user => 'all',
+    },
+    protected => 1,
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           volume => {
+               description => "Volume identifier",
+               type => 'string',
+               completion => \&PVE::Storage::complete_volume,
+           },
+       },
+    },
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+       my $volume = $param->{volume};
+
+       my $rpcenv = PVE::RPCEnvironment::get();
+       my $authuser = $rpcenv->get_user();
+
+       my $storage_cfg = PVE::Storage::config();
+       PVE::Storage::check_volume_access($rpcenv, $authuser, $storage_cfg, undef, $volume);
+
+       my $config_raw = PVE::Storage::extract_vzdump_config($storage_cfg, $volume);
+
+       print "$config_raw\n";
+       return;
+    }});
+
 my $print_content = sub {
     my ($list) = @_;
 
@@ -102,6 +146,152 @@ my $print_status = sub {
     }
 };
 
+__PACKAGE__->register_method ({
+    name => 'export',
+    path => 'export',
+    method => 'GET',
+    description => "Export a volume.",
+    protected => 1,
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           volume => {
+               description => "Volume identifier",
+               type => 'string',
+               completion => \&PVE::Storage::complete_volume,
+           },
+           format => {
+               description => "Export stream format",
+               type => 'string',
+               enum => $KNOWN_EXPORT_FORMATS,
+           },
+           filename => {
+               description => "Destination file name",
+               type => 'string',
+           },
+           base => {
+               description => "Snapshot to start an incremental stream from",
+               type => 'string',
+               pattern => qr/[a-z0-9_\-]{1,40}/,
+               maxLength => 40,
+               optional => 1,
+           },
+           snapshot => {
+               description => "Snapshot to export",
+               type => 'string',
+               pattern => qr/[a-z0-9_\-]{1,40}/,
+               maxLength => 40,
+               optional => 1,
+           },
+           'with-snapshots' => {
+               description =>
+                   "Whether to include intermediate snapshots in the stream",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
+           },
+       },
+    },
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+
+       my $filename = $param->{filename};
+
+       my $outfh;
+       if ($filename eq '-') {
+           $outfh = \*STDOUT;
+       } else {
+           open($outfh, '>', $filename)
+               or die "open($filename): $!\n";
+       }
+
+       eval {
+           my $cfg = PVE::Storage::config();
+           PVE::Storage::volume_export($cfg, $outfh, $param->{volume}, $param->{format},
+               $param->{snapshot}, $param->{base}, $param->{'with-snapshots'});
+       };
+       my $err = $@;
+       if ($filename ne '-') {
+           close($outfh);
+           unlink($filename) if $err;
+       }
+       die $err if $err;
+       return;
+    }
+});
+
+__PACKAGE__->register_method ({
+    name => 'import',
+    path => 'import',
+    method => 'PUT',
+    description => "Import a volume.",
+    protected => 1,
+    parameters => {
+       additionalProperties => 0,
+       properties => {
+           volume => {
+               description => "Volume identifier",
+               type => 'string',
+               completion => \&PVE::Storage::complete_volume,
+           },
+           format => {
+               description => "Import stream format",
+               type => 'string',
+               enum => $KNOWN_EXPORT_FORMATS,
+           },
+           filename => {
+               description => "Source file name",
+               type => 'string',
+           },
+           base => {
+               description => "Base snapshot of an incremental stream",
+               type => 'string',
+               pattern => qr/[a-z0-9_\-]{1,40}/,
+               maxLength => 40,
+               optional => 1,
+           },
+           'with-snapshots' => {
+               description =>
+                   "Whether the stream includes intermediate snapshots",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
+           },
+           'delete-snapshot' => {
+               description => "A snapshot to delete on success",
+               type => 'string',
+               pattern => qr/[a-z0-9_\-]{1,80}/,
+               maxLength => 80,
+               optional => 1,
+           },
+       },
+    },
+    returns => { type => 'null' },
+    code => sub {
+       my ($param) = @_;
+
+       my $filename = $param->{filename};
+
+       my $infh;
+       if ($filename eq '-') {
+           $infh = \*STDIN;
+       } else {
+           open($infh, '<', $filename)
+               or die "open($filename): $!\n";
+       }
+
+       my $cfg = PVE::Storage::config();
+       my $volume = $param->{volume};
+       my $delete = $param->{'delete-snapshot'};
+       PVE::Storage::volume_import($cfg, $infh, $volume, $param->{format},
+           $param->{base}, $param->{'with-snapshots'});
+       PVE::Storage::volume_snapshot_delete($cfg, $volume, $delete)
+           if defined($delete);
+       return;
+    }
+});
+
 our $cmddef = {
     add => [ "PVE::API2::Storage::Config", 'create', ['type', 'storage'] ],
     set => [ "PVE::API2::Storage::Config", 'update', ['storage'] ],
@@ -113,7 +303,7 @@ our $cmddef = {
     alloc => [ "PVE::API2::Storage::Content", 'create', ['storage', 'vmid', 'filename', 'size'],
               { node => $nodename }, sub {
                   my $volid = shift;
-                  print "sucessfuly created '$volid'\n";
+                  print "successfully created '$volid'\n";
               }],
     free => [ "PVE::API2::Storage::Content", 'delete', ['volume'],
              { node => $nodename } ],
@@ -158,6 +348,13 @@ our $cmddef = {
                         printf "$rec->{vg}\n";
                     }
                 }],
+    lvmthinscan => [ "PVE::API2::Storage::Scan", 'lvmthinscan', ['vg'],
+                { node => $nodename }, sub  {
+                    my $res = shift;
+                    foreach my $rec (@$res) {
+                        printf "$rec->{lv}\n";
+                    }
+                }],
     zfsscan => [ "PVE::API2::Storage::Scan", 'zfsscan', [],
                 { node => $nodename }, sub  {
                     my $res = shift;
@@ -167,105 +364,9 @@ our $cmddef = {
                     }
                 }],
     path => [ __PACKAGE__, 'path', ['volume']],
+    extractconfig => [__PACKAGE__, 'extractconfig', ['volume']],
+    export => [ __PACKAGE__, 'export', ['volume', 'format', 'filename']],
+    import => [ __PACKAGE__, 'import', ['volume', 'format', 'filename']],
 };
 
 1;
-
-__END__
-
-=head1 NAME
-
-pvesm - PVE Storage Manager
-
-=head1 SYNOPSIS
-
-=include synopsis
-
-=head1 DESCRIPTION
-
-=head2 Storage pools
-
-Each storage pool is uniquely identified by its <STORAGE_ID>.
-
-=head3 Storage content
-
-A storage can support several content types, for example virtual disk
-images, cdrom iso images, openvz templates or openvz root directories
-(C<images>, C<iso>, C<vztmpl>, C<rootdir>).
-
-=head2 Volumes
-
-A volume is identified by the <STORAGE_ID>, followed by a storage type
-dependent volume name, separated by colon. A valid <VOLUME_ID> looks like:
-
- local:230/example-image.raw
-
- local:iso/debian-501-amd64-netinst.iso
-
- local:vztmpl/debian-5.0-joomla_1.5.9-1_i386.tar.gz
-
- iscsi-storage:0.0.2.scsi-14f504e46494c4500494b5042546d2d646744372d31616d61
-
-To get the filesystem path for a <VOLUME_ID> use:
-
- pvesm path <VOLUME_ID>
-
-
-=head1 EXAMPLES
-
- # scan iscsi host for available targets
- pvesm iscsiscan -portal <HOST[:PORT]>
-
- # scan nfs server for available exports
- pvesm nfsscan <HOST>
-
- # add storage pools
- pvesm add <TYPE> <STORAGE_ID> <OPTIONS>
- pvesm add dir <STORAGE_ID> --path <PATH>
- pvesm add nfs <STORAGE_ID> --path <PATH> --server <SERVER> --export <EXPORT>
- pvesm add lvm <STORAGE_ID> --vgname <VGNAME>
- pvesm add iscsi <STORAGE_ID> --portal <HOST[:PORT]> --target <TARGET>
-
- # disable storage pools
- pvesm set <STORAGE_ID> --disable 1
-
- # enable storage pools
- pvesm set <STORAGE_ID> --disable 0
-
- # change/set storage options
- pvesm set <STORAGE_ID> <OPTIONS>
- pvesm set <STORAGE_ID> --shared 1
- pvesm set local --format qcow2
- pvesm set <STORAGE_ID> --content iso
-
- # remove storage pools - does not delete any data
- pvesm remove <STORAGE_ID>
-
- # alloc volumes
- pvesm alloc <STORAGE_ID> <VMID> <name> <size> [--format <raw|qcow2>]
-
- # alloc 4G volume in local storage - use auto generated name
- pvesm alloc local <VMID> '' 4G
-
- # free volumes (warning: destroy/deletes all volume data)
- pvesm free <VOLUME_ID>
-
- # list storage status
- pvesm status
-
- # list storage contents
- pvesm list <STORAGE_ID> [--vmid <VMID>]
-
- # list volumes allocated by VMID
- pvesm list <STORAGE_ID> --vmid <VMID>
-
- # list iso images
- pvesm list <STORAGE_ID> --iso
-
- # list openvz templates
- pvesm list <STORAGE_ID> --vztmpl
-
- # show filesystem path for a volume
- pvesm path <VOLUME_ID>
-
-=include pve_copyright