]> git.proxmox.com Git - qemu-server.git/commitdiff
fix #1999: create a tree view for qm listsnapshot
authorRhonda D'Vine <rhonda@proxmox.com>
Fri, 10 May 2019 12:45:55 +0000 (14:45 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Mon, 13 May 2019 05:38:36 +0000 (05:38 +0000)
The look of the tree is based on the GUI variant, so that we have a
consistent output when run multiple times, too.

Signed-off-by: Rhonda D'Vine <rhonda@proxmox.com>
PVE/CLI/qm.pm

index cea2549ba56b037adcfd657e05f315b99adadc88..279d0d96860ef8ba4925a3b25e2c50cb08065fc1 100755 (executable)
@@ -11,6 +11,7 @@ use File::Path;
 use IO::Socket::UNIX;
 use IO::Select;
 use URI::Escape;
+use POSIX qw(strftime);
 
 use PVE::Tools qw(extract_param);
 use PVE::Cluster;
@@ -922,12 +923,55 @@ our $cmddef = {
     listsnapshot => [ "PVE::API2::Qemu", 'snapshot_list', ['vmid'], { node => $nodename },
                    sub {
                        my $res = shift;
+
+                       # "our" scope for the snaptimesort function
+                       my $snapshots = { map { $_->{name} => $_ } @$res };
+
+                       my $root;
                        foreach my $e (@$res) {
-                           my $headline = $e->{description} || 'no-description';
-                           $headline =~ s/\n.*//sg;
-                           my $parent = $e->{parent} // 'no-parent';
-                           printf("%-20s %-20s %s\n", $e->{name}, $parent, $headline);
+                           if (my $parent = $e->{parent}) {
+                               push @{$snapshots->{$parent}->{children}}, $e->{name};
+                           } else {
+                               $root = $e->{name};
+                           }
                        }
+
+                       my $prefix = '`->';
+
+                       # sort the elements by snaptime - with "current" (no snaptime) highest
+                       my $snaptimesort = sub {
+                           return +1 if !defined $snapshots->{$a}->{snaptime};
+                           return -1 if !defined $snapshots->{$b}->{snaptime};
+                           return $snapshots->{$a}->{snaptime} <=> $snapshots->{$b}->{snaptime};
+                       };
+
+                       # recursion function for displaying the tree
+                       my $snapshottree;
+                       $snapshottree = sub {
+                           my ($prefix, $root, $snapshots) = @_;
+                           my $e = $snapshots->{$root};
+
+                           my $description = $e->{description} || 'no-description';
+                           ($description) = $description =~ m/(.*)$/m;
+
+                           # create the timestamp string
+                           my $timestring = "";
+                           if (defined $e->{snaptime}) {
+                               $timestring = strftime("%F %H:%M:%S", localtime($e->{snaptime}));
+                           }
+
+                           # for aligning the description
+                           my $len = 30 - length($prefix);
+                           printf("%s %-${len}s %-23s %s\n", $prefix, $root, $timestring, $description);
+                           if ($e->{children}) {
+                               $prefix = "    $prefix";
+                               foreach my $child (sort $snaptimesort @{$e->{children}}) {
+                                   $snapshottree->($prefix, $child, $snapshots);
+                               }
+                           }
+                       };
+
+                       $snapshottree->($prefix, $root, $snapshots);
                    }],
 
     rollback => [ "PVE::API2::Qemu", 'rollback', ['vmid', 'snapname'], { node => $nodename } , $upid_exit ],