X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FCLIHandler.pm;h=516d6320bf7d2f752991fc0aa49d4a877b71b474;hp=8bab06b391f7aed139ded7e9826bea12919d69a7;hb=771d18f5c7be2055f0c9012f7f921f6d5f6337db;hpb=7fe1f565b407d8a3032a7ed0279d4c7b31aae672 diff --git a/src/PVE/CLIHandler.pm b/src/PVE/CLIHandler.pm index 8bab06b..516d632 100644 --- a/src/PVE/CLIHandler.pm +++ b/src/PVE/CLIHandler.pm @@ -34,6 +34,19 @@ my $expand_command_name = sub { return $cmd; }; +my $complete_command_names = sub { + my $res = []; + + return if ref($cmddef) ne 'HASH'; + + foreach my $cmd (keys %$cmddef) { + next if $cmd eq 'help'; + push @$res, $cmd; + } + + return $res; +}; + __PACKAGE__->register_method ({ name => 'help', path => 'help', @@ -46,6 +59,7 @@ __PACKAGE__->register_method ({ description => "Command name", type => 'string', optional => 1, + completion => $complete_command_names, }, verbose => { description => "Verbose output format.", @@ -185,9 +199,8 @@ my $print_bash_completion = sub { my $cmdline = substr($ENV{COMP_LINE}, 0, $ENV{COMP_POINT}); print STDERR "\nCMDLINE: $ENV{COMP_LINE}\n" if $debug; - # fixme: shell quoting?? - my @args = split(/\s+/, $cmdline); - my $pos = scalar(@args) - 2; + my $args = PVE::Tools::split_args($cmdline); + my $pos = scalar(@$args) - 2; $pos += 1 if $cmdline =~ m/\s+$/; print STDERR "CMDLINE:$pos:$cmdline\n" if $debug; @@ -208,7 +221,7 @@ my $print_bash_completion = sub { &$print_result(keys %$cmddef); return; } - $cmd = $args[1]; + $cmd = $args->[1]; } my $def = $cmddef->{$cmd}; @@ -238,7 +251,7 @@ my $print_bash_completion = sub { if ($d->{completion}) { my $vt = ref($d->{completion}); if ($vt eq 'CODE') { - my $res = $d->{completion}->($cmd, $pname, $cur); + my $res = $d->{completion}->($cmd, $pname, $cur, $args); &$print_result(@$res); } } elsif ($d->{type} eq 'boolean') { @@ -283,13 +296,22 @@ sub verify_api { PVE::RESTHandler::validate_method_schemas(); } +my $get_exe_name = sub { + my ($class) = @_; + + my $name = $class; + $name =~ s/^.*:://; + $name =~ s/_/-/g; + + return $name; +}; + sub generate_bash_completions { my ($class) = @_; # generate bash completion config - $exename = $class; - $exename =~ s/^.*:://; + $exename = &$get_exe_name($class); print <<__EOD__; # $exename bash completion @@ -304,17 +326,23 @@ __EOD__ } sub find_cli_class_source { - my ($exename) = @_; + my ($name) = @_; my $filename; - my $cpath = "PVE/CLI/${exename}.pm"; + $name =~ s/-/_/g; + + my $cpath = "PVE/CLI/${name}.pm"; + my $spath = "PVE/Service/${name}.pm"; foreach my $p (@INC) { - my $testfn = "$p/$cpath"; - if (-f $testfn) { - $filename = $testfn; - last; + foreach my $s (($cpath, $spath)) { + my $testfn = "$p/$s"; + if (-f $testfn) { + $filename = $testfn; + last; + } } + last if defined($filename); } return $filename; @@ -323,8 +351,7 @@ sub find_cli_class_source { sub generate_pod_manpage { my ($class, $podfn) = @_; - $exename = $class; - $exename =~ s/^.*:://; + $exename = &$get_exe_name($class); $podfn = find_cli_class_source($exename) if !defined($podfn); @@ -333,32 +360,37 @@ sub generate_pod_manpage { no strict 'refs'; my $def = ${"${class}::cmddef"}; - if (ref($def eq 'ARRAY')) { + if (ref($def) eq 'ARRAY') { print_simple_pod_manpage($podfn, @$def); } else { $cmddef = $def; + + $cmddef->{help} = [ __PACKAGE__, 'help', ['cmd'] ]; + print_pod_manpage($podfn); } } -sub run { +sub run_cli { my ($class, $pwcallback, $podfn, $preparefunc) = @_; $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; - $exename = $class; - $exename =~ s/^.*:://; + $exename = &$get_exe_name($class); initlog($exename); - die "please run as root\n" if $> != 0; - PVE::INotify::inotify_init(); + if ($class !~ m/^PVE::Service::/) { + die "please run as root\n" if $> != 0; - my $rpcenv = PVE::RPCEnvironment->init('cli'); - $rpcenv->init_request(); - $rpcenv->set_language($ENV{LANG}); - $rpcenv->set_user('root@pam'); + PVE::INotify::inotify_init(); + + my $rpcenv = PVE::RPCEnvironment->init('cli'); + $rpcenv->init_request(); + $rpcenv->set_language($ENV{LANG}); + $rpcenv->set_user('root@pam'); + } no strict 'refs'; my $def = ${"${class}::cmddef"}; @@ -389,6 +421,7 @@ sub handle_cmd { PVE::RESTHandler::validate_method_schemas(); return; } elsif ($cmd eq 'printmanpod') { + $podfn = find_cli_class_source($exename) if !defined($podfn); print_pod_manpage($podfn); return; } elsif ($cmd eq 'bashcomplete') {