mirror of https://github.com/Icinga/icinga2.git
parent
d9f5409e8b
commit
2a60ce8625
|
@ -4,6 +4,7 @@ _icinga2()
|
|||
opts="${COMP_WORDS[*]}"
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
COMPREPLY=($(icinga2 --autocomplete $COMP_CWORD ${COMP_WORDS[*]} < /dev/null))
|
||||
[[ $COMPREPLY = */ ]] && compopt -o nospace
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -5,3 +5,5 @@
|
|||
|
||||
const RunAsUser = "@ICINGA2_USER@"
|
||||
const RunAsGroup = "@ICINGA2_GROUP@"
|
||||
|
||||
library "cli"
|
||||
|
|
|
@ -48,6 +48,33 @@ SERVICE_STATUS l_SvcStatus;
|
|||
SERVICE_STATUS_HANDLE l_SvcStatusHandle;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
static std::vector<String> LogLevelCompletion(const String& arg)
|
||||
{
|
||||
std::vector<String> result;
|
||||
|
||||
String debugLevel = "debug";
|
||||
if (debugLevel.Find(arg) == 0)
|
||||
result.push_back(debugLevel);
|
||||
|
||||
String noticeLevel = "notice";
|
||||
if (noticeLevel.Find(arg) == 0)
|
||||
result.push_back(noticeLevel);
|
||||
|
||||
String informationLevel = "information";
|
||||
if (informationLevel.Find(arg) == 0)
|
||||
result.push_back(informationLevel);
|
||||
|
||||
String warningLevel = "warning";
|
||||
if (warningLevel.Find(arg) == 0)
|
||||
result.push_back(warningLevel);
|
||||
|
||||
String criticalLevel = "critical";
|
||||
if (criticalLevel.Find(arg) == 0)
|
||||
result.push_back(criticalLevel);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Main(void)
|
||||
{
|
||||
int argc = Application::GetArgC();
|
||||
|
@ -143,12 +170,16 @@ int Main(void)
|
|||
po::positional_options_description positionalDesc;
|
||||
positionalDesc.add("arg", -1);
|
||||
|
||||
ArgumentCompletionDescription argDesc;
|
||||
argDesc["include"] = BashArgumentCompletion("directory");
|
||||
argDesc["log-level"] = LogLevelCompletion;
|
||||
|
||||
String cmdname;
|
||||
CLICommand::Ptr command;
|
||||
po::variables_map vm;
|
||||
|
||||
try {
|
||||
CLICommand::ParseCommand(argc, argv, visibleDesc, hiddenDesc, positionalDesc, vm, cmdname, command, autocomplete);
|
||||
CLICommand::ParseCommand(argc, argv, visibleDesc, hiddenDesc, positionalDesc, argDesc, vm, cmdname, command, autocomplete);
|
||||
} catch (const std::exception& ex) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Error while parsing command-line options: " << ex.what();
|
||||
|
@ -349,7 +380,7 @@ int Main(void)
|
|||
int rc = 1;
|
||||
|
||||
if (autocomplete) {
|
||||
CLICommand::ShowCommands(argc, argv, &visibleDesc, &hiddenDesc, true, autoindex);
|
||||
CLICommand::ShowCommands(argc, argv, &visibleDesc, &hiddenDesc, &argDesc, true, autoindex);
|
||||
rc = 0;
|
||||
} else if (command) {
|
||||
std::vector<std::string> args;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "base/logger_fwd.hpp"
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
@ -32,6 +33,46 @@ namespace po = boost::program_options;
|
|||
boost::mutex l_RegistryMutex;
|
||||
std::map<std::vector<String>, CLICommand::Ptr> l_Registry;
|
||||
|
||||
static std::vector<String> BashArgumentCompletionHelper(const String& type, const String& arg)
|
||||
{
|
||||
std::vector<String> result;
|
||||
|
||||
#ifndef _WIN32
|
||||
String bashArg = "compgen -A " + Utility::EscapeShellArg(type) + " " + Utility::EscapeShellArg(arg);
|
||||
String cmd = "bash -c " + Utility::EscapeShellArg(bashArg);
|
||||
|
||||
FILE *fp = popen(cmd.CStr(), "r");
|
||||
|
||||
char line[4096];
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
String wline = line;
|
||||
boost::algorithm::trim_right_if(wline, boost::is_any_of("\r\n"));
|
||||
result.push_back(wline);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* Append a slash if there's only one suggestion and it's a directory */
|
||||
if ((type == "file" || type == "directory") && result.size() == 1) {
|
||||
String path = result[0];
|
||||
|
||||
struct stat statbuf;
|
||||
if (lstat(path.CStr(), &statbuf) >= 0) {
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
result.clear(),
|
||||
result.push_back(path + "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ArgumentCompletionCallback icinga::BashArgumentCompletion(const String& type)
|
||||
{
|
||||
return boost::bind(BashArgumentCompletionHelper, type, _1);
|
||||
}
|
||||
|
||||
CLICommand::Ptr CLICommand::GetByName(const std::vector<String>& name)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_RegistryMutex);
|
||||
|
@ -64,8 +105,10 @@ RegisterCLICommandHelper::RegisterCLICommandHelper(const String& name, const CLI
|
|||
}
|
||||
|
||||
bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& visibleDesc,
|
||||
po::options_description& hiddenDesc, po::positional_options_description& positionalDesc, po::variables_map& vm,
|
||||
String& cmdname, CLICommand::Ptr& command, bool autocomplete)
|
||||
po::options_description& hiddenDesc,
|
||||
po::positional_options_description& positionalDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc,
|
||||
po::variables_map& vm, String& cmdname, CLICommand::Ptr& command, bool autocomplete)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_RegistryMutex);
|
||||
|
||||
|
@ -104,7 +147,7 @@ found_command:
|
|||
po::options_description vdesc("Command options");
|
||||
|
||||
if (command)
|
||||
command->InitParameters(vdesc, hiddenDesc);
|
||||
command->InitParameters(vdesc, hiddenDesc, argCompletionDesc);
|
||||
|
||||
visibleDesc.add(vdesc);
|
||||
|
||||
|
@ -122,7 +165,8 @@ found_command:
|
|||
}
|
||||
|
||||
void CLICommand::ShowCommands(int argc, char **argv, po::options_description *visibleDesc,
|
||||
po::options_description *hiddenDesc, bool autocomplete, int autoindex)
|
||||
po::options_description *hiddenDesc, ArgumentCompletionDescription *argCompletionDesc,
|
||||
bool autocomplete, int autoindex)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_RegistryMutex);
|
||||
|
||||
|
@ -198,13 +242,47 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *vi
|
|||
}
|
||||
|
||||
if (command && autocomplete) {
|
||||
po::options_description vdesc("Command options");
|
||||
String aname, prefix, pword;
|
||||
ArgumentCompletionDescription::const_iterator it;
|
||||
const po::option_description *odesc;
|
||||
|
||||
if (autoindex - 2 >= 0 && strcmp(argv[autoindex - 1], "=") == 0 && strstr(argv[autoindex - 2], "--") == argv[autoindex - 2]) {
|
||||
aname = argv[autoindex - 2] + 2;
|
||||
pword = aword;
|
||||
} else if (autoindex - 1 >= 0 && argv[autoindex - 1][0] == '-' && argv[autoindex - 1][1] == '-') {
|
||||
aname = argv[autoindex - 1] + 2;
|
||||
pword = aword;
|
||||
|
||||
if (pword == "=")
|
||||
pword = "";
|
||||
} else if (aword.GetLength() > 1 && aword[0] == '-' && aword[1] != '-') {
|
||||
aname = aword.SubStr(1, 1);
|
||||
prefix = aword.SubStr(0, 2);
|
||||
pword = aword.SubStr(2);
|
||||
} else {
|
||||
goto complete_option;
|
||||
}
|
||||
|
||||
if (command)
|
||||
command->InitParameters(vdesc, *hiddenDesc);
|
||||
odesc = visibleDesc->find_nothrow(aname, false);
|
||||
|
||||
visibleDesc->add(vdesc);
|
||||
if (!odesc)
|
||||
return;
|
||||
|
||||
if (odesc->semantic()->min_tokens() == 0)
|
||||
goto complete_option;
|
||||
|
||||
it = argCompletionDesc->find(odesc->long_name());
|
||||
|
||||
if (it == argCompletionDesc->end())
|
||||
return;
|
||||
|
||||
BOOST_FOREACH(const String& suggestion, it->second(pword)) {
|
||||
std::cout << prefix << suggestion << "\n";
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
complete_option:
|
||||
BOOST_FOREACH(const shared_ptr<po::option_description>& odesc, visibleDesc->options()) {
|
||||
String cname = "--" + odesc->long_name();
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
typedef boost::function<std::vector<String> (const String&)> ArgumentCompletionCallback;
|
||||
typedef std::map<String, ArgumentCompletionCallback> ArgumentCompletionDescription;
|
||||
|
||||
I2_BASE_API ArgumentCompletionCallback BashArgumentCompletion(const String& type);
|
||||
|
||||
/**
|
||||
* A CLI command.
|
||||
*
|
||||
|
@ -41,7 +46,9 @@ public:
|
|||
|
||||
virtual String GetDescription(void) const = 0;
|
||||
virtual String GetShortDescription(void) const = 0;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc, boost::program_options::options_description& hiddenDesc) const = 0;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const = 0;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const = 0;
|
||||
|
||||
static CLICommand::Ptr GetByName(const std::vector<String>& name);
|
||||
|
@ -51,10 +58,15 @@ public:
|
|||
static bool ParseCommand(int argc, char **argv, boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
boost::program_options::positional_options_description& positionalDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc,
|
||||
boost::program_options::variables_map& vm, String& cmdname,
|
||||
CLICommand::Ptr& command, bool autocomplete);
|
||||
static void ShowCommands(int argc, char **argv, boost::program_options::options_description *visibleDesc = NULL,
|
||||
boost::program_options::options_description *hiddenDesc = NULL, bool autocomplete = false, int autoindex = -1);
|
||||
|
||||
static void ShowCommands(int argc, char **argv,
|
||||
boost::program_options::options_description *visibleDesc = NULL,
|
||||
boost::program_options::options_description *hiddenDesc = NULL,
|
||||
ArgumentCompletionDescription *argCompletionDesc = NULL,
|
||||
bool autocomplete = false, int autoindex = -1);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -276,7 +276,8 @@ String DaemonCommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void DaemonCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
visibleDesc.add_options()
|
||||
("config,c", po::value<std::vector<std::string> >(), "parse a configuration file")
|
||||
|
@ -292,6 +293,9 @@ void DaemonCommand::InitParameters(boost::program_options::options_description&
|
|||
hiddenDesc.add_options()
|
||||
("reload-internal", po::value<int>(), "used internally to implement config reload: do not call manually, send SIGHUP instead");
|
||||
#endif /* _WIN32 */
|
||||
|
||||
argCompletionDesc["config"] = BashArgumentCompletion("file");
|
||||
argCompletionDesc["errorlog"] = BashArgumentCompletion("file");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,7 +40,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ String FeatureDisableCommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void FeatureDisableCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
/* Command doesn't support any parameters. */
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
|
|
@ -45,7 +45,8 @@ String FeatureEnableCommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void FeatureEnableCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
/* Command doesn't support any parameters. */
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
|
|
@ -45,7 +45,8 @@ String FeatureListCommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void FeatureListCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
/* Command doesn't support any parameters. */
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -39,7 +39,8 @@ String PKINewCACommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void PKINewCACommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
/* Command doesn't support any parameters. */
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
|
|
@ -38,7 +38,8 @@ String PKINewCertCommand::GetShortDescription(void) const
|
|||
}
|
||||
|
||||
void PKINewCertCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const
|
||||
{
|
||||
visibleDesc.add_options()
|
||||
("cn", po::value<std::string>(), "Common Name")
|
||||
|
|
|
@ -39,7 +39,8 @@ public:
|
|||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
ArgumentCompletionDescription& argCompletionDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue