mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	lstree implementation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@11299 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										655
									
								
								xCAT-server/lib/xcat/plugins/tree.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										655
									
								
								xCAT-server/lib/xcat/plugins/tree.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,655 @@ | ||||
| package xCAT_plugin::tree; | ||||
|  | ||||
| BEGIN | ||||
| { | ||||
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; | ||||
| } | ||||
| use lib "$::XCATROOT/lib/perl"; | ||||
|  | ||||
| use xCAT::NodeRange; | ||||
| use Data::Dumper; | ||||
| use xCAT::Utils; | ||||
| use Sys::Syslog; | ||||
| use xCAT::GlobalDef; | ||||
| use xCAT::Table; | ||||
| use Getopt::Long; | ||||
| use xCAT::SvrUtils; | ||||
| #use strict; | ||||
|  | ||||
| sub handled_commands | ||||
| { | ||||
|     # currently, only for lstree command. | ||||
|     return { | ||||
|         lstree => "tree", | ||||
|     }; | ||||
| } | ||||
|  | ||||
| sub usage | ||||
| { | ||||
|     my $command = shift; | ||||
|     my $callback = shift; | ||||
|  | ||||
|     if($command eq "lstree") | ||||
|     { | ||||
|         &usage_lstree($callback); | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #---------------------------------------------------------------------------- | ||||
|  | ||||
| =head3  usage_lstree | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------------- | ||||
| sub usage_lstree | ||||
| { | ||||
|     my $callback = shift; | ||||
|  | ||||
|     my $rsp; | ||||
|     push @{$rsp->{data}}, | ||||
|       "\n  lstree - Display the tree of service node hierarchy, hardware hierarchy, or VM hierarchy."; | ||||
|     push @{$rsp->{data}}, "  Usage: "; | ||||
|     push @{$rsp->{data}}, "\tlstree [-h | --help]"; | ||||
|     push @{$rsp->{data}}, "or"; | ||||
|     push @{$rsp->{data}}, "\tlstree [-s | --servicenode] [-H | --hardwaremgmt] [-v | --virtualmachine] [noderange]"; | ||||
|      | ||||
|     xCAT::MsgUtils->message("I", $rsp, $callback); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #---------------------------------------------------------------------------- | ||||
|  | ||||
| =head3  process_request | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------------- | ||||
| sub process_request | ||||
| { | ||||
|     my $request = shift; | ||||
|     my $callback = shift; | ||||
|     my @nodes=(); | ||||
|  | ||||
|     if($request->{node}) | ||||
|     { | ||||
|         @nodes = @{$request->{node}}; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         # handle all nodes by default. | ||||
|         my $nodelist = xCAT::Table->new('nodelist'); | ||||
|         unless ($nodelist) | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open nodelist table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         my @entries  = ($nodelist->getAllNodeAttribs([qw(node)])); | ||||
|         foreach (@entries) | ||||
|         { | ||||
|             push @nodes, $_->{node}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     my $command = $request->{command}->[0]; | ||||
|     if($command eq "lstree") | ||||
|     { | ||||
|         &lstree($request, $callback, \@nodes); | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         $callback->({error=>["error in code..."], errorcode=>[127]}); | ||||
|         $request = {}; | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #---------------------------------------------------------------------------- | ||||
|  | ||||
| =head3  lstree | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------------- | ||||
| sub lstree | ||||
| { | ||||
|     my $request = shift; | ||||
|     my $callback = shift; | ||||
|     my $nodelist = shift; | ||||
|  | ||||
|     unless($request->{arg} || defined $nodelist) | ||||
|     { | ||||
|         &usage_lstree($callback); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     # parse the options | ||||
|     Getopt::Long::Configure("no_pass_through"); | ||||
|     Getopt::Long::Configure("bundling"); | ||||
|      | ||||
|     if ($request->{arg}) | ||||
|     { | ||||
|         @ARGV = @{$request->{arg}}; | ||||
|          | ||||
|         if ( | ||||
|             !GetOptions( | ||||
|                         'h|help'           => \$::HELP, | ||||
|                         's|servicenode'    => \$::SVCNODE, | ||||
|                         'H|hardwaremgmt'   => \$::HDWR, | ||||
|                         'v|virtualmachine' => \$::VMACHINE, | ||||
|             ) | ||||
|           ) | ||||
|         { | ||||
|             &usage_lstree($callback); | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if ($::HELP) | ||||
|     { | ||||
|         &usage_lstree($callback); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     if (!$::SVCNODE && !$::HDWR && !$::VMACHINE) | ||||
|     { | ||||
|         # show both vmtree and hwtree by default. | ||||
|         $::SHOWALL = 1; | ||||
|     } | ||||
|  | ||||
|     my %hwtrees; | ||||
|     my %vmtrees; | ||||
|     my %sntrees; | ||||
|      | ||||
|     # servicenode hierarchy | ||||
|     if ($::SVCNODE) | ||||
|     { | ||||
|         # build up sn tree hash. | ||||
|         my $snhash; | ||||
|         my @entries; | ||||
|         my $restab = xCAT::Table->new('noderes'); | ||||
|         if ($restab) | ||||
|         { | ||||
|             $snhash = $restab->getNodesAttribs($nodelist, ['servicenode']); | ||||
|             @entries = $restab->getAllNodeAttribs(['node','servicenode']); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open noderes table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         foreach my $node (@$nodelist) | ||||
|         { | ||||
|             # servicenode defined for this node | ||||
|             if ($snhash->{$node}->[0]->{'servicenode'}) | ||||
|             { | ||||
|                 unless (grep(/$node/, @{$sntrees{$snhash->{$node}->[0]->{'servicenode'}}})) | ||||
|                 { | ||||
|                     push @{$sntrees{$snhash->{$node}->[0]->{'servicenode'}}}, $node; | ||||
|                 } | ||||
|             } | ||||
|             else # need to know if itself is service node | ||||
|             { | ||||
|                 foreach my $ent (@entries) | ||||
|                 { | ||||
|                     if ($ent->{servicenode} eq $node) | ||||
|                     { | ||||
|                         unless (grep(/$ent->{node}/, @{$sntrees{$node}})) | ||||
|                         { | ||||
|                             push @{$sntrees{$node}}, $ent->{node}; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|          | ||||
|         } | ||||
|         #print Dumper(\%sntreehash); | ||||
|  | ||||
|         # show service node tree | ||||
|         &showtree(\%sntrees, 0, 0, $callback); | ||||
|     }     | ||||
|  | ||||
|     # get hwtree hash from each plugin | ||||
|     if ($::HDWR || $::SHOWALL) | ||||
|     { | ||||
|         # classify the nodes | ||||
|         # read nodehm.mgt | ||||
|         my $hmhash; | ||||
|         my $hmtab = xCAT::Table->new('nodehm'); | ||||
|         if ($hmtab) | ||||
|         { | ||||
|             $hmhash = $hmtab->getNodesAttribs($nodelist, ['mgt']); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open nodehm table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         # may add new support later. | ||||
|         my @supportedhw = ("hmc", "fsp", "blade", "ipmi"); | ||||
|         my %hwnodes; | ||||
|  | ||||
|         foreach my $node (@$nodelist) | ||||
|         { | ||||
|             # mgt defined for this node | ||||
|             unless ($hmhash->{$node}->[0]->{'mgt'}) | ||||
|             { | ||||
|                 next; | ||||
|             } | ||||
|  | ||||
|             if (grep(/$hmhash->{$node}->[0]->{'mgt'}/, @supportedhw)) | ||||
|             { | ||||
|                 push @{$hwnodes{$hmhash->{$node}->[0]->{'mgt'}}}, $node; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (%hwnodes) | ||||
|         { | ||||
|             foreach my $type (keys %hwnodes) | ||||
|             { | ||||
|                 $hwtrees{$type} = ${"xCAT_plugin::".$type."::"}{genhwtree}->(\@{$hwnodes{$type}}, $callback); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #print Dumper(\%hwtrees); | ||||
|     } | ||||
|  | ||||
|     if ($::HDWR && !$::VMACHINE) | ||||
|     { | ||||
|         &showtree(0, \%hwtrees, 0, $callback); | ||||
|     } | ||||
|  | ||||
|     # generate vmtree from xcat vm table | ||||
|     if ($::VMACHINE || $::SHOWALL) | ||||
|     { | ||||
|  | ||||
|         # here is a special case for zvm. | ||||
|         ########### start ################ | ||||
|         # read nodehm.mgt | ||||
|         my $hmhash; | ||||
|         my $hmtab = xCAT::Table->new('nodehm'); | ||||
|         if ($hmtab) | ||||
|         { | ||||
|             $hmhash = $hmtab->getNodesAttribs($nodelist, ['mgt']); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open nodehm table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         my @znodes; | ||||
|  | ||||
|         foreach my $node (@$nodelist) | ||||
|         { | ||||
|             # mgt defined for this node | ||||
|             unless ($hmhash->{$node}->[0]->{'mgt'}) | ||||
|             { | ||||
|                 next; | ||||
|             } | ||||
|  | ||||
|             if ($hmhash->{$node}->[0]->{'mgt'} =~ /zvm/) | ||||
|             { | ||||
|                 push @znodes, $node; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         my $ret = xCAT_plugin::zvm::listTree($callback, \@znodes); | ||||
|          | ||||
|         ########### end ################ | ||||
|          | ||||
|         # read vm.host | ||||
|         my $vmhash; | ||||
|          | ||||
|         my $vmtab = xCAT::Table->new('vm'); | ||||
|         if ($vmtab) | ||||
|         { | ||||
|             $vmhash = $vmtab->getNodesAttribs($nodelist, ['host']); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open vm table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         my @entries = $vmtab->getAllNodeAttribs(['node','host']); | ||||
|          | ||||
|         foreach my $node (@$nodelist) | ||||
|         { | ||||
|             foreach my $ent (@entries) | ||||
|             { | ||||
|                 if ($ent->{host} =~ /$node/) # host | ||||
|                 { | ||||
|                     push @{$vmtrees{$node}}, $ent->{node}; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             if ($vmhash && $vmhash->{$node}->[0]->{'host'}) # vm | ||||
|             { | ||||
|                 unless (grep(/$node/, @{$vmtrees{$vmhash->{$node}->[0]->{'host'}}})) | ||||
|                 { | ||||
|                     push @{$vmtrees{$vmhash->{$node}->[0]->{'host'}}}, $node; | ||||
|                 } | ||||
|             } | ||||
|         }         | ||||
|         #print Dumper(\%vmtrees); | ||||
|     } | ||||
|  | ||||
|     # vm tree output | ||||
|     if (!$::HDWR && $::VMACHINE) | ||||
|     { | ||||
|         &showtree(0, 0, \%vmtrees, $callback); | ||||
|     } | ||||
|  | ||||
|     if ($::SHOWALL || ($::HDWR && $::VMACHINE)) | ||||
|     { | ||||
|         &showtree(0, \%hwtrees, \%vmtrees, $callback); | ||||
|     } | ||||
|     return; | ||||
|  | ||||
| } # lstree end | ||||
|  | ||||
| #---------------------------------------------------------------------------- | ||||
|  | ||||
| =head3  showtree | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #----------------------------------------------------------------------------- | ||||
| sub showtree | ||||
| { | ||||
|     my $snthash = shift; | ||||
|     my $hwthash = shift; | ||||
|     my $vmthash = shift; | ||||
|     my $callback = shift; | ||||
|  | ||||
|     my %sntrees = %$snthash; | ||||
|     my %hwtrees = %$hwthash; | ||||
|     my %vmtrees = %$vmthash; | ||||
|  | ||||
|     # temp workaround before we integrate LPARs into vm table | ||||
|     my $lparinvm = 0; | ||||
|     my @entries; | ||||
|  | ||||
|     if (!$lparinvm) | ||||
|     { | ||||
|         # read ppc table | ||||
|         my $ppctab = xCAT::Table->new('ppc'); | ||||
|         unless ($ppctab) | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{data}->[0] = "Can not open ppc table.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1); | ||||
|         } | ||||
|  | ||||
|         @entries = $ppctab->getAllNodeAttribs(['node','id','parent']);     | ||||
|     } | ||||
|  | ||||
|     if (%sntrees) | ||||
|     { | ||||
|         my $rsp; | ||||
|  | ||||
|         foreach my $sn (sort(keys %sntrees)) | ||||
|         { | ||||
|             push @{$rsp->{data}}, "Service Node: $sn"; | ||||
|             foreach my $cn (sort(@{$sntrees{$sn}})) | ||||
|             { | ||||
|                 push @{$rsp->{data}}, "|__$cn"; | ||||
|             } | ||||
|             push @{$rsp->{data}},  | ||||
| "\n"; | ||||
|         } | ||||
|         xCAT::MsgUtils->message("I", $rsp, $callback);   | ||||
|     } | ||||
|  | ||||
|     # show hardware hierarchy | ||||
|     if (%hwtrees)     | ||||
|     { | ||||
|         my $rsp; | ||||
|  | ||||
|         # hmc tree output | ||||
|         foreach my $hmc (sort(keys %{$hwtrees{hmc}})) | ||||
|         { | ||||
|             push @{$rsp->{data}}, "HMC: $hmc"; | ||||
|             foreach my $frame (sort(keys %{$hwtrees{hmc}{$hmc}})) | ||||
|             { | ||||
|                 if ($frame eq '0') | ||||
|                 { | ||||
|                     # no frame | ||||
|                     push @{$rsp->{data}}, "|__Frame: n/a"; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     # get bpas for frame. | ||||
|                     my $bpas = xCAT::DBobjUtils->getchildren($frame); | ||||
|                     my $bpalist = join ',', @$bpas;  | ||||
|                     push @{$rsp->{data}}, "|__Frame: $frame $bpalist"; | ||||
|                 } | ||||
|                  | ||||
|                 foreach my $cec (sort @{$hwtrees{hmc}{$hmc}{$frame}}) | ||||
|                 { | ||||
|  | ||||
|                     # get fsps for cec. | ||||
|                     my $fsps = xCAT::DBobjUtils->getchildren($cec); | ||||
|                     my $fsplist = join ',', @$fsps;  | ||||
|                     push @{$rsp->{data}}, "   |__CEC: $cec $fsplist"; | ||||
|  | ||||
|                     if ($lparinvm) | ||||
|                     { | ||||
|                         # if show both, tailing with vmtree. | ||||
|                         if (%vmtrees) | ||||
|                         { | ||||
|                             foreach my $host (sort(keys %vmtrees)) | ||||
|                             { | ||||
|                                 if ($host =~ /$cec/) | ||||
|                                 { | ||||
|                                     foreach my $vm (sort(@{$vmtrees{$host}})) | ||||
|                                     { | ||||
|                                         push @{$rsp->{data}}, "      |__ $vm"; | ||||
|                                     } | ||||
|  | ||||
|                                     # remove it as shown | ||||
|                                     undef $vmtrees{$host}; | ||||
|                                 } | ||||
|                             } | ||||
|                         }                     | ||||
|                     } | ||||
|                     elsif ($::VMACHINE || $::SHOWALL) # temp workaround before we integrate LPARs into vm table | ||||
|                     { | ||||
|                         my %vm; | ||||
|                         # get all lpars in this cec. | ||||
|                         foreach my $ent (@entries) | ||||
|                         { | ||||
|                             if ($ent->{parent} =~ /$cec/) | ||||
|                             { | ||||
|                                 $vm{$ent->{id}} = $ent->{node}; | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         foreach my $id (sort(keys %vm)) | ||||
|                         { | ||||
|                             push @{$rsp->{data}}, "      |__LPAR $id: $vm{$id}"; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             push @{$rsp->{data}}, "\n"; | ||||
|         } | ||||
|  | ||||
|         # DFM tree output | ||||
|         foreach my $sfp (sort(keys %{$hwtrees{fsp}})) | ||||
|         { | ||||
|             if ($sfp eq '0') | ||||
|             { | ||||
|                 # no frame | ||||
|                 push @{$rsp->{data}}, "Service Focal Point: n/a"; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 push @{$rsp->{data}}, "Service Focal Point: $sfp"; | ||||
|             } | ||||
|  | ||||
|             foreach my $frame (sort(keys %{$hwtrees{fsp}{$sfp}})) | ||||
|             { | ||||
|                 if ($frame eq '0') | ||||
|                 { | ||||
|                     # no frame | ||||
|                     push @{$rsp->{data}}, "|__Frame: n/a"; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     # get bpas for frame. | ||||
|                     my $bpas = xCAT::DBobjUtils->getchildren($frame); | ||||
|                     my $bpalist = join ',', @$bpas;  | ||||
|                     push @{$rsp->{data}}, "|__Frame: $frame $bpalist"; | ||||
|                 } | ||||
|                  | ||||
|                 foreach my $cec (sort @{$hwtrees{fsp}{$sfp}{$frame}}) | ||||
|                 { | ||||
|  | ||||
|                     # get fsps for cec. | ||||
|                     my $fsps = xCAT::DBobjUtils->getchildren($cec); | ||||
|                     my $fsplist = join ',', @$fsps;  | ||||
|                     push @{$rsp->{data}}, "   |__CEC: $cec $fsplist"; | ||||
|  | ||||
|                     if ($lparinvm) | ||||
|                     { | ||||
|                         # if show both, tailing with vmtree. | ||||
|                         if (%vmtrees) | ||||
|                         { | ||||
|                             foreach my $host (sort(keys %vmtrees)) | ||||
|                             { | ||||
|                                 if ($host =~ /$cec/) | ||||
|                                 { | ||||
|                                     foreach my $vm (sort(@{$vmtrees{$host}})) | ||||
|                                     { | ||||
|                                         push @{$rsp->{data}}, "      |__ $vm"; | ||||
|                                     } | ||||
|                                     # remove it as shown | ||||
|                                     undef $vmtrees{$host};                                 | ||||
|                                 } | ||||
|                             } | ||||
|                         }                     | ||||
|                     } | ||||
|                     elsif ($::VMACHINE || $::SHOWALL) # temp workaround before we integrate LPARs into vm table | ||||
|                     { | ||||
|                         my %vm; | ||||
|                         # get all lpars in this cec. | ||||
|                         foreach my $ent (@entries) | ||||
|                         { | ||||
|                             if ($ent->{parent} =~ /$cec/) | ||||
|                             { | ||||
|                                 $vm{$ent->{id}} = $ent->{node}; | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         foreach my $id (sort(keys %vm)) | ||||
|                         { | ||||
|                             push @{$rsp->{data}}, "      |__LPAR $id: $vm{$id}"; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             push @{$rsp->{data}}, "\n"; | ||||
|         } | ||||
|  | ||||
|         # blade tree output | ||||
|         foreach my $mm (sort(keys %{$hwtrees{blade}})) | ||||
|         { | ||||
|             push @{$rsp->{data}}, "Management Module: $mm"; | ||||
|  | ||||
|             foreach my $slot (sort(keys %{$hwtrees{blade}{$mm}})) | ||||
|             { | ||||
|                 my $blade = $hwtrees{blade}{$mm}{$slot}; | ||||
|                 push @{$rsp->{data}}, "|__Blade $slot: $blade";  | ||||
|  | ||||
|                 # if show both, tailing with vmtree. | ||||
|                 if (%vmtrees) | ||||
|                 { | ||||
|                     foreach my $host (sort(keys %vmtrees)) | ||||
|                     { | ||||
|                         if ($host =~ /$blade/) | ||||
|                         { | ||||
|                             foreach my $vm (sort(@{$vmtrees{$host}})) | ||||
|                             { | ||||
|                                 push @{$rsp->{data}}, "   |__ $vm"; | ||||
|                             } | ||||
|                             # remove it as shown | ||||
|                             undef $vmtrees{$host};                             | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             push @{$rsp->{data}}, "\n"; | ||||
|         } | ||||
|  | ||||
|         # ipmi tree output | ||||
|         foreach my $bmc (sort(keys %{$hwtrees{ipmi}})) | ||||
|         { | ||||
|             push @{$rsp->{data}}, "BMC: $bmc"; | ||||
|             foreach my $svr (sort(@{$hwtrees{ipmi}{$bmc}})) | ||||
|             { | ||||
|                 push @{$rsp->{data}}, "|__Server: $svr"; | ||||
|  | ||||
|                 # if show both, tailing with vmtree. | ||||
|                 if (%vmtrees) | ||||
|                 { | ||||
|                     foreach my $host (sort(keys %vmtrees)) | ||||
|                     { | ||||
|                         if ($host =~ /$svr/) | ||||
|                         { | ||||
|                             foreach my $vm (sort(@{$vmtrees{$host}})) | ||||
|                             { | ||||
|                                 push @{$rsp->{data}}, "   |__ $vm"; | ||||
|                             } | ||||
|                             # remove it as shown | ||||
|                             undef $vmtrees{$host};                             | ||||
|                         } | ||||
|                     } | ||||
|                 }                 | ||||
|             } | ||||
|             push @{$rsp->{data}}, "\n"; | ||||
|         }         | ||||
|          | ||||
|         xCAT::MsgUtils->message("I", $rsp, $callback);                     | ||||
|     }     | ||||
|  | ||||
|     # show VM hierarchy | ||||
|     if (%vmtrees) | ||||
|     { | ||||
|         my $rsp; | ||||
|         foreach my $host (sort(keys %vmtrees)) | ||||
|         { | ||||
|             if (defined $vmtrees{$host}) | ||||
|             { | ||||
|                 push @{$rsp->{data}}, "Server: $host"; | ||||
|                 foreach my $vm (sort(@{$vmtrees{$host}})) | ||||
|                 { | ||||
|                     push @{$rsp->{data}}, "|__ $vm"; | ||||
|                 } | ||||
|             } | ||||
|             push @{$rsp->{data}}, "\n"; | ||||
|         } | ||||
|         xCAT::MsgUtils->message("I", $rsp, $callback); | ||||
|          | ||||
|     } | ||||
|      | ||||
|     return; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user